Documentation
¶
Index ¶
Constants ¶
View Source
const ( // Default config file paths DefaultConfigPathYML = ".config/binstaller.yml" DefaultConfigPathYAML = ".config/binstaller.yaml" )
Variables ¶
View Source
var EmbedChecksumsCommand = &cobra.Command{ Use: "embed-checksums", Short: "Embed checksums for release assets into a binstaller configuration", Long: `Reads an InstallSpec configuration file and embeds checksums for the assets. This command supports three modes of operation: - download: Fetches the checksum file from GitHub releases - checksum-file: Uses a local checksum file - calculate: Downloads the assets and calculates checksums directly`, RunE: func(cmd *cobra.Command, args []string) error { log.Info("Running embed-checksums command...") cfgFile, err := resolveConfigFile(configFile) if err != nil { log.WithError(err).Error("Config file detection failed") return err } if configFile == "" { log.Infof("Using default config file: %s", cfgFile) } log.Debugf("Using config file: %s", cfgFile) log.Debugf("Reading InstallSpec from: %s", cfgFile) ast, err := parser.ParseFile(cfgFile, parser.ParseComments) if err != nil { return err } yamlData, err := os.ReadFile(cfgFile) if err != nil { log.WithError(err).Errorf("Failed to read install spec file: %s", cfgFile) return fmt.Errorf("failed to read install spec file %s: %w", cfgFile, err) } log.Debug("Unmarshalling InstallSpec YAML") var installSpec spec.InstallSpec err = yaml.UnmarshalWithOptions(yamlData, &installSpec, yaml.UseOrderedMap()) if err != nil { log.WithError(err).Errorf("Failed to unmarshal install spec YAML from: %s", cfgFile) return fmt.Errorf("failed to unmarshal install spec YAML from %s: %w", cfgFile, err) } // Create the embedder var mode checksums.EmbedMode switch embedMode { case "download": mode = checksums.EmbedModeDownload case "checksum-file": mode = checksums.EmbedModeChecksumFile case "calculate": mode = checksums.EmbedModeCalculate default: return fmt.Errorf("invalid mode: %s. Must be one of: download, checksum-file, calculate", embedMode) } if mode == checksums.EmbedModeChecksumFile && embedFile == "" { log.Error("--file flag is required for checksum-file mode") return fmt.Errorf("--file flag is required for checksum-file mode") } embedder := &checksums.Embedder{ Mode: mode, Version: embedVersion, Spec: &installSpec, SpecAST: ast, ChecksumFile: embedFile, } log.Infof("Embedding checksums using %s mode for version: %s", mode, embedVersion) if err := embedder.Embed(); err != nil { log.WithError(err).Error("Failed to embed checksums") return fmt.Errorf("failed to embed checksums: %w", err) } outputFile := embedOutput if outputFile == "" { outputFile = cfgFile log.Infof("No output specified, overwriting input file: %s", outputFile) } log.Infof("Writing updated InstallSpec to file: %s", outputFile) outputDir := filepath.Dir(outputFile) if err := os.MkdirAll(outputDir, 0755); err != nil { log.WithError(err).Errorf("Failed to create output directory: %s", outputDir) return fmt.Errorf("failed to create output directory %s: %w", outputDir, err) } if err := os.WriteFile(outputFile, []byte(ast.String()), 0644); err != nil { log.WithError(err).Errorf("Failed to write InstallSpec to file: %s", outputFile) return fmt.Errorf("failed to write InstallSpec to file %s: %w", outputFile, err) } log.Infof("InstallSpec successfully updated with embedded checksums") return nil }, }
EmbedChecksumsCommand represents the embed-checksums command
View Source
var GenCommand = &cobra.Command{ Use: "gen", Short: "Generate an installer script from an InstallSpec config file", Long: `Reads an InstallSpec configuration file (e.g., .binstaller.yml) and generates a POSIX-compatible shell installer script.`, RunE: func(cmd *cobra.Command, args []string) error { log.Info("Running gen command...") cfgFile, err := resolveConfigFile(configFile) if err != nil { log.WithError(err).Error("Config file detection failed") return err } if configFile == "" { log.Infof("Using default config file: %s", cfgFile) } log.Debugf("Using config file: %s", cfgFile) log.Debugf("Reading InstallSpec from: %s", cfgFile) var yamlData []byte if cfgFile == "-" { log.Debug("Reading install spec from stdin") yamlData, err = io.ReadAll(os.Stdin) if err != nil { log.WithError(err).Error("Failed to read install spec from stdin") return fmt.Errorf("failed to read install spec from stdin: %w", err) } } else { yamlData, err = os.ReadFile(cfgFile) if err != nil { log.WithError(err).Errorf("Failed to read install spec file: %s", cfgFile) return fmt.Errorf("failed to read install spec file %s: %w", cfgFile, err) } } log.Debug("Unmarshalling InstallSpec YAML") var installSpec spec.InstallSpec err = yaml.Unmarshal(yamlData, &installSpec) if err != nil { log.WithError(err).Errorf("Failed to unmarshal install spec YAML from: %s", cfgFile) return fmt.Errorf("failed to unmarshal install spec YAML from %s: %w", cfgFile, err) } log.Info("Generating installer script...") scriptBytes, err := shell.GenerateWithVersion(&installSpec, genTargetVersion) if err != nil { log.WithError(err).Error("Failed to generate installer script") return fmt.Errorf("failed to generate installer script: %w", err) } log.Debug("Installer script generated successfully") if genOutputFile == "" || genOutputFile == "-" { log.Debug("Writing installer script to stdout") fmt.Print(string(scriptBytes)) log.Info("Installer script written to stdout") } else { log.Infof("Writing installer script to file: %s", genOutputFile) outputDir := filepath.Dir(genOutputFile) if err := os.MkdirAll(outputDir, 0755); err != nil { log.WithError(err).Errorf("Failed to create output directory: %s", outputDir) return fmt.Errorf("failed to create output directory %s: %w", outputDir, err) } err = os.WriteFile(genOutputFile, scriptBytes, 0755) if err != nil { log.WithError(err).Errorf("Failed to write installer script to file: %s", genOutputFile) return fmt.Errorf("failed to write installer script to file %s: %w", genOutputFile, err) } log.Infof("Installer script successfully written to %s", genOutputFile) } return nil }, }
GenCommand represents the gen command
View Source
var InitCommand = &cobra.Command{ Use: "init", Short: "Generate an InstallSpec config file from various sources", Long: `Initializes a binstaller configuration file (.config/binstaller.yml) by detecting settings from a source like a GoReleaser config file or a GitHub repository.`, RunE: func(cmd *cobra.Command, args []string) error { log.Infof("Running init command...") var adapter datasource.SourceAdapter switch initSource { case "goreleaser": adapter = datasource.NewGoReleaserAdapter( initRepo, initSourceFile, initCommitSHA, initName, ) case "github": adapter = datasource.NewGitHubAdapter(initRepo) case "aqua": switch initSourceFile { case "": if initRepo == "" { return fmt.Errorf("--repo is required for aqua source when --file is not specified") } adapter = datasource.NewAquaRegistryAdapterFromRepo(initRepo, initCommitSHA) case "-": adapter = datasource.NewAquaRegistryAdapterFromReader(os.Stdin) default: f, err := os.Open(initSourceFile) if err != nil { return fmt.Errorf("failed to open aqua registry file: %w", err) } defer f.Close() adapter = datasource.NewAquaRegistryAdapterFromReader(f) } default: err := fmt.Errorf("unknown source specified: %s. Valid sources are: goreleaser, github, aqua", initSource) log.WithError(err).Error("invalid source") return err } ctx := context.Background() log.Infof("Generating InstallSpec using source: %s", initSource) installSpec, err := adapter.GenerateInstallSpec(ctx) if err != nil { log.WithError(err).Error("Failed to detect install spec") return fmt.Errorf("failed to detect install spec: %w", err) } if spec.StringValue(installSpec.Schema) == "" { installSpec.Schema = spec.StringPtr("v1") } log.Info("Successfully detected InstallSpec") log.Debug("Marshalling InstallSpec to YAML") yamlData, err := yaml.Marshal(installSpec) if err != nil { log.WithError(err).Error("Failed to marshal InstallSpec to YAML") return fmt.Errorf("failed to marshal install spec to YAML: %w", err) } schemaComment := "# yaml-language-server: $schema=https://raw.githubusercontent.com/binary-install/binstaller/main/schema/output/@typespec/json-schema/InstallSpec.json\n" yamlData = append([]byte(schemaComment), yamlData...) if initOutputFile == "" || initOutputFile == "-" { log.Debug("Writing InstallSpec YAML to stdout") fmt.Println(string(yamlData)) log.Info("InstallSpec YAML written to stdout") } else { log.Infof("Writing InstallSpec YAML to file: %s", initOutputFile) outputDir := filepath.Dir(initOutputFile) if err := os.MkdirAll(outputDir, 0755); err != nil { log.WithError(err).Errorf("Failed to create output directory: %s", outputDir) return fmt.Errorf("failed to create output directory %s: %w", outputDir, err) } err = os.WriteFile(initOutputFile, yamlData, 0644) if err != nil { log.WithError(err).Errorf("Failed to write InstallSpec to file: %s", initOutputFile) return fmt.Errorf("failed to write install spec to file %s: %w", initOutputFile, err) } log.Infof("InstallSpec successfully written to %s", initOutputFile) } return nil }, }
InitCommand represents the init command
View Source
var RootCmd = &cobra.Command{ Use: "binst", Short: "binst installs binaries from various sources using a spec file.", Long: `binstaller (binst) is a tool to generate installer scripts or directly install binaries based on an InstallSpec configuration file. It supports generating the spec from sources like GoReleaser config or GitHub releases.`, PersistentPreRun: func(cmd *cobra.Command, args []string) { log.SetHandler(cli.Default) if verbose { log.SetLevel(log.DebugLevel) log.Debugf("Verbose logging enabled") } else if quiet { log.SetLevel(log.ErrorLevel) } else { log.SetLevel(log.InfoLevel) } log.Debugf("Config file: %s", configFile) }, }
RootCmd represents the base command when called without any subcommands
Functions ¶
Types ¶
This section is empty.
Click to show internal directories.
Click to hide internal directories.