forked from toolshed/abra
		
	refactor: urfave v3
This commit is contained in:
		| @ -1,15 +1,15 @@ | |||||||
| package app | package app | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"github.com/urfave/cli/v2" | 	"github.com/urfave/cli/v3" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| var AppCommand = cli.Command{ | var AppCommand = cli.Command{ | ||||||
| 	Name:            "app", | 	Name:            "app", | ||||||
| 	Aliases:         []string{"a"}, | 	Aliases:         []string{"a"}, | ||||||
| 	Usage:           "Manage apps", | 	Usage:           "Manage apps", | ||||||
| 	ArgsUsage: "<domain>", | 	UsageText:       "abra app [command] [options] [arguments]", | ||||||
| 	Subcommands: []*cli.Command{ | 	Commands: []*cli.Command{ | ||||||
| 		&appBackupCommand, | 		&appBackupCommand, | ||||||
| 		&appCheckCommand, | 		&appCheckCommand, | ||||||
| 		&appCmdCommand, | 		&appCmdCommand, | ||||||
|  | |||||||
| @ -1,13 +1,14 @@ | |||||||
| package app | package app | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
|  | 	"context" | ||||||
| 	"fmt" | 	"fmt" | ||||||
|  |  | ||||||
| 	"coopcloud.tech/abra/cli/internal" | 	"coopcloud.tech/abra/cli/internal" | ||||||
| 	"coopcloud.tech/abra/pkg/autocomplete" | 	"coopcloud.tech/abra/pkg/autocomplete" | ||||||
| 	"coopcloud.tech/abra/pkg/client" | 	"coopcloud.tech/abra/pkg/client" | ||||||
| 	"coopcloud.tech/abra/pkg/log" | 	"coopcloud.tech/abra/pkg/log" | ||||||
| 	"github.com/urfave/cli/v2" | 	"github.com/urfave/cli/v3" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| var snapshot string | var snapshot string | ||||||
| @ -38,16 +39,16 @@ var appBackupListCommand = cli.Command{ | |||||||
| 	Name:    "list", | 	Name:    "list", | ||||||
| 	Aliases: []string{"ls"}, | 	Aliases: []string{"ls"}, | ||||||
| 	Flags: []cli.Flag{ | 	Flags: []cli.Flag{ | ||||||
| 		internal.DebugFlag, |  | ||||||
| 		internal.OfflineFlag, |  | ||||||
| 		snapshotFlag, | 		snapshotFlag, | ||||||
| 		includePathFlag, | 		includePathFlag, | ||||||
| 	}, | 	}, | ||||||
| 	Before:        internal.SubCommandBefore, | 	Before:        internal.SubCommandBefore, | ||||||
| 	Usage:         "List all backups", | 	Usage:         "List all backups", | ||||||
| 	BashComplete: autocomplete.AppNameComplete, | 	UsageText:     "abra app backup list <domain> [options]", | ||||||
| 	Action: func(c *cli.Context) error { | 	ShellComplete: autocomplete.AppNameComplete, | ||||||
| 		app := internal.ValidateApp(c) | 	HideHelp:      true, | ||||||
|  | 	Action: func(ctx context.Context, cmd *cli.Command) error { | ||||||
|  | 		app := internal.ValidateApp(cmd) | ||||||
|  |  | ||||||
| 		if err := app.Recipe.Ensure(internal.Chaos, internal.Offline); err != nil { | 		if err := app.Recipe.Ensure(internal.Chaos, internal.Offline); err != nil { | ||||||
| 			log.Fatal(err) | 			log.Fatal(err) | ||||||
| @ -85,16 +86,16 @@ var appBackupDownloadCommand = cli.Command{ | |||||||
| 	Name:    "download", | 	Name:    "download", | ||||||
| 	Aliases: []string{"d"}, | 	Aliases: []string{"d"}, | ||||||
| 	Flags: []cli.Flag{ | 	Flags: []cli.Flag{ | ||||||
| 		internal.DebugFlag, |  | ||||||
| 		internal.OfflineFlag, |  | ||||||
| 		snapshotFlag, | 		snapshotFlag, | ||||||
| 		includePathFlag, | 		includePathFlag, | ||||||
| 	}, | 	}, | ||||||
| 	Before:        internal.SubCommandBefore, | 	Before:        internal.SubCommandBefore, | ||||||
| 	Usage:         "Download a backup", | 	Usage:         "Download a backup", | ||||||
| 	BashComplete: autocomplete.AppNameComplete, | 	UsageText:     "abra app backup download <domain> [options]", | ||||||
| 	Action: func(c *cli.Context) error { | 	ShellComplete: autocomplete.AppNameComplete, | ||||||
| 		app := internal.ValidateApp(c) | 	HideHelp:      true, | ||||||
|  | 	Action: func(ctx context.Context, cmd *cli.Command) error { | ||||||
|  | 		app := internal.ValidateApp(cmd) | ||||||
|  |  | ||||||
| 		if err := app.Recipe.EnsureExists(); err != nil { | 		if err := app.Recipe.EnsureExists(); err != nil { | ||||||
| 			log.Fatal(err) | 			log.Fatal(err) | ||||||
| @ -156,15 +157,15 @@ var appBackupCreateCommand = cli.Command{ | |||||||
| 	Name:    "create", | 	Name:    "create", | ||||||
| 	Aliases: []string{"c"}, | 	Aliases: []string{"c"}, | ||||||
| 	Flags: []cli.Flag{ | 	Flags: []cli.Flag{ | ||||||
| 		internal.DebugFlag, |  | ||||||
| 		internal.OfflineFlag, |  | ||||||
| 		resticRepoFlag, | 		resticRepoFlag, | ||||||
| 	}, | 	}, | ||||||
| 	Before:        internal.SubCommandBefore, | 	Before:        internal.SubCommandBefore, | ||||||
| 	Usage:         "Create a new backup", | 	Usage:         "Create a new backup", | ||||||
| 	BashComplete: autocomplete.AppNameComplete, | 	UsageText:     "abra app backup create <domain> [options]", | ||||||
| 	Action: func(c *cli.Context) error { | 	ShellComplete: autocomplete.AppNameComplete, | ||||||
| 		app := internal.ValidateApp(c) | 	HideHelp:      true, | ||||||
|  | 	Action: func(ctx context.Context, cmd *cli.Command) error { | ||||||
|  | 		app := internal.ValidateApp(cmd) | ||||||
|  |  | ||||||
| 		if err := app.Recipe.EnsureExists(); err != nil { | 		if err := app.Recipe.EnsureExists(); err != nil { | ||||||
| 			log.Fatal(err) | 			log.Fatal(err) | ||||||
| @ -214,15 +215,15 @@ var appBackupSnapshotsCommand = cli.Command{ | |||||||
| 	Name:    "snapshots", | 	Name:    "snapshots", | ||||||
| 	Aliases: []string{"s"}, | 	Aliases: []string{"s"}, | ||||||
| 	Flags: []cli.Flag{ | 	Flags: []cli.Flag{ | ||||||
| 		internal.DebugFlag, |  | ||||||
| 		internal.OfflineFlag, |  | ||||||
| 		snapshotFlag, | 		snapshotFlag, | ||||||
| 	}, | 	}, | ||||||
| 	Before:        internal.SubCommandBefore, | 	Before:        internal.SubCommandBefore, | ||||||
| 	Usage:         "List backup snapshots", | 	Usage:         "List backup snapshots", | ||||||
| 	BashComplete: autocomplete.AppNameComplete, | 	UsageText:     "abra app backup snapshots <domain> [options]", | ||||||
| 	Action: func(c *cli.Context) error { | 	ShellComplete: autocomplete.AppNameComplete, | ||||||
| 		app := internal.ValidateApp(c) | 	HideHelp:      true, | ||||||
|  | 	Action: func(ctx context.Context, cmd *cli.Command) error { | ||||||
|  | 		app := internal.ValidateApp(cmd) | ||||||
|  |  | ||||||
| 		if err := app.Recipe.EnsureExists(); err != nil { | 		if err := app.Recipe.EnsureExists(); err != nil { | ||||||
| 			log.Fatal(err) | 			log.Fatal(err) | ||||||
| @ -272,8 +273,8 @@ var appBackupCommand = cli.Command{ | |||||||
| 	Name:      "backup", | 	Name:      "backup", | ||||||
| 	Aliases:   []string{"b"}, | 	Aliases:   []string{"b"}, | ||||||
| 	Usage:     "Manage app backups", | 	Usage:     "Manage app backups", | ||||||
| 	ArgsUsage: "<domain>", | 	UsageText: "abra app backup [command] [arguments] [options]", | ||||||
| 	Subcommands: []*cli.Command{ | 	Commands: []*cli.Command{ | ||||||
| 		&appBackupListCommand, | 		&appBackupListCommand, | ||||||
| 		&appBackupSnapshotsCommand, | 		&appBackupSnapshotsCommand, | ||||||
| 		&appBackupDownloadCommand, | 		&appBackupDownloadCommand, | ||||||
|  | |||||||
| @ -1,6 +1,7 @@ | |||||||
| package app | package app | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
|  | 	"context" | ||||||
| 	"fmt" | 	"fmt" | ||||||
|  |  | ||||||
| 	"coopcloud.tech/abra/cli/internal" | 	"coopcloud.tech/abra/cli/internal" | ||||||
| @ -9,16 +10,15 @@ import ( | |||||||
| 	"coopcloud.tech/abra/pkg/formatter" | 	"coopcloud.tech/abra/pkg/formatter" | ||||||
| 	"coopcloud.tech/abra/pkg/log" | 	"coopcloud.tech/abra/pkg/log" | ||||||
| 	"github.com/charmbracelet/lipgloss" | 	"github.com/charmbracelet/lipgloss" | ||||||
| 	"github.com/urfave/cli/v2" | 	"github.com/urfave/cli/v3" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| var appCheckCommand = cli.Command{ | var appCheckCommand = cli.Command{ | ||||||
| 	Name:      "check", | 	Name:      "check", | ||||||
| 	Aliases:   []string{"chk"}, | 	Aliases:   []string{"chk"}, | ||||||
|  | 	UsageText: "abra app check <domain> [options]", | ||||||
| 	Usage:     "Ensure an app is well configured", | 	Usage:     "Ensure an app is well configured", | ||||||
| 	Description: ` | 	Description: `Compare env vars in both the app ".env" and recipe ".env.sample" file. | ||||||
| This command compares env vars in both the app ".env" and recipe ".env.sample" |  | ||||||
| file. |  | ||||||
|  |  | ||||||
| The goal is to ensure that recipe ".env.sample" env vars are defined in your | The goal is to ensure that recipe ".env.sample" env vars are defined in your | ||||||
| app ".env" file. Only env var definitions in the ".env.sample" which are | app ".env" file. Only env var definitions in the ".env.sample" which are | ||||||
| @ -28,16 +28,15 @@ these env vars, then "check" will complain. | |||||||
| Recipe maintainers may or may not provide defaults for env vars within their | Recipe maintainers may or may not provide defaults for env vars within their | ||||||
| recipes regardless of commenting or not (e.g. through the use of | recipes regardless of commenting or not (e.g. through the use of | ||||||
| ${FOO:<default>} syntax). "check" does not confirm or deny this for you.`, | ${FOO:<default>} syntax). "check" does not confirm or deny this for you.`, | ||||||
| 	ArgsUsage: "<domain>", |  | ||||||
| 	Flags: []cli.Flag{ | 	Flags: []cli.Flag{ | ||||||
| 		internal.DebugFlag, |  | ||||||
| 		internal.ChaosFlag, | 		internal.ChaosFlag, | ||||||
| 		internal.OfflineFlag, | 		internal.OfflineFlag, | ||||||
| 	}, | 	}, | ||||||
| 	Before:        internal.SubCommandBefore, | 	Before:        internal.SubCommandBefore, | ||||||
| 	BashComplete: autocomplete.AppNameComplete, | 	ShellComplete: autocomplete.AppNameComplete, | ||||||
| 	Action: func(c *cli.Context) error { | 	HideHelp:      true, | ||||||
| 		app := internal.ValidateApp(c) | 	Action: func(ctx context.Context, cmd *cli.Command) error { | ||||||
|  | 		app := internal.ValidateApp(cmd) | ||||||
|  |  | ||||||
| 		if err := app.Recipe.Ensure(internal.Chaos, internal.Offline); err != nil { | 		if err := app.Recipe.Ensure(internal.Chaos, internal.Offline); err != nil { | ||||||
| 			log.Fatal(err) | 			log.Fatal(err) | ||||||
|  | |||||||
| @ -1,6 +1,7 @@ | |||||||
| package app | package app | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
|  | 	"context" | ||||||
| 	"errors" | 	"errors" | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"os" | 	"os" | ||||||
| @ -14,61 +15,53 @@ import ( | |||||||
| 	"coopcloud.tech/abra/pkg/autocomplete" | 	"coopcloud.tech/abra/pkg/autocomplete" | ||||||
| 	"coopcloud.tech/abra/pkg/client" | 	"coopcloud.tech/abra/pkg/client" | ||||||
| 	"coopcloud.tech/abra/pkg/log" | 	"coopcloud.tech/abra/pkg/log" | ||||||
| 	"github.com/urfave/cli/v2" | 	"coopcloud.tech/abra/pkg/recipe" | ||||||
|  | 	"github.com/urfave/cli/v3" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| var appCmdCommand = cli.Command{ | var appCmdCommand = cli.Command{ | ||||||
| 	Name:      "command", | 	Name:      "command", | ||||||
| 	Aliases:   []string{"cmd"}, | 	Aliases:   []string{"cmd"}, | ||||||
| 	Usage:     "Run app commands", | 	Usage:     "Run app commands", | ||||||
|  | 	UsageText: "abra app cmd <domain> [<service>] <cmd> [<cmd-args>] [options]", | ||||||
| 	Description: `Run an app specific command. | 	Description: `Run an app specific command. | ||||||
|  |  | ||||||
| These commands are bash functions, defined in the abra.sh of the recipe itself. | These commands are bash functions, defined in the abra.sh of the recipe itself. | ||||||
| They can be run within the context of a service (e.g. app) or locally on your | They can be run within the context of a service (e.g. app) or locally on your | ||||||
| work station by passing "--local". Arguments can be passed into these functions | work station by passing "--local".`, | ||||||
| using the "-- <args>" syntax. |  | ||||||
|  |  | ||||||
| **WARNING**: options must be passed directly after the sub-command "cmd". |  | ||||||
|  |  | ||||||
| EXAMPLE: |  | ||||||
|  |  | ||||||
|   abra app cmd --local example.com app create_user -- me@example.com`, |  | ||||||
| 	ArgsUsage: "<domain> [<service>] <command> [-- <args>]", |  | ||||||
| 	Flags: []cli.Flag{ | 	Flags: []cli.Flag{ | ||||||
| 		internal.DebugFlag, |  | ||||||
| 		internal.LocalCmdFlag, | 		internal.LocalCmdFlag, | ||||||
| 		internal.RemoteUserFlag, | 		internal.RemoteUserFlag, | ||||||
| 		internal.TtyFlag, | 		internal.TtyFlag, | ||||||
| 		internal.OfflineFlag, |  | ||||||
| 		internal.ChaosFlag, | 		internal.ChaosFlag, | ||||||
| 	}, | 	}, | ||||||
| 	Before: internal.SubCommandBefore, | 	Before: internal.SubCommandBefore, | ||||||
| 	Subcommands: []*cli.Command{ | 	Commands: []*cli.Command{ | ||||||
| 		&appCmdListCommand, | 		&appCmdListCommand, | ||||||
| 	}, | 	}, | ||||||
| 	BashComplete: func(ctx *cli.Context) { | 	ShellComplete: func(ctx context.Context, cmd *cli.Command) { | ||||||
| 		args := ctx.Args() | 		args := cmd.Args() | ||||||
| 		switch args.Len() { | 		switch args.Len() { | ||||||
| 		case 0: | 		case 0: | ||||||
| 			autocomplete.AppNameComplete(ctx) | 			autocomplete.AppNameComplete(ctx, cmd) | ||||||
| 		case 1: | 		case 1: | ||||||
| 			autocomplete.ServiceNameComplete(args.Get(0)) | 			autocomplete.ServiceNameComplete(args.Get(0)) | ||||||
| 		case 2: | 		case 2: | ||||||
| 			cmdNameComplete(args.Get(0)) | 			cmdNameComplete(args.Get(0)) | ||||||
| 		} | 		} | ||||||
| 	}, | 	}, | ||||||
| 	Action: func(c *cli.Context) error { | 	Action: func(ctx context.Context, cmd *cli.Command) error { | ||||||
| 		app := internal.ValidateApp(c) | 		app := internal.ValidateApp(cmd) | ||||||
|  |  | ||||||
| 		if err := app.Recipe.Ensure(internal.Chaos, internal.Offline); err != nil { | 		if err := app.Recipe.Ensure(internal.Chaos, internal.Offline); err != nil { | ||||||
| 			log.Fatal(err) | 			log.Fatal(err) | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if internal.LocalCmd && internal.RemoteUser != "" { | 		if internal.LocalCmd && internal.RemoteUser != "" { | ||||||
| 			internal.ShowSubcommandHelpAndError(c, errors.New("cannot use --local & --user together")) | 			internal.ShowSubcommandHelpAndError(cmd, errors.New("cannot use --local & --user together")) | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		hasCmdArgs, parsedCmdArgs := parseCmdArgs(c.Args().Slice(), internal.LocalCmd) | 		hasCmdArgs, parsedCmdArgs := parseCmdArgs(cmd.Args().Slice(), internal.LocalCmd) | ||||||
|  |  | ||||||
| 		if _, err := os.Stat(app.Recipe.AbraShPath); err != nil { | 		if _, err := os.Stat(app.Recipe.AbraShPath); err != nil { | ||||||
| 			if os.IsNotExist(err) { | 			if os.IsNotExist(err) { | ||||||
| @ -78,11 +71,11 @@ EXAMPLE: | |||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if internal.LocalCmd { | 		if internal.LocalCmd { | ||||||
| 			if !(c.Args().Len() >= 2) { | 			if !(cmd.Args().Len() >= 2) { | ||||||
| 				internal.ShowSubcommandHelpAndError(c, errors.New("missing arguments")) | 				internal.ShowSubcommandHelpAndError(cmd, errors.New("missing arguments")) | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			cmdName := c.Args().Get(1) | 			cmdName := cmd.Args().Get(1) | ||||||
| 			if err := internal.EnsureCommand(app.Recipe.AbraShPath, app.Recipe.Name, cmdName); err != nil { | 			if err := internal.EnsureCommand(app.Recipe.AbraShPath, app.Recipe.Name, cmdName); err != nil { | ||||||
| 				log.Fatal(err) | 				log.Fatal(err) | ||||||
| 			} | 			} | ||||||
| @ -114,13 +107,13 @@ EXAMPLE: | |||||||
| 				log.Fatal(err) | 				log.Fatal(err) | ||||||
| 			} | 			} | ||||||
| 		} else { | 		} else { | ||||||
| 			if !(c.Args().Len() >= 3) { | 			if !(cmd.Args().Len() >= 3) { | ||||||
| 				internal.ShowSubcommandHelpAndError(c, errors.New("missing arguments")) | 				internal.ShowSubcommandHelpAndError(cmd, errors.New("missing arguments")) | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			targetServiceName := c.Args().Get(1) | 			targetServiceName := cmd.Args().Get(1) | ||||||
|  |  | ||||||
| 			cmdName := c.Args().Get(2) | 			cmdName := cmd.Args().Get(2) | ||||||
| 			if err := internal.EnsureCommand(app.Recipe.AbraShPath, app.Recipe.Name, cmdName); err != nil { | 			if err := internal.EnsureCommand(app.Recipe.AbraShPath, app.Recipe.Name, cmdName); err != nil { | ||||||
| 				log.Fatal(err) | 				log.Fatal(err) | ||||||
| 			} | 			} | ||||||
| @ -200,16 +193,16 @@ var appCmdListCommand = cli.Command{ | |||||||
| 	Name:      "list", | 	Name:      "list", | ||||||
| 	Aliases:   []string{"ls"}, | 	Aliases:   []string{"ls"}, | ||||||
| 	Usage:     "List all available commands", | 	Usage:     "List all available commands", | ||||||
| 	ArgsUsage: "<domain>", | 	UsageText: "abra app cmd ls <domain> [options]", | ||||||
| 	Flags: []cli.Flag{ | 	Flags: []cli.Flag{ | ||||||
| 		internal.DebugFlag, |  | ||||||
| 		internal.OfflineFlag, |  | ||||||
| 		internal.ChaosFlag, | 		internal.ChaosFlag, | ||||||
| 	}, | 	}, | ||||||
| 	BashComplete: autocomplete.AppNameComplete, | 	ShellComplete: autocomplete.AppNameComplete, | ||||||
| 	Before:        internal.SubCommandBefore, | 	Before:        internal.SubCommandBefore, | ||||||
| 	Action: func(c *cli.Context) error { | 	HideHelp:      true, | ||||||
| 		app := internal.ValidateApp(c) | 	Action: func(ctx context.Context, cmd *cli.Command) error { | ||||||
|  | 		app := internal.ValidateApp(cmd) | ||||||
|  | 		r := recipe.Get(app.Recipe.Name) | ||||||
|  |  | ||||||
| 		if err := app.Recipe.EnsureExists(); err != nil { | 		if err := app.Recipe.EnsureExists(); err != nil { | ||||||
| 			log.Fatal(err) | 			log.Fatal(err) | ||||||
|  | |||||||
| @ -1,6 +1,7 @@ | |||||||
| package app | package app | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
|  | 	"context" | ||||||
| 	"errors" | 	"errors" | ||||||
| 	"os" | 	"os" | ||||||
| 	"os/exec" | 	"os/exec" | ||||||
| @ -10,24 +11,22 @@ import ( | |||||||
| 	"coopcloud.tech/abra/pkg/autocomplete" | 	"coopcloud.tech/abra/pkg/autocomplete" | ||||||
| 	"coopcloud.tech/abra/pkg/log" | 	"coopcloud.tech/abra/pkg/log" | ||||||
| 	"github.com/AlecAivazis/survey/v2" | 	"github.com/AlecAivazis/survey/v2" | ||||||
| 	"github.com/urfave/cli/v2" | 	"github.com/urfave/cli/v3" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| var appConfigCommand = cli.Command{ | var appConfigCommand = cli.Command{ | ||||||
| 	Name:          "config", | 	Name:          "config", | ||||||
| 	Aliases:       []string{"cfg"}, | 	Aliases:       []string{"cfg"}, | ||||||
| 	Usage:         "Edit app config", | 	Usage:         "Edit app config", | ||||||
| 	ArgsUsage: "<domain>", | 	UsageText:     "abra app config <domain> [options]", | ||||||
| 	Flags: []cli.Flag{ |  | ||||||
| 		internal.DebugFlag, |  | ||||||
| 	}, |  | ||||||
| 	Before:        internal.SubCommandBefore, | 	Before:        internal.SubCommandBefore, | ||||||
| 	BashComplete: autocomplete.AppNameComplete, | 	ShellComplete: autocomplete.AppNameComplete, | ||||||
| 	Action: func(c *cli.Context) error { | 	HideHelp:      true, | ||||||
| 		appName := c.Args().First() | 	Action: func(ctx context.Context, cmd *cli.Command) error { | ||||||
|  | 		appName := cmd.Args().First() | ||||||
|  |  | ||||||
| 		if appName == "" { | 		if appName == "" { | ||||||
| 			internal.ShowSubcommandHelpAndError(c, errors.New("no app provided")) | 			internal.ShowSubcommandHelpAndError(cmd, errors.New("no app provided")) | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		files, err := appPkg.LoadAppFiles("") | 		files, err := appPkg.LoadAppFiles("") | ||||||
| @ -51,11 +50,11 @@ var appConfigCommand = cli.Command{ | |||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		cmd := exec.Command(ed, appFile.Path) | 		c := exec.Command(ed, appFile.Path) | ||||||
| 		cmd.Stdin = os.Stdin | 		c.Stdin = os.Stdin | ||||||
| 		cmd.Stdout = os.Stdout | 		c.Stdout = os.Stdout | ||||||
| 		cmd.Stderr = os.Stderr | 		c.Stderr = os.Stderr | ||||||
| 		if err := cmd.Run(); err != nil { | 		if err := c.Run(); err != nil { | ||||||
| 			log.Fatal(err) | 			log.Fatal(err) | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|  | |||||||
| @ -22,21 +22,16 @@ import ( | |||||||
| 	dockerClient "github.com/docker/docker/client" | 	dockerClient "github.com/docker/docker/client" | ||||||
| 	"github.com/docker/docker/errdefs" | 	"github.com/docker/docker/errdefs" | ||||||
| 	"github.com/docker/docker/pkg/archive" | 	"github.com/docker/docker/pkg/archive" | ||||||
| 	"github.com/urfave/cli/v2" | 	"github.com/urfave/cli/v3" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| var appCpCommand = cli.Command{ | var appCpCommand = cli.Command{ | ||||||
| 	Name:      "cp", | 	Name:      "cp", | ||||||
| 	Aliases:   []string{"c"}, | 	Aliases:   []string{"c"}, | ||||||
| 	ArgsUsage: "<domain> <src> <dst>", |  | ||||||
| 	Flags: []cli.Flag{ |  | ||||||
| 		internal.DebugFlag, |  | ||||||
| 		internal.NoInputFlag, |  | ||||||
| 	}, |  | ||||||
| 	Before:    internal.SubCommandBefore, | 	Before:    internal.SubCommandBefore, | ||||||
| 	Usage:     "Copy files to/from a deployed app service", | 	Usage:     "Copy files to/from a deployed app service", | ||||||
| 	Description: ` | 	UsageText: "abra app cp <domain> <src> <dst> [options]", | ||||||
| Copy files to and from any app service file system. | 	Description: `Copy files to and from any app service file system. | ||||||
|  |  | ||||||
| If you want to copy a myfile.txt to the root of the app service: | If you want to copy a myfile.txt to the root of the app service: | ||||||
|  |  | ||||||
| @ -44,18 +39,17 @@ If you want to copy a myfile.txt to the root of the app service: | |||||||
|  |  | ||||||
| And if you want to copy that file back to your current working directory locally: | And if you want to copy that file back to your current working directory locally: | ||||||
|  |  | ||||||
|     abra app cp <domain> app:/myfile.txt . |     abra app cp <domain> app:/myfile.txt`, | ||||||
| `, | 	ShellComplete: autocomplete.AppNameComplete, | ||||||
| 	BashComplete: autocomplete.AppNameComplete, | 	HideHelp:      true, | ||||||
| 	Action: func(c *cli.Context) error { | 	Action: func(ctx context.Context, cmd *cli.Command) error { | ||||||
| 		app := internal.ValidateApp(c) | 		app := internal.ValidateApp(cmd) | ||||||
|  |  | ||||||
| 		if err := app.Recipe.Ensure(internal.Chaos, internal.Offline); err != nil { | 		if err := app.Recipe.Ensure(internal.Chaos, internal.Offline); err != nil { | ||||||
| 			log.Fatal(err) | 			log.Fatal(err) | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		src := c.Args().Get(1) | 		src := cmd.Args().Get(1) | ||||||
| 		dst := c.Args().Get(2) | 		dst := cmd.Args().Get(2) | ||||||
| 		if src == "" { | 		if src == "" { | ||||||
| 			log.Fatal("missing <src> argument") | 			log.Fatal("missing <src> argument") | ||||||
| 		} | 		} | ||||||
|  | |||||||
| @ -17,22 +17,19 @@ import ( | |||||||
| 	"coopcloud.tech/abra/pkg/lint" | 	"coopcloud.tech/abra/pkg/lint" | ||||||
| 	"coopcloud.tech/abra/pkg/log" | 	"coopcloud.tech/abra/pkg/log" | ||||||
| 	"coopcloud.tech/abra/pkg/upstream/stack" | 	"coopcloud.tech/abra/pkg/upstream/stack" | ||||||
| 	"github.com/urfave/cli/v2" | 	"github.com/urfave/cli/v3" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| var appDeployCommand = cli.Command{ | var appDeployCommand = cli.Command{ | ||||||
| 	Name:      "deploy", | 	Name:      "deploy", | ||||||
| 	Aliases:   []string{"d"}, | 	Aliases:   []string{"d"}, | ||||||
| 	Usage:     "Deploy an app", | 	Usage:     "Deploy an app", | ||||||
| 	ArgsUsage: "<domain> [<version>]", | 	UsageText: "abra app deploy <domain> [<version>] [options]", | ||||||
| 	Flags: []cli.Flag{ | 	Flags: []cli.Flag{ | ||||||
| 		internal.DebugFlag, |  | ||||||
| 		internal.NoInputFlag, |  | ||||||
| 		internal.ForceFlag, | 		internal.ForceFlag, | ||||||
| 		internal.ChaosFlag, | 		internal.ChaosFlag, | ||||||
| 		internal.NoDomainChecksFlag, | 		internal.NoDomainChecksFlag, | ||||||
| 		internal.DontWaitConvergeFlag, | 		internal.DontWaitConvergeFlag, | ||||||
| 		internal.OfflineFlag, |  | ||||||
| 	}, | 	}, | ||||||
| 	Before: internal.SubCommandBefore, | 	Before: internal.SubCommandBefore, | ||||||
| 	Description: `Deploy an app. | 	Description: `Deploy an app. | ||||||
| @ -40,21 +37,20 @@ var appDeployCommand = cli.Command{ | |||||||
| This command supports chaos operations. Use "--chaos" to deploy your recipe | This command supports chaos operations. Use "--chaos" to deploy your recipe | ||||||
| checkout as-is. Recipe commit hashes are also supported values for | checkout as-is. Recipe commit hashes are also supported values for | ||||||
| "[<version>]". Please note, "upgrade"/"rollback" do not support chaos | "[<version>]". Please note, "upgrade"/"rollback" do not support chaos | ||||||
| operations. | operations.`, | ||||||
|  | 	ShellComplete: autocomplete.AppNameComplete, | ||||||
| EXAMPLE: | 	HideHelp:      true, | ||||||
|  | 	Action: func(ctx context.Context, cmd *cli.Command) error { | ||||||
|     abra app deploy foo.example.com |  | ||||||
|     abra app deploy foo.example.com 1.2.3+3.2.1 |  | ||||||
|     abra app deploy foo.example.com 1e83340e`, |  | ||||||
| 	BashComplete: autocomplete.AppNameComplete, |  | ||||||
| 	Action: func(c *cli.Context) error { |  | ||||||
| 		var warnMessages []string | 		var warnMessages []string | ||||||
|  |  | ||||||
| 		app := internal.ValidateApp(c) | 		app := internal.ValidateApp(cmd) | ||||||
| 		stackName := app.StackName() | 		stackName := app.StackName() | ||||||
|  |  | ||||||
| 		specificVersion := c.Args().Get(1) | 		specificVersion := cmd.Args().Get(1) | ||||||
|  | 		if specificVersion == "" { | ||||||
|  | 			specificVersion = app.Recipe.Version | ||||||
|  | 		} | ||||||
|  |  | ||||||
| 		if specificVersion != "" && internal.Chaos { | 		if specificVersion != "" && internal.Chaos { | ||||||
| 			log.Fatal("cannot use <version> and --chaos together") | 			log.Fatal("cannot use <version> and --chaos together") | ||||||
| 		} | 		} | ||||||
|  | |||||||
| @ -1,6 +1,7 @@ | |||||||
| package app | package app | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
|  | 	"context" | ||||||
| 	"encoding/json" | 	"encoding/json" | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"sort" | 	"sort" | ||||||
| @ -12,7 +13,7 @@ import ( | |||||||
| 	"coopcloud.tech/abra/pkg/formatter" | 	"coopcloud.tech/abra/pkg/formatter" | ||||||
| 	"coopcloud.tech/abra/pkg/log" | 	"coopcloud.tech/abra/pkg/log" | ||||||
| 	"coopcloud.tech/tagcmp" | 	"coopcloud.tech/tagcmp" | ||||||
| 	"github.com/urfave/cli/v2" | 	"github.com/urfave/cli/v3" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| var ( | var ( | ||||||
| @ -73,23 +74,21 @@ var appListCommand = cli.Command{ | |||||||
| 	Name:      "list", | 	Name:      "list", | ||||||
| 	Aliases:   []string{"ls"}, | 	Aliases:   []string{"ls"}, | ||||||
| 	Usage:     "List all managed apps", | 	Usage:     "List all managed apps", | ||||||
| 	Description: ` | 	UsageText: "abra app list [options]", | ||||||
| Read the local file system listing of apps and servers (e.g. ~/.abra/) to | 	Description: `Generate a report of all managed apps. | ||||||
| generate a report of all your apps. |  | ||||||
|  |  | ||||||
| By passing the "--status/-S" flag, you can query all your servers for the | By passing the "--status/-S" flag, you can query all your servers for the | ||||||
| actual live deployment status. Depending on how many servers you manage, this | actual live deployment status. Depending on how many servers you manage, this | ||||||
| can take some time.`, | can take some time.`, | ||||||
| 	Flags: []cli.Flag{ | 	Flags: []cli.Flag{ | ||||||
| 		internal.DebugFlag, |  | ||||||
| 		internal.MachineReadableFlag, | 		internal.MachineReadableFlag, | ||||||
| 		statusFlag, | 		statusFlag, | ||||||
| 		listAppServerFlag, | 		listAppServerFlag, | ||||||
| 		recipeFlag, | 		recipeFlag, | ||||||
| 		internal.OfflineFlag, |  | ||||||
| 	}, | 	}, | ||||||
| 	Before:   internal.SubCommandBefore, | 	Before:   internal.SubCommandBefore, | ||||||
| 	Action: func(c *cli.Context) error { | 	HideHelp: true, | ||||||
|  | 	Action: func(ctx context.Context, cmd *cli.Command) error { | ||||||
| 		appFiles, err := appPkg.LoadAppFiles(listAppServer) | 		appFiles, err := appPkg.LoadAppFiles(listAppServer) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			log.Fatal(err) | 			log.Fatal(err) | ||||||
|  | |||||||
| @ -19,23 +19,23 @@ import ( | |||||||
| 	"github.com/docker/docker/api/types/filters" | 	"github.com/docker/docker/api/types/filters" | ||||||
| 	"github.com/docker/docker/api/types/swarm" | 	"github.com/docker/docker/api/types/swarm" | ||||||
| 	dockerClient "github.com/docker/docker/client" | 	dockerClient "github.com/docker/docker/client" | ||||||
| 	"github.com/urfave/cli/v2" | 	"github.com/urfave/cli/v3" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| var appLogsCommand = cli.Command{ | var appLogsCommand = cli.Command{ | ||||||
| 	Name:      "logs", | 	Name:      "logs", | ||||||
| 	Aliases:   []string{"l"}, | 	Aliases:   []string{"l"}, | ||||||
| 	ArgsUsage: "<domain> [<service>]", |  | ||||||
| 	Usage:     "Tail app logs", | 	Usage:     "Tail app logs", | ||||||
|  | 	UsageText: "abra app logs <domain> [<service>] [options]", | ||||||
| 	Flags: []cli.Flag{ | 	Flags: []cli.Flag{ | ||||||
| 		internal.StdErrOnlyFlag, | 		internal.StdErrOnlyFlag, | ||||||
| 		internal.SinceLogsFlag, | 		internal.SinceLogsFlag, | ||||||
| 		internal.DebugFlag, |  | ||||||
| 	}, | 	}, | ||||||
| 	Before:        internal.SubCommandBefore, | 	Before:        internal.SubCommandBefore, | ||||||
| 	BashComplete: autocomplete.AppNameComplete, | 	ShellComplete: autocomplete.AppNameComplete, | ||||||
| 	Action: func(c *cli.Context) error { | 	HideHelp:      true, | ||||||
| 		app := internal.ValidateApp(c) | 	Action: func(ctx context.Context, cmd *cli.Command) error { | ||||||
|  | 		app := internal.ValidateApp(cmd) | ||||||
| 		stackName := app.StackName() | 		stackName := app.StackName() | ||||||
|  |  | ||||||
| 		if err := app.Recipe.EnsureExists(); err != nil { | 		if err := app.Recipe.EnsureExists(); err != nil { | ||||||
| @ -56,7 +56,7 @@ var appLogsCommand = cli.Command{ | |||||||
| 			log.Fatalf("%s is not deployed?", app.Name) | 			log.Fatalf("%s is not deployed?", app.Name) | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		serviceName := c.Args().Get(1) | 		serviceName := cmd.Args().Get(1) | ||||||
| 		serviceNames := []string{} | 		serviceNames := []string{} | ||||||
| 		if serviceName != "" { | 		if serviceName != "" { | ||||||
| 			serviceNames = []string{serviceName} | 			serviceNames = []string{serviceName} | ||||||
|  | |||||||
| @ -1,6 +1,7 @@ | |||||||
| package app | package app | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
|  | 	"context" | ||||||
| 	"fmt" | 	"fmt" | ||||||
|  |  | ||||||
| 	"coopcloud.tech/abra/cli/internal" | 	"coopcloud.tech/abra/cli/internal" | ||||||
| @ -16,12 +17,13 @@ import ( | |||||||
| 	"github.com/AlecAivazis/survey/v2" | 	"github.com/AlecAivazis/survey/v2" | ||||||
| 	"github.com/charmbracelet/lipgloss/table" | 	"github.com/charmbracelet/lipgloss/table" | ||||||
| 	dockerClient "github.com/docker/docker/client" | 	dockerClient "github.com/docker/docker/client" | ||||||
| 	"github.com/urfave/cli/v2" | 	"github.com/urfave/cli/v3" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| var appNewDescription = ` | var appNewDescription = `Creates a new app from a default recipe. | ||||||
| Creates a new app from a default recipe. This new app configuration is stored |  | ||||||
| in your $ABRA_DIR directory under the appropriate server. | This new app configuration is stored in your $ABRA_DIR directory under the | ||||||
|  | appropriate server. | ||||||
|  |  | ||||||
| This command does not deploy your app for you. You will need to run "abra app | This command does not deploy your app for you. You will need to run "abra app | ||||||
| deploy <domain>" to do so. | deploy <domain>" to do so. | ||||||
| @ -44,30 +46,28 @@ var appNewCommand = cli.Command{ | |||||||
| 	Name:        "new", | 	Name:        "new", | ||||||
| 	Aliases:     []string{"n"}, | 	Aliases:     []string{"n"}, | ||||||
| 	Usage:       "Create a new app", | 	Usage:       "Create a new app", | ||||||
|  | 	UsageText:   "abra app new [<recipe>] [<version>] [options]", | ||||||
| 	Description: appNewDescription, | 	Description: appNewDescription, | ||||||
| 	Flags: []cli.Flag{ | 	Flags: []cli.Flag{ | ||||||
| 		internal.DebugFlag, |  | ||||||
| 		internal.NoInputFlag, |  | ||||||
| 		internal.NewAppServerFlag, | 		internal.NewAppServerFlag, | ||||||
| 		internal.DomainFlag, | 		internal.DomainFlag, | ||||||
| 		internal.PassFlag, | 		internal.PassFlag, | ||||||
| 		internal.SecretsFlag, | 		internal.SecretsFlag, | ||||||
| 		internal.OfflineFlag, |  | ||||||
| 		internal.ChaosFlag, | 		internal.ChaosFlag, | ||||||
| 	}, | 	}, | ||||||
| 	Before:   internal.SubCommandBefore, | 	Before:   internal.SubCommandBefore, | ||||||
| 	ArgsUsage: "[<recipe>] [<version>]", | 	HideHelp: true, | ||||||
| 	BashComplete: func(ctx *cli.Context) { | 	ShellComplete: func(ctx context.Context, cmd *cli.Command) { | ||||||
| 		args := ctx.Args() | 		args := cmd.Args() | ||||||
| 		switch args.Len() { | 		switch args.Len() { | ||||||
| 		case 0: | 		case 0: | ||||||
| 			autocomplete.RecipeNameComplete(ctx) | 			autocomplete.RecipeNameComplete(ctx, cmd) | ||||||
| 		case 1: | 		case 1: | ||||||
| 			autocomplete.RecipeVersionComplete(ctx.Args().Get(0)) | 			autocomplete.RecipeVersionComplete(cmd.Args().Get(0)) | ||||||
| 		} | 		} | ||||||
| 	}, | 	}, | ||||||
| 	Action: func(c *cli.Context) error { | 	Action: func(ctx context.Context, cmd *cli.Command) error { | ||||||
| 		recipe := internal.ValidateRecipe(c) | 		recipe := internal.ValidateRecipe(cmd) | ||||||
|  |  | ||||||
| 		var version string | 		var version string | ||||||
| 		if !internal.Chaos { | 		if !internal.Chaos { | ||||||
| @ -80,7 +80,7 @@ var appNewCommand = cli.Command{ | |||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			if c.Args().Get(1) == "" { | 			if cmd.Args().Get(1) == "" { | ||||||
| 				recipeVersions, err := recipe.GetRecipeVersions() | 				recipeVersions, err := recipe.GetRecipeVersions() | ||||||
| 				if err != nil { | 				if err != nil { | ||||||
| 					log.Fatal(err) | 					log.Fatal(err) | ||||||
| @ -101,7 +101,7 @@ var appNewCommand = cli.Command{ | |||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
| 			} else { | 			} else { | ||||||
| 				version = c.Args().Get(1) | 				version = cmd.Args().Get(1) | ||||||
| 				if _, err := recipe.EnsureVersion(version); err != nil { | 				if _, err := recipe.EnsureVersion(version); err != nil { | ||||||
| 					log.Fatal(err) | 					log.Fatal(err) | ||||||
| 				} | 				} | ||||||
|  | |||||||
| @ -18,25 +18,25 @@ import ( | |||||||
| 	containerTypes "github.com/docker/docker/api/types/container" | 	containerTypes "github.com/docker/docker/api/types/container" | ||||||
| 	"github.com/docker/docker/api/types/filters" | 	"github.com/docker/docker/api/types/filters" | ||||||
| 	dockerClient "github.com/docker/docker/client" | 	dockerClient "github.com/docker/docker/client" | ||||||
| 	"github.com/urfave/cli/v2" | 	"github.com/urfave/cli/v3" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| var appPsCommand = cli.Command{ | var appPsCommand = cli.Command{ | ||||||
| 	Name:        "ps", | 	Name:        "ps", | ||||||
| 	Aliases:     []string{"p"}, | 	Aliases:     []string{"p"}, | ||||||
| 	Usage:       "Check app status", | 	Usage:       "Check app status", | ||||||
| 	ArgsUsage:   "<domain>", | 	UsageText:   "abra app ps <domain> [options]", | ||||||
| 	Description: "Show status of a deployed app.", | 	Description: "Show status of a deployed app.", | ||||||
| 	Flags: []cli.Flag{ | 	Flags: []cli.Flag{ | ||||||
| 		internal.MachineReadableFlag, | 		internal.MachineReadableFlag, | ||||||
| 		internal.DebugFlag, |  | ||||||
| 		internal.ChaosFlag, | 		internal.ChaosFlag, | ||||||
| 		internal.OfflineFlag, | 		internal.OfflineFlag, | ||||||
| 	}, | 	}, | ||||||
| 	Before:        internal.SubCommandBefore, | 	Before:        internal.SubCommandBefore, | ||||||
| 	BashComplete: autocomplete.AppNameComplete, | 	ShellComplete: autocomplete.AppNameComplete, | ||||||
| 	Action: func(c *cli.Context) error { | 	HideHelp:      true, | ||||||
| 		app := internal.ValidateApp(c) | 	Action: func(ctx context.Context, cmd *cli.Command) error { | ||||||
|  | 		app := internal.ValidateApp(cmd) | ||||||
| 		if err := app.Recipe.Ensure(internal.Chaos, internal.Offline); err != nil { | 		if err := app.Recipe.Ensure(internal.Chaos, internal.Offline); err != nil { | ||||||
| 			log.Fatal(err) | 			log.Fatal(err) | ||||||
| 		} | 		} | ||||||
|  | |||||||
| @ -12,16 +12,15 @@ import ( | |||||||
| 	stack "coopcloud.tech/abra/pkg/upstream/stack" | 	stack "coopcloud.tech/abra/pkg/upstream/stack" | ||||||
| 	"github.com/AlecAivazis/survey/v2" | 	"github.com/AlecAivazis/survey/v2" | ||||||
| 	"github.com/docker/docker/api/types" | 	"github.com/docker/docker/api/types" | ||||||
| 	"github.com/urfave/cli/v2" | 	"github.com/urfave/cli/v3" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| var appRemoveCommand = cli.Command{ | var appRemoveCommand = cli.Command{ | ||||||
| 	Name:      "remove", | 	Name:      "remove", | ||||||
| 	Aliases:   []string{"rm"}, | 	Aliases:   []string{"rm"}, | ||||||
| 	ArgsUsage: "<domain>", | 	UsageText: "abra app remove <domain> [options]", | ||||||
| 	Usage:     "Remove all app data, locally and remotely", | 	Usage:     "Remove all app data, locally and remotely", | ||||||
| 	Description: ` | 	Description: `Remove everything related to an app which is already undeployed. | ||||||
| This command removes everything related to an app which is already undeployed. |  | ||||||
|  |  | ||||||
| By default, it will prompt for confirmation before proceeding. All secrets, | By default, it will prompt for confirmation before proceeding. All secrets, | ||||||
| volumes and the local app env file will be deleted. | volumes and the local app env file will be deleted. | ||||||
| @ -39,14 +38,12 @@ To delete everything without prompt, use the "--force/-f" or the "--no-input/n" | |||||||
| flag.`, | flag.`, | ||||||
| 	Flags: []cli.Flag{ | 	Flags: []cli.Flag{ | ||||||
| 		internal.ForceFlag, | 		internal.ForceFlag, | ||||||
| 		internal.DebugFlag, |  | ||||||
| 		internal.NoInputFlag, |  | ||||||
| 		internal.OfflineFlag, |  | ||||||
| 	}, | 	}, | ||||||
| 	BashComplete: autocomplete.AppNameComplete, | 	ShellComplete: autocomplete.AppNameComplete, | ||||||
| 	Before:        internal.SubCommandBefore, | 	Before:        internal.SubCommandBefore, | ||||||
| 	Action: func(c *cli.Context) error { | 	HideHelp:      true, | ||||||
| 		app := internal.ValidateApp(c) | 	Action: func(ctx context.Context, cmd *cli.Command) error { | ||||||
|  | 		app := internal.ValidateApp(cmd) | ||||||
|  |  | ||||||
| 		if !internal.Force && !internal.NoInput { | 		if !internal.Force && !internal.NoInput { | ||||||
| 			log.Warnf("ALERTA ALERTA: this will completely remove %s data and config locally and remotely", app.Name) | 			log.Warnf("ALERTA ALERTA: this will completely remove %s data and config locally and remotely", app.Name) | ||||||
|  | |||||||
| @ -12,41 +12,35 @@ import ( | |||||||
| 	"coopcloud.tech/abra/pkg/log" | 	"coopcloud.tech/abra/pkg/log" | ||||||
| 	upstream "coopcloud.tech/abra/pkg/upstream/service" | 	upstream "coopcloud.tech/abra/pkg/upstream/service" | ||||||
| 	stack "coopcloud.tech/abra/pkg/upstream/stack" | 	stack "coopcloud.tech/abra/pkg/upstream/stack" | ||||||
| 	"github.com/urfave/cli/v2" | 	"github.com/urfave/cli/v3" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| var appRestartCommand = cli.Command{ | var appRestartCommand = cli.Command{ | ||||||
| 	Name:      "restart", | 	Name:      "restart", | ||||||
| 	Aliases:   []string{"re"}, | 	Aliases:   []string{"re"}, | ||||||
| 	Usage:     "Restart an app", | 	Usage:     "Restart an app", | ||||||
| 	ArgsUsage: "<domain> [<service>]", | 	UsageText: "abra app restart <domain> [<service>] [options]", | ||||||
| 	Flags: []cli.Flag{ | 	Flags: []cli.Flag{ | ||||||
| 		internal.DebugFlag, |  | ||||||
| 		internal.OfflineFlag, |  | ||||||
| 		internal.AllServicesFlag, | 		internal.AllServicesFlag, | ||||||
| 	}, | 	}, | ||||||
| 	Before: internal.SubCommandBefore, | 	Before: internal.SubCommandBefore, | ||||||
| 	Description: ` | 	Description: `This command restarts services within a deployed app. | ||||||
| This command restarts services within a deployed app. |  | ||||||
|  |  | ||||||
| Run "abra app ps <domain>" to see a list of service names. | Run "abra app ps <domain>" to see a list of service names. | ||||||
|  |  | ||||||
| Pass "--all-services/-a" to restart all services. | Pass "--all-services/-a" to restart all services.`, | ||||||
|  | 	ShellComplete: autocomplete.AppNameComplete, | ||||||
| EXAMPLE: | 	HideHelp:      true, | ||||||
|  | 	Action: func(ctx context.Context, cmd *cli.Command) error { | ||||||
|     abra app restart example.com app`, | 		app := internal.ValidateApp(cmd) | ||||||
| 	BashComplete: autocomplete.AppNameComplete, |  | ||||||
| 	Action: func(c *cli.Context) error { |  | ||||||
| 		app := internal.ValidateApp(c) |  | ||||||
| 		if err := app.Recipe.Ensure(false, false); err != nil { | 		if err := app.Recipe.Ensure(false, false); err != nil { | ||||||
| 			log.Fatal(err) | 			log.Fatal(err) | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		serviceName := c.Args().Get(1) | 		serviceName := cmd.Args().Get(1) | ||||||
| 		if serviceName == "" && !internal.AllServices { | 		if serviceName == "" && !internal.AllServices { | ||||||
| 			err := errors.New("missing <service>") | 			err := errors.New("missing <service>") | ||||||
| 			internal.ShowSubcommandHelpAndError(c, err) | 			internal.ShowSubcommandHelpAndError(cmd, err) | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if serviceName != "" && internal.AllServices { | 		if serviceName != "" && internal.AllServices { | ||||||
|  | |||||||
| @ -1,13 +1,14 @@ | |||||||
| package app | package app | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
|  | 	"context" | ||||||
| 	"fmt" | 	"fmt" | ||||||
|  |  | ||||||
| 	"coopcloud.tech/abra/cli/internal" | 	"coopcloud.tech/abra/cli/internal" | ||||||
| 	"coopcloud.tech/abra/pkg/autocomplete" | 	"coopcloud.tech/abra/pkg/autocomplete" | ||||||
| 	"coopcloud.tech/abra/pkg/client" | 	"coopcloud.tech/abra/pkg/client" | ||||||
| 	"coopcloud.tech/abra/pkg/log" | 	"coopcloud.tech/abra/pkg/log" | ||||||
| 	"github.com/urfave/cli/v2" | 	"github.com/urfave/cli/v3" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| var targetPath string | var targetPath string | ||||||
| @ -22,16 +23,15 @@ var appRestoreCommand = cli.Command{ | |||||||
| 	Name:      "restore", | 	Name:      "restore", | ||||||
| 	Aliases:   []string{"rs"}, | 	Aliases:   []string{"rs"}, | ||||||
| 	Usage:     "Restore an app backup", | 	Usage:     "Restore an app backup", | ||||||
| 	ArgsUsage: "<domain> <service>", | 	UsageText: "abra app restore <domain> <service> [options]", | ||||||
| 	Flags: []cli.Flag{ | 	Flags: []cli.Flag{ | ||||||
| 		internal.DebugFlag, |  | ||||||
| 		internal.OfflineFlag, |  | ||||||
| 		targetPathFlag, | 		targetPathFlag, | ||||||
| 	}, | 	}, | ||||||
| 	Before:        internal.SubCommandBefore, | 	Before:        internal.SubCommandBefore, | ||||||
| 	BashComplete: autocomplete.AppNameComplete, | 	ShellComplete: autocomplete.AppNameComplete, | ||||||
| 	Action: func(c *cli.Context) error { | 	HideHelp:      true, | ||||||
| 		app := internal.ValidateApp(c) | 	Action: func(ctx context.Context, cmd *cli.Command) error { | ||||||
|  | 		app := internal.ValidateApp(cmd) | ||||||
| 		if err := app.Recipe.Ensure(internal.Chaos, internal.Offline); err != nil { | 		if err := app.Recipe.Ensure(internal.Chaos, internal.Offline); err != nil { | ||||||
| 			log.Fatal(err) | 			log.Fatal(err) | ||||||
| 		} | 		} | ||||||
|  | |||||||
| @ -16,44 +16,36 @@ import ( | |||||||
| 	"coopcloud.tech/abra/pkg/client" | 	"coopcloud.tech/abra/pkg/client" | ||||||
| 	"coopcloud.tech/abra/pkg/log" | 	"coopcloud.tech/abra/pkg/log" | ||||||
| 	"github.com/AlecAivazis/survey/v2" | 	"github.com/AlecAivazis/survey/v2" | ||||||
| 	"github.com/urfave/cli/v2" | 	"github.com/urfave/cli/v3" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| var appRollbackCommand = cli.Command{ | var appRollbackCommand = cli.Command{ | ||||||
| 	Name:      "rollback", | 	Name:      "rollback", | ||||||
| 	Aliases:   []string{"rl"}, | 	Aliases:   []string{"rl"}, | ||||||
| 	Usage:     "Roll an app back to a previous version", | 	Usage:     "Roll an app back to a previous version", | ||||||
| 	ArgsUsage: "<domain> [<version>]", | 	UsageText: "abra app rollback <domain> [<version>] [options]", | ||||||
| 	Flags: []cli.Flag{ | 	Flags: []cli.Flag{ | ||||||
| 		internal.DebugFlag, |  | ||||||
| 		internal.NoInputFlag, |  | ||||||
| 		internal.ForceFlag, | 		internal.ForceFlag, | ||||||
| 		internal.NoDomainChecksFlag, | 		internal.NoDomainChecksFlag, | ||||||
| 		internal.DontWaitConvergeFlag, | 		internal.DontWaitConvergeFlag, | ||||||
| 		internal.OfflineFlag, |  | ||||||
| 	}, | 	}, | ||||||
| 	Before: internal.SubCommandBefore, | 	Before: internal.SubCommandBefore, | ||||||
| 	Description: ` | 	Description: `This command rolls an app back to a previous version. | ||||||
| This command rolls an app back to a previous version. |  | ||||||
|  |  | ||||||
| Unlike "deploy", chaos operations are not supported here. Only recipe versions | Unlike "deploy", chaos operations are not supported here. Only recipe versions | ||||||
| are supported values for "[<version>]". | are supported values for "[<version>]". | ||||||
|  |  | ||||||
| A rollback can be destructive, please ensure you have a copy of your app data | A rollback can be destructive, please ensure you have a copy of your app data | ||||||
| beforehand. | beforehand.`, | ||||||
|  | 	ShellComplete: autocomplete.AppNameComplete, | ||||||
| EXAMPLE: | 	HideHelp:      true, | ||||||
|  | 	Action: func(ctx context.Context, cmd *cli.Command) error { | ||||||
|     abra app rollback foo.example.com |  | ||||||
|     abra app rollback foo.example.com 1.2.3+3.2.1`, |  | ||||||
| 	BashComplete: autocomplete.AppNameComplete, |  | ||||||
| 	Action: func(c *cli.Context) error { |  | ||||||
| 		var warnMessages []string | 		var warnMessages []string | ||||||
|  |  | ||||||
| 		app := internal.ValidateApp(c) | 		app := internal.ValidateApp(cmd) | ||||||
| 		stackName := app.StackName() | 		stackName := app.StackName() | ||||||
|  |  | ||||||
| 		specificVersion := c.Args().Get(1) | 		specificVersion := cmd.Args().Get(1) | ||||||
| 		if specificVersion != "" { | 		if specificVersion != "" { | ||||||
| 			log.Debugf("overriding env file version (%s) with %s", app.Recipe.Version, specificVersion) | 			log.Debugf("overriding env file version (%s) with %s", app.Recipe.Version, specificVersion) | ||||||
| 			app.Recipe.Version = specificVersion | 			app.Recipe.Version = specificVersion | ||||||
|  | |||||||
| @ -14,7 +14,7 @@ import ( | |||||||
| 	"github.com/docker/cli/cli/command" | 	"github.com/docker/cli/cli/command" | ||||||
| 	"github.com/docker/docker/api/types" | 	"github.com/docker/docker/api/types" | ||||||
| 	"github.com/docker/docker/api/types/filters" | 	"github.com/docker/docker/api/types/filters" | ||||||
| 	"github.com/urfave/cli/v2" | 	"github.com/urfave/cli/v3" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| var user string | var user string | ||||||
| @ -36,23 +36,23 @@ var appRunCommand = cli.Command{ | |||||||
| 	Name:    "run", | 	Name:    "run", | ||||||
| 	Aliases: []string{"r"}, | 	Aliases: []string{"r"}, | ||||||
| 	Flags: []cli.Flag{ | 	Flags: []cli.Flag{ | ||||||
| 		internal.DebugFlag, |  | ||||||
| 		noTTYFlag, | 		noTTYFlag, | ||||||
| 		userFlag, | 		userFlag, | ||||||
| 	}, | 	}, | ||||||
| 	Before:        internal.SubCommandBefore, | 	Before:        internal.SubCommandBefore, | ||||||
| 	ArgsUsage:    "<domain> <service> <args>...", | 	Usage:         "Run a command in an app service", | ||||||
| 	Usage:        "Run a command in a service container", | 	UsageText:     "abra app run <domain> <service> <args> [options]", | ||||||
| 	BashComplete: autocomplete.AppNameComplete, | 	ShellComplete: autocomplete.AppNameComplete, | ||||||
| 	Action: func(c *cli.Context) error { | 	HideHelp:      true, | ||||||
| 		app := internal.ValidateApp(c) | 	Action: func(ctx context.Context, cmd *cli.Command) error { | ||||||
|  | 		app := internal.ValidateApp(cmd) | ||||||
|  |  | ||||||
| 		if c.Args().Len() < 2 { | 		if cmd.Args().Len() < 2 { | ||||||
| 			internal.ShowSubcommandHelpAndError(c, errors.New("no <service> provided?")) | 			internal.ShowSubcommandHelpAndError(cmd, errors.New("no <service> provided?")) | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if c.Args().Len() < 3 { | 		if cmd.Args().Len() < 3 { | ||||||
| 			internal.ShowSubcommandHelpAndError(c, errors.New("no <args> provided?")) | 			internal.ShowSubcommandHelpAndError(cmd, errors.New("no <args> provided?")) | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		cl, err := client.New(app.Server) | 		cl, err := client.New(app.Server) | ||||||
| @ -60,7 +60,7 @@ var appRunCommand = cli.Command{ | |||||||
| 			log.Fatal(err) | 			log.Fatal(err) | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		serviceName := c.Args().Get(1) | 		serviceName := cmd.Args().Get(1) | ||||||
| 		stackAndServiceName := fmt.Sprintf("^%s_%s", app.StackName(), serviceName) | 		stackAndServiceName := fmt.Sprintf("^%s_%s", app.StackName(), serviceName) | ||||||
| 		filters := filters.NewArgs() | 		filters := filters.NewArgs() | ||||||
| 		filters.Add("name", stackAndServiceName) | 		filters.Add("name", stackAndServiceName) | ||||||
| @ -70,12 +70,12 @@ var appRunCommand = cli.Command{ | |||||||
| 			log.Fatal(err) | 			log.Fatal(err) | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		cmd := c.Args().Slice()[2:] | 		c := cmd.Args().Slice()[2:] | ||||||
| 		execCreateOpts := types.ExecConfig{ | 		execCreateOpts := types.ExecConfig{ | ||||||
| 			AttachStderr: true, | 			AttachStderr: true, | ||||||
| 			AttachStdin:  true, | 			AttachStdin:  true, | ||||||
| 			AttachStdout: true, | 			AttachStdout: true, | ||||||
| 			Cmd:          cmd, | 			Cmd:          c, | ||||||
| 			Detach:       false, | 			Detach:       false, | ||||||
| 			Tty:          true, | 			Tty:          true, | ||||||
| 		} | 		} | ||||||
|  | |||||||
| @ -17,7 +17,7 @@ import ( | |||||||
| 	"coopcloud.tech/abra/pkg/secret" | 	"coopcloud.tech/abra/pkg/secret" | ||||||
| 	"github.com/docker/docker/api/types" | 	"github.com/docker/docker/api/types" | ||||||
| 	dockerClient "github.com/docker/docker/client" | 	dockerClient "github.com/docker/docker/client" | ||||||
| 	"github.com/urfave/cli/v2" | 	"github.com/urfave/cli/v3" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| var ( | var ( | ||||||
| @ -44,31 +44,30 @@ var appSecretGenerateCommand = cli.Command{ | |||||||
| 	Name:      "generate", | 	Name:      "generate", | ||||||
| 	Aliases:   []string{"g"}, | 	Aliases:   []string{"g"}, | ||||||
| 	Usage:     "Generate secrets", | 	Usage:     "Generate secrets", | ||||||
| 	ArgsUsage: "<domain> <secret> <version>", | 	UsageText: "abra app secret generate <domain> <secret> <version> [options]", | ||||||
| 	Flags: []cli.Flag{ | 	Flags: []cli.Flag{ | ||||||
| 		internal.DebugFlag, |  | ||||||
| 		allSecretsFlag, | 		allSecretsFlag, | ||||||
| 		internal.PassFlag, | 		internal.PassFlag, | ||||||
| 		internal.MachineReadableFlag, | 		internal.MachineReadableFlag, | ||||||
| 		internal.OfflineFlag, |  | ||||||
| 		internal.ChaosFlag, | 		internal.ChaosFlag, | ||||||
| 	}, | 	}, | ||||||
| 	Before:        internal.SubCommandBefore, | 	Before:        internal.SubCommandBefore, | ||||||
| 	BashComplete: autocomplete.AppNameComplete, | 	ShellComplete: autocomplete.AppNameComplete, | ||||||
| 	Action: func(c *cli.Context) error { | 	HideHelp:      true, | ||||||
| 		app := internal.ValidateApp(c) | 	Action: func(ctx context.Context, cmd *cli.Command) error { | ||||||
|  | 		app := internal.ValidateApp(cmd) | ||||||
| 		if err := app.Recipe.Ensure(internal.Chaos, internal.Offline); err != nil { | 		if err := app.Recipe.Ensure(internal.Chaos, internal.Offline); err != nil { | ||||||
| 			log.Fatal(err) | 			log.Fatal(err) | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if c.Args().Len() == 1 && !allSecrets { | 		if cmd.Args().Len() == 1 && !allSecrets { | ||||||
| 			err := errors.New("missing arguments <secret>/<version> or '--all'") | 			err := errors.New("missing arguments <secret>/<version> or '--all'") | ||||||
| 			internal.ShowSubcommandHelpAndError(c, err) | 			internal.ShowSubcommandHelpAndError(cmd, err) | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if c.Args().Get(1) != "" && allSecrets { | 		if cmd.Args().Get(1) != "" && allSecrets { | ||||||
| 			err := errors.New("cannot use '<secret> <version>' and '--all' together") | 			err := errors.New("cannot use '<secret> <version>' and '--all' together") | ||||||
| 			internal.ShowSubcommandHelpAndError(c, err) | 			internal.ShowSubcommandHelpAndError(cmd, err) | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		composeFiles, err := app.Recipe.GetComposeFiles(app.Env) | 		composeFiles, err := app.Recipe.GetComposeFiles(app.Env) | ||||||
| @ -82,8 +81,8 @@ var appSecretGenerateCommand = cli.Command{ | |||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if !allSecrets { | 		if !allSecrets { | ||||||
| 			secretName := c.Args().Get(1) | 			secretName := cmd.Args().Get(1) | ||||||
| 			secretVersion := c.Args().Get(2) | 			secretVersion := cmd.Args().Get(2) | ||||||
| 			s, ok := secrets[secretName] | 			s, ok := secrets[secretName] | ||||||
| 			if !ok { | 			if !ok { | ||||||
| 				log.Fatalf("%s doesn't exist in the env config?", secretName) | 				log.Fatalf("%s doesn't exist in the env config?", secretName) | ||||||
| @ -157,36 +156,29 @@ var appSecretInsertCommand = cli.Command{ | |||||||
| 	Name:      "insert", | 	Name:      "insert", | ||||||
| 	Aliases:   []string{"i"}, | 	Aliases:   []string{"i"}, | ||||||
| 	Usage:     "Insert secret", | 	Usage:     "Insert secret", | ||||||
|  | 	UsageText: "abra app secret insert <domain> <secret> <version> <data> [options]", | ||||||
| 	Flags: []cli.Flag{ | 	Flags: []cli.Flag{ | ||||||
| 		internal.DebugFlag, |  | ||||||
| 		internal.PassFlag, | 		internal.PassFlag, | ||||||
| 		internal.FileFlag, | 		internal.FileFlag, | ||||||
| 		internal.TrimFlag, | 		internal.TrimFlag, | ||||||
| 		internal.ChaosFlag, | 		internal.ChaosFlag, | ||||||
| 	}, | 	}, | ||||||
| 	Before:          internal.SubCommandBefore, | 	Before:          internal.SubCommandBefore, | ||||||
| 	ArgsUsage:    "<domain> <secret-name> <version> <data>", | 	ShellComplete:   autocomplete.AppNameComplete, | ||||||
| 	BashComplete: autocomplete.AppNameComplete, | 	HideHelpCommand: true, | ||||||
| 	Description: ` | 	Description: `This command inserts a secret into an app environment. | ||||||
| This command inserts a secret into an app environment. |  | ||||||
|  |  | ||||||
| This can be useful when you want to manually generate secrets for an app | This can be useful when you want to manually generate secrets for an app | ||||||
| environment. Typically, you can let Abra generate them for you on app creation | environment. Typically, you can let Abra generate them for you on app creation | ||||||
| (see "abra app new --secrets" for more). | (see "abra app new --secrets" for more).`, | ||||||
|  | 	Action: func(ctx context.Context, cmd *cli.Command) error { | ||||||
| Example: | 		app := internal.ValidateApp(cmd) | ||||||
|  |  | ||||||
|     abra app secret insert myapp db_pass v1 mySecretPassword |  | ||||||
|  |  | ||||||
| `, |  | ||||||
| 	Action: func(c *cli.Context) error { |  | ||||||
| 		app := internal.ValidateApp(c) |  | ||||||
| 		if err := app.Recipe.Ensure(internal.Chaos, internal.Offline); err != nil { | 		if err := app.Recipe.Ensure(internal.Chaos, internal.Offline); err != nil { | ||||||
| 			log.Fatal(err) | 			log.Fatal(err) | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if c.Args().Len() != 4 { | 		if cmd.Args().Len() != 4 { | ||||||
| 			internal.ShowSubcommandHelpAndError(c, errors.New("missing arguments?")) | 			internal.ShowSubcommandHelpAndError(cmd, errors.New("missing arguments?")) | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		cl, err := client.New(app.Server) | 		cl, err := client.New(app.Server) | ||||||
| @ -194,9 +186,9 @@ Example: | |||||||
| 			log.Fatal(err) | 			log.Fatal(err) | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		name := c.Args().Get(1) | 		name := cmd.Args().Get(1) | ||||||
| 		version := c.Args().Get(2) | 		version := cmd.Args().Get(2) | ||||||
| 		data := c.Args().Get(3) | 		data := cmd.Args().Get(3) | ||||||
|  |  | ||||||
| 		if internal.File { | 		if internal.File { | ||||||
| 			raw, err := os.ReadFile(data) | 			raw, err := os.ReadFile(data) | ||||||
| @ -250,8 +242,8 @@ var appSecretRmCommand = cli.Command{ | |||||||
| 	Name:      "remove", | 	Name:      "remove", | ||||||
| 	Aliases:   []string{"rm"}, | 	Aliases:   []string{"rm"}, | ||||||
| 	Usage:     "Remove a secret", | 	Usage:     "Remove a secret", | ||||||
|  | 	UsageText: "abra app remove <domainabra app remove <domain> [options]", | ||||||
| 	Flags: []cli.Flag{ | 	Flags: []cli.Flag{ | ||||||
| 		internal.DebugFlag, |  | ||||||
| 		internal.NoInputFlag, | 		internal.NoInputFlag, | ||||||
| 		rmAllSecretsFlag, | 		rmAllSecretsFlag, | ||||||
| 		internal.PassRemoveFlag, | 		internal.PassRemoveFlag, | ||||||
| @ -259,17 +251,16 @@ var appSecretRmCommand = cli.Command{ | |||||||
| 		internal.ChaosFlag, | 		internal.ChaosFlag, | ||||||
| 	}, | 	}, | ||||||
| 	Before:        internal.SubCommandBefore, | 	Before:        internal.SubCommandBefore, | ||||||
| 	ArgsUsage:    "<domain> [<secret-name>]", | 	ShellComplete: autocomplete.AppNameComplete, | ||||||
| 	BashComplete: autocomplete.AppNameComplete, |  | ||||||
| 	Description: ` | 	Description: ` | ||||||
| This command removes app secrets. | This command removes app secrets. | ||||||
|  |  | ||||||
| Example: | Example: | ||||||
|  |  | ||||||
|     abra app secret remove myapp db_pass |     abra app secret remove myapp db_pass`, | ||||||
| `, | 	HideHelp: true, | ||||||
| 	Action: func(c *cli.Context) error { | 	Action: func(ctx context.Context, cmd *cli.Command) error { | ||||||
| 		app := internal.ValidateApp(c) | 		app := internal.ValidateApp(cmd) | ||||||
| 		if err := app.Recipe.Ensure(internal.Chaos, internal.Offline); err != nil { | 		if err := app.Recipe.Ensure(internal.Chaos, internal.Offline); err != nil { | ||||||
| 			log.Fatal(err) | 			log.Fatal(err) | ||||||
| 		} | 		} | ||||||
| @ -284,12 +275,12 @@ Example: | |||||||
| 			log.Fatal(err) | 			log.Fatal(err) | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if c.Args().Get(1) != "" && rmAllSecrets { | 		if cmd.Args().Get(1) != "" && rmAllSecrets { | ||||||
| 			internal.ShowSubcommandHelpAndError(c, errors.New("cannot use '<secret-name>' and '--all' together")) | 			internal.ShowSubcommandHelpAndError(cmd, errors.New("cannot use '<secret-name>' and '--all' together")) | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if c.Args().Get(1) == "" && !rmAllSecrets { | 		if cmd.Args().Get(1) == "" && !rmAllSecrets { | ||||||
| 			internal.ShowSubcommandHelpAndError(c, errors.New("no secret(s) specified?")) | 			internal.ShowSubcommandHelpAndError(cmd, errors.New("no secret(s) specified?")) | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		cl, err := client.New(app.Server) | 		cl, err := client.New(app.Server) | ||||||
| @ -313,7 +304,7 @@ Example: | |||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		match := false | 		match := false | ||||||
| 		secretToRm := c.Args().Get(1) | 		secretToRm := cmd.Args().Get(1) | ||||||
| 		for secretName, val := range secrets { | 		for secretName, val := range secrets { | ||||||
| 			secretRemoteName := fmt.Sprintf("%s_%s_%s", app.StackName(), secretName, val.Version) | 			secretRemoteName := fmt.Sprintf("%s_%s_%s", app.StackName(), secretName, val.Version) | ||||||
| 			if _, ok := remoteSecretNames[secretRemoteName]; ok { | 			if _, ok := remoteSecretNames[secretRemoteName]; ok { | ||||||
| @ -351,16 +342,17 @@ var appSecretLsCommand = cli.Command{ | |||||||
| 	Name:    "list", | 	Name:    "list", | ||||||
| 	Aliases: []string{"ls"}, | 	Aliases: []string{"ls"}, | ||||||
| 	Flags: []cli.Flag{ | 	Flags: []cli.Flag{ | ||||||
| 		internal.DebugFlag, |  | ||||||
| 		internal.OfflineFlag, | 		internal.OfflineFlag, | ||||||
| 		internal.ChaosFlag, | 		internal.ChaosFlag, | ||||||
| 		internal.MachineReadableFlag, | 		internal.MachineReadableFlag, | ||||||
| 	}, | 	}, | ||||||
| 	Before:        internal.SubCommandBefore, | 	Before:        internal.SubCommandBefore, | ||||||
| 	Usage:         "List all secrets", | 	Usage:         "List all secrets", | ||||||
| 	BashComplete: autocomplete.AppNameComplete, | 	UsageText:     "abra app secret list [options]", | ||||||
| 	Action: func(c *cli.Context) error { | 	HideHelp:      true, | ||||||
| 		app := internal.ValidateApp(c) | 	ShellComplete: autocomplete.AppNameComplete, | ||||||
|  | 	Action: func(ctx context.Context, cmd *cli.Command) error { | ||||||
|  | 		app := internal.ValidateApp(cmd) | ||||||
| 		if err := app.Recipe.Ensure(internal.Chaos, internal.Offline); err != nil { | 		if err := app.Recipe.Ensure(internal.Chaos, internal.Offline); err != nil { | ||||||
| 			log.Fatal(err) | 			log.Fatal(err) | ||||||
| 		} | 		} | ||||||
| @ -420,8 +412,8 @@ var appSecretCommand = cli.Command{ | |||||||
| 	Name:      "secret", | 	Name:      "secret", | ||||||
| 	Aliases:   []string{"s"}, | 	Aliases:   []string{"s"}, | ||||||
| 	Usage:     "Manage app secrets", | 	Usage:     "Manage app secrets", | ||||||
| 	ArgsUsage: "<domain>", | 	UsageText: "abra app secret [command] [arguments] [options]", | ||||||
| 	Subcommands: []*cli.Command{ | 	Commands: []*cli.Command{ | ||||||
| 		&appSecretGenerateCommand, | 		&appSecretGenerateCommand, | ||||||
| 		&appSecretInsertCommand, | 		&appSecretInsertCommand, | ||||||
| 		&appSecretRmCommand, | 		&appSecretRmCommand, | ||||||
|  | |||||||
| @ -13,21 +13,19 @@ import ( | |||||||
| 	"coopcloud.tech/abra/pkg/service" | 	"coopcloud.tech/abra/pkg/service" | ||||||
| 	stack "coopcloud.tech/abra/pkg/upstream/stack" | 	stack "coopcloud.tech/abra/pkg/upstream/stack" | ||||||
| 	containerTypes "github.com/docker/docker/api/types/container" | 	containerTypes "github.com/docker/docker/api/types/container" | ||||||
| 	"github.com/urfave/cli/v2" | 	"github.com/urfave/cli/v3" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| var appServicesCommand = cli.Command{ | var appServicesCommand = cli.Command{ | ||||||
| 	Name:          "services", | 	Name:          "services", | ||||||
| 	Aliases:       []string{"sr"}, | 	Aliases:       []string{"sr"}, | ||||||
| 	Usage:         "Display all services of an app", | 	Usage:         "Display all services of an app", | ||||||
| 	ArgsUsage: "<domain>", | 	UsageText:     "abra app services <domain> [options]", | ||||||
| 	Flags: []cli.Flag{ |  | ||||||
| 		internal.DebugFlag, |  | ||||||
| 	}, |  | ||||||
| 	Before:        internal.SubCommandBefore, | 	Before:        internal.SubCommandBefore, | ||||||
| 	BashComplete: autocomplete.AppNameComplete, | 	ShellComplete: autocomplete.AppNameComplete, | ||||||
| 	Action: func(c *cli.Context) error { | 	HideHelp:      true, | ||||||
| 		app := internal.ValidateApp(c) | 	Action: func(ctx context.Context, cmd *cli.Command) error { | ||||||
|  | 		app := internal.ValidateApp(cmd) | ||||||
| 		if err := app.Recipe.Ensure(internal.Chaos, internal.Offline); err != nil { | 		if err := app.Recipe.Ensure(internal.Chaos, internal.Offline); err != nil { | ||||||
| 			log.Fatal(err) | 			log.Fatal(err) | ||||||
| 		} | 		} | ||||||
|  | |||||||
| @ -14,7 +14,7 @@ import ( | |||||||
| 	stack "coopcloud.tech/abra/pkg/upstream/stack" | 	stack "coopcloud.tech/abra/pkg/upstream/stack" | ||||||
| 	"github.com/docker/docker/api/types/filters" | 	"github.com/docker/docker/api/types/filters" | ||||||
| 	dockerClient "github.com/docker/docker/client" | 	dockerClient "github.com/docker/docker/client" | ||||||
| 	"github.com/urfave/cli/v2" | 	"github.com/urfave/cli/v3" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| var prune bool | var prune bool | ||||||
| @ -65,25 +65,24 @@ func pruneApp(cl *dockerClient.Client, app appPkg.App) error { | |||||||
| var appUndeployCommand = cli.Command{ | var appUndeployCommand = cli.Command{ | ||||||
| 	Name:      "undeploy", | 	Name:      "undeploy", | ||||||
| 	Aliases:   []string{"un"}, | 	Aliases:   []string{"un"}, | ||||||
| 	ArgsUsage: "<domain>", | 	UsageText: "abra app undeploy <domain> [options]", | ||||||
| 	Flags: []cli.Flag{ | 	Flags: []cli.Flag{ | ||||||
| 		internal.DebugFlag, |  | ||||||
| 		internal.NoInputFlag, | 		internal.NoInputFlag, | ||||||
| 		internal.OfflineFlag, | 		internal.OfflineFlag, | ||||||
| 		pruneFlag, | 		pruneFlag, | ||||||
| 	}, | 	}, | ||||||
| 	Before:        internal.SubCommandBefore, | 	Before:        internal.SubCommandBefore, | ||||||
| 	Usage:         "Undeploy an app", | 	Usage:         "Undeploy an app", | ||||||
| 	BashComplete: autocomplete.AppNameComplete, | 	ShellComplete: autocomplete.AppNameComplete, | ||||||
| 	Description: ` | 	HideHelp:      true, | ||||||
| This does not destroy any of the application data. | 	Description: `This does not destroy any of the application data. | ||||||
|  |  | ||||||
| However, you should remain vigilant, as your swarm installation will consider | However, you should remain vigilant, as your swarm installation will consider | ||||||
| any previously attached volumes as eligible for pruning once undeployed. | any previously attached volumes as eligible for pruning once undeployed. | ||||||
|  |  | ||||||
| Passing "-p/--prune" does not remove those volumes.`, | Passing "-p/--prune" does not remove those volumes.`, | ||||||
| 	Action: func(c *cli.Context) error { | 	Action: func(ctx context.Context, cmd *cli.Command) error { | ||||||
| 		app := internal.ValidateApp(c) | 		app := internal.ValidateApp(cmd) | ||||||
| 		stackName := app.StackName() | 		stackName := app.StackName() | ||||||
|  |  | ||||||
| 		cl, err := client.New(app.Server) | 		cl, err := client.New(app.Server) | ||||||
|  | |||||||
| @ -15,45 +15,37 @@ import ( | |||||||
| 	stack "coopcloud.tech/abra/pkg/upstream/stack" | 	stack "coopcloud.tech/abra/pkg/upstream/stack" | ||||||
| 	"coopcloud.tech/tagcmp" | 	"coopcloud.tech/tagcmp" | ||||||
| 	"github.com/AlecAivazis/survey/v2" | 	"github.com/AlecAivazis/survey/v2" | ||||||
| 	"github.com/urfave/cli/v2" | 	"github.com/urfave/cli/v3" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| var appUpgradeCommand = cli.Command{ | var appUpgradeCommand = cli.Command{ | ||||||
| 	Name:      "upgrade", | 	Name:      "upgrade", | ||||||
| 	Aliases:   []string{"up"}, | 	Aliases:   []string{"up"}, | ||||||
| 	Usage:     "Upgrade an app", | 	Usage:     "Upgrade an app", | ||||||
| 	ArgsUsage: "<domain> [<version>]", | 	UsageText: "abra app upgrade <domain> [<version>] [options]", | ||||||
| 	Flags: []cli.Flag{ | 	Flags: []cli.Flag{ | ||||||
| 		internal.DebugFlag, |  | ||||||
| 		internal.NoInputFlag, |  | ||||||
| 		internal.ForceFlag, | 		internal.ForceFlag, | ||||||
| 		internal.NoDomainChecksFlag, | 		internal.NoDomainChecksFlag, | ||||||
| 		internal.DontWaitConvergeFlag, | 		internal.DontWaitConvergeFlag, | ||||||
| 		internal.OfflineFlag, |  | ||||||
| 		internal.ReleaseNotesFlag, | 		internal.ReleaseNotesFlag, | ||||||
| 	}, | 	}, | ||||||
| 	Before: internal.SubCommandBefore, | 	Before: internal.SubCommandBefore, | ||||||
| 	Description: ` | 	Description: `Upgrade an app. | ||||||
| Upgrade an app. |  | ||||||
|  |  | ||||||
| Unlike "deploy", chaos operations are not supported here. Only recipe versions | Unlike "deploy", chaos operations are not supported here. Only recipe versions | ||||||
| are supported values for "[<version>]". | are supported values for "[<version>]". | ||||||
|  |  | ||||||
| An upgrade can be destructive, please ensure you have a copy of your app data | An upgrade can be destructive, please ensure you have a copy of your app data | ||||||
| beforehand. | beforehand.`, | ||||||
|  | 	HideHelp:      true, | ||||||
| EXAMPLE: | 	ShellComplete: autocomplete.AppNameComplete, | ||||||
|  | 	Action: func(ctx context.Context, cmd *cli.Command) error { | ||||||
|     abra app upgrade foo.example.com |  | ||||||
|     abra app upgrade foo.example.com 1.2.3+3.2.1`, |  | ||||||
| 	BashComplete: autocomplete.AppNameComplete, |  | ||||||
| 	Action: func(c *cli.Context) error { |  | ||||||
| 		var warnMessages []string | 		var warnMessages []string | ||||||
|  |  | ||||||
| 		app := internal.ValidateApp(c) | 		app := internal.ValidateApp(cmd) | ||||||
| 		stackName := app.StackName() | 		stackName := app.StackName() | ||||||
|  |  | ||||||
| 		specificVersion := c.Args().Get(1) | 		specificVersion := cmd.Args().Get(1) | ||||||
| 		if specificVersion != "" { | 		if specificVersion != "" { | ||||||
| 			log.Debugf("overriding env file version (%s) with %s", app.Recipe.Version, specificVersion) | 			log.Debugf("overriding env file version (%s) with %s", app.Recipe.Version, specificVersion) | ||||||
| 			app.Recipe.Version = specificVersion | 			app.Recipe.Version = specificVersion | ||||||
|  | |||||||
| @ -11,22 +11,19 @@ import ( | |||||||
| 	"coopcloud.tech/abra/pkg/log" | 	"coopcloud.tech/abra/pkg/log" | ||||||
| 	"coopcloud.tech/abra/pkg/upstream/stack" | 	"coopcloud.tech/abra/pkg/upstream/stack" | ||||||
| 	"github.com/AlecAivazis/survey/v2" | 	"github.com/AlecAivazis/survey/v2" | ||||||
| 	"github.com/urfave/cli/v2" | 	"github.com/urfave/cli/v3" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| var appVolumeListCommand = cli.Command{ | var appVolumeListCommand = cli.Command{ | ||||||
| 	Name:          "list", | 	Name:          "list", | ||||||
| 	Aliases:       []string{"ls"}, | 	Aliases:       []string{"ls"}, | ||||||
| 	ArgsUsage: "<domain>", | 	UsageText:     "abra app volume list <domain> [options]", | ||||||
| 	Flags: []cli.Flag{ |  | ||||||
| 		internal.DebugFlag, |  | ||||||
| 		internal.NoInputFlag, |  | ||||||
| 	}, |  | ||||||
| 	Before:        internal.SubCommandBefore, | 	Before:        internal.SubCommandBefore, | ||||||
| 	Usage:         "List volumes associated with an app", | 	Usage:         "List volumes associated with an app", | ||||||
| 	BashComplete: autocomplete.AppNameComplete, | 	ShellComplete: autocomplete.AppNameComplete, | ||||||
| 	Action: func(c *cli.Context) error { | 	HideHelp:      true, | ||||||
| 		app := internal.ValidateApp(c) | 	Action: func(ctx context.Context, cmd *cli.Command) error { | ||||||
|  | 		app := internal.ValidateApp(cmd) | ||||||
|  |  | ||||||
| 		cl, err := client.New(app.Server) | 		cl, err := client.New(app.Server) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| @ -74,27 +71,26 @@ var appVolumeListCommand = cli.Command{ | |||||||
| var appVolumeRemoveCommand = cli.Command{ | var appVolumeRemoveCommand = cli.Command{ | ||||||
| 	Name:  "remove", | 	Name:  "remove", | ||||||
| 	Usage: "Remove volume(s) associated with an app", | 	Usage: "Remove volume(s) associated with an app", | ||||||
| 	Description: ` | 	Description: `Remove volumes associated with an app. | ||||||
| This command supports removing volumes associated with an app. The app in |  | ||||||
| question must be undeployed before you try to remove volumes. See "abra app | The app in question must be undeployed before you try to remove volumes. See | ||||||
| undeploy <domain>" for more. | "abra app undeploy <domain>" for more. | ||||||
|  |  | ||||||
| The command is interactive and will show a multiple select input which allows | The command is interactive and will show a multiple select input which allows | ||||||
| you to make a seclection. Use the "?" key to see more help on navigating this | you to make a seclection. Use the "?" key to see more help on navigating this | ||||||
| interface. | interface. | ||||||
|  |  | ||||||
| Passing "--force/-f" will select all volumes for removal. Be careful.`, | Passing "--force/-f" will select all volumes for removal. Be careful.`, | ||||||
| 	ArgsUsage: "<domain>", | 	UsageText: "abra app volume remove [options] <domain>", | ||||||
| 	Aliases:   []string{"rm"}, | 	Aliases:   []string{"rm"}, | ||||||
| 	Flags: []cli.Flag{ | 	Flags: []cli.Flag{ | ||||||
| 		internal.DebugFlag, |  | ||||||
| 		internal.NoInputFlag, | 		internal.NoInputFlag, | ||||||
| 		internal.ForceFlag, | 		internal.ForceFlag, | ||||||
| 	}, | 	}, | ||||||
| 	Before:        internal.SubCommandBefore, | 	Before:        internal.SubCommandBefore, | ||||||
| 	BashComplete: autocomplete.AppNameComplete, | 	ShellComplete: autocomplete.AppNameComplete, | ||||||
| 	Action: func(c *cli.Context) error { | 	Action: func(ctx context.Context, cmd *cli.Command) error { | ||||||
| 		app := internal.ValidateApp(c) | 		app := internal.ValidateApp(cmd) | ||||||
|  |  | ||||||
| 		cl, err := client.New(app.Server) | 		cl, err := client.New(app.Server) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| @ -158,8 +154,8 @@ var appVolumeCommand = cli.Command{ | |||||||
| 	Name:      "volume", | 	Name:      "volume", | ||||||
| 	Aliases:   []string{"vl"}, | 	Aliases:   []string{"vl"}, | ||||||
| 	Usage:     "Manage app volumes", | 	Usage:     "Manage app volumes", | ||||||
| 	ArgsUsage: "<domain>", | 	UsageText: "abra app volume [command] [options] [arguments]", | ||||||
| 	Subcommands: []*cli.Command{ | 	Commands: []*cli.Command{ | ||||||
| 		&appVolumeListCommand, | 		&appVolumeListCommand, | ||||||
| 		&appVolumeRemoveCommand, | 		&appVolumeRemoveCommand, | ||||||
| 	}, | 	}, | ||||||
|  | |||||||
| @ -1,6 +1,7 @@ | |||||||
| package catalogue | package catalogue | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
|  | 	"context" | ||||||
| 	"encoding/json" | 	"encoding/json" | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"io/ioutil" | 	"io/ioutil" | ||||||
| @ -15,25 +16,22 @@ import ( | |||||||
| 	"coopcloud.tech/abra/pkg/log" | 	"coopcloud.tech/abra/pkg/log" | ||||||
| 	"coopcloud.tech/abra/pkg/recipe" | 	"coopcloud.tech/abra/pkg/recipe" | ||||||
| 	"github.com/go-git/go-git/v5" | 	"github.com/go-git/go-git/v5" | ||||||
| 	"github.com/urfave/cli/v2" | 	"github.com/urfave/cli/v3" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| var catalogueGenerateCommand = cli.Command{ | var catalogueGenerateCommand = cli.Command{ | ||||||
| 	Name:      "generate", | 	Name:      "generate", | ||||||
| 	Aliases:   []string{"g"}, | 	Aliases:   []string{"g"}, | ||||||
| 	Usage:     "Generate the recipe catalogue", | 	Usage:     "Generate the recipe catalogue", | ||||||
|  | 	UsageText: "abra catalogue generate [<recipe>] [options]", | ||||||
| 	Flags: []cli.Flag{ | 	Flags: []cli.Flag{ | ||||||
| 		internal.DebugFlag, |  | ||||||
| 		internal.NoInputFlag, |  | ||||||
| 		internal.PublishFlag, | 		internal.PublishFlag, | ||||||
| 		internal.DryFlag, | 		internal.DryFlag, | ||||||
| 		internal.SkipUpdatesFlag, | 		internal.SkipUpdatesFlag, | ||||||
| 		internal.ChaosFlag, | 		internal.ChaosFlag, | ||||||
| 		internal.OfflineFlag, |  | ||||||
| 	}, | 	}, | ||||||
| 	Before: internal.SubCommandBefore, | 	Before: internal.SubCommandBefore, | ||||||
| 	Description: ` | 	Description: `Generate a new copy of the recipe catalogue. | ||||||
| Generate a new copy of the recipe catalogue. |  | ||||||
|  |  | ||||||
| It is possible to generate new metadata for a single recipe by passing | It is possible to generate new metadata for a single recipe by passing | ||||||
| <recipe>. The existing local catalogue will be updated, not overwritten. | <recipe>. The existing local catalogue will be updated, not overwritten. | ||||||
| @ -45,14 +43,14 @@ If you have a Hub account you can have Abra log you in to avoid this. Pass | |||||||
| Push your new release to git.coopcloud.tech with "-p/--publish". This requires | Push your new release to git.coopcloud.tech with "-p/--publish". This requires | ||||||
| that you have permission to git push to these repositories and have your SSH | that you have permission to git push to these repositories and have your SSH | ||||||
| keys configured on your account.`, | keys configured on your account.`, | ||||||
| 	ArgsUsage:    "[<recipe>]", | 	ShellComplete: autocomplete.RecipeNameComplete, | ||||||
| 	BashComplete: autocomplete.RecipeNameComplete, | 	HideHelp:      true, | ||||||
| 	Action: func(c *cli.Context) error { | 	Action: func(ctx context.Context, cmd *cli.Command) error { | ||||||
| 		recipeName := c.Args().First() | 		recipeName := cmd.Args().First() | ||||||
| 		r := recipe.Get(recipeName) | 		r := recipe.Get(recipeName) | ||||||
|  |  | ||||||
| 		if recipeName != "" { | 		if recipeName != "" { | ||||||
| 			internal.ValidateRecipe(c) | 			internal.ValidateRecipe(cmd) | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if !internal.Chaos { | 		if !internal.Chaos { | ||||||
| @ -208,8 +206,8 @@ var CatalogueCommand = cli.Command{ | |||||||
| 	Name:      "catalogue", | 	Name:      "catalogue", | ||||||
| 	Usage:     "Manage the recipe catalogue", | 	Usage:     "Manage the recipe catalogue", | ||||||
| 	Aliases:   []string{"c"}, | 	Aliases:   []string{"c"}, | ||||||
| 	ArgsUsage: "<recipe>", | 	UsageText: "abra catalogue [command] [options] [arguments]", | ||||||
| 	Subcommands: []*cli.Command{ | 	Commands: []*cli.Command{ | ||||||
| 		&catalogueGenerateCommand, | 		&catalogueGenerateCommand, | ||||||
| 	}, | 	}, | ||||||
| } | } | ||||||
|  | |||||||
							
								
								
									
										83
									
								
								cli/cli.go
									
									
									
									
									
								
							
							
						
						
									
										83
									
								
								cli/cli.go
									
									
									
									
									
								
							| @ -2,6 +2,7 @@ | |||||||
| package cli | package cli | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
|  | 	"context" | ||||||
| 	"errors" | 	"errors" | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"os" | 	"os" | ||||||
| @ -18,7 +19,7 @@ import ( | |||||||
| 	"coopcloud.tech/abra/pkg/log" | 	"coopcloud.tech/abra/pkg/log" | ||||||
| 	"coopcloud.tech/abra/pkg/web" | 	"coopcloud.tech/abra/pkg/web" | ||||||
| 	charmLog "github.com/charmbracelet/log" | 	charmLog "github.com/charmbracelet/log" | ||||||
| 	"github.com/urfave/cli/v2" | 	"github.com/urfave/cli/v3" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| // AutoCompleteCommand helps people set up auto-complete in their shells | // AutoCompleteCommand helps people set up auto-complete in their shells | ||||||
| @ -26,23 +27,16 @@ var AutoCompleteCommand = cli.Command{ | |||||||
| 	Name:      "autocomplete", | 	Name:      "autocomplete", | ||||||
| 	Aliases:   []string{"ac"}, | 	Aliases:   []string{"ac"}, | ||||||
| 	Usage:     "Configure shell autocompletion", | 	Usage:     "Configure shell autocompletion", | ||||||
| 	Description: ` | 	UsageText: "abra autocomplete <shell> [options]", | ||||||
| Set up shell auto-completion. | 	Description: `Set up shell auto-completion. | ||||||
|  |  | ||||||
| Supported shells are: bash, fish, fizsh & zsh. | Supported shells are: bash, fish, fizsh & zsh.`, | ||||||
|  | 	HideHelp: true, | ||||||
| EXAMPLE: | 	Action: func(ctx context.Context, cmd *cli.Command) error { | ||||||
|  | 		shellType := cmd.Args().First() | ||||||
|     abra autocomplete bash`, |  | ||||||
| 	ArgsUsage: "<shell>", |  | ||||||
| 	Flags: []cli.Flag{ |  | ||||||
| 		internal.DebugFlag, |  | ||||||
| 	}, |  | ||||||
| 	Action: func(c *cli.Context) error { |  | ||||||
| 		shellType := c.Args().First() |  | ||||||
|  |  | ||||||
| 		if shellType == "" { | 		if shellType == "" { | ||||||
| 			internal.ShowSubcommandHelpAndError(c, errors.New("no shell provided")) | 			internal.ShowSubcommandHelpAndError(cmd, errors.New("no shell provided")) | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		supportedShells := map[string]bool{ | 		supportedShells := map[string]bool{ | ||||||
| @ -116,30 +110,26 @@ var UpgradeCommand = cli.Command{ | |||||||
| 	Name:      "upgrade", | 	Name:      "upgrade", | ||||||
| 	Aliases:   []string{"u"}, | 	Aliases:   []string{"u"}, | ||||||
| 	Usage:     "Upgrade abra", | 	Usage:     "Upgrade abra", | ||||||
| 	Description: ` | 	UsageText: "abra upgrade [options]", | ||||||
| Upgrade abra in-place with the latest stable or release candidate. | 	Description: `Upgrade abra in-place with the latest stable or release candidate. | ||||||
|  |  | ||||||
| Use "-r/--rc" to install the latest release candidate. Please bear in mind that | Use "--rc/-r" to install the latest release candidate. Please bear in mind that | ||||||
| it may contain absolutely catastrophic deal-breaker bugs. Thank you very much | it may contain absolutely catastrophic deal-breaker bugs. Thank you very much | ||||||
| for the testing efforts 💗 | for the testing efforts 💗`, | ||||||
|  |  | ||||||
| EXAMPLE: |  | ||||||
|  |  | ||||||
|     abra upgrade |  | ||||||
| 		abra upgrade --rc`, |  | ||||||
| 	Flags:    []cli.Flag{internal.RCFlag}, | 	Flags:    []cli.Flag{internal.RCFlag}, | ||||||
| 	Action: func(c *cli.Context) error { | 	HideHelp: true, | ||||||
|  | 	Action: func(ctx context.Context, cmd *cli.Command) error { | ||||||
| 		mainURL := "https://install.abra.coopcloud.tech" | 		mainURL := "https://install.abra.coopcloud.tech" | ||||||
| 		cmd := exec.Command("bash", "-c", fmt.Sprintf("wget -q -O- %s | bash", mainURL)) | 		c := exec.Command("bash", "-c", fmt.Sprintf("wget -q -O- %s | bash", mainURL)) | ||||||
|  |  | ||||||
| 		if internal.RC { | 		if internal.RC { | ||||||
| 			releaseCandidateURL := "https://git.coopcloud.tech/coop-cloud/abra/raw/branch/main/scripts/installer/installer" | 			releaseCandidateURL := "https://git.coopcloud.tech/coop-cloud/abra/raw/branch/main/scripts/installer/installer" | ||||||
| 			cmd = exec.Command("bash", "-c", fmt.Sprintf("wget -q -O- %s | bash -s -- --rc", releaseCandidateURL)) | 			c = exec.Command("bash", "-c", fmt.Sprintf("wget -q -O- %s | bash -s -- --rc", releaseCandidateURL)) | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		log.Debugf("attempting to run %s", cmd) | 		log.Debugf("attempting to run %s", c) | ||||||
|  |  | ||||||
| 		if err := internal.RunCmd(cmd); err != nil { | 		if err := internal.RunCmd(c); err != nil { | ||||||
| 			log.Fatal(err) | 			log.Fatal(err) | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| @ -147,18 +137,16 @@ EXAMPLE: | |||||||
| 	}, | 	}, | ||||||
| } | } | ||||||
|  |  | ||||||
| func newAbraApp(version, commit string) *cli.App { | func newAbraApp(version, commit string) *cli.Command { | ||||||
| 	app := &cli.App{ | 	app := &cli.Command{ | ||||||
| 		Name:      "abra", | 		Name:      "abra", | ||||||
| 		Usage: `the Co-op Cloud command-line utility belt 🎩🐇 | 		Usage:     "The Co-op Cloud command-line utility belt 🎩🐇", | ||||||
|     ____                           ____ _                 _ | 		UsageText: "abra [command] [arguments] [options]", | ||||||
|    / ___|___         ___  _ __    / ___| | ___  _   _  __| | |  | ||||||
|   | |   / _ \ _____ / _ \| '_ \  | |   | |/ _ \| | | |/ _' | |  | ||||||
|   | |__| (_) |_____| (_) | |_) | | |___| | (_) | |_| | (_| | |  | ||||||
|    \____\___/       \___/| .__/   \____|_|\___/ \__,_|\__,_| |  | ||||||
|                          |_| |  | ||||||
| `, |  | ||||||
| 		Version:   fmt.Sprintf("%s-%s", version, commit[:7]), | 		Version:   fmt.Sprintf("%s-%s", version, commit[:7]), | ||||||
|  | 		Flags: []cli.Flag{ | ||||||
|  | 			// NOTE(d1): "GLOBAL OPTIONS" flags | ||||||
|  | 			internal.DebugFlag, | ||||||
|  | 		}, | ||||||
| 		Commands: []*cli.Command{ | 		Commands: []*cli.Command{ | ||||||
| 			&app.AppCommand, | 			&app.AppCommand, | ||||||
| 			&server.ServerCommand, | 			&server.ServerCommand, | ||||||
| @ -167,12 +155,13 @@ func newAbraApp(version, commit string) *cli.App { | |||||||
| 			&UpgradeCommand, | 			&UpgradeCommand, | ||||||
| 			&AutoCompleteCommand, | 			&AutoCompleteCommand, | ||||||
| 		}, | 		}, | ||||||
| 		BashComplete: autocomplete.SubcommandComplete, | 		EnableShellCompletion:  true, | ||||||
|  | 		UseShortOptionHandling: true, | ||||||
|  | 		HideHelpCommand:        true, | ||||||
|  | 		ShellComplete:          autocomplete.SubcommandComplete, | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	app.EnableBashCompletion = true | 	app.Before = func(ctx context.Context, cmd *cli.Command) error { | ||||||
|  |  | ||||||
| 	app.Before = func(c *cli.Context) error { |  | ||||||
| 		paths := []string{ | 		paths := []string{ | ||||||
| 			config.ABRA_DIR, | 			config.ABRA_DIR, | ||||||
| 			config.SERVERS_DIR, | 			config.SERVERS_DIR, | ||||||
| @ -198,6 +187,12 @@ func newAbraApp(version, commit string) *cli.App { | |||||||
| 		return nil | 		return nil | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	cli.HelpFlag = &cli.BoolFlag{ | ||||||
|  | 		Name:    "help", | ||||||
|  | 		Aliases: []string{"h, H"}, | ||||||
|  | 		Usage:   "Show help", | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	return app | 	return app | ||||||
| } | } | ||||||
|  |  | ||||||
| @ -205,7 +200,7 @@ func newAbraApp(version, commit string) *cli.App { | |||||||
| func RunApp(version, commit string) { | func RunApp(version, commit string) { | ||||||
| 	app := newAbraApp(version, commit) | 	app := newAbraApp(version, commit) | ||||||
|  |  | ||||||
| 	if err := app.Run(os.Args); err != nil { | 	if err := app.Run(context.Background(), os.Args); err != nil { | ||||||
| 		log.Fatal(err) | 		log.Fatal(err) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  | |||||||
| @ -1,10 +1,11 @@ | |||||||
| package internal | package internal | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
|  | 	"context" | ||||||
| 	"os" | 	"os" | ||||||
|  |  | ||||||
| 	"coopcloud.tech/abra/pkg/log" | 	"coopcloud.tech/abra/pkg/log" | ||||||
| 	"github.com/urfave/cli/v2" | 	"github.com/urfave/cli/v3" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| // Secrets stores the variable from SecretsFlag | // Secrets stores the variable from SecretsFlag | ||||||
| @ -74,7 +75,7 @@ var Chaos bool | |||||||
| var ChaosFlag = &cli.BoolFlag{ | var ChaosFlag = &cli.BoolFlag{ | ||||||
| 	Name:        "chaos", | 	Name:        "chaos", | ||||||
| 	Aliases:     []string{"C"}, | 	Aliases:     []string{"C"}, | ||||||
| 	Usage:       "Proceed with uncommitted recipes changes. Use with care!", | 	Usage:       "Ignore uncommitted recipes changes. Use with care!", | ||||||
| 	Destination: &Chaos, | 	Destination: &Chaos, | ||||||
| } | } | ||||||
|  |  | ||||||
| @ -116,7 +117,7 @@ var OfflineFlag = &cli.BoolFlag{ | |||||||
| 	Name:        "offline", | 	Name:        "offline", | ||||||
| 	Aliases:     []string{"o"}, | 	Aliases:     []string{"o"}, | ||||||
| 	Destination: &Offline, | 	Destination: &Offline, | ||||||
| 	Usage:       "Prefer offline & filesystem access when possible", | 	Usage:       "Prefer offline & filesystem access", | ||||||
| } | } | ||||||
|  |  | ||||||
| // ReleaseNotes stores the variable from ReleaseNotesFlag. | // ReleaseNotes stores the variable from ReleaseNotesFlag. | ||||||
| @ -138,7 +139,7 @@ var MachineReadableFlag = &cli.BoolFlag{ | |||||||
| 	Name:        "machine", | 	Name:        "machine", | ||||||
| 	Aliases:     []string{"m"}, | 	Aliases:     []string{"m"}, | ||||||
| 	Destination: &MachineReadable, | 	Destination: &MachineReadable, | ||||||
| 	Usage:       "Output in a machine-readable format (where supported)", | 	Usage:       "Machine-readable output", | ||||||
| } | } | ||||||
|  |  | ||||||
| // RC signifies the latest release candidate | // RC signifies the latest release candidate | ||||||
| @ -319,7 +320,7 @@ var AllServicesFlag = &cli.BoolFlag{ | |||||||
| } | } | ||||||
|  |  | ||||||
| // SubCommandBefore wires up pre-action machinery (e.g. --debug handling). | // SubCommandBefore wires up pre-action machinery (e.g. --debug handling). | ||||||
| func SubCommandBefore(c *cli.Context) error { | func SubCommandBefore(ctx context.Context, cmd *cli.Command) error { | ||||||
| 	if Debug { | 	if Debug { | ||||||
| 		log.SetLevel(log.DebugLevel) | 		log.SetLevel(log.DebugLevel) | ||||||
| 		log.SetOutput(os.Stderr) | 		log.SetOutput(os.Stderr) | ||||||
|  | |||||||
| @ -4,13 +4,13 @@ import ( | |||||||
| 	"os" | 	"os" | ||||||
|  |  | ||||||
| 	"coopcloud.tech/abra/pkg/log" | 	"coopcloud.tech/abra/pkg/log" | ||||||
| 	"github.com/urfave/cli/v2" | 	"github.com/urfave/cli/v3" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| // ShowSubcommandHelpAndError exits the program on error, logs the error to the | // ShowSubcommandHelpAndError exits the program on error, logs the error to the | ||||||
| // terminal, and shows the help command. | // terminal, and shows the help command. | ||||||
| func ShowSubcommandHelpAndError(c *cli.Context, err interface{}) { | func ShowSubcommandHelpAndError(cmd *cli.Command, err interface{}) { | ||||||
| 	if err2 := cli.ShowSubcommandHelp(c); err2 != nil { | 	if err2 := cli.ShowSubcommandHelp(cmd); err2 != nil { | ||||||
| 		log.Error(err2) | 		log.Error(err2) | ||||||
| 	} | 	} | ||||||
| 	log.Error(err) | 	log.Error(err) | ||||||
|  | |||||||
| @ -9,12 +9,12 @@ import ( | |||||||
| 	"coopcloud.tech/abra/pkg/log" | 	"coopcloud.tech/abra/pkg/log" | ||||||
| 	"coopcloud.tech/abra/pkg/recipe" | 	"coopcloud.tech/abra/pkg/recipe" | ||||||
| 	"github.com/AlecAivazis/survey/v2" | 	"github.com/AlecAivazis/survey/v2" | ||||||
| 	"github.com/urfave/cli/v2" | 	"github.com/urfave/cli/v3" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| // ValidateRecipe ensures the recipe arg is valid. | // ValidateRecipe ensures the recipe arg is valid. | ||||||
| func ValidateRecipe(c *cli.Context) recipe.Recipe { | func ValidateRecipe(cmd *cli.Command) recipe.Recipe { | ||||||
| 	recipeName := c.Args().First() | 	recipeName := cmd.Args().First() | ||||||
|  |  | ||||||
| 	if recipeName == "" && !NoInput { | 	if recipeName == "" && !NoInput { | ||||||
| 		var recipes []string | 		var recipes []string | ||||||
| @ -54,7 +54,7 @@ func ValidateRecipe(c *cli.Context) recipe.Recipe { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if recipeName == "" { | 	if recipeName == "" { | ||||||
| 		ShowSubcommandHelpAndError(c, errors.New("no recipe name provided")) | 		ShowSubcommandHelpAndError(cmd, errors.New("no recipe name provided")) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	chosenRecipe := recipe.Get(recipeName) | 	chosenRecipe := recipe.Get(recipeName) | ||||||
| @ -64,7 +64,7 @@ func ValidateRecipe(c *cli.Context) recipe.Recipe { | |||||||
| 	} | 	} | ||||||
| 	_, err = chosenRecipe.GetComposeConfig(nil) | 	_, err = chosenRecipe.GetComposeConfig(nil) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		if c.Command.Name == "generate" { | 		if cmd.Name == "generate" { | ||||||
| 			if strings.Contains(err.Error(), "missing a compose") { | 			if strings.Contains(err.Error(), "missing a compose") { | ||||||
| 				log.Fatal(err) | 				log.Fatal(err) | ||||||
| 			} | 			} | ||||||
| @ -83,11 +83,11 @@ func ValidateRecipe(c *cli.Context) recipe.Recipe { | |||||||
| } | } | ||||||
|  |  | ||||||
| // ValidateApp ensures the app name arg is valid. | // ValidateApp ensures the app name arg is valid. | ||||||
| func ValidateApp(c *cli.Context) app.App { | func ValidateApp(cmd *cli.Command) app.App { | ||||||
| 	appName := c.Args().First() | 	appName := cmd.Args().First() | ||||||
|  |  | ||||||
| 	if appName == "" { | 	if appName == "" { | ||||||
| 		ShowSubcommandHelpAndError(c, errors.New("no app provided")) | 		ShowSubcommandHelpAndError(cmd, errors.New("no app provided")) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	app, err := app.Get(appName) | 	app, err := app.Get(appName) | ||||||
| @ -101,8 +101,8 @@ func ValidateApp(c *cli.Context) app.App { | |||||||
| } | } | ||||||
|  |  | ||||||
| // ValidateDomain ensures the domain name arg is valid. | // ValidateDomain ensures the domain name arg is valid. | ||||||
| func ValidateDomain(c *cli.Context) string { | func ValidateDomain(cmd *cli.Command) string { | ||||||
| 	domainName := c.Args().First() | 	domainName := cmd.Args().First() | ||||||
|  |  | ||||||
| 	if domainName == "" && !NoInput { | 	if domainName == "" && !NoInput { | ||||||
| 		prompt := &survey.Input{ | 		prompt := &survey.Input{ | ||||||
| @ -115,7 +115,7 @@ func ValidateDomain(c *cli.Context) string { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if domainName == "" { | 	if domainName == "" { | ||||||
| 		ShowSubcommandHelpAndError(c, errors.New("no domain provided")) | 		ShowSubcommandHelpAndError(cmd, errors.New("no domain provided")) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	log.Debugf("validated %s as domain argument", domainName) | 	log.Debugf("validated %s as domain argument", domainName) | ||||||
| @ -124,10 +124,10 @@ func ValidateDomain(c *cli.Context) string { | |||||||
| } | } | ||||||
|  |  | ||||||
| // ValidateSubCmdFlags ensures flag order conforms to correct order | // ValidateSubCmdFlags ensures flag order conforms to correct order | ||||||
| func ValidateSubCmdFlags(c *cli.Context) bool { | func ValidateSubCmdFlags(cmd *cli.Command) bool { | ||||||
| 	for argIdx, arg := range c.Args().Slice() { | 	for argIdx, arg := range cmd.Args().Slice() { | ||||||
| 		if !strings.HasPrefix(arg, "--") { | 		if !strings.HasPrefix(arg, "--") { | ||||||
| 			for _, flag := range c.Args().Slice()[argIdx:] { | 			for _, flag := range cmd.Args().Slice()[argIdx:] { | ||||||
| 				if strings.HasPrefix(flag, "--") { | 				if strings.HasPrefix(flag, "--") { | ||||||
| 					return false | 					return false | ||||||
| 				} | 				} | ||||||
| @ -138,8 +138,8 @@ func ValidateSubCmdFlags(c *cli.Context) bool { | |||||||
| } | } | ||||||
|  |  | ||||||
| // ValidateServer ensures the server name arg is valid. | // ValidateServer ensures the server name arg is valid. | ||||||
| func ValidateServer(c *cli.Context) string { | func ValidateServer(cmd *cli.Command) string { | ||||||
| 	serverName := c.Args().First() | 	serverName := cmd.Args().First() | ||||||
|  |  | ||||||
| 	serverNames, err := config.ReadServerNames() | 	serverNames, err := config.ReadServerNames() | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| @ -164,11 +164,11 @@ func ValidateServer(c *cli.Context) string { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if serverName == "" { | 	if serverName == "" { | ||||||
| 		ShowSubcommandHelpAndError(c, errors.New("no server provided")) | 		ShowSubcommandHelpAndError(cmd, errors.New("no server provided")) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if !matched { | 	if !matched { | ||||||
| 		ShowSubcommandHelpAndError(c, errors.New("server doesn't exist?")) | 		ShowSubcommandHelpAndError(cmd, errors.New("server doesn't exist?")) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	log.Debugf("validated %s as server argument", serverName) | 	log.Debugf("validated %s as server argument", serverName) | ||||||
|  | |||||||
| @ -1,11 +1,13 @@ | |||||||
| package recipe | package recipe | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
|  | 	"context" | ||||||
|  |  | ||||||
| 	"coopcloud.tech/abra/cli/internal" | 	"coopcloud.tech/abra/cli/internal" | ||||||
| 	"coopcloud.tech/abra/pkg/autocomplete" | 	"coopcloud.tech/abra/pkg/autocomplete" | ||||||
| 	gitPkg "coopcloud.tech/abra/pkg/git" | 	gitPkg "coopcloud.tech/abra/pkg/git" | ||||||
| 	"coopcloud.tech/abra/pkg/log" | 	"coopcloud.tech/abra/pkg/log" | ||||||
| 	"github.com/urfave/cli/v2" | 	"github.com/urfave/cli/v3" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| var recipeDiffCommand = cli.Command{ | var recipeDiffCommand = cli.Command{ | ||||||
| @ -13,15 +15,12 @@ var recipeDiffCommand = cli.Command{ | |||||||
| 	Usage:         "Show unstaged changes in recipe config", | 	Usage:         "Show unstaged changes in recipe config", | ||||||
| 	Description:   "This command requires /usr/bin/git.", | 	Description:   "This command requires /usr/bin/git.", | ||||||
| 	Aliases:       []string{"d"}, | 	Aliases:       []string{"d"}, | ||||||
| 	ArgsUsage:   "<recipe>", | 	UsageText:     "abra recipe diff <recipe> [options]", | ||||||
| 	Flags: []cli.Flag{ |  | ||||||
| 		internal.DebugFlag, |  | ||||||
| 		internal.NoInputFlag, |  | ||||||
| 	}, |  | ||||||
| 	Before:        internal.SubCommandBefore, | 	Before:        internal.SubCommandBefore, | ||||||
| 	BashComplete: autocomplete.RecipeNameComplete, | 	ShellComplete: autocomplete.RecipeNameComplete, | ||||||
| 	Action: func(c *cli.Context) error { | 	HideHelp:      true, | ||||||
| 		r := internal.ValidateRecipe(c) | 	Action: func(ctx context.Context, cmd *cli.Command) error { | ||||||
|  | 		r := internal.ValidateRecipe(cmd) | ||||||
|  |  | ||||||
| 		if err := gitPkg.DiffUnstaged(r.Dir); err != nil { | 		if err := gitPkg.DiffUnstaged(r.Dir); err != nil { | ||||||
| 			log.Fatal(err) | 			log.Fatal(err) | ||||||
|  | |||||||
| @ -1,32 +1,30 @@ | |||||||
| package recipe | package recipe | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
|  | 	"context" | ||||||
|  |  | ||||||
| 	"coopcloud.tech/abra/cli/internal" | 	"coopcloud.tech/abra/cli/internal" | ||||||
| 	"coopcloud.tech/abra/pkg/autocomplete" | 	"coopcloud.tech/abra/pkg/autocomplete" | ||||||
| 	"coopcloud.tech/abra/pkg/formatter" | 	"coopcloud.tech/abra/pkg/formatter" | ||||||
| 	"coopcloud.tech/abra/pkg/log" | 	"coopcloud.tech/abra/pkg/log" | ||||||
| 	"coopcloud.tech/abra/pkg/recipe" | 	"coopcloud.tech/abra/pkg/recipe" | ||||||
| 	"github.com/urfave/cli/v2" | 	"github.com/urfave/cli/v3" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| var recipeFetchCommand = cli.Command{ | var recipeFetchCommand = cli.Command{ | ||||||
| 	Name:          "fetch", | 	Name:          "fetch", | ||||||
| 	Usage:         "Fetch recipe(s)", | 	Usage:         "Fetch recipe(s)", | ||||||
| 	Aliases:       []string{"f"}, | 	Aliases:       []string{"f"}, | ||||||
| 	ArgsUsage:   "[<recipe>]", | 	UsageText:     "abra recipe fetch [<recipe>] [options]", | ||||||
| 	Description:   "Retrieves all recipes if no <recipe> argument is passed", | 	Description:   "Retrieves all recipes if no <recipe> argument is passed", | ||||||
| 	Flags: []cli.Flag{ |  | ||||||
| 		internal.DebugFlag, |  | ||||||
| 		internal.NoInputFlag, |  | ||||||
| 		internal.OfflineFlag, |  | ||||||
| 	}, |  | ||||||
| 	Before:        internal.SubCommandBefore, | 	Before:        internal.SubCommandBefore, | ||||||
| 	BashComplete: autocomplete.RecipeNameComplete, | 	ShellComplete: autocomplete.RecipeNameComplete, | ||||||
| 	Action: func(c *cli.Context) error { | 	HideHelp:      true, | ||||||
| 		recipeName := c.Args().First() | 	Action: func(ctx context.Context, cmd *cli.Command) error { | ||||||
|  | 		recipeName := cmd.Args().First() | ||||||
| 		r := recipe.Get(recipeName) | 		r := recipe.Get(recipeName) | ||||||
| 		if recipeName != "" { | 		if recipeName != "" { | ||||||
| 			internal.ValidateRecipe(c) | 			internal.ValidateRecipe(cmd) | ||||||
| 			if err := r.Ensure(false, false); err != nil { | 			if err := r.Ensure(false, false); err != nil { | ||||||
| 				log.Fatal(err) | 				log.Fatal(err) | ||||||
| 			} | 			} | ||||||
|  | |||||||
| @ -1,6 +1,7 @@ | |||||||
| package recipe | package recipe | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
|  | 	"context" | ||||||
| 	"fmt" | 	"fmt" | ||||||
|  |  | ||||||
| 	"coopcloud.tech/abra/cli/internal" | 	"coopcloud.tech/abra/cli/internal" | ||||||
| @ -8,25 +9,23 @@ import ( | |||||||
| 	"coopcloud.tech/abra/pkg/formatter" | 	"coopcloud.tech/abra/pkg/formatter" | ||||||
| 	"coopcloud.tech/abra/pkg/lint" | 	"coopcloud.tech/abra/pkg/lint" | ||||||
| 	"coopcloud.tech/abra/pkg/log" | 	"coopcloud.tech/abra/pkg/log" | ||||||
| 	"github.com/urfave/cli/v2" | 	"github.com/urfave/cli/v3" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| var recipeLintCommand = cli.Command{ | var recipeLintCommand = cli.Command{ | ||||||
| 	Name:      "lint", | 	Name:      "lint", | ||||||
| 	Usage:     "Lint a recipe", | 	Usage:     "Lint a recipe", | ||||||
| 	Aliases:   []string{"l"}, | 	Aliases:   []string{"l"}, | ||||||
| 	ArgsUsage: "<recipe>", | 	UsageText: "abra recipe lint <recipe> [options]", | ||||||
| 	Flags: []cli.Flag{ | 	Flags: []cli.Flag{ | ||||||
| 		internal.DebugFlag, |  | ||||||
| 		internal.OnlyErrorFlag, | 		internal.OnlyErrorFlag, | ||||||
| 		internal.OfflineFlag, |  | ||||||
| 		internal.NoInputFlag, |  | ||||||
| 		internal.ChaosFlag, | 		internal.ChaosFlag, | ||||||
| 	}, | 	}, | ||||||
| 	Before:        internal.SubCommandBefore, | 	Before:        internal.SubCommandBefore, | ||||||
| 	BashComplete: autocomplete.RecipeNameComplete, | 	ShellComplete: autocomplete.RecipeNameComplete, | ||||||
| 	Action: func(c *cli.Context) error { | 	HideHelp:      true, | ||||||
| 		recipe := internal.ValidateRecipe(c) | 	Action: func(ctx context.Context, cmd *cli.Command) error { | ||||||
|  | 		recipe := internal.ValidateRecipe(cmd) | ||||||
|  |  | ||||||
| 		if err := recipe.Ensure(internal.Chaos, internal.Offline); err != nil { | 		if err := recipe.Ensure(internal.Chaos, internal.Offline); err != nil { | ||||||
| 			log.Fatal(err) | 			log.Fatal(err) | ||||||
|  | |||||||
| @ -1,6 +1,7 @@ | |||||||
| package recipe | package recipe | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
|  | 	"context" | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"sort" | 	"sort" | ||||||
| 	"strconv" | 	"strconv" | ||||||
| @ -10,7 +11,7 @@ import ( | |||||||
| 	"coopcloud.tech/abra/pkg/formatter" | 	"coopcloud.tech/abra/pkg/formatter" | ||||||
| 	"coopcloud.tech/abra/pkg/log" | 	"coopcloud.tech/abra/pkg/log" | ||||||
| 	"coopcloud.tech/abra/pkg/recipe" | 	"coopcloud.tech/abra/pkg/recipe" | ||||||
| 	"github.com/urfave/cli/v2" | 	"github.com/urfave/cli/v3" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| var pattern string | var pattern string | ||||||
| @ -24,16 +25,16 @@ var patternFlag = &cli.StringFlag{ | |||||||
|  |  | ||||||
| var recipeListCommand = cli.Command{ | var recipeListCommand = cli.Command{ | ||||||
| 	Name:      "list", | 	Name:      "list", | ||||||
| 	Usage:   "List available recipes", | 	Usage:     "List recipes", | ||||||
|  | 	UsageText: "abra recipe list [options]", | ||||||
| 	Aliases:   []string{"ls"}, | 	Aliases:   []string{"ls"}, | ||||||
| 	Flags: []cli.Flag{ | 	Flags: []cli.Flag{ | ||||||
| 		internal.DebugFlag, |  | ||||||
| 		internal.MachineReadableFlag, | 		internal.MachineReadableFlag, | ||||||
| 		patternFlag, | 		patternFlag, | ||||||
| 		internal.OfflineFlag, |  | ||||||
| 	}, | 	}, | ||||||
| 	Before:   internal.SubCommandBefore, | 	Before:   internal.SubCommandBefore, | ||||||
| 	Action: func(c *cli.Context) error { | 	HideHelp: true, | ||||||
|  | 	Action: func(ctx context.Context, cmd *cli.Command) error { | ||||||
| 		catl, err := recipe.ReadRecipeCatalogue(internal.Offline) | 		catl, err := recipe.ReadRecipeCatalogue(internal.Offline) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			log.Fatal(err.Error()) | 			log.Fatal(err.Error()) | ||||||
|  | |||||||
| @ -2,6 +2,7 @@ package recipe | |||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"bytes" | 	"bytes" | ||||||
|  | 	"context" | ||||||
| 	"errors" | 	"errors" | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"os" | 	"os" | ||||||
| @ -13,7 +14,7 @@ import ( | |||||||
| 	"coopcloud.tech/abra/pkg/git" | 	"coopcloud.tech/abra/pkg/git" | ||||||
| 	"coopcloud.tech/abra/pkg/log" | 	"coopcloud.tech/abra/pkg/log" | ||||||
| 	"coopcloud.tech/abra/pkg/recipe" | 	"coopcloud.tech/abra/pkg/recipe" | ||||||
| 	"github.com/urfave/cli/v2" | 	"github.com/urfave/cli/v3" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| // recipeMetadata is the recipe metadata for the README.md | // recipeMetadata is the recipe metadata for the README.md | ||||||
| @ -34,27 +35,24 @@ var recipeNewCommand = cli.Command{ | |||||||
| 	Name:    "new", | 	Name:    "new", | ||||||
| 	Aliases: []string{"n"}, | 	Aliases: []string{"n"}, | ||||||
| 	Flags: []cli.Flag{ | 	Flags: []cli.Flag{ | ||||||
| 		internal.DebugFlag, |  | ||||||
| 		internal.NoInputFlag, |  | ||||||
| 		internal.OfflineFlag, |  | ||||||
| 		internal.GitNameFlag, | 		internal.GitNameFlag, | ||||||
| 		internal.GitEmailFlag, | 		internal.GitEmailFlag, | ||||||
| 	}, | 	}, | ||||||
| 	Before:    internal.SubCommandBefore, | 	Before:    internal.SubCommandBefore, | ||||||
| 	Usage:     "Create a new recipe", | 	Usage:     "Create a new recipe", | ||||||
| 	ArgsUsage: "<recipe>", | 	UsageText: "abra recipe new <recipe> [options]", | ||||||
| 	Description: ` | 	Description: `Create a new recipe. | ||||||
| Create a new recipe. |  | ||||||
|  |  | ||||||
| Abra uses the built-in example repository which is available here: | Abra uses the built-in example repository which is available here: | ||||||
|  |  | ||||||
|     https://git.coopcloud.tech/coop-cloud/example`, |     https://git.coopcloud.tech/coop-cloud/example`, | ||||||
| 	Action: func(c *cli.Context) error { | 	HideHelp: true, | ||||||
| 		recipeName := c.Args().First() | 	Action: func(ctx context.Context, cmd *cli.Command) error { | ||||||
|  | 		recipeName := cmd.Args().First() | ||||||
| 		r := recipe.Get(recipeName) | 		r := recipe.Get(recipeName) | ||||||
|  |  | ||||||
| 		if recipeName == "" { | 		if recipeName == "" { | ||||||
| 			internal.ShowSubcommandHelpAndError(c, errors.New("no recipe name provided")) | 			internal.ShowSubcommandHelpAndError(cmd, errors.New("no recipe name provided")) | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if _, err := os.Stat(r.Dir); !os.IsNotExist(err) { | 		if _, err := os.Stat(r.Dir); !os.IsNotExist(err) { | ||||||
|  | |||||||
| @ -1,7 +1,7 @@ | |||||||
| package recipe | package recipe | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"github.com/urfave/cli/v2" | 	"github.com/urfave/cli/v3" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| // RecipeCommand defines all recipe related sub-commands. | // RecipeCommand defines all recipe related sub-commands. | ||||||
| @ -9,17 +9,17 @@ var RecipeCommand = cli.Command{ | |||||||
| 	Name:      "recipe", | 	Name:      "recipe", | ||||||
| 	Aliases:   []string{"r"}, | 	Aliases:   []string{"r"}, | ||||||
| 	Usage:     "Manage recipes", | 	Usage:     "Manage recipes", | ||||||
| 	ArgsUsage: "<recipe>", | 	UsageText: "abra recipe [command] [arguments] [options]", | ||||||
| 	Description: ` | 	Description: `A recipe is a blueprint for an app. | ||||||
| A recipe is a blueprint for an app. It is a bunch of config files which |  | ||||||
| describe how to deploy and maintain an app. Recipes are maintained by the Co-op | It is a bunch of config files which describe how to deploy and maintain an app. | ||||||
| Cloud community and you can use Abra to read them, deploy them and create apps | Recipes are maintained by the Co-op Cloud community and you can use Abra to | ||||||
| for you. | read them, deploy them and create apps for you. | ||||||
|  |  | ||||||
| Anyone who uses a recipe can become a maintainer. Maintainers typically make | Anyone who uses a recipe can become a maintainer. Maintainers typically make | ||||||
| sure the recipe is in good working order and the config upgraded in a timely | sure the recipe is in good working order and the config upgraded in a timely | ||||||
| manner.`, | manner.`, | ||||||
| 	Subcommands: []*cli.Command{ | 	Commands: []*cli.Command{ | ||||||
| 		&recipeFetchCommand, | 		&recipeFetchCommand, | ||||||
| 		&recipeLintCommand, | 		&recipeLintCommand, | ||||||
| 		&recipeListCommand, | 		&recipeListCommand, | ||||||
|  | |||||||
| @ -1,6 +1,7 @@ | |||||||
| package recipe | package recipe | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
|  | 	"context" | ||||||
| 	"errors" | 	"errors" | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"os" | 	"os" | ||||||
| @ -18,17 +19,18 @@ import ( | |||||||
| 	"github.com/AlecAivazis/survey/v2" | 	"github.com/AlecAivazis/survey/v2" | ||||||
| 	"github.com/distribution/reference" | 	"github.com/distribution/reference" | ||||||
| 	"github.com/go-git/go-git/v5" | 	"github.com/go-git/go-git/v5" | ||||||
| 	"github.com/urfave/cli/v2" | 	"github.com/urfave/cli/v3" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| var recipeReleaseCommand = cli.Command{ | var recipeReleaseCommand = cli.Command{ | ||||||
| 	Name:      "release", | 	Name:      "release", | ||||||
| 	Aliases:   []string{"rl"}, | 	Aliases:   []string{"rl"}, | ||||||
| 	Usage:     "Release a new recipe version", | 	Usage:     "Release a new recipe version", | ||||||
| 	ArgsUsage: "<recipe> [<version>]", | 	UsageText: "abra recipe release <recipe> [<version>] [options]", | ||||||
| 	Description: ` | 	Description: `Create a new version of a recipe. | ||||||
| Create a new version of a recipe. These versions are then published on the |  | ||||||
| Co-op Cloud recipe catalogue. These versions take the following form: | These versions are then published on the Co-op Cloud recipe catalogue. These | ||||||
|  | versions take the following form: | ||||||
|  |  | ||||||
|     a.b.c+x.y.z |     a.b.c+x.y.z | ||||||
|  |  | ||||||
| @ -46,19 +48,17 @@ Publish your new release to git.coopcloud.tech with "-p/--publish". This | |||||||
| requires that you have permission to git push to these repositories and have | requires that you have permission to git push to these repositories and have | ||||||
| your SSH keys configured on your account.`, | your SSH keys configured on your account.`, | ||||||
| 	Flags: []cli.Flag{ | 	Flags: []cli.Flag{ | ||||||
| 		internal.DebugFlag, |  | ||||||
| 		internal.NoInputFlag, |  | ||||||
| 		internal.DryFlag, | 		internal.DryFlag, | ||||||
| 		internal.MajorFlag, | 		internal.MajorFlag, | ||||||
| 		internal.MinorFlag, | 		internal.MinorFlag, | ||||||
| 		internal.PatchFlag, | 		internal.PatchFlag, | ||||||
| 		internal.PublishFlag, | 		internal.PublishFlag, | ||||||
| 		internal.OfflineFlag, |  | ||||||
| 	}, | 	}, | ||||||
| 	Before:        internal.SubCommandBefore, | 	Before:        internal.SubCommandBefore, | ||||||
| 	BashComplete: autocomplete.RecipeNameComplete, | 	ShellComplete: autocomplete.RecipeNameComplete, | ||||||
| 	Action: func(c *cli.Context) error { | 	HideHelp:      true, | ||||||
| 		recipe := internal.ValidateRecipe(c) | 	Action: func(ctx context.Context, cmd *cli.Command) error { | ||||||
|  | 		recipe := internal.ValidateRecipe(cmd) | ||||||
|  |  | ||||||
| 		imagesTmp, err := getImageVersions(recipe) | 		imagesTmp, err := getImageVersions(recipe) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| @ -75,7 +75,7 @@ your SSH keys configured on your account.`, | |||||||
| 			log.Fatalf("main app service version for %s is empty?", recipe.Name) | 			log.Fatalf("main app service version for %s is empty?", recipe.Name) | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		tagString := c.Args().Get(1) | 		tagString := cmd.Args().Get(1) | ||||||
| 		if tagString != "" { | 		if tagString != "" { | ||||||
| 			if _, err := tagcmp.Parse(tagString); err != nil { | 			if _, err := tagcmp.Parse(tagString); err != nil { | ||||||
| 				log.Fatalf("cannot parse %s, invalid tag specified?", tagString) | 				log.Fatalf("cannot parse %s, invalid tag specified?", tagString) | ||||||
|  | |||||||
| @ -1,12 +1,14 @@ | |||||||
| package recipe | package recipe | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
|  | 	"context" | ||||||
|  |  | ||||||
| 	"coopcloud.tech/abra/cli/internal" | 	"coopcloud.tech/abra/cli/internal" | ||||||
| 	"coopcloud.tech/abra/pkg/autocomplete" | 	"coopcloud.tech/abra/pkg/autocomplete" | ||||||
| 	"coopcloud.tech/abra/pkg/log" | 	"coopcloud.tech/abra/pkg/log" | ||||||
| 	"coopcloud.tech/abra/pkg/recipe" | 	"coopcloud.tech/abra/pkg/recipe" | ||||||
| 	"github.com/go-git/go-git/v5" | 	"github.com/go-git/go-git/v5" | ||||||
| 	"github.com/urfave/cli/v2" | 	"github.com/urfave/cli/v3" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| var recipeResetCommand = cli.Command{ | var recipeResetCommand = cli.Command{ | ||||||
| @ -14,19 +16,16 @@ var recipeResetCommand = cli.Command{ | |||||||
| 	Usage:         "Remove all unstaged changes from recipe config", | 	Usage:         "Remove all unstaged changes from recipe config", | ||||||
| 	Description:   "WARNING: this will delete your changes. Be Careful.", | 	Description:   "WARNING: this will delete your changes. Be Careful.", | ||||||
| 	Aliases:       []string{"rs"}, | 	Aliases:       []string{"rs"}, | ||||||
| 	ArgsUsage:   "<recipe>", | 	UsageText:     "abra recipe reset <recipe> [options]", | ||||||
| 	Flags: []cli.Flag{ |  | ||||||
| 		internal.DebugFlag, |  | ||||||
| 		internal.NoInputFlag, |  | ||||||
| 	}, |  | ||||||
| 	Before:        internal.SubCommandBefore, | 	Before:        internal.SubCommandBefore, | ||||||
| 	BashComplete: autocomplete.RecipeNameComplete, | 	ShellComplete: autocomplete.RecipeNameComplete, | ||||||
| 	Action: func(c *cli.Context) error { | 	HideHelp:      true, | ||||||
| 		recipeName := c.Args().First() | 	Action: func(ctx context.Context, cmd *cli.Command) error { | ||||||
|  | 		recipeName := cmd.Args().First() | ||||||
| 		r := recipe.Get(recipeName) | 		r := recipe.Get(recipeName) | ||||||
|  |  | ||||||
| 		if recipeName != "" { | 		if recipeName != "" { | ||||||
| 			internal.ValidateRecipe(c) | 			internal.ValidateRecipe(cmd) | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		repo, err := git.PlainOpen(r.Dir) | 		repo, err := git.PlainOpen(r.Dir) | ||||||
|  | |||||||
| @ -1,6 +1,7 @@ | |||||||
| package recipe | package recipe | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
|  | 	"context" | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"strconv" | 	"strconv" | ||||||
|  |  | ||||||
| @ -12,35 +13,34 @@ import ( | |||||||
| 	"github.com/AlecAivazis/survey/v2" | 	"github.com/AlecAivazis/survey/v2" | ||||||
| 	"github.com/go-git/go-git/v5" | 	"github.com/go-git/go-git/v5" | ||||||
| 	"github.com/go-git/go-git/v5/plumbing" | 	"github.com/go-git/go-git/v5/plumbing" | ||||||
| 	"github.com/urfave/cli/v2" | 	"github.com/urfave/cli/v3" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| var recipeSyncCommand = cli.Command{ | var recipeSyncCommand = cli.Command{ | ||||||
| 	Name:      "sync", | 	Name:      "sync", | ||||||
| 	Aliases:   []string{"s"}, | 	Aliases:   []string{"s"}, | ||||||
| 	Usage:     "Sync recipe version label", | 	Usage:     "Sync recipe version label", | ||||||
| 	ArgsUsage: "<recipe> [<version>]", | 	UsageText: "abra recipe lint <recipe> [<version>] [options]", | ||||||
| 	Flags: []cli.Flag{ | 	Flags: []cli.Flag{ | ||||||
| 		internal.DebugFlag, |  | ||||||
| 		internal.NoInputFlag, |  | ||||||
| 		internal.DryFlag, | 		internal.DryFlag, | ||||||
| 		internal.MajorFlag, | 		internal.MajorFlag, | ||||||
| 		internal.MinorFlag, | 		internal.MinorFlag, | ||||||
| 		internal.PatchFlag, | 		internal.PatchFlag, | ||||||
| 	}, | 	}, | ||||||
| 	Before: internal.SubCommandBefore, | 	Before: internal.SubCommandBefore, | ||||||
| 	Description: ` | 	Description: `Generate labels for the main recipe service. | ||||||
| Generate labels for the main recipe service (i.e. by convention, the service |  | ||||||
| named "app") which corresponds to the following format: | By convention, the service named "app" using the following format: | ||||||
|  |  | ||||||
|     coop-cloud.${STACK_NAME}.version=<version> |     coop-cloud.${STACK_NAME}.version=<version> | ||||||
|  |  | ||||||
| Where <version> can be specifed on the command-line or Abra can attempt to | Where <version> can be specifed on the command-line or Abra can attempt to | ||||||
| auto-generate it for you. The <recipe> configuration will be updated on the | auto-generate it for you. The <recipe> configuration will be updated on the | ||||||
| local file system.`, | local file system.`, | ||||||
| 	BashComplete: autocomplete.RecipeNameComplete, | 	ShellComplete: autocomplete.RecipeNameComplete, | ||||||
| 	Action: func(c *cli.Context) error { | 	HideHelp:      true, | ||||||
| 		recipe := internal.ValidateRecipe(c) | 	Action: func(ctx context.Context, cmd *cli.Command) error { | ||||||
|  | 		recipe := internal.ValidateRecipe(cmd) | ||||||
|  |  | ||||||
| 		mainApp, err := internal.GetMainAppImage(recipe) | 		mainApp, err := internal.GetMainAppImage(recipe) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| @ -59,7 +59,7 @@ local file system.`, | |||||||
| 			log.Fatal(err) | 			log.Fatal(err) | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		nextTag := c.Args().Get(1) | 		nextTag := cmd.Args().Get(1) | ||||||
| 		if len(tags) == 0 && nextTag == "" { | 		if len(tags) == 0 && nextTag == "" { | ||||||
| 			log.Warnf("no git tags found for %s", recipe.Name) | 			log.Warnf("no git tags found for %s", recipe.Name) | ||||||
| 			if internal.NoInput { | 			if internal.NoInput { | ||||||
|  | |||||||
| @ -2,6 +2,7 @@ package recipe | |||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"bufio" | 	"bufio" | ||||||
|  | 	"context" | ||||||
| 	"encoding/json" | 	"encoding/json" | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"os" | 	"os" | ||||||
| @ -19,7 +20,7 @@ import ( | |||||||
| 	"coopcloud.tech/tagcmp" | 	"coopcloud.tech/tagcmp" | ||||||
| 	"github.com/AlecAivazis/survey/v2" | 	"github.com/AlecAivazis/survey/v2" | ||||||
| 	"github.com/distribution/reference" | 	"github.com/distribution/reference" | ||||||
| 	"github.com/urfave/cli/v2" | 	"github.com/urfave/cli/v3" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| type imgPin struct { | type imgPin struct { | ||||||
| @ -27,8 +28,8 @@ type imgPin struct { | |||||||
| 	version tagcmp.Tag | 	version tagcmp.Tag | ||||||
| } | } | ||||||
|  |  | ||||||
| // anUpgrade represents a single service upgrade (as within a recipe), and the list of tags that it can be upgraded to, | // anUpgrade represents a single service upgrade (as within a recipe), and the | ||||||
| // for serialization purposes. | // list of tags that it can be upgraded to, for serialization purposes. | ||||||
| type anUpgrade struct { | type anUpgrade struct { | ||||||
| 	Service     string   `json:"service"` | 	Service     string   `json:"service"` | ||||||
| 	Image       string   `json:"image"` | 	Image       string   `json:"image"` | ||||||
| @ -40,10 +41,10 @@ var recipeUpgradeCommand = cli.Command{ | |||||||
| 	Name:      "upgrade", | 	Name:      "upgrade", | ||||||
| 	Aliases:   []string{"u"}, | 	Aliases:   []string{"u"}, | ||||||
| 	Usage:     "Upgrade recipe image tags", | 	Usage:     "Upgrade recipe image tags", | ||||||
| 	Description: ` | 	UsageText: "abra recipe upgrade [<recipe>] [options]", | ||||||
| Parse all image tags within the given <recipe> configuration and prompt with | 	Description: `Upgrade a given <recipe> configuration. | ||||||
| more recent tags to upgrade to. It will update the relevant compose file tags |  | ||||||
| on the local file system. | It will update the relevant compose file tags on the local file system. | ||||||
|  |  | ||||||
| Some image tags cannot be parsed because they do not follow some sort of | Some image tags cannot be parsed because they do not follow some sort of | ||||||
| semver-like convention. In this case, all possible tags will be listed and it | semver-like convention. In this case, all possible tags will be listed and it | ||||||
| @ -53,15 +54,8 @@ The command is interactive and will show a select input which allows you to | |||||||
| make a seclection. Use the "?" key to see more help on navigating this | make a seclection. Use the "?" key to see more help on navigating this | ||||||
| interface. | interface. | ||||||
|  |  | ||||||
| You may invoke this command in "wizard" mode and be prompted for input. | You may invoke this command in "wizard" mode and be prompted for input.`, | ||||||
|  |  | ||||||
| EXAMPLE: |  | ||||||
|  |  | ||||||
|     abra recipe upgrade`, |  | ||||||
| 	ArgsUsage: "<recipe>", |  | ||||||
| 	Flags: []cli.Flag{ | 	Flags: []cli.Flag{ | ||||||
| 		internal.DebugFlag, |  | ||||||
| 		internal.NoInputFlag, |  | ||||||
| 		internal.PatchFlag, | 		internal.PatchFlag, | ||||||
| 		internal.MinorFlag, | 		internal.MinorFlag, | ||||||
| 		internal.MajorFlag, | 		internal.MajorFlag, | ||||||
| @ -69,9 +63,10 @@ EXAMPLE: | |||||||
| 		internal.AllTagsFlag, | 		internal.AllTagsFlag, | ||||||
| 	}, | 	}, | ||||||
| 	Before:        internal.SubCommandBefore, | 	Before:        internal.SubCommandBefore, | ||||||
| 	BashComplete: autocomplete.RecipeNameComplete, | 	ShellComplete: autocomplete.RecipeNameComplete, | ||||||
| 	Action: func(c *cli.Context) error { | 	HideHelp:      true, | ||||||
| 		recipe := internal.ValidateRecipe(c) | 	Action: func(ctx context.Context, cmd *cli.Command) error { | ||||||
|  | 		recipe := internal.ValidateRecipe(cmd) | ||||||
|  |  | ||||||
| 		if err := recipe.Ensure(internal.Chaos, internal.Offline); err != nil { | 		if err := recipe.Ensure(internal.Chaos, internal.Offline); err != nil { | ||||||
| 			log.Fatal(err) | 			log.Fatal(err) | ||||||
|  | |||||||
| @ -1,6 +1,7 @@ | |||||||
| package recipe | package recipe | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
|  | 	"context" | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"sort" | 	"sort" | ||||||
|  |  | ||||||
| @ -9,7 +10,7 @@ import ( | |||||||
| 	"coopcloud.tech/abra/pkg/formatter" | 	"coopcloud.tech/abra/pkg/formatter" | ||||||
| 	"coopcloud.tech/abra/pkg/log" | 	"coopcloud.tech/abra/pkg/log" | ||||||
| 	recipePkg "coopcloud.tech/abra/pkg/recipe" | 	recipePkg "coopcloud.tech/abra/pkg/recipe" | ||||||
| 	"github.com/urfave/cli/v2" | 	"github.com/urfave/cli/v3" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| func sortServiceByName(versions [][]string) func(i, j int) bool { | func sortServiceByName(versions [][]string) func(i, j int) bool { | ||||||
| @ -26,19 +27,17 @@ var recipeVersionCommand = cli.Command{ | |||||||
| 	Name:      "versions", | 	Name:      "versions", | ||||||
| 	Aliases:   []string{"v"}, | 	Aliases:   []string{"v"}, | ||||||
| 	Usage:     "List recipe versions", | 	Usage:     "List recipe versions", | ||||||
| 	ArgsUsage: "<recipe>", | 	UsageText: "abra recipe version <recipe> [options]", | ||||||
| 	Flags: []cli.Flag{ | 	Flags: []cli.Flag{ | ||||||
| 		internal.DebugFlag, |  | ||||||
| 		internal.OfflineFlag, |  | ||||||
| 		internal.NoInputFlag, |  | ||||||
| 		internal.MachineReadableFlag, | 		internal.MachineReadableFlag, | ||||||
| 	}, | 	}, | ||||||
| 	Before:        internal.SubCommandBefore, | 	Before:        internal.SubCommandBefore, | ||||||
| 	BashComplete: autocomplete.RecipeNameComplete, | 	ShellComplete: autocomplete.RecipeNameComplete, | ||||||
| 	Action: func(c *cli.Context) error { | 	HideHelp:      true, | ||||||
|  | 	Action: func(ctx context.Context, cmd *cli.Command) error { | ||||||
| 		var warnMessages []string | 		var warnMessages []string | ||||||
|  |  | ||||||
| 		recipe := internal.ValidateRecipe(c) | 		recipe := internal.ValidateRecipe(cmd) | ||||||
|  |  | ||||||
| 		catl, err := recipePkg.ReadRecipeCatalogue(internal.Offline) | 		catl, err := recipePkg.ReadRecipeCatalogue(internal.Offline) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
|  | |||||||
| @ -1,6 +1,7 @@ | |||||||
| package server | package server | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
|  | 	"context" | ||||||
| 	"errors" | 	"errors" | ||||||
| 	"os" | 	"os" | ||||||
| 	"path/filepath" | 	"path/filepath" | ||||||
| @ -13,7 +14,7 @@ import ( | |||||||
| 	"coopcloud.tech/abra/pkg/log" | 	"coopcloud.tech/abra/pkg/log" | ||||||
| 	"coopcloud.tech/abra/pkg/server" | 	"coopcloud.tech/abra/pkg/server" | ||||||
| 	sshPkg "coopcloud.tech/abra/pkg/ssh" | 	sshPkg "coopcloud.tech/abra/pkg/ssh" | ||||||
| 	"github.com/urfave/cli/v2" | 	"github.com/urfave/cli/v3" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| var local bool | var local bool | ||||||
| @ -95,13 +96,13 @@ func createServerDir(name string) (bool, error) { | |||||||
| var serverAddCommand = cli.Command{ | var serverAddCommand = cli.Command{ | ||||||
| 	Name:      "add", | 	Name:      "add", | ||||||
| 	Aliases:   []string{"a"}, | 	Aliases:   []string{"a"}, | ||||||
| 	Usage:   "Add a new server to your configuration", | 	Usage:     "Add a new server", | ||||||
| 	Description: ` | 	UsageText: "abra server add <domain> [options]", | ||||||
| Add a new server to your configuration so that it can be managed by Abra. | 	Description: `Add a new server to your configuration so that it can be managed by Abra. | ||||||
|  |  | ||||||
| Abra relies on the standard SSH command-line and ~/.ssh/config for client | Abra relies on the standard SSH command-line and ~/.ssh/config for client | ||||||
| connection details. You must configure an entry per-host in your ~/.ssh/config | connection details. You must configure an entry per-host in your ~/.ssh/config | ||||||
| for each server. For example: | for each server: | ||||||
|  |  | ||||||
|   Host example.com example |   Host example.com example | ||||||
|     Hostname example.com |     Hostname example.com | ||||||
| @ -109,10 +110,6 @@ for each server. For example: | |||||||
|     Port 12345 |     Port 12345 | ||||||
|     IdentityFile ~/.ssh/example@somewhere |     IdentityFile ~/.ssh/example@somewhere | ||||||
|  |  | ||||||
| You can then add a server like so: |  | ||||||
|  |  | ||||||
|   abra server add example.com |  | ||||||
|  |  | ||||||
| If "--local" is passed, then Abra assumes that the current local server is | If "--local" is passed, then Abra assumes that the current local server is | ||||||
| intended as the target server. This is useful when you want to have your entire | intended as the target server. This is useful when you want to have your entire | ||||||
| Co-op Cloud config located on the server itself, and not on your local | Co-op Cloud config located on the server itself, and not on your local | ||||||
| @ -120,28 +117,24 @@ developer machine. The domain is then set to "default". | |||||||
|  |  | ||||||
| You can also pass "--no-domain-checks/-D" flag to use any arbitrary name | You can also pass "--no-domain-checks/-D" flag to use any arbitrary name | ||||||
| instead of a real domain. The host will be resolved with the "Hostname" entry | instead of a real domain. The host will be resolved with the "Hostname" entry | ||||||
| of your ~/.ssh/config. Checks for a valid online domain will be skipped: | of your ~/.ssh/config. Checks for a valid online domain will be skipped.`, | ||||||
|  |  | ||||||
|   abra server add -D example`, |  | ||||||
| 	Flags: []cli.Flag{ | 	Flags: []cli.Flag{ | ||||||
| 		internal.DebugFlag, |  | ||||||
| 		internal.NoInputFlag, |  | ||||||
| 		internal.NoDomainChecksFlag, | 		internal.NoDomainChecksFlag, | ||||||
| 		localFlag, | 		localFlag, | ||||||
| 	}, | 	}, | ||||||
| 	Before:   internal.SubCommandBefore, | 	Before:   internal.SubCommandBefore, | ||||||
| 	ArgsUsage: "<name>", | 	HideHelp: true, | ||||||
| 	Action: func(c *cli.Context) error { | 	Action: func(ctx context.Context, cmd *cli.Command) error { | ||||||
| 		if c.Args().Len() > 0 && local || !internal.ValidateSubCmdFlags(c) { | 		if cmd.Args().Len() > 0 && local || !internal.ValidateSubCmdFlags(cmd) { | ||||||
| 			err := errors.New("cannot use <name> and --local together") | 			err := errors.New("cannot use <name> and --local together") | ||||||
| 			internal.ShowSubcommandHelpAndError(c, err) | 			internal.ShowSubcommandHelpAndError(cmd, err) | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		var name string | 		var name string | ||||||
| 		if local { | 		if local { | ||||||
| 			name = "default" | 			name = "default" | ||||||
| 		} else { | 		} else { | ||||||
| 			name = internal.ValidateDomain(c) | 			name = internal.ValidateDomain(cmd) | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		// NOTE(d1): reasonable 5 second timeout for connections which can't | 		// NOTE(d1): reasonable 5 second timeout for connections which can't | ||||||
|  | |||||||
| @ -1,30 +1,31 @@ | |||||||
| package server | package server | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
|  | 	"context" | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"strings" | 	"strings" | ||||||
|  |  | ||||||
| 	"coopcloud.tech/abra/cli/internal" | 	"coopcloud.tech/abra/cli/internal" | ||||||
| 	"coopcloud.tech/abra/pkg/config" | 	"coopcloud.tech/abra/pkg/config" | ||||||
| 	"coopcloud.tech/abra/pkg/context" | 	contextPkg "coopcloud.tech/abra/pkg/context" | ||||||
| 	"coopcloud.tech/abra/pkg/formatter" | 	"coopcloud.tech/abra/pkg/formatter" | ||||||
| 	"coopcloud.tech/abra/pkg/log" | 	"coopcloud.tech/abra/pkg/log" | ||||||
| 	"github.com/docker/cli/cli/connhelper/ssh" | 	"github.com/docker/cli/cli/connhelper/ssh" | ||||||
| 	"github.com/urfave/cli/v2" | 	"github.com/urfave/cli/v3" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| var serverListCommand = cli.Command{ | var serverListCommand = cli.Command{ | ||||||
| 	Name:      "list", | 	Name:      "list", | ||||||
| 	Aliases:   []string{"ls"}, | 	Aliases:   []string{"ls"}, | ||||||
| 	Usage:     "List managed servers", | 	Usage:     "List managed servers", | ||||||
|  | 	UsageText: "abra server list [options]", | ||||||
| 	Flags: []cli.Flag{ | 	Flags: []cli.Flag{ | ||||||
| 		internal.DebugFlag, |  | ||||||
| 		internal.MachineReadableFlag, | 		internal.MachineReadableFlag, | ||||||
| 		internal.OfflineFlag, |  | ||||||
| 	}, | 	}, | ||||||
| 	Before:   internal.SubCommandBefore, | 	Before:   internal.SubCommandBefore, | ||||||
| 	Action: func(c *cli.Context) error { | 	HideHelp: true, | ||||||
| 		dockerContextStore := context.NewDefaultDockerContextStore() | 	Action: func(ctx context.Context, cmd *cli.Command) error { | ||||||
|  | 		dockerContextStore := contextPkg.NewDefaultDockerContextStore() | ||||||
| 		contexts, err := dockerContextStore.Store.List() | 		contexts, err := dockerContextStore.Store.List() | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			log.Fatal(err) | 			log.Fatal(err) | ||||||
| @ -46,14 +47,14 @@ var serverListCommand = cli.Command{ | |||||||
| 		var rows [][]string | 		var rows [][]string | ||||||
| 		for _, serverName := range serverNames { | 		for _, serverName := range serverNames { | ||||||
| 			var row []string | 			var row []string | ||||||
| 			for _, ctx := range contexts { | 			for _, dockerCtx := range contexts { | ||||||
| 				endpoint, err := context.GetContextEndpoint(ctx) | 				endpoint, err := contextPkg.GetContextEndpoint(dockerCtx) | ||||||
| 				if err != nil && strings.Contains(err.Error(), "does not exist") { | 				if err != nil && strings.Contains(err.Error(), "does not exist") { | ||||||
| 					// No local context found, we can continue safely | 					// No local context found, we can continue safely | ||||||
| 					continue | 					continue | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
| 				if ctx.Name == serverName { | 				if dockerCtx.Name == serverName { | ||||||
| 					sp, err := ssh.ParseURL(endpoint) | 					sp, err := ssh.ParseURL(endpoint) | ||||||
| 					if err != nil { | 					if err != nil { | ||||||
| 						log.Fatal(err) | 						log.Fatal(err) | ||||||
|  | |||||||
| @ -9,7 +9,7 @@ import ( | |||||||
| 	"coopcloud.tech/abra/pkg/formatter" | 	"coopcloud.tech/abra/pkg/formatter" | ||||||
| 	"coopcloud.tech/abra/pkg/log" | 	"coopcloud.tech/abra/pkg/log" | ||||||
| 	"github.com/docker/docker/api/types/filters" | 	"github.com/docker/docker/api/types/filters" | ||||||
| 	"github.com/urfave/cli/v2" | 	"github.com/urfave/cli/v3" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| var allFilter bool | var allFilter bool | ||||||
| @ -34,23 +34,20 @@ var serverPruneCommand = cli.Command{ | |||||||
| 	Name:      "prune", | 	Name:      "prune", | ||||||
| 	Aliases:   []string{"p"}, | 	Aliases:   []string{"p"}, | ||||||
| 	Usage:     "Prune resources on a server", | 	Usage:     "Prune resources on a server", | ||||||
| 	Description: ` | 	UsageText: "abra server prune <server> [options]", | ||||||
| Prunes unused containers, networks, and dangling images. | 	Description: `Prunes unused containers, networks, and dangling images. | ||||||
|  |  | ||||||
| Use "-v/--volumes" to remove volumes that are not associated with a deployed | Use "-v/--volumes" to remove volumes that are not associated with a deployed | ||||||
| app. This can result in unwanted data loss if not used carefully.`, | app. This can result in unwanted data loss if not used carefully.`, | ||||||
| 	ArgsUsage: "[<server>]", |  | ||||||
| 	Flags: []cli.Flag{ | 	Flags: []cli.Flag{ | ||||||
| 		allFilterFlag, | 		allFilterFlag, | ||||||
| 		volumesFilterFlag, | 		volumesFilterFlag, | ||||||
| 		internal.DebugFlag, |  | ||||||
| 		internal.OfflineFlag, |  | ||||||
| 		internal.NoInputFlag, |  | ||||||
| 	}, | 	}, | ||||||
| 	Before:        internal.SubCommandBefore, | 	Before:        internal.SubCommandBefore, | ||||||
| 	BashComplete: autocomplete.ServerNameComplete, | 	ShellComplete: autocomplete.ServerNameComplete, | ||||||
| 	Action: func(c *cli.Context) error { | 	HideHelp:      true, | ||||||
| 		serverName := internal.ValidateServer(c) | 	Action: func(ctx context.Context, cmd *cli.Command) error { | ||||||
|  | 		serverName := internal.ValidateServer(cmd) | ||||||
|  |  | ||||||
| 		cl, err := client.New(serverName) | 		cl, err := client.New(serverName) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| @ -59,7 +56,6 @@ app. This can result in unwanted data loss if not used carefully.`, | |||||||
|  |  | ||||||
| 		var args filters.Args | 		var args filters.Args | ||||||
|  |  | ||||||
| 		ctx := context.Background() |  | ||||||
| 		cr, err := cl.ContainersPrune(ctx, args) | 		cr, err := cl.ContainersPrune(ctx, args) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			log.Fatal(err) | 			log.Fatal(err) | ||||||
|  | |||||||
| @ -1,6 +1,7 @@ | |||||||
| package server | package server | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
|  | 	"context" | ||||||
| 	"os" | 	"os" | ||||||
| 	"path/filepath" | 	"path/filepath" | ||||||
|  |  | ||||||
| @ -9,29 +10,24 @@ import ( | |||||||
| 	"coopcloud.tech/abra/pkg/client" | 	"coopcloud.tech/abra/pkg/client" | ||||||
| 	"coopcloud.tech/abra/pkg/config" | 	"coopcloud.tech/abra/pkg/config" | ||||||
| 	"coopcloud.tech/abra/pkg/log" | 	"coopcloud.tech/abra/pkg/log" | ||||||
| 	"github.com/urfave/cli/v2" | 	"github.com/urfave/cli/v3" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| var serverRemoveCommand = cli.Command{ | var serverRemoveCommand = cli.Command{ | ||||||
| 	Name:      "remove", | 	Name:      "remove", | ||||||
| 	Aliases:   []string{"rm"}, | 	Aliases:   []string{"rm"}, | ||||||
| 	ArgsUsage: "<server>", | 	UsageText: "abra server remove <domain> [options]", | ||||||
| 	Usage:     "Remove a managed server", | 	Usage:     "Remove a managed server", | ||||||
| 	Description: ` | 	Description: `Remove a managed server. | ||||||
| Remove a managed server. |  | ||||||
|  |  | ||||||
| Abra will remove the internal bookkeeping (~/.abra/servers/...) and underlying | Abra will remove the internal bookkeeping ($ABRA_DIR/servers/...) and | ||||||
| client connection context. This server will then be lost in time, like tears in | underlying client connection context. This server will then be lost in time, | ||||||
| rain.`, | like tears in rain.`, | ||||||
| 	Flags: []cli.Flag{ |  | ||||||
| 		internal.DebugFlag, |  | ||||||
| 		internal.NoInputFlag, |  | ||||||
| 		internal.OfflineFlag, |  | ||||||
| 	}, |  | ||||||
| 	Before:        internal.SubCommandBefore, | 	Before:        internal.SubCommandBefore, | ||||||
| 	BashComplete: autocomplete.ServerNameComplete, | 	ShellComplete: autocomplete.ServerNameComplete, | ||||||
| 	Action: func(c *cli.Context) error { | 	HideHelp:      true, | ||||||
| 		serverName := internal.ValidateServer(c) | 	Action: func(ctx context.Context, cmd *cli.Command) error { | ||||||
|  | 		serverName := internal.ValidateServer(cmd) | ||||||
|  |  | ||||||
| 		if err := client.DeleteContext(serverName); err != nil { | 		if err := client.DeleteContext(serverName); err != nil { | ||||||
| 			log.Fatal(err) | 			log.Fatal(err) | ||||||
|  | |||||||
| @ -1,7 +1,7 @@ | |||||||
| package server | package server | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"github.com/urfave/cli/v2" | 	"github.com/urfave/cli/v3" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| // ServerCommand defines the `abra server` command and its subcommands | // ServerCommand defines the `abra server` command and its subcommands | ||||||
| @ -9,7 +9,8 @@ var ServerCommand = cli.Command{ | |||||||
| 	Name:      "server", | 	Name:      "server", | ||||||
| 	Aliases:   []string{"s"}, | 	Aliases:   []string{"s"}, | ||||||
| 	Usage:     "Manage servers", | 	Usage:     "Manage servers", | ||||||
| 	Subcommands: []*cli.Command{ | 	UsageText: "abra server [command] [arguments] [options]", | ||||||
|  | 	Commands: []*cli.Command{ | ||||||
| 		&serverAddCommand, | 		&serverAddCommand, | ||||||
| 		&serverListCommand, | 		&serverListCommand, | ||||||
| 		&serverRemoveCommand, | 		&serverRemoveCommand, | ||||||
|  | |||||||
| @ -23,7 +23,7 @@ import ( | |||||||
| 	dockerclient "github.com/docker/docker/client" | 	dockerclient "github.com/docker/docker/client" | ||||||
|  |  | ||||||
| 	"coopcloud.tech/abra/pkg/log" | 	"coopcloud.tech/abra/pkg/log" | ||||||
| 	"github.com/urfave/cli/v2" | 	"github.com/urfave/cli/v3" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| const SERVER = "localhost" | const SERVER = "localhost" | ||||||
| @ -49,20 +49,18 @@ var Notify = cli.Command{ | |||||||
| 	Name:      "notify", | 	Name:      "notify", | ||||||
| 	Aliases:   []string{"n"}, | 	Aliases:   []string{"n"}, | ||||||
| 	Usage:     "Check for available upgrades", | 	Usage:     "Check for available upgrades", | ||||||
|  | 	UsageText: "kadabra notify [options]", | ||||||
| 	Flags: []cli.Flag{ | 	Flags: []cli.Flag{ | ||||||
| 		internal.DebugFlag, |  | ||||||
| 		majorFlag, | 		majorFlag, | ||||||
| 		internal.OfflineFlag, |  | ||||||
| 	}, | 	}, | ||||||
| 	Before: internal.SubCommandBefore, | 	Before: internal.SubCommandBefore, | ||||||
| 	Description: ` | 	Description: `Notify on new versions for deployed apps. | ||||||
| Read the deployed app versions and look for new versions in the recipe |  | ||||||
| catalogue. |  | ||||||
|  |  | ||||||
| If a new patch/minor version is available, a notification is printed. | If a new patch/minor version is available, a notification is printed. | ||||||
|  |  | ||||||
| Use "--major" to include new major versions.`, | Use "--major" to include new major versions.`, | ||||||
| 	Action: func(c *cli.Context) error { | 	HideHelp: true, | ||||||
|  | 	Action: func(ctx context.Context, cmd *cli.Command) error { | ||||||
| 		cl, err := client.New("default") | 		cl, err := client.New("default") | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			log.Fatal(err) | 			log.Fatal(err) | ||||||
| @ -97,17 +95,14 @@ var UpgradeApp = cli.Command{ | |||||||
| 	Name:      "upgrade", | 	Name:      "upgrade", | ||||||
| 	Aliases:   []string{"u"}, | 	Aliases:   []string{"u"}, | ||||||
| 	Usage:     "Upgrade apps", | 	Usage:     "Upgrade apps", | ||||||
| 	ArgsUsage: "<stack-name> <recipe>", | 	UsageText: "kadabra notify <stack> <recipe> [options]", | ||||||
| 	Flags: []cli.Flag{ | 	Flags: []cli.Flag{ | ||||||
| 		internal.DebugFlag, |  | ||||||
| 		internal.ChaosFlag, | 		internal.ChaosFlag, | ||||||
| 		majorFlag, | 		majorFlag, | ||||||
| 		allFlag, | 		allFlag, | ||||||
| 		internal.OfflineFlag, |  | ||||||
| 	}, | 	}, | ||||||
| 	Before: internal.SubCommandBefore, | 	Before: internal.SubCommandBefore, | ||||||
| 	Description: ` | 	Description: `Upgrade an app by specifying stack name and recipe.  | ||||||
| Upgrade an app by specifying stack name and recipe.  |  | ||||||
|  |  | ||||||
| Use "--all" to upgrade every deployed app. | Use "--all" to upgrade every deployed app. | ||||||
|  |  | ||||||
| @ -118,15 +113,16 @@ available, the app is upgraded. | |||||||
| To include major versions use the "--major" flag. You probably don't want that | To include major versions use the "--major" flag. You probably don't want that | ||||||
| as it will break things. Only apps that are not deployed with "--chaos" are | as it will break things. Only apps that are not deployed with "--chaos" are | ||||||
| upgraded, to update chaos deployments use the "--chaos" flag. Use it with care.`, | upgraded, to update chaos deployments use the "--chaos" flag. Use it with care.`, | ||||||
| 	Action: func(c *cli.Context) error { | 	HideHelp: true, | ||||||
|  | 	Action: func(ctx context.Context, cmd *cli.Command) error { | ||||||
| 		cl, err := client.New("default") | 		cl, err := client.New("default") | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			log.Fatal(err) | 			log.Fatal(err) | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if !updateAll { | 		if !updateAll { | ||||||
| 			stackName := c.Args().Get(0) | 			stackName := cmd.Args().Get(0) | ||||||
| 			recipeName := c.Args().Get(1) | 			recipeName := cmd.Args().Get(1) | ||||||
| 			err = tryUpgrade(cl, stackName, recipeName) | 			err = tryUpgrade(cl, stackName, recipeName) | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				log.Fatal(err) | 				log.Fatal(err) | ||||||
| @ -470,25 +466,25 @@ func upgrade(cl *dockerclient.Client, stackName, recipeName, upgradeVersion stri | |||||||
| 	return err | 	return err | ||||||
| } | } | ||||||
|  |  | ||||||
| func newAbraApp(version, commit string) *cli.App { | func newKadabraApp(version, commit string) *cli.Command { | ||||||
| 	app := &cli.App{ | 	app := &cli.Command{ | ||||||
| 		Name:                   "kadabra", | 		Name:                   "kadabra", | ||||||
| 		Usage: `The Co-op Cloud auto-updater |  | ||||||
|     ____                           ____ _                 _ |  | ||||||
|    / ___|___         ___  _ __    / ___| | ___  _   _  __| | |  | ||||||
|   | |   / _ \ _____ / _ \| '_ \  | |   | |/ _ \| | | |/ _' | |  | ||||||
|   | |__| (_) |_____| (_) | |_) | | |___| | (_) | |_| | (_| | |  | ||||||
|    \____\___/       \___/| .__/   \____|_|\___/ \__,_|\__,_| |  | ||||||
|                          |_| |  | ||||||
| `, |  | ||||||
| 		Version:                fmt.Sprintf("%s-%s", version, commit[:7]), | 		Version:                fmt.Sprintf("%s-%s", version, commit[:7]), | ||||||
|  | 		Usage:                  "The Co-op Cloud auto-updater 🤖 🚀", | ||||||
|  | 		UsageText:              "kadabra [command] [options]", | ||||||
|  | 		UseShortOptionHandling: true, | ||||||
|  | 		HideHelpCommand:        true, | ||||||
|  | 		Flags: []cli.Flag{ | ||||||
|  | 			// NOTE(d1): "GLOBAL OPTIONS" flags | ||||||
|  | 			internal.DebugFlag, | ||||||
|  | 		}, | ||||||
| 		Commands: []*cli.Command{ | 		Commands: []*cli.Command{ | ||||||
| 			&Notify, | 			&Notify, | ||||||
| 			&UpgradeApp, | 			&UpgradeApp, | ||||||
| 		}, | 		}, | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	app.Before = func(c *cli.Context) error { | 	app.Before = func(ctx context.Context, cmd *cli.Command) error { | ||||||
| 		log.Logger.SetStyles(log.Styles()) | 		log.Logger.SetStyles(log.Styles()) | ||||||
| 		charmLog.SetDefault(log.Logger) | 		charmLog.SetDefault(log.Logger) | ||||||
|  |  | ||||||
| @ -497,14 +493,20 @@ func newAbraApp(version, commit string) *cli.App { | |||||||
| 		return nil | 		return nil | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	cli.HelpFlag = &cli.BoolFlag{ | ||||||
|  | 		Name:    "help", | ||||||
|  | 		Aliases: []string{"h, H"}, | ||||||
|  | 		Usage:   "Show help", | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	return app | 	return app | ||||||
| } | } | ||||||
|  |  | ||||||
| // RunApp runs CLI abra app. | // RunApp runs CLI abra app. | ||||||
| func RunApp(version, commit string) { | func RunApp(version, commit string) { | ||||||
| 	app := newAbraApp(version, commit) | 	app := newKadabraApp(version, commit) | ||||||
|  |  | ||||||
| 	if err := app.Run(os.Args); err != nil { | 	if err := app.Run(context.Background(), os.Args); err != nil { | ||||||
| 		log.Fatal(err) | 		log.Fatal(err) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  | |||||||
							
								
								
									
										7
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										7
									
								
								go.mod
									
									
									
									
									
								
							| @ -2,6 +2,8 @@ module coopcloud.tech/abra | |||||||
|  |  | ||||||
| go 1.21 | go 1.21 | ||||||
|  |  | ||||||
|  | replace github.com/urfave/cli/v3 => github.com/urfave/cli/v3 v3.0.0-alpha9.1.0.20241019193437-5053ec708a44 | ||||||
|  |  | ||||||
| require ( | require ( | ||||||
| 	coopcloud.tech/tagcmp v0.0.0-20230809071031-eb3e7758d4eb | 	coopcloud.tech/tagcmp v0.0.0-20230809071031-eb3e7758d4eb | ||||||
| 	git.coopcloud.tech/coop-cloud/godotenv v1.5.2-0.20231130100509-01bff8284355 | 	git.coopcloud.tech/coop-cloud/godotenv v1.5.2-0.20231130100509-01bff8284355 | ||||||
| @ -18,7 +20,7 @@ require ( | |||||||
| 	github.com/moby/term v0.5.0 | 	github.com/moby/term v0.5.0 | ||||||
| 	github.com/pkg/errors v0.9.1 | 	github.com/pkg/errors v0.9.1 | ||||||
| 	github.com/schollz/progressbar/v3 v3.14.4 | 	github.com/schollz/progressbar/v3 v3.14.4 | ||||||
| 	github.com/urfave/cli/v2 v2.27.2 | 	github.com/urfave/cli/v3 v3.0.0-alpha9 | ||||||
| 	golang.org/x/term v0.22.0 | 	golang.org/x/term v0.22.0 | ||||||
| 	gopkg.in/yaml.v3 v3.0.1 | 	gopkg.in/yaml.v3 v3.0.1 | ||||||
| 	gotest.tools/v3 v3.5.1 | 	gotest.tools/v3 v3.5.1 | ||||||
| @ -37,7 +39,6 @@ require ( | |||||||
| 	github.com/charmbracelet/x/ansi v0.1.3 // indirect | 	github.com/charmbracelet/x/ansi v0.1.3 // indirect | ||||||
| 	github.com/cloudflare/circl v1.3.9 // indirect | 	github.com/cloudflare/circl v1.3.9 // indirect | ||||||
| 	github.com/containerd/log v0.1.0 // indirect | 	github.com/containerd/log v0.1.0 // indirect | ||||||
| 	github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect |  | ||||||
| 	github.com/cyphar/filepath-securejoin v0.2.5 // indirect | 	github.com/cyphar/filepath-securejoin v0.2.5 // indirect | ||||||
| 	github.com/davecgh/go-spew v1.1.1 // indirect | 	github.com/davecgh/go-spew v1.1.1 // indirect | ||||||
| 	github.com/docker/distribution v2.8.3+incompatible // indirect | 	github.com/docker/distribution v2.8.3+incompatible // indirect | ||||||
| @ -85,14 +86,12 @@ require ( | |||||||
| 	github.com/prometheus/common v0.55.0 // indirect | 	github.com/prometheus/common v0.55.0 // indirect | ||||||
| 	github.com/prometheus/procfs v0.15.1 // indirect | 	github.com/prometheus/procfs v0.15.1 // indirect | ||||||
| 	github.com/rivo/uniseg v0.4.7 // indirect | 	github.com/rivo/uniseg v0.4.7 // indirect | ||||||
| 	github.com/russross/blackfriday/v2 v2.1.0 // indirect |  | ||||||
| 	github.com/sirupsen/logrus v1.9.3 // indirect | 	github.com/sirupsen/logrus v1.9.3 // indirect | ||||||
| 	github.com/skeema/knownhosts v1.2.2 // indirect | 	github.com/skeema/knownhosts v1.2.2 // indirect | ||||||
| 	github.com/spf13/pflag v1.0.5 // indirect | 	github.com/spf13/pflag v1.0.5 // indirect | ||||||
| 	github.com/xanzy/ssh-agent v0.3.3 // indirect | 	github.com/xanzy/ssh-agent v0.3.3 // indirect | ||||||
| 	github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect | 	github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect | ||||||
| 	github.com/xeipuuv/gojsonschema v1.2.0 // indirect | 	github.com/xeipuuv/gojsonschema v1.2.0 // indirect | ||||||
| 	github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913 // indirect |  | ||||||
| 	go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 // indirect | 	go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 // indirect | ||||||
| 	go.opentelemetry.io/otel v1.28.0 // indirect | 	go.opentelemetry.io/otel v1.28.0 // indirect | ||||||
| 	go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.28.0 // indirect | 	go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.28.0 // indirect | ||||||
|  | |||||||
							
								
								
									
										8
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										8
									
								
								go.sum
									
									
									
									
									
								
							| @ -273,7 +273,6 @@ github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfc | |||||||
| github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= | github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= | ||||||
| github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= | github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= | ||||||
| github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= | github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= | ||||||
| github.com/cpuguy83/go-md2man/v2 v2.0.4 h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lVfRxZq4= |  | ||||||
| github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= | github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= | ||||||
| github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= | github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= | ||||||
| github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= | github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= | ||||||
| @ -799,7 +798,6 @@ github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR | |||||||
| github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= | github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= | ||||||
| github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= | github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= | ||||||
| github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= | github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= | ||||||
| github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= |  | ||||||
| github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= | github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= | ||||||
| github.com/safchain/ethtool v0.0.0-20190326074333-42ed695e3de8/go.mod h1:Z0q5wiBQGYcxhMZ6gUqHn6pYNLypFAvaL3UvgZLR0U4= | github.com/safchain/ethtool v0.0.0-20190326074333-42ed695e3de8/go.mod h1:Z0q5wiBQGYcxhMZ6gUqHn6pYNLypFAvaL3UvgZLR0U4= | ||||||
| github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= | github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= | ||||||
| @ -883,8 +881,8 @@ github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijb | |||||||
| github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= | github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= | ||||||
| github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= | github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= | ||||||
| github.com/urfave/cli v1.22.4/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= | github.com/urfave/cli v1.22.4/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= | ||||||
| github.com/urfave/cli/v2 v2.27.2 h1:6e0H+AkS+zDckwPCUrZkKX38mRaau4nL2uipkJpbkcI= | github.com/urfave/cli/v3 v3.0.0-alpha9.1.0.20241019193437-5053ec708a44 h1:BeSTAZEDkDVNv9EOrycIGCkEg+6EhRRgSsbdc93Q3OM= | ||||||
| github.com/urfave/cli/v2 v2.27.2/go.mod h1:g0+79LmHHATl7DAcHO99smiR/T7uGLw84w8Y42x+4eM= | github.com/urfave/cli/v3 v3.0.0-alpha9.1.0.20241019193437-5053ec708a44/go.mod h1:FnIeEMYu+ko8zP1F9Ypr3xkZMIDqW3DR92yUtY39q1Y= | ||||||
| github.com/vbatts/tar-split v0.11.2/go.mod h1:vV3ZuO2yWSVsz+pfFzDG/upWH1JhjOiEaWq6kXyQ3VI= | github.com/vbatts/tar-split v0.11.2/go.mod h1:vV3ZuO2yWSVsz+pfFzDG/upWH1JhjOiEaWq6kXyQ3VI= | ||||||
| github.com/vishvananda/netlink v0.0.0-20181108222139-023a6dafdcdf/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk= | github.com/vishvananda/netlink v0.0.0-20181108222139-023a6dafdcdf/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk= | ||||||
| github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= | github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= | ||||||
| @ -906,8 +904,6 @@ github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17 | |||||||
| github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= | github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= | ||||||
| github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= | github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= | ||||||
| github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= | github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= | ||||||
| github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913 h1:+qGGcbkzsfDQNPPe9UDgpxAWQrhbbBXOYJFQDq/dtJw= |  | ||||||
| github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913/go.mod h1:4aEEwZQutDLsQv2Deui4iYQ6DWTxR14g6m8Wv88+Xqk= |  | ||||||
| github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= | github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= | ||||||
| github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= | github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= | ||||||
| github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= | github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= | ||||||
|  | |||||||
| @ -1,22 +1,23 @@ | |||||||
| package autocomplete | package autocomplete | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
|  | 	"context" | ||||||
| 	"fmt" | 	"fmt" | ||||||
|  |  | ||||||
| 	"coopcloud.tech/abra/pkg/app" | 	"coopcloud.tech/abra/pkg/app" | ||||||
| 	"coopcloud.tech/abra/pkg/log" | 	"coopcloud.tech/abra/pkg/log" | ||||||
| 	"coopcloud.tech/abra/pkg/recipe" | 	"coopcloud.tech/abra/pkg/recipe" | ||||||
| 	"github.com/urfave/cli/v2" | 	"github.com/urfave/cli/v3" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| // AppNameComplete copletes app names. | // AppNameComplete copletes app names. | ||||||
| func AppNameComplete(c *cli.Context) { | func AppNameComplete(ctx context.Context, cmd *cli.Command) { | ||||||
| 	appNames, err := app.GetAppNames() | 	appNames, err := app.GetAppNames() | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		log.Warn(err) | 		log.Warn(err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if c.NArg() > 0 { | 	if cmd.NArg() > 0 { | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @ -36,13 +37,13 @@ func ServiceNameComplete(appName string) { | |||||||
| } | } | ||||||
|  |  | ||||||
| // RecipeNameComplete completes recipe names. | // RecipeNameComplete completes recipe names. | ||||||
| func RecipeNameComplete(c *cli.Context) { | func RecipeNameComplete(ctx context.Context, cmd *cli.Command) { | ||||||
| 	catl, err := recipe.ReadRecipeCatalogue(false) | 	catl, err := recipe.ReadRecipeCatalogue(false) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		log.Warn(err) | 		log.Warn(err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if c.NArg() > 0 { | 	if cmd.NArg() > 0 { | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @ -66,13 +67,13 @@ func RecipeVersionComplete(recipeName string) { | |||||||
| } | } | ||||||
|  |  | ||||||
| // ServerNameComplete completes server names. | // ServerNameComplete completes server names. | ||||||
| func ServerNameComplete(c *cli.Context) { | func ServerNameComplete(ctx context.Context, cmd *cli.Command) { | ||||||
| 	files, err := app.LoadAppFiles("") | 	files, err := app.LoadAppFiles("") | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		log.Fatal(err) | 		log.Fatal(err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if c.NArg() > 0 { | 	if cmd.NArg() > 0 { | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @ -82,8 +83,8 @@ func ServerNameComplete(c *cli.Context) { | |||||||
| } | } | ||||||
|  |  | ||||||
| // SubcommandComplete completes sub-commands. | // SubcommandComplete completes sub-commands. | ||||||
| func SubcommandComplete(c *cli.Context) { | func SubcommandComplete(ctx context.Context, cmd *cli.Command) { | ||||||
| 	if c.NArg() > 0 { | 	if cmd.NArg() > 0 { | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | |||||||
| @ -2,16 +2,30 @@ | |||||||
|  |  | ||||||
| : ${PROG:=$(basename ${BASH_SOURCE})} | : ${PROG:=$(basename ${BASH_SOURCE})} | ||||||
|  |  | ||||||
|  | # Macs have bash3 for which the bash-completion package doesn't include | ||||||
|  | # _init_completion. This is a minimal version of that function. | ||||||
|  | _cli_init_completion() { | ||||||
|  |   COMPREPLY=() | ||||||
|  |   _get_comp_words_by_ref "$@" cur prev words cword | ||||||
|  | } | ||||||
|  |  | ||||||
| _cli_bash_autocomplete() { | _cli_bash_autocomplete() { | ||||||
|   if [[ "${COMP_WORDS[0]}" != "source" ]]; then |   if [[ "${COMP_WORDS[0]}" != "source" ]]; then | ||||||
|     local cur opts base |     local cur opts base words | ||||||
|     COMPREPLY=() |     COMPREPLY=() | ||||||
|     cur="${COMP_WORDS[COMP_CWORD]}" |     cur="${COMP_WORDS[COMP_CWORD]}" | ||||||
|     if [[ "$cur" == "-"* ]]; then |     if declare -F _init_completion >/dev/null 2>&1; then | ||||||
|       opts=$( ${COMP_WORDS[@]:0:$COMP_CWORD} ${cur} --generate-bash-completion ) |       _init_completion -n "=:" || return | ||||||
|     else |     else | ||||||
|       opts=$( ${COMP_WORDS[@]:0:$COMP_CWORD} --generate-bash-completion ) |       _cli_init_completion -n "=:" || return | ||||||
|     fi |     fi | ||||||
|  |     words=("${words[@]:0:$cword}") | ||||||
|  |     if [[ "$cur" == "-"* ]]; then | ||||||
|  |       requestComp="${words[*]} ${cur} --generate-shell-completion" | ||||||
|  |     else | ||||||
|  |       requestComp="${words[*]} --generate-shell-completion" | ||||||
|  |     fi | ||||||
|  |     opts=$(eval "${requestComp}" 2>/dev/null) | ||||||
|     COMPREPLY=($(compgen -W "${opts}" -- ${cur})) |     COMPREPLY=($(compgen -W "${opts}" -- ${cur})) | ||||||
|     return 0 |     return 0 | ||||||
|   fi |   fi | ||||||
|  | |||||||
| @ -1,5 +1,5 @@ | |||||||
| function complete_abra_args | function complete_abra_args | ||||||
|     set -l cmd (commandline -poc) --generate-bash-completion |     set -l cmd (commandline -poc) --generate-shell-completion | ||||||
|     $cmd |     $cmd | ||||||
| end | end | ||||||
| complete -c abra -f -n "not __fish_seen_subcommand_from -h --help -v --version complete_abra_args" -a "(complete_abra_args)" | complete -c abra -f -n "not __fish_seen_subcommand_from -h --help -v --version complete_abra_args" -a "(complete_abra_args)" | ||||||
|  | |||||||
| @ -2,7 +2,7 @@ $fn = $($MyInvocation.MyCommand.Name) | |||||||
| $name = $fn -replace "(.*)\.ps1$", '$1' | $name = $fn -replace "(.*)\.ps1$", '$1' | ||||||
| Register-ArgumentCompleter -Native -CommandName $name -ScriptBlock { | Register-ArgumentCompleter -Native -CommandName $name -ScriptBlock { | ||||||
|      param($commandName, $wordToComplete, $cursorPosition) |      param($commandName, $wordToComplete, $cursorPosition) | ||||||
|      $other = "$wordToComplete --generate-bash-completion" |      $other = "$wordToComplete --generate-shell-completion" | ||||||
|          Invoke-Expression $other | ForEach-Object { |          Invoke-Expression $other | ForEach-Object { | ||||||
|             [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_) |             [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_) | ||||||
|          } |          } | ||||||
|  | |||||||
| @ -1,14 +1,16 @@ | |||||||
| #compdef $PROG | #compdef abra | ||||||
|  | compdef _abra abra | ||||||
|  |  | ||||||
| _cli_zsh_autocomplete() { | # https://github.com/urfave/cli/blob/main/autocomplete/zsh_autocomplete | ||||||
|  |  | ||||||
|  | _abra() { | ||||||
| 	local -a opts | 	local -a opts | ||||||
| 	local cur | 	local cur | ||||||
| 	cur=${words[-1]} | 	cur=${words[-1]} | ||||||
| 	if [[ "$cur" == "-"* ]]; then | 	if [[ "$cur" == "-"* ]]; then | ||||||
|     opts=("${(@f)$(_CLI_ZSH_AUTOCOMPLETE_HACK=1 ${words[@]:0:#words[@]-1} ${cur} --generate-bash-completion)}") | 		opts=("${(@f)$(${words[@]:0:#words[@]-1} ${cur} --generate-shell-completion)}") | ||||||
| 	else | 	else | ||||||
|     opts=("${(@f)$(_CLI_ZSH_AUTOCOMPLETE_HACK=1 ${words[@]:0:#words[@]-1} --generate-bash-completion)}") | 		opts=("${(@f)$(${words[@]:0:#words[@]-1} --generate-shell-completion)}") | ||||||
| 	fi | 	fi | ||||||
|  |  | ||||||
| 	if [[ "${opts[1]}" != "" ]]; then | 	if [[ "${opts[1]}" != "" ]]; then | ||||||
| @ -16,8 +18,9 @@ _cli_zsh_autocomplete() { | |||||||
| 	else | 	else | ||||||
| 		_files | 		_files | ||||||
| 	fi | 	fi | ||||||
|  |  | ||||||
|   return |  | ||||||
| } | } | ||||||
|  |  | ||||||
| compdef _cli_zsh_autocomplete $PROG | # don't run the completion function when being source-ed or eval-ed | ||||||
|  | if [ "$funcstack[1]" = "_abra" ]; then | ||||||
|  | 	_abra | ||||||
|  | fi | ||||||
|  | |||||||
							
								
								
									
										1
									
								
								vendor/github.com/Azure/go-ansiterm/winterm/ansi.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								vendor/github.com/Azure/go-ansiterm/winterm/ansi.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @ -1,4 +1,3 @@ | |||||||
| //go:build windows |  | ||||||
| // +build windows | // +build windows | ||||||
|  |  | ||||||
| package winterm | package winterm | ||||||
|  | |||||||
							
								
								
									
										1
									
								
								vendor/github.com/Azure/go-ansiterm/winterm/api.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								vendor/github.com/Azure/go-ansiterm/winterm/api.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @ -1,4 +1,3 @@ | |||||||
| //go:build windows |  | ||||||
| // +build windows | // +build windows | ||||||
|  |  | ||||||
| package winterm | package winterm | ||||||
|  | |||||||
							
								
								
									
										1
									
								
								vendor/github.com/Azure/go-ansiterm/winterm/attr_translation.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								vendor/github.com/Azure/go-ansiterm/winterm/attr_translation.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @ -1,4 +1,3 @@ | |||||||
| //go:build windows |  | ||||||
| // +build windows | // +build windows | ||||||
|  |  | ||||||
| package winterm | package winterm | ||||||
|  | |||||||
							
								
								
									
										1
									
								
								vendor/github.com/Azure/go-ansiterm/winterm/cursor_helpers.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								vendor/github.com/Azure/go-ansiterm/winterm/cursor_helpers.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @ -1,4 +1,3 @@ | |||||||
| //go:build windows |  | ||||||
| // +build windows | // +build windows | ||||||
|  |  | ||||||
| package winterm | package winterm | ||||||
|  | |||||||
							
								
								
									
										1
									
								
								vendor/github.com/Azure/go-ansiterm/winterm/erase_helpers.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								vendor/github.com/Azure/go-ansiterm/winterm/erase_helpers.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @ -1,4 +1,3 @@ | |||||||
| //go:build windows |  | ||||||
| // +build windows | // +build windows | ||||||
|  |  | ||||||
| package winterm | package winterm | ||||||
|  | |||||||
							
								
								
									
										1
									
								
								vendor/github.com/Azure/go-ansiterm/winterm/scroll_helper.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								vendor/github.com/Azure/go-ansiterm/winterm/scroll_helper.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @ -1,4 +1,3 @@ | |||||||
| //go:build windows |  | ||||||
| // +build windows | // +build windows | ||||||
|  |  | ||||||
| package winterm | package winterm | ||||||
|  | |||||||
							
								
								
									
										1
									
								
								vendor/github.com/Azure/go-ansiterm/winterm/utilities.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								vendor/github.com/Azure/go-ansiterm/winterm/utilities.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @ -1,4 +1,3 @@ | |||||||
| //go:build windows |  | ||||||
| // +build windows | // +build windows | ||||||
|  |  | ||||||
| package winterm | package winterm | ||||||
|  | |||||||
							
								
								
									
										1
									
								
								vendor/github.com/Azure/go-ansiterm/winterm/win_event_handler.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								vendor/github.com/Azure/go-ansiterm/winterm/win_event_handler.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @ -1,4 +1,3 @@ | |||||||
| //go:build windows |  | ||||||
| // +build windows | // +build windows | ||||||
|  |  | ||||||
| package winterm | package winterm | ||||||
|  | |||||||
							
								
								
									
										9
									
								
								vendor/github.com/ProtonMail/go-crypto/openpgp/s2k/s2k.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										9
									
								
								vendor/github.com/ProtonMail/go-crypto/openpgp/s2k/s2k.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @ -306,12 +306,9 @@ func (params *Params) Dummy() bool { | |||||||
|  |  | ||||||
| func (params *Params) salt() []byte { | func (params *Params) salt() []byte { | ||||||
| 	switch params.mode { | 	switch params.mode { | ||||||
| 	case SaltedS2K, IteratedSaltedS2K: | 		case SaltedS2K, IteratedSaltedS2K: return params.saltBytes[:8] | ||||||
| 		return params.saltBytes[:8] | 		case Argon2S2K: return params.saltBytes[:Argon2SaltSize] | ||||||
| 	case Argon2S2K: | 		default: return nil | ||||||
| 		return params.saltBytes[:Argon2SaltSize] |  | ||||||
| 	default: |  | ||||||
| 		return nil |  | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | |||||||
							
								
								
									
										2
									
								
								vendor/github.com/beorn7/perks/quantile/stream.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/beorn7/perks/quantile/stream.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @ -9,7 +9,7 @@ | |||||||
| // | // | ||||||
| // For more detailed information about the algorithm used, see: | // For more detailed information about the algorithm used, see: | ||||||
| // | // | ||||||
| // # Effective Computation of Biased Quantiles over Data Streams | // Effective Computation of Biased Quantiles over Data Streams | ||||||
| // | // | ||||||
| // http://www.cs.rutgers.edu/~muthu/bquant.pdf | // http://www.cs.rutgers.edu/~muthu/bquant.pdf | ||||||
| package quantile | package quantile | ||||||
|  | |||||||
							
								
								
									
										2
									
								
								vendor/github.com/cenkalti/backoff/v4/exponential.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/cenkalti/backoff/v4/exponential.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @ -167,7 +167,6 @@ func (b *ExponentialBackOff) Reset() { | |||||||
| } | } | ||||||
|  |  | ||||||
| // NextBackOff calculates the next backoff interval using the formula: | // NextBackOff calculates the next backoff interval using the formula: | ||||||
| // |  | ||||||
| // 	Randomized interval = RetryInterval * (1 ± RandomizationFactor) | // 	Randomized interval = RetryInterval * (1 ± RandomizationFactor) | ||||||
| func (b *ExponentialBackOff) NextBackOff() time.Duration { | func (b *ExponentialBackOff) NextBackOff() time.Duration { | ||||||
| 	// Make sure we have not gone over the maximum elapsed time. | 	// Make sure we have not gone over the maximum elapsed time. | ||||||
| @ -201,7 +200,6 @@ func (b *ExponentialBackOff) incrementCurrentInterval() { | |||||||
| } | } | ||||||
|  |  | ||||||
| // Returns a random value from the following interval: | // Returns a random value from the following interval: | ||||||
| // |  | ||||||
| // 	[currentInterval - randomizationFactor * currentInterval, currentInterval + randomizationFactor * currentInterval]. | // 	[currentInterval - randomizationFactor * currentInterval, currentInterval + randomizationFactor * currentInterval]. | ||||||
| func getRandomValueFromInterval(randomizationFactor, random float64, currentInterval time.Duration) time.Duration { | func getRandomValueFromInterval(randomizationFactor, random float64, currentInterval time.Duration) time.Duration { | ||||||
| 	if randomizationFactor == 0 { | 	if randomizationFactor == 0 { | ||||||
|  | |||||||
							
								
								
									
										1
									
								
								vendor/github.com/containers/image/pkg/docker/config/config_unsupported.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								vendor/github.com/containers/image/pkg/docker/config/config_unsupported.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @ -1,4 +1,3 @@ | |||||||
| //go:build !linux && (!386 || !amd64) |  | ||||||
| // +build !linux | // +build !linux | ||||||
| // +build !386 !amd64 | // +build !386 !amd64 | ||||||
|  |  | ||||||
|  | |||||||
							
								
								
									
										1
									
								
								vendor/github.com/containers/image/pkg/keyctl/key.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								vendor/github.com/containers/image/pkg/keyctl/key.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @ -2,7 +2,6 @@ | |||||||
| // Use of this source code is governed by a BSD-style | // Use of this source code is governed by a BSD-style | ||||||
| // license that can be found in the LICENSE file. | // license that can be found in the LICENSE file. | ||||||
|  |  | ||||||
| //go:build linux |  | ||||||
| // +build linux | // +build linux | ||||||
|  |  | ||||||
| package keyctl | package keyctl | ||||||
|  | |||||||
							
								
								
									
										1
									
								
								vendor/github.com/containers/image/pkg/keyctl/keyring.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								vendor/github.com/containers/image/pkg/keyctl/keyring.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @ -2,7 +2,6 @@ | |||||||
| // Use of this source code is governed by a BSD-style | // Use of this source code is governed by a BSD-style | ||||||
| // license that can be found in the LICENSE file. | // license that can be found in the LICENSE file. | ||||||
|  |  | ||||||
| //go:build linux |  | ||||||
| // +build linux | // +build linux | ||||||
|  |  | ||||||
| // Package keyctl is a Go interface to linux kernel keyrings (keyctl interface) | // Package keyctl is a Go interface to linux kernel keyrings (keyctl interface) | ||||||
|  | |||||||
							
								
								
									
										1
									
								
								vendor/github.com/containers/image/pkg/keyctl/perm.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								vendor/github.com/containers/image/pkg/keyctl/perm.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @ -2,7 +2,6 @@ | |||||||
| // Use of this source code is governed by a BSD-style | // Use of this source code is governed by a BSD-style | ||||||
| // license that can be found in the LICENSE file. | // license that can be found in the LICENSE file. | ||||||
|  |  | ||||||
| //go:build linux |  | ||||||
| // +build linux | // +build linux | ||||||
|  |  | ||||||
| package keyctl | package keyctl | ||||||
|  | |||||||
							
								
								
									
										1
									
								
								vendor/github.com/containers/image/pkg/keyctl/sys_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								vendor/github.com/containers/image/pkg/keyctl/sys_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @ -2,7 +2,6 @@ | |||||||
| // Use of this source code is governed by a BSD-style | // Use of this source code is governed by a BSD-style | ||||||
| // license that can be found in the LICENSE file. | // license that can be found in the LICENSE file. | ||||||
|  |  | ||||||
| //go:build linux |  | ||||||
| // +build linux | // +build linux | ||||||
|  |  | ||||||
| package keyctl | package keyctl | ||||||
|  | |||||||
							
								
								
									
										1
									
								
								vendor/github.com/containers/image/types/types.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								vendor/github.com/containers/image/types/types.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @ -131,7 +131,6 @@ type BICReplacementCandidate struct { | |||||||
| // BlobInfoCache records data useful for reusing blobs, or substituing equivalent ones, to avoid unnecessary blob copies. | // BlobInfoCache records data useful for reusing blobs, or substituing equivalent ones, to avoid unnecessary blob copies. | ||||||
| // | // | ||||||
| // It records two kinds of data: | // It records two kinds of data: | ||||||
| // |  | ||||||
| // - Sets of corresponding digest vs. uncompressed digest ("DiffID") pairs: | // - Sets of corresponding digest vs. uncompressed digest ("DiffID") pairs: | ||||||
| //   One of the two digests is known to be uncompressed, and a single uncompressed digest may correspond to more than one compressed digest. | //   One of the two digests is known to be uncompressed, and a single uncompressed digest may correspond to more than one compressed digest. | ||||||
| //   This allows matching compressed layer blobs to existing local uncompressed layers (to avoid unnecessary download and decompresssion), | //   This allows matching compressed layer blobs to existing local uncompressed layers (to avoid unnecessary download and decompresssion), | ||||||
|  | |||||||
							
								
								
									
										21
									
								
								vendor/github.com/cpuguy83/go-md2man/v2/LICENSE.md
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										21
									
								
								vendor/github.com/cpuguy83/go-md2man/v2/LICENSE.md
									
									
									
										generated
									
									
										vendored
									
									
								
							| @ -1,21 +0,0 @@ | |||||||
| The MIT License (MIT) |  | ||||||
|  |  | ||||||
| Copyright (c) 2014 Brian Goff |  | ||||||
|  |  | ||||||
| Permission is hereby granted, free of charge, to any person obtaining a copy |  | ||||||
| of this software and associated documentation files (the "Software"), to deal |  | ||||||
| in the Software without restriction, including without limitation the rights |  | ||||||
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |  | ||||||
| copies of the Software, and to permit persons to whom the Software is |  | ||||||
| furnished to do so, subject to the following conditions: |  | ||||||
|  |  | ||||||
| The above copyright notice and this permission notice shall be included in all |  | ||||||
| copies or substantial portions of the Software. |  | ||||||
|  |  | ||||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |  | ||||||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |  | ||||||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |  | ||||||
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |  | ||||||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |  | ||||||
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |  | ||||||
| SOFTWARE. |  | ||||||
							
								
								
									
										16
									
								
								vendor/github.com/cpuguy83/go-md2man/v2/md2man/md2man.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										16
									
								
								vendor/github.com/cpuguy83/go-md2man/v2/md2man/md2man.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @ -1,16 +0,0 @@ | |||||||
| package md2man |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	"github.com/russross/blackfriday/v2" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| // Render converts a markdown document into a roff formatted document. |  | ||||||
| func Render(doc []byte) []byte { |  | ||||||
| 	renderer := NewRoffRenderer() |  | ||||||
|  |  | ||||||
| 	return blackfriday.Run(doc, |  | ||||||
| 		[]blackfriday.Option{ |  | ||||||
| 			blackfriday.WithRenderer(renderer), |  | ||||||
| 			blackfriday.WithExtensions(renderer.GetExtensions()), |  | ||||||
| 		}...) |  | ||||||
| } |  | ||||||
							
								
								
									
										382
									
								
								vendor/github.com/cpuguy83/go-md2man/v2/md2man/roff.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										382
									
								
								vendor/github.com/cpuguy83/go-md2man/v2/md2man/roff.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @ -1,382 +0,0 @@ | |||||||
| package md2man |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	"bufio" |  | ||||||
| 	"bytes" |  | ||||||
| 	"fmt" |  | ||||||
| 	"io" |  | ||||||
| 	"os" |  | ||||||
| 	"strings" |  | ||||||
|  |  | ||||||
| 	"github.com/russross/blackfriday/v2" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| // roffRenderer implements the blackfriday.Renderer interface for creating |  | ||||||
| // roff format (manpages) from markdown text |  | ||||||
| type roffRenderer struct { |  | ||||||
| 	extensions   blackfriday.Extensions |  | ||||||
| 	listCounters []int |  | ||||||
| 	firstHeader  bool |  | ||||||
| 	firstDD      bool |  | ||||||
| 	listDepth    int |  | ||||||
| } |  | ||||||
|  |  | ||||||
| const ( |  | ||||||
| 	titleHeader       = ".TH " |  | ||||||
| 	topLevelHeader    = "\n\n.SH " |  | ||||||
| 	secondLevelHdr    = "\n.SH " |  | ||||||
| 	otherHeader       = "\n.SS " |  | ||||||
| 	crTag             = "\n" |  | ||||||
| 	emphTag           = "\\fI" |  | ||||||
| 	emphCloseTag      = "\\fP" |  | ||||||
| 	strongTag         = "\\fB" |  | ||||||
| 	strongCloseTag    = "\\fP" |  | ||||||
| 	breakTag          = "\n.br\n" |  | ||||||
| 	paraTag           = "\n.PP\n" |  | ||||||
| 	hruleTag          = "\n.ti 0\n\\l'\\n(.lu'\n" |  | ||||||
| 	linkTag           = "\n\\[la]" |  | ||||||
| 	linkCloseTag      = "\\[ra]" |  | ||||||
| 	codespanTag       = "\\fB" |  | ||||||
| 	codespanCloseTag  = "\\fR" |  | ||||||
| 	codeTag           = "\n.EX\n" |  | ||||||
| 	codeCloseTag      = ".EE\n" // Do not prepend a newline character since code blocks, by definition, include a newline already (or at least as how blackfriday gives us on). |  | ||||||
| 	quoteTag          = "\n.PP\n.RS\n" |  | ||||||
| 	quoteCloseTag     = "\n.RE\n" |  | ||||||
| 	listTag           = "\n.RS\n" |  | ||||||
| 	listCloseTag      = "\n.RE\n" |  | ||||||
| 	dtTag             = "\n.TP\n" |  | ||||||
| 	dd2Tag            = "\n" |  | ||||||
| 	tableStart        = "\n.TS\nallbox;\n" |  | ||||||
| 	tableEnd          = ".TE\n" |  | ||||||
| 	tableCellStart    = "T{\n" |  | ||||||
| 	tableCellEnd      = "\nT}\n" |  | ||||||
| 	tablePreprocessor = `'\" t` |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| // NewRoffRenderer creates a new blackfriday Renderer for generating roff documents |  | ||||||
| // from markdown |  | ||||||
| func NewRoffRenderer() *roffRenderer { // nolint: golint |  | ||||||
| 	var extensions blackfriday.Extensions |  | ||||||
|  |  | ||||||
| 	extensions |= blackfriday.NoIntraEmphasis |  | ||||||
| 	extensions |= blackfriday.Tables |  | ||||||
| 	extensions |= blackfriday.FencedCode |  | ||||||
| 	extensions |= blackfriday.SpaceHeadings |  | ||||||
| 	extensions |= blackfriday.Footnotes |  | ||||||
| 	extensions |= blackfriday.Titleblock |  | ||||||
| 	extensions |= blackfriday.DefinitionLists |  | ||||||
| 	return &roffRenderer{ |  | ||||||
| 		extensions: extensions, |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // GetExtensions returns the list of extensions used by this renderer implementation |  | ||||||
| func (r *roffRenderer) GetExtensions() blackfriday.Extensions { |  | ||||||
| 	return r.extensions |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // RenderHeader handles outputting the header at document start |  | ||||||
| func (r *roffRenderer) RenderHeader(w io.Writer, ast *blackfriday.Node) { |  | ||||||
| 	// We need to walk the tree to check if there are any tables. |  | ||||||
| 	// If there are, we need to enable the roff table preprocessor. |  | ||||||
| 	ast.Walk(func(node *blackfriday.Node, entering bool) blackfriday.WalkStatus { |  | ||||||
| 		if node.Type == blackfriday.Table { |  | ||||||
| 			out(w, tablePreprocessor+"\n") |  | ||||||
| 			return blackfriday.Terminate |  | ||||||
| 		} |  | ||||||
| 		return blackfriday.GoToNext |  | ||||||
| 	}) |  | ||||||
|  |  | ||||||
| 	// disable hyphenation |  | ||||||
| 	out(w, ".nh\n") |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // RenderFooter handles outputting the footer at the document end; the roff |  | ||||||
| // renderer has no footer information |  | ||||||
| func (r *roffRenderer) RenderFooter(w io.Writer, ast *blackfriday.Node) { |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // RenderNode is called for each node in a markdown document; based on the node |  | ||||||
| // type the equivalent roff output is sent to the writer |  | ||||||
| func (r *roffRenderer) RenderNode(w io.Writer, node *blackfriday.Node, entering bool) blackfriday.WalkStatus { |  | ||||||
| 	walkAction := blackfriday.GoToNext |  | ||||||
|  |  | ||||||
| 	switch node.Type { |  | ||||||
| 	case blackfriday.Text: |  | ||||||
| 		escapeSpecialChars(w, node.Literal) |  | ||||||
| 	case blackfriday.Softbreak: |  | ||||||
| 		out(w, crTag) |  | ||||||
| 	case blackfriday.Hardbreak: |  | ||||||
| 		out(w, breakTag) |  | ||||||
| 	case blackfriday.Emph: |  | ||||||
| 		if entering { |  | ||||||
| 			out(w, emphTag) |  | ||||||
| 		} else { |  | ||||||
| 			out(w, emphCloseTag) |  | ||||||
| 		} |  | ||||||
| 	case blackfriday.Strong: |  | ||||||
| 		if entering { |  | ||||||
| 			out(w, strongTag) |  | ||||||
| 		} else { |  | ||||||
| 			out(w, strongCloseTag) |  | ||||||
| 		} |  | ||||||
| 	case blackfriday.Link: |  | ||||||
| 		// Don't render the link text for automatic links, because this |  | ||||||
| 		// will only duplicate the URL in the roff output. |  | ||||||
| 		// See https://daringfireball.net/projects/markdown/syntax#autolink |  | ||||||
| 		if !bytes.Equal(node.LinkData.Destination, node.FirstChild.Literal) { |  | ||||||
| 			out(w, string(node.FirstChild.Literal)) |  | ||||||
| 		} |  | ||||||
| 		// Hyphens in a link must be escaped to avoid word-wrap in the rendered man page. |  | ||||||
| 		escapedLink := strings.ReplaceAll(string(node.LinkData.Destination), "-", "\\-") |  | ||||||
| 		out(w, linkTag+escapedLink+linkCloseTag) |  | ||||||
| 		walkAction = blackfriday.SkipChildren |  | ||||||
| 	case blackfriday.Image: |  | ||||||
| 		// ignore images |  | ||||||
| 		walkAction = blackfriday.SkipChildren |  | ||||||
| 	case blackfriday.Code: |  | ||||||
| 		out(w, codespanTag) |  | ||||||
| 		escapeSpecialChars(w, node.Literal) |  | ||||||
| 		out(w, codespanCloseTag) |  | ||||||
| 	case blackfriday.Document: |  | ||||||
| 		break |  | ||||||
| 	case blackfriday.Paragraph: |  | ||||||
| 		// roff .PP markers break lists |  | ||||||
| 		if r.listDepth > 0 { |  | ||||||
| 			return blackfriday.GoToNext |  | ||||||
| 		} |  | ||||||
| 		if entering { |  | ||||||
| 			out(w, paraTag) |  | ||||||
| 		} else { |  | ||||||
| 			out(w, crTag) |  | ||||||
| 		} |  | ||||||
| 	case blackfriday.BlockQuote: |  | ||||||
| 		if entering { |  | ||||||
| 			out(w, quoteTag) |  | ||||||
| 		} else { |  | ||||||
| 			out(w, quoteCloseTag) |  | ||||||
| 		} |  | ||||||
| 	case blackfriday.Heading: |  | ||||||
| 		r.handleHeading(w, node, entering) |  | ||||||
| 	case blackfriday.HorizontalRule: |  | ||||||
| 		out(w, hruleTag) |  | ||||||
| 	case blackfriday.List: |  | ||||||
| 		r.handleList(w, node, entering) |  | ||||||
| 	case blackfriday.Item: |  | ||||||
| 		r.handleItem(w, node, entering) |  | ||||||
| 	case blackfriday.CodeBlock: |  | ||||||
| 		out(w, codeTag) |  | ||||||
| 		escapeSpecialChars(w, node.Literal) |  | ||||||
| 		out(w, codeCloseTag) |  | ||||||
| 	case blackfriday.Table: |  | ||||||
| 		r.handleTable(w, node, entering) |  | ||||||
| 	case blackfriday.TableHead: |  | ||||||
| 	case blackfriday.TableBody: |  | ||||||
| 	case blackfriday.TableRow: |  | ||||||
| 		// no action as cell entries do all the nroff formatting |  | ||||||
| 		return blackfriday.GoToNext |  | ||||||
| 	case blackfriday.TableCell: |  | ||||||
| 		r.handleTableCell(w, node, entering) |  | ||||||
| 	case blackfriday.HTMLSpan: |  | ||||||
| 		// ignore other HTML tags |  | ||||||
| 	case blackfriday.HTMLBlock: |  | ||||||
| 		if bytes.HasPrefix(node.Literal, []byte("<!--")) { |  | ||||||
| 			break // ignore comments, no warning |  | ||||||
| 		} |  | ||||||
| 		fmt.Fprintln(os.Stderr, "WARNING: go-md2man does not handle node type "+node.Type.String()) |  | ||||||
| 	default: |  | ||||||
| 		fmt.Fprintln(os.Stderr, "WARNING: go-md2man does not handle node type "+node.Type.String()) |  | ||||||
| 	} |  | ||||||
| 	return walkAction |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (r *roffRenderer) handleHeading(w io.Writer, node *blackfriday.Node, entering bool) { |  | ||||||
| 	if entering { |  | ||||||
| 		switch node.Level { |  | ||||||
| 		case 1: |  | ||||||
| 			if !r.firstHeader { |  | ||||||
| 				out(w, titleHeader) |  | ||||||
| 				r.firstHeader = true |  | ||||||
| 				break |  | ||||||
| 			} |  | ||||||
| 			out(w, topLevelHeader) |  | ||||||
| 		case 2: |  | ||||||
| 			out(w, secondLevelHdr) |  | ||||||
| 		default: |  | ||||||
| 			out(w, otherHeader) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (r *roffRenderer) handleList(w io.Writer, node *blackfriday.Node, entering bool) { |  | ||||||
| 	openTag := listTag |  | ||||||
| 	closeTag := listCloseTag |  | ||||||
| 	if node.ListFlags&blackfriday.ListTypeDefinition != 0 { |  | ||||||
| 		// tags for definition lists handled within Item node |  | ||||||
| 		openTag = "" |  | ||||||
| 		closeTag = "" |  | ||||||
| 	} |  | ||||||
| 	if entering { |  | ||||||
| 		r.listDepth++ |  | ||||||
| 		if node.ListFlags&blackfriday.ListTypeOrdered != 0 { |  | ||||||
| 			r.listCounters = append(r.listCounters, 1) |  | ||||||
| 		} |  | ||||||
| 		out(w, openTag) |  | ||||||
| 	} else { |  | ||||||
| 		if node.ListFlags&blackfriday.ListTypeOrdered != 0 { |  | ||||||
| 			r.listCounters = r.listCounters[:len(r.listCounters)-1] |  | ||||||
| 		} |  | ||||||
| 		out(w, closeTag) |  | ||||||
| 		r.listDepth-- |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (r *roffRenderer) handleItem(w io.Writer, node *blackfriday.Node, entering bool) { |  | ||||||
| 	if entering { |  | ||||||
| 		if node.ListFlags&blackfriday.ListTypeOrdered != 0 { |  | ||||||
| 			out(w, fmt.Sprintf(".IP \"%3d.\" 5\n", r.listCounters[len(r.listCounters)-1])) |  | ||||||
| 			r.listCounters[len(r.listCounters)-1]++ |  | ||||||
| 		} else if node.ListFlags&blackfriday.ListTypeTerm != 0 { |  | ||||||
| 			// DT (definition term): line just before DD (see below). |  | ||||||
| 			out(w, dtTag) |  | ||||||
| 			r.firstDD = true |  | ||||||
| 		} else if node.ListFlags&blackfriday.ListTypeDefinition != 0 { |  | ||||||
| 			// DD (definition description): line that starts with ": ". |  | ||||||
| 			// |  | ||||||
| 			// We have to distinguish between the first DD and the |  | ||||||
| 			// subsequent ones, as there should be no vertical |  | ||||||
| 			// whitespace between the DT and the first DD. |  | ||||||
| 			if r.firstDD { |  | ||||||
| 				r.firstDD = false |  | ||||||
| 			} else { |  | ||||||
| 				out(w, dd2Tag) |  | ||||||
| 			} |  | ||||||
| 		} else { |  | ||||||
| 			out(w, ".IP \\(bu 2\n") |  | ||||||
| 		} |  | ||||||
| 	} else { |  | ||||||
| 		out(w, "\n") |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (r *roffRenderer) handleTable(w io.Writer, node *blackfriday.Node, entering bool) { |  | ||||||
| 	if entering { |  | ||||||
| 		out(w, tableStart) |  | ||||||
| 		// call walker to count cells (and rows?) so format section can be produced |  | ||||||
| 		columns := countColumns(node) |  | ||||||
| 		out(w, strings.Repeat("l ", columns)+"\n") |  | ||||||
| 		out(w, strings.Repeat("l ", columns)+".\n") |  | ||||||
| 	} else { |  | ||||||
| 		out(w, tableEnd) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (r *roffRenderer) handleTableCell(w io.Writer, node *blackfriday.Node, entering bool) { |  | ||||||
| 	if entering { |  | ||||||
| 		var start string |  | ||||||
| 		if node.Prev != nil && node.Prev.Type == blackfriday.TableCell { |  | ||||||
| 			start = "\t" |  | ||||||
| 		} |  | ||||||
| 		if node.IsHeader { |  | ||||||
| 			start += strongTag |  | ||||||
| 		} else if nodeLiteralSize(node) > 30 { |  | ||||||
| 			start += tableCellStart |  | ||||||
| 		} |  | ||||||
| 		out(w, start) |  | ||||||
| 	} else { |  | ||||||
| 		var end string |  | ||||||
| 		if node.IsHeader { |  | ||||||
| 			end = strongCloseTag |  | ||||||
| 		} else if nodeLiteralSize(node) > 30 { |  | ||||||
| 			end = tableCellEnd |  | ||||||
| 		} |  | ||||||
| 		if node.Next == nil && end != tableCellEnd { |  | ||||||
| 			// Last cell: need to carriage return if we are at the end of the |  | ||||||
| 			// header row and content isn't wrapped in a "tablecell" |  | ||||||
| 			end += crTag |  | ||||||
| 		} |  | ||||||
| 		out(w, end) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func nodeLiteralSize(node *blackfriday.Node) int { |  | ||||||
| 	total := 0 |  | ||||||
| 	for n := node.FirstChild; n != nil; n = n.FirstChild { |  | ||||||
| 		total += len(n.Literal) |  | ||||||
| 	} |  | ||||||
| 	return total |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // because roff format requires knowing the column count before outputting any table |  | ||||||
| // data we need to walk a table tree and count the columns |  | ||||||
| func countColumns(node *blackfriday.Node) int { |  | ||||||
| 	var columns int |  | ||||||
|  |  | ||||||
| 	node.Walk(func(node *blackfriday.Node, entering bool) blackfriday.WalkStatus { |  | ||||||
| 		switch node.Type { |  | ||||||
| 		case blackfriday.TableRow: |  | ||||||
| 			if !entering { |  | ||||||
| 				return blackfriday.Terminate |  | ||||||
| 			} |  | ||||||
| 		case blackfriday.TableCell: |  | ||||||
| 			if entering { |  | ||||||
| 				columns++ |  | ||||||
| 			} |  | ||||||
| 		default: |  | ||||||
| 		} |  | ||||||
| 		return blackfriday.GoToNext |  | ||||||
| 	}) |  | ||||||
| 	return columns |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func out(w io.Writer, output string) { |  | ||||||
| 	io.WriteString(w, output) // nolint: errcheck |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func escapeSpecialChars(w io.Writer, text []byte) { |  | ||||||
| 	scanner := bufio.NewScanner(bytes.NewReader(text)) |  | ||||||
|  |  | ||||||
| 	// count the number of lines in the text |  | ||||||
| 	// we need to know this to avoid adding a newline after the last line |  | ||||||
| 	n := bytes.Count(text, []byte{'\n'}) |  | ||||||
| 	idx := 0 |  | ||||||
|  |  | ||||||
| 	for scanner.Scan() { |  | ||||||
| 		dt := scanner.Bytes() |  | ||||||
| 		if idx < n { |  | ||||||
| 			idx++ |  | ||||||
| 			dt = append(dt, '\n') |  | ||||||
| 		} |  | ||||||
| 		escapeSpecialCharsLine(w, dt) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if err := scanner.Err(); err != nil { |  | ||||||
| 		panic(err) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func escapeSpecialCharsLine(w io.Writer, text []byte) { |  | ||||||
| 	for i := 0; i < len(text); i++ { |  | ||||||
| 		// escape initial apostrophe or period |  | ||||||
| 		if len(text) >= 1 && (text[0] == '\'' || text[0] == '.') { |  | ||||||
| 			out(w, "\\&") |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		// directly copy normal characters |  | ||||||
| 		org := i |  | ||||||
|  |  | ||||||
| 		for i < len(text) && text[i] != '\\' { |  | ||||||
| 			i++ |  | ||||||
| 		} |  | ||||||
| 		if i > org { |  | ||||||
| 			w.Write(text[org:i]) // nolint: errcheck |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		// escape a character |  | ||||||
| 		if i >= len(text) { |  | ||||||
| 			break |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		w.Write([]byte{'\\', text[i]}) // nolint: errcheck |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
							
								
								
									
										1
									
								
								vendor/github.com/davecgh/go-spew/spew/bypass.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								vendor/github.com/davecgh/go-spew/spew/bypass.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @ -18,7 +18,6 @@ | |||||||
| // tag is deprecated and thus should not be used. | // tag is deprecated and thus should not be used. | ||||||
| // Go versions prior to 1.4 are disabled because they use a different layout | // Go versions prior to 1.4 are disabled because they use a different layout | ||||||
| // for interfaces which make the implementation of unsafeReflectValue more complex. | // for interfaces which make the implementation of unsafeReflectValue more complex. | ||||||
| //go:build !js && !appengine && !safe && !disableunsafe && go1.4 |  | ||||||
| // +build !js,!appengine,!safe,!disableunsafe,go1.4 | // +build !js,!appengine,!safe,!disableunsafe,go1.4 | ||||||
|  |  | ||||||
| package spew | package spew | ||||||
|  | |||||||
							
								
								
									
										1
									
								
								vendor/github.com/davecgh/go-spew/spew/bypasssafe.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								vendor/github.com/davecgh/go-spew/spew/bypasssafe.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @ -16,7 +16,6 @@ | |||||||
| // when the code is running on Google App Engine, compiled by GopherJS, or | // when the code is running on Google App Engine, compiled by GopherJS, or | ||||||
| // "-tags safe" is added to the go build command line.  The "disableunsafe" | // "-tags safe" is added to the go build command line.  The "disableunsafe" | ||||||
| // tag is deprecated and thus should not be used. | // tag is deprecated and thus should not be used. | ||||||
| //go:build js || appengine || safe || disableunsafe || !go1.4 |  | ||||||
| // +build js appengine safe disableunsafe !go1.4 | // +build js appengine safe disableunsafe !go1.4 | ||||||
|  |  | ||||||
| package spew | package spew | ||||||
|  | |||||||
							
								
								
									
										10
									
								
								vendor/github.com/davecgh/go-spew/spew/config.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										10
									
								
								vendor/github.com/davecgh/go-spew/spew/config.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @ -254,14 +254,14 @@ pointer addresses used to indirect to the final value.  It provides the | |||||||
| following features over the built-in printing facilities provided by the fmt | following features over the built-in printing facilities provided by the fmt | ||||||
| package: | package: | ||||||
|  |  | ||||||
|   - Pointers are dereferenced and followed | 	* Pointers are dereferenced and followed | ||||||
|   - Circular data structures are detected and handled properly | 	* Circular data structures are detected and handled properly | ||||||
|   - Custom Stringer/error interfaces are optionally invoked, including | 	* Custom Stringer/error interfaces are optionally invoked, including | ||||||
| 	  on unexported types | 	  on unexported types | ||||||
|   - Custom types which only implement the Stringer/error interfaces via | 	* Custom types which only implement the Stringer/error interfaces via | ||||||
| 	  a pointer receiver are optionally invoked when passing non-pointer | 	  a pointer receiver are optionally invoked when passing non-pointer | ||||||
| 	  variables | 	  variables | ||||||
|   - Byte arrays and slices are dumped like the hexdump -C command which | 	* Byte arrays and slices are dumped like the hexdump -C command which | ||||||
| 	  includes offsets, byte values in hex, and ASCII output | 	  includes offsets, byte values in hex, and ASCII output | ||||||
|  |  | ||||||
| The configuration options are controlled by modifying the public members | The configuration options are controlled by modifying the public members | ||||||
|  | |||||||
							
								
								
									
										54
									
								
								vendor/github.com/davecgh/go-spew/spew/doc.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										54
									
								
								vendor/github.com/davecgh/go-spew/spew/doc.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @ -21,36 +21,35 @@ debugging. | |||||||
| A quick overview of the additional features spew provides over the built-in | A quick overview of the additional features spew provides over the built-in | ||||||
| printing facilities for Go data types are as follows: | printing facilities for Go data types are as follows: | ||||||
|  |  | ||||||
|   - Pointers are dereferenced and followed | 	* Pointers are dereferenced and followed | ||||||
|   - Circular data structures are detected and handled properly | 	* Circular data structures are detected and handled properly | ||||||
|   - Custom Stringer/error interfaces are optionally invoked, including | 	* Custom Stringer/error interfaces are optionally invoked, including | ||||||
| 	  on unexported types | 	  on unexported types | ||||||
|   - Custom types which only implement the Stringer/error interfaces via | 	* Custom types which only implement the Stringer/error interfaces via | ||||||
| 	  a pointer receiver are optionally invoked when passing non-pointer | 	  a pointer receiver are optionally invoked when passing non-pointer | ||||||
| 	  variables | 	  variables | ||||||
|   - Byte arrays and slices are dumped like the hexdump -C command which | 	* Byte arrays and slices are dumped like the hexdump -C command which | ||||||
| 	  includes offsets, byte values in hex, and ASCII output (only when using | 	  includes offsets, byte values in hex, and ASCII output (only when using | ||||||
| 	  Dump style) | 	  Dump style) | ||||||
|  |  | ||||||
| There are two different approaches spew allows for dumping Go data structures: | There are two different approaches spew allows for dumping Go data structures: | ||||||
|  |  | ||||||
|   - Dump style which prints with newlines, customizable indentation, | 	* Dump style which prints with newlines, customizable indentation, | ||||||
| 	  and additional debug information such as types and all pointer addresses | 	  and additional debug information such as types and all pointer addresses | ||||||
| 	  used to indirect to the final value | 	  used to indirect to the final value | ||||||
|   - A custom Formatter interface that integrates cleanly with the standard fmt | 	* A custom Formatter interface that integrates cleanly with the standard fmt | ||||||
| 	  package and replaces %v, %+v, %#v, and %#+v to provide inline printing | 	  package and replaces %v, %+v, %#v, and %#+v to provide inline printing | ||||||
| 	  similar to the default %v while providing the additional functionality | 	  similar to the default %v while providing the additional functionality | ||||||
| 	  outlined above and passing unsupported format verbs such as %x and %q | 	  outlined above and passing unsupported format verbs such as %x and %q | ||||||
| 	  along to fmt | 	  along to fmt | ||||||
|  |  | ||||||
| # Quick Start | Quick Start | ||||||
|  |  | ||||||
| This section demonstrates how to quickly get started with spew.  See the | This section demonstrates how to quickly get started with spew.  See the | ||||||
| sections below for further details on formatting and configuration options. | sections below for further details on formatting and configuration options. | ||||||
|  |  | ||||||
| To dump a variable with full newlines, indentation, type, and pointer | To dump a variable with full newlines, indentation, type, and pointer | ||||||
| information use Dump, Fdump, or Sdump: | information use Dump, Fdump, or Sdump: | ||||||
|  |  | ||||||
| 	spew.Dump(myVar1, myVar2, ...) | 	spew.Dump(myVar1, myVar2, ...) | ||||||
| 	spew.Fdump(someWriter, myVar1, myVar2, ...) | 	spew.Fdump(someWriter, myVar1, myVar2, ...) | ||||||
| 	str := spew.Sdump(myVar1, myVar2, ...) | 	str := spew.Sdump(myVar1, myVar2, ...) | ||||||
| @ -59,13 +58,12 @@ Alternatively, if you would prefer to use format strings with a compacted inline | |||||||
| printing style, use the convenience wrappers Printf, Fprintf, etc with | printing style, use the convenience wrappers Printf, Fprintf, etc with | ||||||
| %v (most compact), %+v (adds pointer addresses), %#v (adds types), or | %v (most compact), %+v (adds pointer addresses), %#v (adds types), or | ||||||
| %#+v (adds types and pointer addresses): | %#+v (adds types and pointer addresses): | ||||||
|  |  | ||||||
| 	spew.Printf("myVar1: %v -- myVar2: %+v", myVar1, myVar2) | 	spew.Printf("myVar1: %v -- myVar2: %+v", myVar1, myVar2) | ||||||
| 	spew.Printf("myVar3: %#v -- myVar4: %#+v", myVar3, myVar4) | 	spew.Printf("myVar3: %#v -- myVar4: %#+v", myVar3, myVar4) | ||||||
| 	spew.Fprintf(someWriter, "myVar1: %v -- myVar2: %+v", myVar1, myVar2) | 	spew.Fprintf(someWriter, "myVar1: %v -- myVar2: %+v", myVar1, myVar2) | ||||||
| 	spew.Fprintf(someWriter, "myVar3: %#v -- myVar4: %#+v", myVar3, myVar4) | 	spew.Fprintf(someWriter, "myVar3: %#v -- myVar4: %#+v", myVar3, myVar4) | ||||||
|  |  | ||||||
| # Configuration Options | Configuration Options | ||||||
|  |  | ||||||
| Configuration of spew is handled by fields in the ConfigState type.  For | Configuration of spew is handled by fields in the ConfigState type.  For | ||||||
| convenience, all of the top-level functions use a global state available | convenience, all of the top-level functions use a global state available | ||||||
| @ -76,38 +74,37 @@ equivalent to the top-level functions.  This allows concurrent configuration | |||||||
| options.  See the ConfigState documentation for more details. | options.  See the ConfigState documentation for more details. | ||||||
|  |  | ||||||
| The following configuration options are available: | The following configuration options are available: | ||||||
|  | 	* Indent | ||||||
|   - Indent |  | ||||||
| 		String to use for each indentation level for Dump functions. | 		String to use for each indentation level for Dump functions. | ||||||
| 		It is a single space by default.  A popular alternative is "\t". | 		It is a single space by default.  A popular alternative is "\t". | ||||||
|  |  | ||||||
|   - MaxDepth | 	* MaxDepth | ||||||
| 		Maximum number of levels to descend into nested data structures. | 		Maximum number of levels to descend into nested data structures. | ||||||
| 		There is no limit by default. | 		There is no limit by default. | ||||||
|  |  | ||||||
|   - DisableMethods | 	* DisableMethods | ||||||
| 		Disables invocation of error and Stringer interface methods. | 		Disables invocation of error and Stringer interface methods. | ||||||
| 		Method invocation is enabled by default. | 		Method invocation is enabled by default. | ||||||
|  |  | ||||||
|   - DisablePointerMethods | 	* DisablePointerMethods | ||||||
| 		Disables invocation of error and Stringer interface methods on types | 		Disables invocation of error and Stringer interface methods on types | ||||||
| 		which only accept pointer receivers from non-pointer variables. | 		which only accept pointer receivers from non-pointer variables. | ||||||
| 		Pointer method invocation is enabled by default. | 		Pointer method invocation is enabled by default. | ||||||
|  |  | ||||||
|   - DisablePointerAddresses | 	* DisablePointerAddresses | ||||||
| 		DisablePointerAddresses specifies whether to disable the printing of | 		DisablePointerAddresses specifies whether to disable the printing of | ||||||
| 		pointer addresses. This is useful when diffing data structures in tests. | 		pointer addresses. This is useful when diffing data structures in tests. | ||||||
|  |  | ||||||
|   - DisableCapacities | 	* DisableCapacities | ||||||
| 		DisableCapacities specifies whether to disable the printing of | 		DisableCapacities specifies whether to disable the printing of | ||||||
| 		capacities for arrays, slices, maps and channels. This is useful when | 		capacities for arrays, slices, maps and channels. This is useful when | ||||||
| 		diffing data structures in tests. | 		diffing data structures in tests. | ||||||
|  |  | ||||||
|   - ContinueOnMethod | 	* ContinueOnMethod | ||||||
| 		Enables recursion into types after invoking error and Stringer interface | 		Enables recursion into types after invoking error and Stringer interface | ||||||
| 		methods. Recursion after method invocation is disabled by default. | 		methods. Recursion after method invocation is disabled by default. | ||||||
|  |  | ||||||
|   - SortKeys | 	* SortKeys | ||||||
| 		Specifies map keys should be sorted before being printed. Use | 		Specifies map keys should be sorted before being printed. Use | ||||||
| 		this to have a more deterministic, diffable output.  Note that | 		this to have a more deterministic, diffable output.  Note that | ||||||
| 		only native types (bool, int, uint, floats, uintptr and string) | 		only native types (bool, int, uint, floats, uintptr and string) | ||||||
| @ -116,12 +113,12 @@ The following configuration options are available: | |||||||
| 		reflect.Value.String() output which guarantees display | 		reflect.Value.String() output which guarantees display | ||||||
| 		stability.  Natural map order is used by default. | 		stability.  Natural map order is used by default. | ||||||
|  |  | ||||||
|   - SpewKeys | 	* SpewKeys | ||||||
| 		Specifies that, as a last resort attempt, map keys should be | 		Specifies that, as a last resort attempt, map keys should be | ||||||
| 		spewed to strings and sorted by those strings.  This is only | 		spewed to strings and sorted by those strings.  This is only | ||||||
| 		considered if SortKeys is true. | 		considered if SortKeys is true. | ||||||
|  |  | ||||||
| # Dump Usage | Dump Usage | ||||||
|  |  | ||||||
| Simply call spew.Dump with a list of variables you want to dump: | Simply call spew.Dump with a list of variables you want to dump: | ||||||
|  |  | ||||||
| @ -136,7 +133,7 @@ A third option is to call spew.Sdump to get the formatted output as a string: | |||||||
|  |  | ||||||
| 	str := spew.Sdump(myVar1, myVar2, ...) | 	str := spew.Sdump(myVar1, myVar2, ...) | ||||||
|  |  | ||||||
| # Sample Dump Output | Sample Dump Output | ||||||
|  |  | ||||||
| See the Dump example for details on the setup of the types and variables being | See the Dump example for details on the setup of the types and variables being | ||||||
| shown here. | shown here. | ||||||
| @ -153,14 +150,13 @@ shown here. | |||||||
|  |  | ||||||
| Byte (and uint8) arrays and slices are displayed uniquely like the hexdump -C | Byte (and uint8) arrays and slices are displayed uniquely like the hexdump -C | ||||||
| command as shown. | command as shown. | ||||||
|  |  | ||||||
| 	([]uint8) (len=32 cap=32) { | 	([]uint8) (len=32 cap=32) { | ||||||
| 	 00000000  11 12 13 14 15 16 17 18  19 1a 1b 1c 1d 1e 1f 20  |............... | | 	 00000000  11 12 13 14 15 16 17 18  19 1a 1b 1c 1d 1e 1f 20  |............... | | ||||||
| 	 00000010  21 22 23 24 25 26 27 28  29 2a 2b 2c 2d 2e 2f 30  |!"#$%&'()*+,-./0| | 	 00000010  21 22 23 24 25 26 27 28  29 2a 2b 2c 2d 2e 2f 30  |!"#$%&'()*+,-./0| | ||||||
| 	 00000020  31 32                                             |12| | 	 00000020  31 32                                             |12| | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| # Custom Formatter | Custom Formatter | ||||||
|  |  | ||||||
| Spew provides a custom formatter that implements the fmt.Formatter interface | Spew provides a custom formatter that implements the fmt.Formatter interface | ||||||
| so that it integrates cleanly with standard fmt package printing functions. The | so that it integrates cleanly with standard fmt package printing functions. The | ||||||
| @ -174,7 +170,7 @@ standard fmt package for formatting.  In addition, the custom formatter ignores | |||||||
| the width and precision arguments (however they will still work on the format | the width and precision arguments (however they will still work on the format | ||||||
| specifiers not handled by the custom formatter). | specifiers not handled by the custom formatter). | ||||||
|  |  | ||||||
| # Custom Formatter Usage | Custom Formatter Usage | ||||||
|  |  | ||||||
| The simplest way to make use of the spew custom formatter is to call one of the | The simplest way to make use of the spew custom formatter is to call one of the | ||||||
| convenience functions such as spew.Printf, spew.Println, or spew.Printf.  The | convenience functions such as spew.Printf, spew.Println, or spew.Printf.  The | ||||||
| @ -188,17 +184,15 @@ functions have syntax you are most likely already familiar with: | |||||||
|  |  | ||||||
| See the Index for the full list convenience functions. | See the Index for the full list convenience functions. | ||||||
|  |  | ||||||
| # Sample Formatter Output | Sample Formatter Output | ||||||
|  |  | ||||||
| Double pointer to a uint8: | Double pointer to a uint8: | ||||||
|  |  | ||||||
| 	  %v: <**>5 | 	  %v: <**>5 | ||||||
| 	 %+v: <**>(0xf8400420d0->0xf8400420c8)5 | 	 %+v: <**>(0xf8400420d0->0xf8400420c8)5 | ||||||
| 	 %#v: (**uint8)5 | 	 %#v: (**uint8)5 | ||||||
| 	%#+v: (**uint8)(0xf8400420d0->0xf8400420c8)5 | 	%#+v: (**uint8)(0xf8400420d0->0xf8400420c8)5 | ||||||
|  |  | ||||||
| Pointer to circular struct with a uint8 field and a pointer to itself: | Pointer to circular struct with a uint8 field and a pointer to itself: | ||||||
|  |  | ||||||
| 	  %v: <*>{1 <*><shown>} | 	  %v: <*>{1 <*><shown>} | ||||||
| 	 %+v: <*>(0xf84003e260){ui8:1 c:<*>(0xf84003e260)<shown>} | 	 %+v: <*>(0xf84003e260){ui8:1 c:<*>(0xf84003e260)<shown>} | ||||||
| 	 %#v: (*main.circular){ui8:(uint8)1 c:(*main.circular)<shown>} | 	 %#v: (*main.circular){ui8:(uint8)1 c:(*main.circular)<shown>} | ||||||
| @ -207,7 +201,7 @@ Pointer to circular struct with a uint8 field and a pointer to itself: | |||||||
| See the Printf example for details on the setup of variables being shown | See the Printf example for details on the setup of variables being shown | ||||||
| here. | here. | ||||||
|  |  | ||||||
| # Errors | Errors | ||||||
|  |  | ||||||
| Since it is possible for custom Stringer/error interfaces to panic, spew | Since it is possible for custom Stringer/error interfaces to panic, spew | ||||||
| detects them and handles them internally by printing the panic information | detects them and handles them internally by printing the panic information | ||||||
|  | |||||||
							
								
								
									
										10
									
								
								vendor/github.com/davecgh/go-spew/spew/dump.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										10
									
								
								vendor/github.com/davecgh/go-spew/spew/dump.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @ -488,14 +488,14 @@ pointer addresses used to indirect to the final value.  It provides the | |||||||
| following features over the built-in printing facilities provided by the fmt | following features over the built-in printing facilities provided by the fmt | ||||||
| package: | package: | ||||||
|  |  | ||||||
|   - Pointers are dereferenced and followed | 	* Pointers are dereferenced and followed | ||||||
|   - Circular data structures are detected and handled properly | 	* Circular data structures are detected and handled properly | ||||||
|   - Custom Stringer/error interfaces are optionally invoked, including | 	* Custom Stringer/error interfaces are optionally invoked, including | ||||||
| 	  on unexported types | 	  on unexported types | ||||||
|   - Custom types which only implement the Stringer/error interfaces via | 	* Custom types which only implement the Stringer/error interfaces via | ||||||
| 	  a pointer receiver are optionally invoked when passing non-pointer | 	  a pointer receiver are optionally invoked when passing non-pointer | ||||||
| 	  variables | 	  variables | ||||||
|   - Byte arrays and slices are dumped like the hexdump -C command which | 	* Byte arrays and slices are dumped like the hexdump -C command which | ||||||
| 	  includes offsets, byte values in hex, and ASCII output | 	  includes offsets, byte values in hex, and ASCII output | ||||||
|  |  | ||||||
| The configuration options are controlled by an exported package global, | The configuration options are controlled by an exported package global, | ||||||
|  | |||||||
							
								
								
									
										3
									
								
								vendor/github.com/docker/go/canonical/json/decode.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								vendor/github.com/docker/go/canonical/json/decode.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @ -74,13 +74,14 @@ import ( | |||||||
| // | // | ||||||
| // The JSON null value unmarshals into an interface, map, pointer, or slice | // The JSON null value unmarshals into an interface, map, pointer, or slice | ||||||
| // by setting that Go value to nil. Because null is often used in JSON to mean | // by setting that Go value to nil. Because null is often used in JSON to mean | ||||||
| // “not present,” unmarshaling a JSON null into any other Go type has no effect | // ``not present,'' unmarshaling a JSON null into any other Go type has no effect | ||||||
| // on the value and produces no error. | // on the value and produces no error. | ||||||
| // | // | ||||||
| // When unmarshaling quoted strings, invalid UTF-8 or | // When unmarshaling quoted strings, invalid UTF-8 or | ||||||
| // invalid UTF-16 surrogate pairs are not treated as an error. | // invalid UTF-16 surrogate pairs are not treated as an error. | ||||||
| // Instead, they are replaced by the Unicode replacement | // Instead, they are replaced by the Unicode replacement | ||||||
| // character U+FFFD. | // character U+FFFD. | ||||||
|  | // | ||||||
| func Unmarshal(data []byte, v interface{}) error { | func Unmarshal(data []byte, v interface{}) error { | ||||||
| 	// Check for well-formedness. | 	// Check for well-formedness. | ||||||
| 	// Avoids filling out half a data structure | 	// Avoids filling out half a data structure | ||||||
|  | |||||||
							
								
								
									
										2
									
								
								vendor/github.com/docker/go/canonical/json/encode.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/docker/go/canonical/json/encode.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @ -58,7 +58,6 @@ import ( | |||||||
| // becomes a member of the object unless | // becomes a member of the object unless | ||||||
| //   - the field's tag is "-", or | //   - the field's tag is "-", or | ||||||
| //   - the field is empty and its tag specifies the "omitempty" option. | //   - the field is empty and its tag specifies the "omitempty" option. | ||||||
| // |  | ||||||
| // The empty values are false, 0, any | // The empty values are false, 0, any | ||||||
| // nil pointer or interface value, and any array, slice, map, or string of | // nil pointer or interface value, and any array, slice, map, or string of | ||||||
| // length zero. The object's default key string is the struct field name | // length zero. The object's default key string is the struct field name | ||||||
| @ -134,6 +133,7 @@ import ( | |||||||
| // JSON cannot represent cyclic data structures and Marshal does not | // JSON cannot represent cyclic data structures and Marshal does not | ||||||
| // handle them.  Passing cyclic structures to Marshal will result in | // handle them.  Passing cyclic structures to Marshal will result in | ||||||
| // an infinite recursion. | // an infinite recursion. | ||||||
|  | // | ||||||
| func Marshal(v interface{}) ([]byte, error) { | func Marshal(v interface{}) ([]byte, error) { | ||||||
| 	return marshal(v, false) | 	return marshal(v, false) | ||||||
| } | } | ||||||
|  | |||||||
							
								
								
									
										5
									
								
								vendor/github.com/docker/go/canonical/json/fold.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										5
									
								
								vendor/github.com/docker/go/canonical/json/fold.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @ -24,9 +24,8 @@ const ( | |||||||
| // 4) simpleLetterEqualFold, no specials, no non-letters. | // 4) simpleLetterEqualFold, no specials, no non-letters. | ||||||
| // | // | ||||||
| // The letters S and K are special because they map to 3 runes, not just 2: | // The letters S and K are special because they map to 3 runes, not just 2: | ||||||
| //   - S maps to s and to U+017F 'ſ' Latin small letter long s | //  * S maps to s and to U+017F 'ſ' Latin small letter long s | ||||||
| //   - k maps to K and to U+212A 'K' Kelvin sign | //  * k maps to K and to U+212A 'K' Kelvin sign | ||||||
| // |  | ||||||
| // See https://play.golang.org/p/tTxjOc0OGo | // See https://play.golang.org/p/tTxjOc0OGo | ||||||
| // | // | ||||||
| // The returned function is specialized for matching against s and | // The returned function is specialized for matching against s and | ||||||
|  | |||||||
							
								
								
									
										1
									
								
								vendor/github.com/docker/go/canonical/json/stream.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								vendor/github.com/docker/go/canonical/json/stream.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @ -242,6 +242,7 @@ var _ Unmarshaler = (*RawMessage)(nil) | |||||||
| //	Number, for JSON numbers | //	Number, for JSON numbers | ||||||
| //	string, for JSON string literals | //	string, for JSON string literals | ||||||
| //	nil, for JSON null | //	nil, for JSON null | ||||||
|  | // | ||||||
| type Token interface{} | type Token interface{} | ||||||
|  |  | ||||||
| const ( | const ( | ||||||
|  | |||||||
							
								
								
									
										4
									
								
								vendor/github.com/emirpasic/gods/containers/iterator.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								vendor/github.com/emirpasic/gods/containers/iterator.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @ -72,7 +72,7 @@ type IteratorWithKey interface { | |||||||
| // | // | ||||||
| // Essentially it is the same as IteratorWithIndex, but provides additional: | // Essentially it is the same as IteratorWithIndex, but provides additional: | ||||||
| // | // | ||||||
| // # Prev() function to enable traversal in reverse | // Prev() function to enable traversal in reverse | ||||||
| // | // | ||||||
| // Last() function to move the iterator to the last element. | // Last() function to move the iterator to the last element. | ||||||
| // | // | ||||||
| @ -105,7 +105,7 @@ type ReverseIteratorWithIndex interface { | |||||||
| // | // | ||||||
| // Essentially it is the same as IteratorWithKey, but provides additional: | // Essentially it is the same as IteratorWithKey, but provides additional: | ||||||
| // | // | ||||||
| // # Prev() function to enable traversal in reverse | // Prev() function to enable traversal in reverse | ||||||
| // | // | ||||||
| // Last() function to move the iterator to the last element. | // Last() function to move the iterator to the last element. | ||||||
| type ReverseIteratorWithKey interface { | type ReverseIteratorWithKey interface { | ||||||
|  | |||||||
							
								
								
									
										1
									
								
								vendor/github.com/emirpasic/gods/utils/comparator.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								vendor/github.com/emirpasic/gods/utils/comparator.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @ -10,7 +10,6 @@ import "time" | |||||||
| // which will panic if a or b are not of the asserted type. | // which will panic if a or b are not of the asserted type. | ||||||
| // | // | ||||||
| // Should return a number: | // Should return a number: | ||||||
| // |  | ||||||
| //    negative , if a < b | //    negative , if a < b | ||||||
| //    zero     , if a == b | //    zero     , if a == b | ||||||
| //    positive , if a > b | //    positive , if a > b | ||||||
|  | |||||||
							
								
								
									
										2
									
								
								vendor/github.com/felixge/httpsnoop/wrap_generated_gteq_1.8.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/felixge/httpsnoop/wrap_generated_gteq_1.8.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @ -1,6 +1,4 @@ | |||||||
| //go:build go1.8 |  | ||||||
| // +build go1.8 | // +build go1.8 | ||||||
|  |  | ||||||
| // Code generated by "httpsnoop/codegen"; DO NOT EDIT. | // Code generated by "httpsnoop/codegen"; DO NOT EDIT. | ||||||
|  |  | ||||||
| package httpsnoop | package httpsnoop | ||||||
|  | |||||||
							
								
								
									
										2
									
								
								vendor/github.com/felixge/httpsnoop/wrap_generated_lt_1.8.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/felixge/httpsnoop/wrap_generated_lt_1.8.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @ -1,6 +1,4 @@ | |||||||
| //go:build !go1.8 |  | ||||||
| // +build !go1.8 | // +build !go1.8 | ||||||
|  |  | ||||||
| // Code generated by "httpsnoop/codegen"; DO NOT EDIT. | // Code generated by "httpsnoop/codegen"; DO NOT EDIT. | ||||||
|  |  | ||||||
| package httpsnoop | package httpsnoop | ||||||
|  | |||||||
							
								
								
									
										5
									
								
								vendor/github.com/ghodss/yaml/fields.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										5
									
								
								vendor/github.com/ghodss/yaml/fields.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @ -347,9 +347,8 @@ const ( | |||||||
| // 4) simpleLetterEqualFold, no specials, no non-letters. | // 4) simpleLetterEqualFold, no specials, no non-letters. | ||||||
| // | // | ||||||
| // The letters S and K are special because they map to 3 runes, not just 2: | // The letters S and K are special because they map to 3 runes, not just 2: | ||||||
| //   - S maps to s and to U+017F 'ſ' Latin small letter long s | //  * S maps to s and to U+017F 'ſ' Latin small letter long s | ||||||
| //   - k maps to K and to U+212A 'K' Kelvin sign | //  * k maps to K and to U+212A 'K' Kelvin sign | ||||||
| // |  | ||||||
| // See http://play.golang.org/p/tTxjOc0OGo | // See http://play.golang.org/p/tTxjOc0OGo | ||||||
| // | // | ||||||
| // The returned function is specialized for matching against s and | // The returned function is specialized for matching against s and | ||||||
|  | |||||||
							
								
								
									
										4
									
								
								vendor/github.com/ghodss/yaml/yaml.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								vendor/github.com/ghodss/yaml/yaml.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @ -64,9 +64,9 @@ func JSONToYAML(j []byte) ([]byte, error) { | |||||||
| // this method should be a no-op. | // this method should be a no-op. | ||||||
| // | // | ||||||
| // Things YAML can do that are not supported by JSON: | // Things YAML can do that are not supported by JSON: | ||||||
| //   - In YAML you can have binary and null keys in your maps. These are invalid | // * In YAML you can have binary and null keys in your maps. These are invalid | ||||||
| //   in JSON. (int and float keys are converted to strings.) | //   in JSON. (int and float keys are converted to strings.) | ||||||
| //   - Binary data in YAML with the !!binary tag is not supported. If you want to | // * Binary data in YAML with the !!binary tag is not supported. If you want to | ||||||
| //   use binary data with this library, encode the data as base64 as usual but do | //   use binary data with this library, encode the data as base64 as usual but do | ||||||
| //   not use the !!binary tag in your YAML. This will ensure the original base64 | //   not use the !!binary tag in your YAML. This will ensure the original base64 | ||||||
| //   encoded data makes it all the way through to the JSON. | //   encoded data makes it all the way through to the JSON. | ||||||
|  | |||||||
							
								
								
									
										11
									
								
								vendor/github.com/go-git/gcfg/doc.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										11
									
								
								vendor/github.com/go-git/gcfg/doc.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @ -4,7 +4,7 @@ | |||||||
| // This package is still a work in progress; see the sections below for planned | // This package is still a work in progress; see the sections below for planned | ||||||
| // changes. | // changes. | ||||||
| // | // | ||||||
| // # Syntax | // Syntax | ||||||
| // | // | ||||||
| // The syntax is based on that used by git config: | // The syntax is based on that used by git config: | ||||||
| // http://git-scm.com/docs/git-config#_syntax . | // http://git-scm.com/docs/git-config#_syntax . | ||||||
| @ -26,7 +26,7 @@ | |||||||
| //      - subsection: '[sec "A"]' -> '[sec "B"]' -> '[sec "A"]' is an error | //      - subsection: '[sec "A"]' -> '[sec "B"]' -> '[sec "A"]' is an error | ||||||
| //      - multivalued variable: 'multi=a' -> 'other=x' -> 'multi=b' is an error | //      - multivalued variable: 'multi=a' -> 'other=x' -> 'multi=b' is an error | ||||||
| // | // | ||||||
| // # Data structure | // Data structure | ||||||
| // | // | ||||||
| // The functions in this package read values into a user-defined struct. | // The functions in this package read values into a user-defined struct. | ||||||
| // Each section corresponds to a struct field in the config struct, and each | // Each section corresponds to a struct field in the config struct, and each | ||||||
| @ -56,7 +56,7 @@ | |||||||
| // or when a field is not of a suitable type (either a struct or a map with | // or when a field is not of a suitable type (either a struct or a map with | ||||||
| // string keys and pointer-to-struct values). | // string keys and pointer-to-struct values). | ||||||
| // | // | ||||||
| // # Parsing of values | // Parsing of values | ||||||
| // | // | ||||||
| // The section structs in the config struct may contain single-valued or | // The section structs in the config struct may contain single-valued or | ||||||
| // multi-valued variables. Variables of unnamed slice type (that is, a type | // multi-valued variables. Variables of unnamed slice type (that is, a type | ||||||
| @ -98,7 +98,7 @@ | |||||||
| // The types subpackage for provides helpers for parsing "enum-like" and integer | // The types subpackage for provides helpers for parsing "enum-like" and integer | ||||||
| // types. | // types. | ||||||
| // | // | ||||||
| // # Error handling | // Error handling | ||||||
| // | // | ||||||
| // There are 3 types of errors: | // There are 3 types of errors: | ||||||
| // | // | ||||||
| @ -122,7 +122,7 @@ | |||||||
| // filtered out programmatically. To ignore extra data warnings, wrap the | // filtered out programmatically. To ignore extra data warnings, wrap the | ||||||
| // gcfg.Read*Into invocation into a call to gcfg.FatalOnly. | // gcfg.Read*Into invocation into a call to gcfg.FatalOnly. | ||||||
| // | // | ||||||
| // # TODO | // TODO | ||||||
| // | // | ||||||
| // The following is a list of changes under consideration: | // The following is a list of changes under consideration: | ||||||
| //  - documentation | //  - documentation | ||||||
| @ -141,4 +141,5 @@ | |||||||
| //  - error handling | //  - error handling | ||||||
| //    - make error context accessible programmatically? | //    - make error context accessible programmatically? | ||||||
| //    - limit input size? | //    - limit input size? | ||||||
|  | // | ||||||
| package gcfg // import "github.com/go-git/gcfg" | package gcfg // import "github.com/go-git/gcfg" | ||||||
|  | |||||||
							
								
								
									
										1
									
								
								vendor/github.com/go-git/gcfg/errors.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								vendor/github.com/go-git/gcfg/errors.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @ -11,6 +11,7 @@ import ( | |||||||
| //  err := gcfg.FatalOnly(gcfg.ReadFileInto(&cfg, configFile)) | //  err := gcfg.FatalOnly(gcfg.ReadFileInto(&cfg, configFile)) | ||||||
| //  if err != nil { | //  if err != nil { | ||||||
| //      ... | //      ... | ||||||
|  | // | ||||||
| func FatalOnly(err error) error { | func FatalOnly(err error) error { | ||||||
| 	return warnings.FatalOnly(err) | 	return warnings.FatalOnly(err) | ||||||
| } | } | ||||||
|  | |||||||
							
								
								
									
										4
									
								
								vendor/github.com/go-git/gcfg/scanner/errors.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								vendor/github.com/go-git/gcfg/scanner/errors.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @ -18,6 +18,7 @@ import ( | |||||||
| // The position Pos, if valid, points to the beginning of | // The position Pos, if valid, points to the beginning of | ||||||
| // the offending token, and the error condition is described | // the offending token, and the error condition is described | ||||||
| // by Msg. | // by Msg. | ||||||
|  | // | ||||||
| type Error struct { | type Error struct { | ||||||
| 	Pos token.Position | 	Pos token.Position | ||||||
| 	Msg string | 	Msg string | ||||||
| @ -35,6 +36,7 @@ func (e Error) Error() string { | |||||||
|  |  | ||||||
| // ErrorList is a list of *Errors. | // ErrorList is a list of *Errors. | ||||||
| // The zero value for an ErrorList is an empty ErrorList ready to use. | // The zero value for an ErrorList is an empty ErrorList ready to use. | ||||||
|  | // | ||||||
| type ErrorList []*Error | type ErrorList []*Error | ||||||
|  |  | ||||||
| // Add adds an Error with given position and error message to an ErrorList. | // Add adds an Error with given position and error message to an ErrorList. | ||||||
| @ -64,6 +66,7 @@ func (p ErrorList) Less(i, j int) bool { | |||||||
| // Sort sorts an ErrorList. *Error entries are sorted by position, | // Sort sorts an ErrorList. *Error entries are sorted by position, | ||||||
| // other errors are sorted by error message, and before any *Error | // other errors are sorted by error message, and before any *Error | ||||||
| // entry. | // entry. | ||||||
|  | // | ||||||
| func (p ErrorList) Sort() { | func (p ErrorList) Sort() { | ||||||
| 	sort.Sort(p) | 	sort.Sort(p) | ||||||
| } | } | ||||||
| @ -106,6 +109,7 @@ func (p ErrorList) Err() error { | |||||||
| // PrintError is a utility function that prints a list of errors to w, | // PrintError is a utility function that prints a list of errors to w, | ||||||
| // one error per line, if the err parameter is an ErrorList. Otherwise | // one error per line, if the err parameter is an ErrorList. Otherwise | ||||||
| // it prints the err string. | // it prints the err string. | ||||||
|  | // | ||||||
| func PrintError(w io.Writer, err error) { | func PrintError(w io.Writer, err error) { | ||||||
| 	if list, ok := err.(ErrorList); ok { | 	if list, ok := err.(ErrorList); ok { | ||||||
| 		for _, e := range list { | 		for _, e := range list { | ||||||
|  | |||||||
							
								
								
									
										17
									
								
								vendor/github.com/go-git/gcfg/token/position.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										17
									
								
								vendor/github.com/go-git/gcfg/token/position.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @ -18,6 +18,7 @@ import ( | |||||||
| // Position describes an arbitrary source position | // Position describes an arbitrary source position | ||||||
| // including the file, line, and column location. | // including the file, line, and column location. | ||||||
| // A Position is valid if the line number is > 0. | // A Position is valid if the line number is > 0. | ||||||
|  | // | ||||||
| type Position struct { | type Position struct { | ||||||
| 	Filename string // filename, if any | 	Filename string // filename, if any | ||||||
| 	Offset   int    // offset, starting at 0 | 	Offset   int    // offset, starting at 0 | ||||||
| @ -34,6 +35,7 @@ func (pos *Position) IsValid() bool { return pos.Line > 0 } | |||||||
| //	line:column         valid position without file name | //	line:column         valid position without file name | ||||||
| //	file                invalid position with file name | //	file                invalid position with file name | ||||||
| //	-                   invalid position without file name | //	-                   invalid position without file name | ||||||
|  | // | ||||||
| func (pos Position) String() string { | func (pos Position) String() string { | ||||||
| 	s := pos.Filename | 	s := pos.Filename | ||||||
| 	if pos.IsValid() { | 	if pos.IsValid() { | ||||||
| @ -67,12 +69,14 @@ func (pos Position) String() string { | |||||||
| // equivalent to comparing the respective source file offsets. If p and q | // equivalent to comparing the respective source file offsets. If p and q | ||||||
| // are in different files, p < q is true if the file implied by p was added | // are in different files, p < q is true if the file implied by p was added | ||||||
| // to the respective file set before the file implied by q. | // to the respective file set before the file implied by q. | ||||||
|  | // | ||||||
| type Pos int | type Pos int | ||||||
|  |  | ||||||
| // The zero value for Pos is NoPos; there is no file and line information | // The zero value for Pos is NoPos; there is no file and line information | ||||||
| // associated with it, and NoPos().IsValid() is false. NoPos is always | // associated with it, and NoPos().IsValid() is false. NoPos is always | ||||||
| // smaller than any other Pos value. The corresponding Position value | // smaller than any other Pos value. The corresponding Position value | ||||||
| // for NoPos is the zero value for Position. | // for NoPos is the zero value for Position. | ||||||
|  | // | ||||||
| const NoPos Pos = 0 | const NoPos Pos = 0 | ||||||
|  |  | ||||||
| // IsValid returns true if the position is valid. | // IsValid returns true if the position is valid. | ||||||
| @ -85,6 +89,7 @@ func (p Pos) IsValid() bool { | |||||||
|  |  | ||||||
| // A File is a handle for a file belonging to a FileSet. | // A File is a handle for a file belonging to a FileSet. | ||||||
| // A File has a name, size, and line offset table. | // A File has a name, size, and line offset table. | ||||||
|  | // | ||||||
| type File struct { | type File struct { | ||||||
| 	set  *FileSet | 	set  *FileSet | ||||||
| 	name string // file name as provided to AddFile | 	name string // file name as provided to AddFile | ||||||
| @ -122,6 +127,7 @@ func (f *File) LineCount() int { | |||||||
| // AddLine adds the line offset for a new line. | // AddLine adds the line offset for a new line. | ||||||
| // The line offset must be larger than the offset for the previous line | // The line offset must be larger than the offset for the previous line | ||||||
| // and smaller than the file size; otherwise the line offset is ignored. | // and smaller than the file size; otherwise the line offset is ignored. | ||||||
|  | // | ||||||
| func (f *File) AddLine(offset int) { | func (f *File) AddLine(offset int) { | ||||||
| 	f.set.mutex.Lock() | 	f.set.mutex.Lock() | ||||||
| 	if i := len(f.lines); (i == 0 || f.lines[i-1] < offset) && offset < f.size { | 	if i := len(f.lines); (i == 0 || f.lines[i-1] < offset) && offset < f.size { | ||||||
| @ -137,6 +143,7 @@ func (f *File) AddLine(offset int) { | |||||||
| // Each line offset must be larger than the offset for the previous line | // Each line offset must be larger than the offset for the previous line | ||||||
| // and smaller than the file size; otherwise SetLines fails and returns | // and smaller than the file size; otherwise SetLines fails and returns | ||||||
| // false. | // false. | ||||||
|  | // | ||||||
| func (f *File) SetLines(lines []int) bool { | func (f *File) SetLines(lines []int) bool { | ||||||
| 	// verify validity of lines table | 	// verify validity of lines table | ||||||
| 	size := f.size | 	size := f.size | ||||||
| @ -190,6 +197,7 @@ type lineInfo struct { | |||||||
| // | // | ||||||
| // AddLineInfo is typically used to register alternative position | // AddLineInfo is typically used to register alternative position | ||||||
| // information for //line filename:line comments in source files. | // information for //line filename:line comments in source files. | ||||||
|  | // | ||||||
| func (f *File) AddLineInfo(offset int, filename string, line int) { | func (f *File) AddLineInfo(offset int, filename string, line int) { | ||||||
| 	f.set.mutex.Lock() | 	f.set.mutex.Lock() | ||||||
| 	if i := len(f.infos); i == 0 || f.infos[i-1].Offset < offset && offset < f.size { | 	if i := len(f.infos); i == 0 || f.infos[i-1].Offset < offset && offset < f.size { | ||||||
| @ -201,6 +209,7 @@ func (f *File) AddLineInfo(offset int, filename string, line int) { | |||||||
| // Pos returns the Pos value for the given file offset; | // Pos returns the Pos value for the given file offset; | ||||||
| // the offset must be <= f.Size(). | // the offset must be <= f.Size(). | ||||||
| // f.Pos(f.Offset(p)) == p. | // f.Pos(f.Offset(p)) == p. | ||||||
|  | // | ||||||
| func (f *File) Pos(offset int) Pos { | func (f *File) Pos(offset int) Pos { | ||||||
| 	if offset > f.size { | 	if offset > f.size { | ||||||
| 		panic("illegal file offset") | 		panic("illegal file offset") | ||||||
| @ -211,6 +220,7 @@ func (f *File) Pos(offset int) Pos { | |||||||
| // Offset returns the offset for the given file position p; | // Offset returns the offset for the given file position p; | ||||||
| // p must be a valid Pos value in that file. | // p must be a valid Pos value in that file. | ||||||
| // f.Offset(f.Pos(offset)) == offset. | // f.Offset(f.Pos(offset)) == offset. | ||||||
|  | // | ||||||
| func (f *File) Offset(p Pos) int { | func (f *File) Offset(p Pos) int { | ||||||
| 	if int(p) < f.base || int(p) > f.base+f.size { | 	if int(p) < f.base || int(p) > f.base+f.size { | ||||||
| 		panic("illegal Pos value") | 		panic("illegal Pos value") | ||||||
| @ -220,6 +230,7 @@ func (f *File) Offset(p Pos) int { | |||||||
|  |  | ||||||
| // Line returns the line number for the given file position p; | // Line returns the line number for the given file position p; | ||||||
| // p must be a Pos value in that file or NoPos. | // p must be a Pos value in that file or NoPos. | ||||||
|  | // | ||||||
| func (f *File) Line(p Pos) int { | func (f *File) Line(p Pos) int { | ||||||
| 	// TODO(gri) this can be implemented much more efficiently | 	// TODO(gri) this can be implemented much more efficiently | ||||||
| 	return f.Position(p).Line | 	return f.Position(p).Line | ||||||
| @ -257,6 +268,7 @@ func (f *File) position(p Pos) (pos Position) { | |||||||
|  |  | ||||||
| // Position returns the Position value for the given file position p; | // Position returns the Position value for the given file position p; | ||||||
| // p must be a Pos value in that file or NoPos. | // p must be a Pos value in that file or NoPos. | ||||||
|  | // | ||||||
| func (f *File) Position(p Pos) (pos Position) { | func (f *File) Position(p Pos) (pos Position) { | ||||||
| 	if p != NoPos { | 	if p != NoPos { | ||||||
| 		if int(p) < f.base || int(p) > f.base+f.size { | 		if int(p) < f.base || int(p) > f.base+f.size { | ||||||
| @ -273,6 +285,7 @@ func (f *File) Position(p Pos) (pos Position) { | |||||||
| // A FileSet represents a set of source files. | // A FileSet represents a set of source files. | ||||||
| // Methods of file sets are synchronized; multiple goroutines | // Methods of file sets are synchronized; multiple goroutines | ||||||
| // may invoke them concurrently. | // may invoke them concurrently. | ||||||
|  | // | ||||||
| type FileSet struct { | type FileSet struct { | ||||||
| 	mutex sync.RWMutex // protects the file set | 	mutex sync.RWMutex // protects the file set | ||||||
| 	base  int          // base offset for the next file | 	base  int          // base offset for the next file | ||||||
| @ -289,6 +302,7 @@ func NewFileSet() *FileSet { | |||||||
|  |  | ||||||
| // Base returns the minimum base offset that must be provided to | // Base returns the minimum base offset that must be provided to | ||||||
| // AddFile when adding the next file. | // AddFile when adding the next file. | ||||||
|  | // | ||||||
| func (s *FileSet) Base() int { | func (s *FileSet) Base() int { | ||||||
| 	s.mutex.RLock() | 	s.mutex.RLock() | ||||||
| 	b := s.base | 	b := s.base | ||||||
| @ -311,6 +325,7 @@ func (s *FileSet) Base() int { | |||||||
| // with offs in the range [0, size] and thus p in the range [base, base+size]. | // with offs in the range [0, size] and thus p in the range [base, base+size]. | ||||||
| // For convenience, File.Pos may be used to create file-specific position | // For convenience, File.Pos may be used to create file-specific position | ||||||
| // values from a file offset. | // values from a file offset. | ||||||
|  | // | ||||||
| func (s *FileSet) AddFile(filename string, base, size int) *File { | func (s *FileSet) AddFile(filename string, base, size int) *File { | ||||||
| 	s.mutex.Lock() | 	s.mutex.Lock() | ||||||
| 	defer s.mutex.Unlock() | 	defer s.mutex.Unlock() | ||||||
| @ -332,6 +347,7 @@ func (s *FileSet) AddFile(filename string, base, size int) *File { | |||||||
|  |  | ||||||
| // Iterate calls f for the files in the file set in the order they were added | // Iterate calls f for the files in the file set in the order they were added | ||||||
| // until f returns false. | // until f returns false. | ||||||
|  | // | ||||||
| func (s *FileSet) Iterate(f func(*File) bool) { | func (s *FileSet) Iterate(f func(*File) bool) { | ||||||
| 	for i := 0; ; i++ { | 	for i := 0; ; i++ { | ||||||
| 		var file *File | 		var file *File | ||||||
| @ -370,6 +386,7 @@ func (s *FileSet) file(p Pos) *File { | |||||||
| // File returns the file that contains the position p. | // File returns the file that contains the position p. | ||||||
| // If no such file is found (for instance for p == NoPos), | // If no such file is found (for instance for p == NoPos), | ||||||
| // the result is nil. | // the result is nil. | ||||||
|  | // | ||||||
| func (s *FileSet) File(p Pos) (f *File) { | func (s *FileSet) File(p Pos) (f *File) { | ||||||
| 	if p != NoPos { | 	if p != NoPos { | ||||||
| 		s.mutex.RLock() | 		s.mutex.RLock() | ||||||
|  | |||||||
							
								
								
									
										4
									
								
								vendor/github.com/go-git/gcfg/token/token.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								vendor/github.com/go-git/gcfg/token/token.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @ -7,6 +7,7 @@ | |||||||
| // | // | ||||||
| // Note that the API for the token package may change to accommodate new | // Note that the API for the token package may change to accommodate new | ||||||
| // features or implementation changes in gcfg. | // features or implementation changes in gcfg. | ||||||
|  | // | ||||||
| package token | package token | ||||||
|  |  | ||||||
| import "strconv" | import "strconv" | ||||||
| @ -57,6 +58,7 @@ var tokens = [...]string{ | |||||||
| // sequence (e.g., for the token ASSIGN, the string is "="). For all other | // sequence (e.g., for the token ASSIGN, the string is "="). For all other | ||||||
| // tokens the string corresponds to the token constant name (e.g. for the | // tokens the string corresponds to the token constant name (e.g. for the | ||||||
| // token IDENT, the string is "IDENT"). | // token IDENT, the string is "IDENT"). | ||||||
|  | // | ||||||
| func (tok Token) String() string { | func (tok Token) String() string { | ||||||
| 	s := "" | 	s := "" | ||||||
| 	if 0 <= tok && tok < Token(len(tokens)) { | 	if 0 <= tok && tok < Token(len(tokens)) { | ||||||
| @ -72,8 +74,10 @@ func (tok Token) String() string { | |||||||
|  |  | ||||||
| // IsLiteral returns true for tokens corresponding to identifiers | // IsLiteral returns true for tokens corresponding to identifiers | ||||||
| // and basic type literals; it returns false otherwise. | // and basic type literals; it returns false otherwise. | ||||||
|  | // | ||||||
| func (tok Token) IsLiteral() bool { return literal_beg < tok && tok < literal_end } | func (tok Token) IsLiteral() bool { return literal_beg < tok && tok < literal_end } | ||||||
|  |  | ||||||
| // IsOperator returns true for tokens corresponding to operators and | // IsOperator returns true for tokens corresponding to operators and | ||||||
| // delimiters; it returns false otherwise. | // delimiters; it returns false otherwise. | ||||||
|  | // | ||||||
| func (tok Token) IsOperator() bool { return operator_beg < tok && tok < operator_end } | func (tok Token) IsOperator() bool { return operator_beg < tok && tok < operator_end } | ||||||
|  | |||||||
							
								
								
									
										1
									
								
								vendor/github.com/go-git/go-git/v5/plumbing/format/config/doc.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								vendor/github.com/go-git/go-git/v5/plumbing/format/config/doc.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @ -118,4 +118,5 @@ | |||||||
| // 			path = /path/to/foo.inc ; include by absolute path | // 			path = /path/to/foo.inc ; include by absolute path | ||||||
| // 			path = foo ; expand "foo" relative to the current file | // 			path = foo ; expand "foo" relative to the current file | ||||||
| // 			path = ~/foo ; expand "foo" in your `$HOME` directory | // 			path = ~/foo ; expand "foo" in your `$HOME` directory | ||||||
|  | // | ||||||
| package config | package config | ||||||
|  | |||||||
							
								
								
									
										1
									
								
								vendor/github.com/go-git/go-git/v5/plumbing/format/config/encoder.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								vendor/github.com/go-git/go-git/v5/plumbing/format/config/encoder.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @ -15,7 +15,6 @@ var ( | |||||||
| 	subsectionReplacer = strings.NewReplacer(`"`, `\"`, `\`, `\\`) | 	subsectionReplacer = strings.NewReplacer(`"`, `\"`, `\`, `\\`) | ||||||
| 	valueReplacer = strings.NewReplacer(`"`, `\"`, `\`, `\\`, "\n", `\n`, "\t", `\t`, "\b", `\b`) | 	valueReplacer = strings.NewReplacer(`"`, `\"`, `\`, `\\`, "\n", `\n`, "\t", `\t`, "\b", `\b`) | ||||||
| ) | ) | ||||||
|  |  | ||||||
| // NewEncoder returns a new encoder that writes to w. | // NewEncoder returns a new encoder that writes to w. | ||||||
| func NewEncoder(w io.Writer) *Encoder { | func NewEncoder(w io.Writer) *Encoder { | ||||||
| 	return &Encoder{w} | 	return &Encoder{w} | ||||||
|  | |||||||
							
								
								
									
										2
									
								
								vendor/github.com/go-git/go-git/v5/plumbing/format/config/option.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/go-git/go-git/v5/plumbing/format/config/option.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @ -34,7 +34,7 @@ func (opts Options) GoString() string { | |||||||
| // Get gets the value for the given key if set, | // Get gets the value for the given key if set, | ||||||
| // otherwise it returns the empty string. | // otherwise it returns the empty string. | ||||||
| // | // | ||||||
| // # Note that there is no difference | // Note that there is no difference | ||||||
| // | // | ||||||
| // This matches git behaviour since git v1.8.1-rc1, | // This matches git behaviour since git v1.8.1-rc1, | ||||||
| // if there are multiple definitions of a key, the | // if there are multiple definitions of a key, the | ||||||
|  | |||||||
							
								
								
									
										1
									
								
								vendor/github.com/go-git/go-git/v5/plumbing/format/config/section.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								vendor/github.com/go-git/go-git/v5/plumbing/format/config/section.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @ -25,6 +25,7 @@ import ( | |||||||
| //         option2 | //         option2 | ||||||
| //     [section "subsection2"] | //     [section "subsection2"] | ||||||
| //         option3 = value2 | //         option3 = value2 | ||||||
|  | // | ||||||
| type Section struct { | type Section struct { | ||||||
| 	Name        string | 	Name        string | ||||||
| 	Options     Options | 	Options     Options | ||||||
|  | |||||||
							
								
								
									
										1
									
								
								vendor/github.com/go-git/go-git/v5/plumbing/format/packfile/doc.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								vendor/github.com/go-git/go-git/v5/plumbing/format/packfile/doc.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @ -33,6 +33,7 @@ | |||||||
| // | // | ||||||
| //   - The trailer records 20-byte SHA1 checksum of all of the above. | //   - The trailer records 20-byte SHA1 checksum of all of the above. | ||||||
| // | // | ||||||
|  | // | ||||||
| // Source: | // Source: | ||||||
| // https://www.kernel.org/pub/software/scm/git/docs/v1.7.5/technical/pack-protocol.txt | // https://www.kernel.org/pub/software/scm/git/docs/v1.7.5/technical/pack-protocol.txt | ||||||
| package packfile | package packfile | ||||||
|  | |||||||
							
								
								
									
										1
									
								
								vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/updreq.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/updreq.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @ -48,7 +48,6 @@ func NewReferenceUpdateRequest() *ReferenceUpdateRequest { | |||||||
| //   - ofs-delta | //   - ofs-delta | ||||||
| //   - ref-delta | //   - ref-delta | ||||||
| //   - delete-refs | //   - delete-refs | ||||||
| // |  | ||||||
| // It leaves up to the user to add the following capabilities later: | // It leaves up to the user to add the following capabilities later: | ||||||
| //   - atomic | //   - atomic | ||||||
| //   - ofs-delta | //   - ofs-delta | ||||||
|  | |||||||
							
								
								
									
										1
									
								
								vendor/github.com/go-git/go-git/v5/utils/binary/read.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								vendor/github.com/go-git/go-git/v5/utils/binary/read.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @ -83,6 +83,7 @@ func ReadUntilFromBufioReader(r *bufio.Reader, delim byte) ([]byte, error) { | |||||||
| //     dheader[pos] = ofs & 127; | //     dheader[pos] = ofs & 127; | ||||||
| //     while (ofs >>= 7) | //     while (ofs >>= 7) | ||||||
| //         dheader[--pos] = 128 | (--ofs & 127); | //         dheader[--pos] = 128 | (--ofs & 127); | ||||||
|  | // | ||||||
| func ReadVariableWidthInt(r io.Reader) (int64, error) { | func ReadVariableWidthInt(r io.Reader) (int64, error) { | ||||||
| 	var c byte | 	var c byte | ||||||
| 	if err := Read(r, &c); err != nil { | 	if err := Read(r, &c); err != nil { | ||||||
|  | |||||||
							
								
								
									
										1
									
								
								vendor/github.com/go-git/go-git/v5/utils/merkletrie/internal/frame/frame.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								vendor/github.com/go-git/go-git/v5/utils/merkletrie/internal/frame/frame.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @ -42,7 +42,6 @@ func New(n noder.Noder) (*Frame, error) { | |||||||
| // separated by comas. | // separated by comas. | ||||||
| // | // | ||||||
| // Examples: | // Examples: | ||||||
| // |  | ||||||
| //     [] | //     [] | ||||||
| //     ["a", "b"] | //     ["a", "b"] | ||||||
| func (f *Frame) String() string { | func (f *Frame) String() string { | ||||||
|  | |||||||
							
								
								
									
										1
									
								
								vendor/github.com/go-git/go-git/v5/utils/merkletrie/iter.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								vendor/github.com/go-git/go-git/v5/utils/merkletrie/iter.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @ -26,6 +26,7 @@ import ( | |||||||
| //      / \                d/b | //      / \                d/b | ||||||
| //     b   a               z | //     b   a               z | ||||||
| // | // | ||||||
|  | // | ||||||
| // This iterator is somewhat especial as you can chose to skip whole | // This iterator is somewhat especial as you can chose to skip whole | ||||||
| // "directories" when iterating: | // "directories" when iterating: | ||||||
| // | // | ||||||
|  | |||||||
							
								
								
									
										1
									
								
								vendor/github.com/go-git/go-git/v5/worktree_bsd.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								vendor/github.com/go-git/go-git/v5/worktree_bsd.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @ -1,4 +1,3 @@ | |||||||
| //go:build darwin || freebsd || netbsd |  | ||||||
| // +build darwin freebsd netbsd | // +build darwin freebsd netbsd | ||||||
|  |  | ||||||
| package git | package git | ||||||
|  | |||||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user