package cli import ( "context" "fmt" "io" "strings" "gitea.maximumdirect.net/eric/distributor/internal/app" ) func manifestCommand(ctx context.Context, args []string, stdout, stderr io.Writer) int { if len(args) == 0 || args[0] == "-h" || args[0] == "--help" || args[0] == "help" { printManifestHelp(stdout) return exitOK } switch args[0] { case "create": return manifestCreateCommand(ctx, args[1:], stdout, stderr) default: fmt.Fprintf(stderr, "%s: manifest unknown command %q\n\n", app.Name, args[0]) printManifestHelp(stderr) return exitUsage } } func manifestCreateCommand(ctx context.Context, args []string, stdout, stderr io.Writer) int { if hasHelp(args) { printManifestCreateHelp(stdout) return exitOK } flags := newFlagSet("manifest create", stderr) id := flags.String("id", "", "source bundle id") created := flags.String("created", "", "source created timestamp") overwrite := flags.Bool("overwrite", false, "replace an existing manifest.json") formatFlag := addFormatFlag(flags) var files repeatedFlag flags.Var(&files, "file", "bundle-relative file to include") flagArgs, positionalArgs, ok := splitManifestCreateArgs(stderr, args) if !ok { return exitUsage } if err := flags.Parse(flagArgs); err != nil { return exitUsage } if len(positionalArgs) != 1 { fmt.Fprintf(stderr, "%s: manifest create requires exactly one bundle path\n", app.Name) return exitUsage } format, ok := parseOutputFormat(stderr, "manifest create", *formatFlag) if !ok { return exitUsage } err := app.ManifestCreate(ctx, app.ManifestCreateOptions{ Root: positionalArgs[0], ID: *id, Created: *created, Files: []string(files), Overwrite: *overwrite, Stdout: stdout, OutputFormat: format, }) if err != nil { return fail(stderr, err) } return exitOK } func splitManifestCreateArgs(stderr io.Writer, args []string) ([]string, []string, bool) { var flagArgs []string var positionalArgs []string for index := 0; index < len(args); index++ { arg := args[index] switch arg { case "--overwrite": flagArgs = append(flagArgs, arg) case "--id", "--created", "--file", "--format": if index+1 >= len(args) { fmt.Fprintf(stderr, "%s: manifest create %s requires a value\n", app.Name, arg) return nil, nil, false } flagArgs = append(flagArgs, arg, args[index+1]) index++ default: if strings.HasPrefix(arg, "--id=") || strings.HasPrefix(arg, "--created=") || strings.HasPrefix(arg, "--file=") || strings.HasPrefix(arg, "--format=") { flagArgs = append(flagArgs, arg) continue } if strings.HasPrefix(arg, "-") { flagArgs = append(flagArgs, arg) continue } positionalArgs = append(positionalArgs, arg) } } return flagArgs, positionalArgs, true } type repeatedFlag []string func (f *repeatedFlag) String() string { return fmt.Sprint([]string(*f)) } func (f *repeatedFlag) Set(value string) error { *f = append(*f, value) return nil } func printManifestHelp(w io.Writer) { fmt.Fprint(w, `Usage: distributor manifest [options] Commands: create Create a source bundle manifest Use "distributor manifest --help" for command-specific help. `) } func printManifestCreateHelp(w io.Writer) { fmt.Fprint(w, `Usage: distributor manifest create --id [options] Options: --id Source bundle id --file Bundle-relative file to include; repeatable --created