feat: translation support
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
See #483
This commit is contained in:
@ -4,15 +4,16 @@ import (
|
||||
"coopcloud.tech/abra/cli/internal"
|
||||
"coopcloud.tech/abra/pkg/autocomplete"
|
||||
gitPkg "coopcloud.tech/abra/pkg/git"
|
||||
"coopcloud.tech/abra/pkg/i18n"
|
||||
"coopcloud.tech/abra/pkg/log"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var RecipeDiffCommand = &cobra.Command{
|
||||
Use: "diff <recipe> [flags]",
|
||||
Aliases: []string{"d"},
|
||||
Short: "Show unstaged changes in recipe config",
|
||||
Long: "This command requires /usr/bin/git.",
|
||||
Use: i18n.G("diff <recipe> [flags]"),
|
||||
Aliases: []string{i18n.G("d")},
|
||||
Short: i18n.G("Show unstaged changes in recipe config"),
|
||||
Long: i18n.G("This command requires /usr/bin/git."),
|
||||
Args: cobra.MinimumNArgs(1),
|
||||
ValidArgsFunction: func(
|
||||
cmd *cobra.Command,
|
||||
|
@ -6,6 +6,7 @@ import (
|
||||
"coopcloud.tech/abra/cli/internal"
|
||||
"coopcloud.tech/abra/pkg/autocomplete"
|
||||
"coopcloud.tech/abra/pkg/formatter"
|
||||
"coopcloud.tech/abra/pkg/i18n"
|
||||
"coopcloud.tech/abra/pkg/log"
|
||||
"coopcloud.tech/abra/pkg/recipe"
|
||||
"github.com/go-git/go-git/v5"
|
||||
@ -14,19 +15,19 @@ import (
|
||||
)
|
||||
|
||||
var RecipeFetchCommand = &cobra.Command{
|
||||
Use: "fetch [recipe | --all] [flags]",
|
||||
Aliases: []string{"f"},
|
||||
Short: "Clone recipe(s) locally",
|
||||
Long: `Using "--force/-f" Git syncs an existing recipe. It does not erase unstaged changes.`,
|
||||
Use: i18n.G("fetch [recipe | --all] [flags]"),
|
||||
Aliases: []string{i18n.G("f")},
|
||||
Short: i18n.G("Clone recipe(s) locally"),
|
||||
Long: i18n.G(`Using "--force/-f" Git syncs an existing recipe. It does not erase unstaged changes.`),
|
||||
Args: cobra.RangeArgs(0, 1),
|
||||
Example: ` # fetch from recipe catalogue
|
||||
Example: i18n.G(` # fetch from recipe catalogue
|
||||
abra recipe fetch gitea
|
||||
|
||||
# fetch from remote recipe
|
||||
abra recipe fetch git.foo.org/recipes/myrecipe
|
||||
|
||||
# fetch with ssh remote for hacking
|
||||
abra recipe fetch gitea --ssh`,
|
||||
abra recipe fetch gitea --ssh`),
|
||||
ValidArgsFunction: func(
|
||||
cmd *cobra.Command,
|
||||
args []string,
|
||||
@ -40,18 +41,18 @@ var RecipeFetchCommand = &cobra.Command{
|
||||
}
|
||||
|
||||
if recipeName == "" && !fetchAllRecipes {
|
||||
log.Fatal("missing [recipe] or --all/-a")
|
||||
log.Fatal(i18n.G("missing [recipe] or --all/-a"))
|
||||
}
|
||||
|
||||
if recipeName != "" && fetchAllRecipes {
|
||||
log.Fatal("cannot use [recipe] and --all/-a together")
|
||||
log.Fatal(i18n.G("cannot use [recipe] and --all/-a together"))
|
||||
}
|
||||
|
||||
if recipeName != "" {
|
||||
r := recipe.Get(recipeName)
|
||||
if _, err := os.Stat(r.Dir); !os.IsNotExist(err) {
|
||||
if !force {
|
||||
log.Warnf("%s is already fetched", r.Name)
|
||||
log.Warn(i18n.G("%s is already fetched", r.Name))
|
||||
return
|
||||
}
|
||||
}
|
||||
@ -60,24 +61,24 @@ var RecipeFetchCommand = &cobra.Command{
|
||||
|
||||
if sshRemote {
|
||||
if r.SSHURL == "" {
|
||||
log.Warnf("unable to discover SSH remote for %s", r.Name)
|
||||
log.Warn(i18n.G("unable to discover SSH remote for %s", r.Name))
|
||||
return
|
||||
}
|
||||
|
||||
repo, err := git.PlainOpen(r.Dir)
|
||||
if err != nil {
|
||||
log.Fatalf("unable to open %s: %s", r.Dir, err)
|
||||
log.Fatal(i18n.G("unable to open %s: %s", r.Dir, err))
|
||||
}
|
||||
|
||||
if err = repo.DeleteRemote("origin"); err != nil {
|
||||
log.Fatalf("unable to remove default remote in %s: %s", r.Dir, err)
|
||||
log.Fatal(i18n.G("unable to remove default remote in %s: %s", r.Dir, err))
|
||||
}
|
||||
|
||||
if _, err := repo.CreateRemote(&gitCfg.RemoteConfig{
|
||||
Name: "origin",
|
||||
URLs: []string{r.SSHURL},
|
||||
}); err != nil {
|
||||
log.Fatalf("unable to set SSH remote in %s: %s", r.Dir, err)
|
||||
log.Fatal(i18n.G("unable to set SSH remote in %s: %s", r.Dir, err))
|
||||
}
|
||||
}
|
||||
|
||||
@ -89,7 +90,7 @@ var RecipeFetchCommand = &cobra.Command{
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
catlBar := formatter.CreateProgressbar(len(catalogue), "fetching latest recipes...")
|
||||
catlBar := formatter.CreateProgressbar(len(catalogue), i18n.G("fetching latest recipes..."))
|
||||
ensureCtx := internal.GetEnsureContext()
|
||||
for recipeName := range catalogue {
|
||||
r := recipe.Get(recipeName)
|
||||
@ -110,25 +111,25 @@ var (
|
||||
func init() {
|
||||
RecipeFetchCommand.Flags().BoolVarP(
|
||||
&fetchAllRecipes,
|
||||
"all",
|
||||
"a",
|
||||
i18n.G("all"),
|
||||
i18n.G("a"),
|
||||
false,
|
||||
"fetch all recipes",
|
||||
i18n.G("fetch all recipes"),
|
||||
)
|
||||
|
||||
RecipeFetchCommand.Flags().BoolVarP(
|
||||
&sshRemote,
|
||||
"ssh",
|
||||
"s",
|
||||
i18n.G("ssh"),
|
||||
i18n.G("s"),
|
||||
false,
|
||||
"automatically set ssh remote",
|
||||
i18n.G("automatically set ssh remote"),
|
||||
)
|
||||
|
||||
RecipeFetchCommand.Flags().BoolVarP(
|
||||
&force,
|
||||
"force",
|
||||
"f",
|
||||
i18n.G("force"),
|
||||
i18n.G("f"),
|
||||
false,
|
||||
"force re-fetch",
|
||||
i18n.G("force re-fetch"),
|
||||
)
|
||||
}
|
||||
|
@ -4,15 +4,16 @@ import (
|
||||
"coopcloud.tech/abra/cli/internal"
|
||||
"coopcloud.tech/abra/pkg/autocomplete"
|
||||
"coopcloud.tech/abra/pkg/formatter"
|
||||
"coopcloud.tech/abra/pkg/i18n"
|
||||
"coopcloud.tech/abra/pkg/lint"
|
||||
"coopcloud.tech/abra/pkg/log"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var RecipeLintCommand = &cobra.Command{
|
||||
Use: "lint <recipe> [flags]",
|
||||
Short: "Lint a recipe",
|
||||
Aliases: []string{"l"},
|
||||
Use: i18n.G("lint <recipe> [flags]"),
|
||||
Short: i18n.G("Lint a recipe"),
|
||||
Aliases: []string{i18n.G("l")},
|
||||
Args: cobra.MinimumNArgs(1),
|
||||
ValidArgsFunction: func(
|
||||
cmd *cobra.Command,
|
||||
@ -28,12 +29,12 @@ var RecipeLintCommand = &cobra.Command{
|
||||
}
|
||||
|
||||
headers := []string{
|
||||
"ref",
|
||||
"rule",
|
||||
"severity",
|
||||
"satisfied",
|
||||
"skipped",
|
||||
"resolve",
|
||||
i18n.G("ref"),
|
||||
i18n.G("rule"),
|
||||
i18n.G("severity"),
|
||||
i18n.G("satisfied"),
|
||||
i18n.G("skipped"),
|
||||
i18n.G("resolve"),
|
||||
}
|
||||
|
||||
table, err := formatter.CreateTable()
|
||||
@ -49,7 +50,7 @@ var RecipeLintCommand = &cobra.Command{
|
||||
for level := range lint.LintRules {
|
||||
for _, rule := range lint.LintRules[level] {
|
||||
if onlyError && rule.Level != "error" {
|
||||
log.Debugf("skipping %s, does not have level \"error\"", rule.Ref)
|
||||
log.Debug(i18n.G("skipping %s, does not have level \"error\"", rule.Ref))
|
||||
continue
|
||||
}
|
||||
|
||||
@ -70,7 +71,7 @@ var RecipeLintCommand = &cobra.Command{
|
||||
warnMessages = append(warnMessages, err.Error())
|
||||
}
|
||||
|
||||
if !ok && rule.Level == "error" {
|
||||
if !ok && rule.Level == i18n.G("error") {
|
||||
hasError = true
|
||||
}
|
||||
|
||||
@ -111,7 +112,7 @@ var RecipeLintCommand = &cobra.Command{
|
||||
}
|
||||
|
||||
if hasError {
|
||||
log.Warnf("critical errors present in %s config", recipe.Name)
|
||||
log.Warn(i18n.G("critical errors present in %s config", recipe.Name))
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -124,17 +125,17 @@ var (
|
||||
func init() {
|
||||
RecipeLintCommand.Flags().BoolVarP(
|
||||
&internal.Chaos,
|
||||
"chaos",
|
||||
"C",
|
||||
i18n.G("chaos"),
|
||||
i18n.G("C"),
|
||||
false,
|
||||
"ignore uncommitted recipes changes",
|
||||
i18n.G("ignore uncommitted recipes changes"),
|
||||
)
|
||||
|
||||
RecipeLintCommand.Flags().BoolVarP(
|
||||
&onlyError,
|
||||
"error",
|
||||
"e",
|
||||
i18n.G("error"),
|
||||
i18n.G("e"),
|
||||
false,
|
||||
"only show errors",
|
||||
i18n.G("only show errors"),
|
||||
)
|
||||
}
|
||||
|
@ -8,15 +8,16 @@ import (
|
||||
|
||||
"coopcloud.tech/abra/cli/internal"
|
||||
"coopcloud.tech/abra/pkg/formatter"
|
||||
"coopcloud.tech/abra/pkg/i18n"
|
||||
"coopcloud.tech/abra/pkg/log"
|
||||
"coopcloud.tech/abra/pkg/recipe"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var RecipeListCommand = &cobra.Command{
|
||||
Use: "list",
|
||||
Short: "List recipes",
|
||||
Aliases: []string{"ls"},
|
||||
Use: i18n.G("list"),
|
||||
Short: i18n.G("List recipes"),
|
||||
Aliases: []string{i18n.G("ls")},
|
||||
Args: cobra.NoArgs,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
catl, err := recipe.ReadRecipeCatalogue(internal.Offline)
|
||||
@ -33,14 +34,14 @@ var RecipeListCommand = &cobra.Command{
|
||||
}
|
||||
|
||||
headers := []string{
|
||||
"name",
|
||||
"category",
|
||||
"status",
|
||||
"healthcheck",
|
||||
"backups",
|
||||
"email",
|
||||
"tests",
|
||||
"SSO",
|
||||
i18n.G("name"),
|
||||
i18n.G("category"),
|
||||
i18n.G("status"),
|
||||
i18n.G("healthcheck"),
|
||||
i18n.G("backups"),
|
||||
i18n.G("email"),
|
||||
i18n.G("tests"),
|
||||
i18n.G("SSO"),
|
||||
}
|
||||
|
||||
table.Headers(headers...)
|
||||
@ -73,7 +74,7 @@ var RecipeListCommand = &cobra.Command{
|
||||
if internal.MachineReadable {
|
||||
out, err := formatter.ToJSON(headers, rows)
|
||||
if err != nil {
|
||||
log.Fatal("unable to render to JSON: %s", err)
|
||||
log.Fatal(i18n.G("unable to render to JSON: %s", err))
|
||||
}
|
||||
fmt.Println(out)
|
||||
return
|
||||
@ -93,17 +94,17 @@ var (
|
||||
func init() {
|
||||
RecipeListCommand.Flags().BoolVarP(
|
||||
&internal.MachineReadable,
|
||||
"machine",
|
||||
"m",
|
||||
i18n.G("machine"),
|
||||
i18n.G("m"),
|
||||
false,
|
||||
"print machine-readable output",
|
||||
i18n.G("print machine-readable output"),
|
||||
)
|
||||
|
||||
RecipeListCommand.Flags().StringVarP(
|
||||
&pattern,
|
||||
"pattern",
|
||||
"p",
|
||||
i18n.G("pattern"),
|
||||
i18n.G("p"),
|
||||
"",
|
||||
"filter by recipe",
|
||||
i18n.G("filter by recipe"),
|
||||
)
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ import (
|
||||
"coopcloud.tech/abra/pkg/autocomplete"
|
||||
"coopcloud.tech/abra/pkg/config"
|
||||
"coopcloud.tech/abra/pkg/git"
|
||||
"coopcloud.tech/abra/pkg/i18n"
|
||||
"coopcloud.tech/abra/pkg/log"
|
||||
"coopcloud.tech/abra/pkg/recipe"
|
||||
"github.com/spf13/cobra"
|
||||
@ -30,10 +31,10 @@ type recipeMetadata struct {
|
||||
}
|
||||
|
||||
var RecipeNewCommand = &cobra.Command{
|
||||
Use: "new <recipe> [flags]",
|
||||
Aliases: []string{"n"},
|
||||
Short: "Create a new recipe",
|
||||
Long: `A community managed recipe template is used.`,
|
||||
Use: i18n.G("new <recipe> [flags]"),
|
||||
Aliases: []string{i18n.G("n")},
|
||||
Short: i18n.G("Create a new recipe"),
|
||||
Long: i18n.G(`A community managed recipe template is used.`),
|
||||
Args: cobra.ExactArgs(1),
|
||||
ValidArgsFunction: func(
|
||||
cmd *cobra.Command,
|
||||
@ -46,10 +47,10 @@ var RecipeNewCommand = &cobra.Command{
|
||||
|
||||
r := recipe.Get(recipeName)
|
||||
if _, err := os.Stat(r.Dir); !os.IsNotExist(err) {
|
||||
log.Fatalf("%s recipe directory already exists?", r.Dir)
|
||||
log.Fatal(i18n.G("%s recipe directory already exists?", r.Dir))
|
||||
}
|
||||
|
||||
url := fmt.Sprintf("%s/example.git", config.REPOS_BASE_URL)
|
||||
url := i18n.G("%s/example.git", config.REPOS_BASE_URL)
|
||||
if err := git.Clone(r.Dir, url); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
@ -58,7 +59,7 @@ var RecipeNewCommand = &cobra.Command{
|
||||
if err := os.RemoveAll(gitRepo); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
log.Debugf("removed .git repo in %s", gitRepo)
|
||||
log.Debug(i18n.G("removed .git repo in %s", gitRepo))
|
||||
|
||||
meta := newRecipeMeta(recipeName)
|
||||
|
||||
@ -82,8 +83,8 @@ var RecipeNewCommand = &cobra.Command{
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
log.Infof("new recipe '%s' created: %s", recipeName, path.Join(r.Dir))
|
||||
log.Info("happy hacking 🎉")
|
||||
log.Info(i18n.G("new recipe '%s' created: %s", recipeName, path.Join(r.Dir)))
|
||||
log.Info(i18n.G("happy hacking 🎉"))
|
||||
},
|
||||
}
|
||||
|
||||
@ -111,17 +112,17 @@ var (
|
||||
func init() {
|
||||
RecipeNewCommand.Flags().StringVarP(
|
||||
&gitName,
|
||||
"git-name",
|
||||
"N",
|
||||
i18n.G("git-name"),
|
||||
i18n.G("N"),
|
||||
"",
|
||||
"Git (user) name to do commits with",
|
||||
i18n.G("Git (user) name to do commits with"),
|
||||
)
|
||||
|
||||
RecipeNewCommand.Flags().StringVarP(
|
||||
&gitEmail,
|
||||
"git-email",
|
||||
"e",
|
||||
i18n.G("git-email"),
|
||||
i18n.G("e"),
|
||||
"",
|
||||
"Git email name to do commits with",
|
||||
i18n.G("Git email name to do commits with"),
|
||||
)
|
||||
}
|
||||
|
@ -1,13 +1,16 @@
|
||||
package recipe
|
||||
|
||||
import "github.com/spf13/cobra"
|
||||
import (
|
||||
"coopcloud.tech/abra/pkg/i18n"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
// RecipeCommand defines all recipe related sub-commands.
|
||||
var RecipeCommand = &cobra.Command{
|
||||
Use: "recipe [cmd] [args] [flags]",
|
||||
Aliases: []string{"r"},
|
||||
Short: "Manage recipes",
|
||||
Long: `A recipe is a blueprint for an app.
|
||||
Use: i18n.G("recipe [cmd] [args] [flags]"),
|
||||
Aliases: []string{i18n.G("r")},
|
||||
Short: i18n.G("Manage recipes"),
|
||||
Long: i18n.G(`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 Cloud community and you can use Abra to
|
||||
@ -15,5 +18,5 @@ read them, deploy them and create apps for you.
|
||||
|
||||
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
|
||||
manner.`,
|
||||
manner.`),
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ import (
|
||||
"coopcloud.tech/abra/pkg/autocomplete"
|
||||
"coopcloud.tech/abra/pkg/formatter"
|
||||
gitPkg "coopcloud.tech/abra/pkg/git"
|
||||
"coopcloud.tech/abra/pkg/i18n"
|
||||
"coopcloud.tech/abra/pkg/log"
|
||||
"coopcloud.tech/abra/pkg/recipe"
|
||||
"coopcloud.tech/tagcmp"
|
||||
@ -22,10 +23,10 @@ import (
|
||||
)
|
||||
|
||||
var RecipeReleaseCommand = &cobra.Command{
|
||||
Use: "release <recipe> [version] [flags]",
|
||||
Aliases: []string{"rl"},
|
||||
Short: "Release a new recipe version",
|
||||
Long: `Create a new version of a recipe.
|
||||
Use: i18n.G("release <recipe> [version] [flags]"),
|
||||
Aliases: []string{i18n.G("rl")},
|
||||
Short: i18n.G("Release a new recipe version"),
|
||||
Long: i18n.G(`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:
|
||||
@ -44,7 +45,7 @@ major and therefore require intervention while doing the upgrade work.
|
||||
|
||||
Publish your new release to git.coopcloud.tech with "--publish/-p". This
|
||||
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.`),
|
||||
Args: cobra.RangeArgs(1, 2),
|
||||
ValidArgsFunction: func(
|
||||
cmd *cobra.Command,
|
||||
@ -74,7 +75,7 @@ your SSH keys configured on your account.`,
|
||||
|
||||
mainAppVersion := imagesTmp[mainApp]
|
||||
if mainAppVersion == "" {
|
||||
log.Fatalf("main app service version for %s is empty?", recipe.Name)
|
||||
log.Fatal(i18n.G("main app service version for %s is empty?", recipe.Name))
|
||||
}
|
||||
|
||||
var tagString string
|
||||
@ -84,12 +85,12 @@ your SSH keys configured on your account.`,
|
||||
|
||||
if tagString != "" {
|
||||
if _, err := tagcmp.Parse(tagString); err != nil {
|
||||
log.Fatalf("cannot parse %s, invalid tag specified?", tagString)
|
||||
log.Fatal(i18n.G("cannot parse %s, invalid tag specified?", tagString))
|
||||
}
|
||||
}
|
||||
|
||||
if (internal.Major || internal.Minor || internal.Patch) && tagString != "" {
|
||||
log.Fatal("cannot specify tag and bump type at the same time")
|
||||
log.Fatal(i18n.G("cannot specify tag and bump type at the same time"))
|
||||
}
|
||||
|
||||
if tagString != "" {
|
||||
@ -117,19 +118,19 @@ your SSH keys configured on your account.`,
|
||||
}
|
||||
|
||||
if !isClean {
|
||||
log.Infof("%s currently has these unstaged changes 👇", recipe.Name)
|
||||
log.Info(i18n.G("%s currently has these unstaged changes 👇", recipe.Name))
|
||||
if err := gitPkg.DiffUnstaged(recipe.Dir); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
if len(tags) > 0 {
|
||||
log.Warnf("previous git tags detected, assuming this is a new semver release")
|
||||
log.Warn(i18n.G("previous git tags detected, assuming this is a new semver release"))
|
||||
if err := createReleaseFromPreviousTag(tagString, mainAppVersion, recipe, tags); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
} else {
|
||||
log.Warnf("no tag specified and no previous tag available for %s, assuming this is the initial release", recipe.Name)
|
||||
log.Warn(i18n.G("no tag specified and no previous tag available for %s, assuming this is the initial release", recipe.Name))
|
||||
|
||||
if err := createReleaseFromTag(recipe, tagString, mainAppVersion); err != nil {
|
||||
if cleanUpErr := cleanUpTag(recipe, tagString); err != nil {
|
||||
@ -181,7 +182,7 @@ func getImageVersions(recipe recipe.Recipe) (map[string]string, error) {
|
||||
}
|
||||
|
||||
if missingTag {
|
||||
return services, fmt.Errorf("app service is missing image tag?")
|
||||
return services, errors.New(i18n.G("app service is missing image tag?"))
|
||||
}
|
||||
|
||||
return services, nil
|
||||
@ -245,7 +246,7 @@ func btoi(b bool) int {
|
||||
|
||||
// getTagCreateOptions constructs git tag create options
|
||||
func getTagCreateOptions(tag string) (git.CreateTagOptions, error) {
|
||||
msg := fmt.Sprintf("chore: publish %s release", tag)
|
||||
msg := i18n.G("chore: publish %s release", tag)
|
||||
return git.CreateTagOptions{Message: msg}, nil
|
||||
}
|
||||
|
||||
@ -273,13 +274,13 @@ func addReleaseNotes(recipe recipe.Recipe, tag string) error {
|
||||
if _, err := os.Stat(nextReleaseNotePath); err == nil {
|
||||
// release/next note exists. Move it to release/<tag>
|
||||
if internal.Dry {
|
||||
log.Debugf("dry run: move release note from 'next' to %s", tag)
|
||||
log.Debug(i18n.G("dry run: move release note from 'next' to %s", tag))
|
||||
return nil
|
||||
}
|
||||
|
||||
if !internal.NoInput {
|
||||
prompt := &survey.Confirm{
|
||||
Message: "Use release note in release/next?",
|
||||
Message: i18n.G("Use release note in release/next?"),
|
||||
}
|
||||
|
||||
if err := survey.AskOne(prompt, &addNextAsReleaseNotes); err != nil {
|
||||
@ -313,7 +314,7 @@ func addReleaseNotes(recipe recipe.Recipe, tag string) error {
|
||||
}
|
||||
|
||||
prompt := &survey.Input{
|
||||
Message: "Release Note (leave empty for no release note)",
|
||||
Message: i18n.G("Release Note (leave empty for no release note)"),
|
||||
}
|
||||
|
||||
var releaseNote string
|
||||
@ -338,7 +339,7 @@ func addReleaseNotes(recipe recipe.Recipe, tag string) error {
|
||||
|
||||
func commitRelease(recipe recipe.Recipe, tag string) error {
|
||||
if internal.Dry {
|
||||
log.Debugf("dry run: no changes committed")
|
||||
log.Debug(i18n.G("dry run: no changes committed"))
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -349,7 +350,7 @@ func commitRelease(recipe recipe.Recipe, tag string) error {
|
||||
|
||||
if isClean {
|
||||
if !internal.Dry {
|
||||
return fmt.Errorf("no changes discovered in %s, nothing to publish?", recipe.Dir)
|
||||
return errors.New(i18n.G("no changes discovered in %s, nothing to publish?", recipe.Dir))
|
||||
}
|
||||
}
|
||||
|
||||
@ -363,7 +364,7 @@ func commitRelease(recipe recipe.Recipe, tag string) error {
|
||||
|
||||
func tagRelease(tagString string, repo *git.Repository) error {
|
||||
if internal.Dry {
|
||||
log.Debugf("dry run: no git tag created (%s)", tagString)
|
||||
log.Debug(i18n.G("dry run: no git tag created (%s)", tagString))
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -383,20 +384,20 @@ func tagRelease(tagString string, repo *git.Repository) error {
|
||||
}
|
||||
|
||||
hash := formatter.SmallSHA(head.Hash().String())
|
||||
log.Debugf(fmt.Sprintf("created tag %s at %s", tagString, hash))
|
||||
log.Debug(i18n.G("created tag %s at %s", tagString, hash))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func pushRelease(recipe recipe.Recipe, tagString string) error {
|
||||
if internal.Dry {
|
||||
log.Info("dry run: no changes published")
|
||||
log.Info(i18n.G("dry run: no changes published"))
|
||||
return nil
|
||||
}
|
||||
|
||||
if !publish && !internal.NoInput {
|
||||
prompt := &survey.Confirm{
|
||||
Message: "publish new release?",
|
||||
Message: i18n.G("publish new release?"),
|
||||
}
|
||||
|
||||
if err := survey.AskOne(prompt, &publish); err != nil {
|
||||
@ -409,9 +410,9 @@ func pushRelease(recipe recipe.Recipe, tagString string) error {
|
||||
return err
|
||||
}
|
||||
url := fmt.Sprintf("%s/src/tag/%s", recipe.GitURL, tagString)
|
||||
log.Infof("new release published: %s", url)
|
||||
log.Info(i18n.G("new release published: %s", url))
|
||||
} else {
|
||||
log.Info("no -p/--publish passed, not publishing")
|
||||
log.Info(i18n.G("no -p/--publish passed, not publishing"))
|
||||
}
|
||||
|
||||
return nil
|
||||
@ -426,7 +427,7 @@ func createReleaseFromPreviousTag(tagString, mainAppVersion string, recipe recip
|
||||
bumpType := btoi(internal.Major)*4 + btoi(internal.Minor)*2 + btoi(internal.Patch)
|
||||
if bumpType != 0 {
|
||||
if (bumpType & (bumpType - 1)) != 0 {
|
||||
return fmt.Errorf("you can only use one of: --major, --minor, --patch")
|
||||
return errors.New(i18n.G("you can only use one of: --major, --minor, --patch"))
|
||||
}
|
||||
}
|
||||
|
||||
@ -483,12 +484,12 @@ func createReleaseFromPreviousTag(tagString, mainAppVersion string, recipe recip
|
||||
}
|
||||
|
||||
if lastGitTag.String() == tagString {
|
||||
log.Fatalf("latest git tag (%s) and synced label (%s) are the same?", lastGitTag, tagString)
|
||||
log.Fatal(i18n.G("latest git tag (%s) and synced label (%s) are the same?", lastGitTag, tagString))
|
||||
}
|
||||
|
||||
if !internal.NoInput {
|
||||
prompt := &survey.Confirm{
|
||||
Message: fmt.Sprintf("current: %s, new: %s, correct?", lastGitTag, tagString),
|
||||
Message: i18n.G("current: %s, new: %s, correct?", lastGitTag, tagString),
|
||||
}
|
||||
|
||||
var ok bool
|
||||
@ -497,7 +498,7 @@ func createReleaseFromPreviousTag(tagString, mainAppVersion string, recipe recip
|
||||
}
|
||||
|
||||
if !ok {
|
||||
log.Fatal("exiting as requested")
|
||||
log.Fatal(i18n.G("exiting as requested"))
|
||||
}
|
||||
}
|
||||
|
||||
@ -506,15 +507,15 @@ func createReleaseFromPreviousTag(tagString, mainAppVersion string, recipe recip
|
||||
}
|
||||
|
||||
if err := commitRelease(recipe, tagString); err != nil {
|
||||
log.Fatalf("failed to commit changes: %s", err.Error())
|
||||
log.Fatal(i18n.G("failed to commit changes: %s", err.Error()))
|
||||
}
|
||||
|
||||
if err := tagRelease(tagString, repo); err != nil {
|
||||
log.Fatalf("failed to tag release: %s", err.Error())
|
||||
log.Fatal(i18n.G("failed to tag release: %s", err.Error()))
|
||||
}
|
||||
|
||||
if err := pushRelease(recipe, tagString); err != nil {
|
||||
log.Fatalf("failed to publish new release: %s", err.Error())
|
||||
log.Fatal(i18n.G("failed to publish new release: %s", err.Error()))
|
||||
}
|
||||
|
||||
return nil
|
||||
@ -533,7 +534,7 @@ func cleanUpTag(recipe recipe.Recipe, tag string) error {
|
||||
}
|
||||
}
|
||||
|
||||
log.Debugf("removed freshly created tag %s", tag)
|
||||
log.Debug(i18n.G("removed freshly created tag %s", tag))
|
||||
|
||||
return nil
|
||||
}
|
||||
@ -545,20 +546,20 @@ func getLabelVersion(recipe recipe.Recipe, prompt bool) (string, error) {
|
||||
}
|
||||
|
||||
if initTag == "" {
|
||||
log.Fatalf("unable to read version for %s from synced label. Did you try running \"abra recipe sync %s\" already?", recipe.Name, recipe.Name)
|
||||
log.Fatal(i18n.G("unable to read version for %s from synced label. Did you try running \"abra recipe sync %s\" already?", recipe.Name, recipe.Name))
|
||||
}
|
||||
|
||||
log.Warnf("discovered %s as currently synced recipe label", initTag)
|
||||
log.Warn(i18n.G("discovered %s as currently synced recipe label", initTag))
|
||||
|
||||
if prompt && !internal.NoInput {
|
||||
var response bool
|
||||
prompt := &survey.Confirm{Message: fmt.Sprintf("use %s as the new version?", initTag)}
|
||||
prompt := &survey.Confirm{Message: i18n.G("use %s as the new version?", initTag)}
|
||||
if err := survey.AskOne(prompt, &response); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if !response {
|
||||
return "", fmt.Errorf("please fix your synced label for %s and re-run this command", recipe.Name)
|
||||
return "", errors.New(i18n.G("please fix your synced label for %s and re-run this command", recipe.Name))
|
||||
}
|
||||
}
|
||||
|
||||
@ -572,42 +573,41 @@ var (
|
||||
func init() {
|
||||
RecipeReleaseCommand.Flags().BoolVarP(
|
||||
&internal.Dry,
|
||||
"dry-run",
|
||||
"r",
|
||||
i18n.G("dry-run"),
|
||||
i18n.G("r"),
|
||||
false,
|
||||
"report changes that would be made",
|
||||
i18n.G("report changes that would be made"),
|
||||
)
|
||||
|
||||
RecipeReleaseCommand.Flags().BoolVarP(
|
||||
&internal.Major,
|
||||
"major",
|
||||
"x",
|
||||
i18n.G("major"),
|
||||
i18n.G("x"),
|
||||
false,
|
||||
"increase the major part of the version",
|
||||
i18n.G("increase the major part of the version"),
|
||||
)
|
||||
|
||||
RecipeReleaseCommand.Flags().BoolVarP(
|
||||
&internal.Minor,
|
||||
"minor",
|
||||
"y",
|
||||
i18n.G("minor"),
|
||||
i18n.G("y"),
|
||||
false,
|
||||
"increase the minor part of the version",
|
||||
i18n.G("increase the minor part of the version"),
|
||||
)
|
||||
|
||||
RecipeReleaseCommand.Flags().BoolVarP(
|
||||
&internal.Patch,
|
||||
"patch",
|
||||
"z",
|
||||
i18n.G("patch"),
|
||||
i18n.G("z"),
|
||||
false,
|
||||
"increase the patch part of the version",
|
||||
i18n.G("increase the patch part of the version"),
|
||||
)
|
||||
|
||||
RecipeReleaseCommand.Flags().BoolVarP(
|
||||
&publish,
|
||||
"publish",
|
||||
"p",
|
||||
i18n.G("publish"),
|
||||
i18n.G("p"),
|
||||
false,
|
||||
"publish changes to git.coopcloud.tech",
|
||||
i18n.G("publish changes to git.coopcloud.tech"),
|
||||
)
|
||||
|
||||
}
|
||||
|
@ -3,16 +3,17 @@ package recipe
|
||||
import (
|
||||
"coopcloud.tech/abra/cli/internal"
|
||||
"coopcloud.tech/abra/pkg/autocomplete"
|
||||
"coopcloud.tech/abra/pkg/i18n"
|
||||
"coopcloud.tech/abra/pkg/log"
|
||||
"github.com/go-git/go-git/v5"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var RecipeResetCommand = &cobra.Command{
|
||||
Use: "reset <recipe> [flags]",
|
||||
Aliases: []string{"rs"},
|
||||
Short: "Remove all unstaged changes from recipe config",
|
||||
Long: "WARNING: this will delete your changes. Be Careful.",
|
||||
Use: i18n.G("reset <recipe> [flags]"),
|
||||
Aliases: []string{i18n.G("rs")},
|
||||
Short: i18n.G("Remove all unstaged changes from recipe config"),
|
||||
Long: i18n.G("WARNING: this will delete your changes. Be Careful."),
|
||||
Args: cobra.ExactArgs(1),
|
||||
ValidArgsFunction: func(
|
||||
cmd *cobra.Command,
|
||||
|
@ -7,6 +7,7 @@ import (
|
||||
"coopcloud.tech/abra/cli/internal"
|
||||
"coopcloud.tech/abra/pkg/autocomplete"
|
||||
gitPkg "coopcloud.tech/abra/pkg/git"
|
||||
"coopcloud.tech/abra/pkg/i18n"
|
||||
"coopcloud.tech/abra/pkg/log"
|
||||
"coopcloud.tech/tagcmp"
|
||||
"github.com/AlecAivazis/survey/v2"
|
||||
@ -16,10 +17,10 @@ import (
|
||||
)
|
||||
|
||||
var RecipeSyncCommand = &cobra.Command{
|
||||
Use: "sync <recipe> [version] [flags]",
|
||||
Aliases: []string{"s"},
|
||||
Short: "Sync recipe version label",
|
||||
Long: `Generate labels for the main recipe service.
|
||||
Use: i18n.G("sync <recipe> [version] [flags]"),
|
||||
Aliases: []string{i18n.G("s")},
|
||||
Short: i18n.G("Sync recipe version label"),
|
||||
Long: i18n.G(`Generate labels for the main recipe service.
|
||||
|
||||
By convention, the service named "app" using the following format:
|
||||
|
||||
@ -27,7 +28,7 @@ By convention, the service named "app" using the following format:
|
||||
|
||||
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
|
||||
local file system.`,
|
||||
local file system.`),
|
||||
Args: cobra.RangeArgs(1, 2),
|
||||
ValidArgsFunction: func(
|
||||
cmd *cobra.Command,
|
||||
@ -68,11 +69,11 @@ local file system.`,
|
||||
}
|
||||
|
||||
if len(tags) == 0 && nextTag == "" {
|
||||
log.Warnf("no git tags found for %s", recipe.Name)
|
||||
log.Warn(i18n.G("no git tags found for %s", recipe.Name))
|
||||
if internal.NoInput {
|
||||
log.Fatalf("unable to continue, input required for initial version")
|
||||
log.Fatal(i18n.G("unable to continue, input required for initial version"))
|
||||
}
|
||||
fmt.Println(fmt.Sprintf(`
|
||||
fmt.Println(i18n.G(`
|
||||
The following options are two types of initial semantic version that you can
|
||||
pick for %s that will be published in the recipe catalogue. This follows the
|
||||
semver convention (more on https://semver.org), here is a short cheatsheet
|
||||
@ -92,7 +93,7 @@ likely to change.
|
||||
`, recipe.Name, recipe.Name))
|
||||
var chosenVersion string
|
||||
edPrompt := &survey.Select{
|
||||
Message: "which version do you want to begin with?",
|
||||
Message: i18n.G("which version do you want to begin with?"),
|
||||
Options: []string{"0.1.0", "1.0.0"},
|
||||
}
|
||||
|
||||
@ -125,7 +126,7 @@ likely to change.
|
||||
if err := iter.ForEach(func(ref *plumbing.Reference) error {
|
||||
obj, err := repo.TagObject(ref.Hash())
|
||||
if err != nil {
|
||||
log.Fatal("Tag at commit ", ref.Hash(), " is unannotated or otherwise broken. Please fix it.")
|
||||
log.Fatal(i18n.G("tag at commit %s is unannotated or otherwise broken", ref.Hash()))
|
||||
return err
|
||||
}
|
||||
|
||||
@ -150,7 +151,7 @@ likely to change.
|
||||
if bumpType != 0 {
|
||||
// a bitwise check if the number is a power of 2
|
||||
if (bumpType & (bumpType - 1)) != 0 {
|
||||
log.Fatal("you can only use one version flag: --major, --minor or --patch")
|
||||
log.Fatal(i18n.G("you can only use one version flag: --major, --minor or --patch"))
|
||||
}
|
||||
}
|
||||
|
||||
@ -184,22 +185,22 @@ likely to change.
|
||||
}
|
||||
|
||||
newTag.Metadata = mainAppVersion
|
||||
log.Debugf("choosing %s as new version for %s", newTag.String(), recipe.Name)
|
||||
log.Debug(i18n.G("choosing %s as new version for %s", newTag.String(), recipe.Name))
|
||||
nextTag = newTag.String()
|
||||
}
|
||||
|
||||
if _, err := tagcmp.Parse(nextTag); err != nil {
|
||||
log.Fatalf("invalid version %s specified", nextTag)
|
||||
log.Fatal(i18n.G("invalid version %s specified", nextTag))
|
||||
}
|
||||
|
||||
mainService := "app"
|
||||
label := fmt.Sprintf("coop-cloud.${STACK_NAME}.version=%s", nextTag)
|
||||
label := i18n.G("coop-cloud.${STACK_NAME}.version=%s", nextTag)
|
||||
if !internal.Dry {
|
||||
if err := recipe.UpdateLabel("compose.y*ml", mainService, label); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
} else {
|
||||
log.Infof("dry run: not syncing label %s for recipe %s", nextTag, recipe.Name)
|
||||
log.Info(i18n.G("dry run: not syncing label %s for recipe %s", nextTag, recipe.Name))
|
||||
}
|
||||
|
||||
isClean, err := gitPkg.IsClean(recipe.Dir)
|
||||
@ -207,7 +208,7 @@ likely to change.
|
||||
log.Fatal(err)
|
||||
}
|
||||
if !isClean {
|
||||
log.Infof("%s currently has these unstaged changes 👇", recipe.Name)
|
||||
log.Info(i18n.G("%s currently has these unstaged changes 👇", recipe.Name))
|
||||
if err := gitPkg.DiffUnstaged(recipe.Dir); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
@ -218,33 +219,33 @@ likely to change.
|
||||
func init() {
|
||||
RecipeSyncCommand.Flags().BoolVarP(
|
||||
&internal.Dry,
|
||||
"dry-run",
|
||||
"r",
|
||||
i18n.G("dry-run"),
|
||||
i18n.G("r"),
|
||||
false,
|
||||
"report changes that would be made",
|
||||
i18n.G("report changes that would be made"),
|
||||
)
|
||||
|
||||
RecipeSyncCommand.Flags().BoolVarP(
|
||||
&internal.Major,
|
||||
"major",
|
||||
"x",
|
||||
i18n.G("major"),
|
||||
i18n.G("x"),
|
||||
false,
|
||||
"increase the major part of the version",
|
||||
i18n.G("increase the major part of the version"),
|
||||
)
|
||||
|
||||
RecipeSyncCommand.Flags().BoolVarP(
|
||||
&internal.Minor,
|
||||
"minor",
|
||||
"y",
|
||||
i18n.G("minor"),
|
||||
i18n.G("y"),
|
||||
false,
|
||||
"increase the minor part of the version",
|
||||
i18n.G("increase the minor part of the version"),
|
||||
)
|
||||
|
||||
RecipeSyncCommand.Flags().BoolVarP(
|
||||
&internal.Patch,
|
||||
"patch",
|
||||
"z",
|
||||
i18n.G("patch"),
|
||||
i18n.G("z"),
|
||||
false,
|
||||
"increase the patch part of the version",
|
||||
i18n.G("increase the patch part of the version"),
|
||||
)
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ import (
|
||||
"coopcloud.tech/abra/pkg/client"
|
||||
"coopcloud.tech/abra/pkg/formatter"
|
||||
gitPkg "coopcloud.tech/abra/pkg/git"
|
||||
"coopcloud.tech/abra/pkg/i18n"
|
||||
"coopcloud.tech/abra/pkg/log"
|
||||
recipePkg "coopcloud.tech/abra/pkg/recipe"
|
||||
"coopcloud.tech/tagcmp"
|
||||
@ -37,10 +38,10 @@ type anUpgrade struct {
|
||||
}
|
||||
|
||||
var RecipeUpgradeCommand = &cobra.Command{
|
||||
Use: "upgrade <recipe> [flags]",
|
||||
Aliases: []string{"u"},
|
||||
Short: "Upgrade recipe image tags",
|
||||
Long: `Upgrade a given <recipe> configuration.
|
||||
Use: i18n.G("upgrade <recipe> [flags]"),
|
||||
Aliases: []string{i18n.G("u")},
|
||||
Short: i18n.G("Upgrade recipe image tags"),
|
||||
Long: i18n.G(`Upgrade a given <recipe> configuration.
|
||||
|
||||
It will update the relevant compose file tags on the local file system.
|
||||
|
||||
@ -52,7 +53,7 @@ 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
|
||||
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.`),
|
||||
Args: cobra.RangeArgs(0, 1),
|
||||
ValidArgsFunction: func(
|
||||
cmd *cobra.Command,
|
||||
@ -71,7 +72,7 @@ You may invoke this command in "wizard" mode and be prompted for input.`,
|
||||
if bumpType != 0 {
|
||||
// a bitwise check if the number is a power of 2
|
||||
if (bumpType & (bumpType - 1)) != 0 {
|
||||
log.Fatal("you can only use one of: --major, --minor, --patch.")
|
||||
log.Fatal(i18n.G("you can only use one of: --major, --minor, --patch."))
|
||||
}
|
||||
}
|
||||
|
||||
@ -87,7 +88,7 @@ You may invoke this command in "wizard" mode and be prompted for input.`,
|
||||
versionsPath := path.Join(recipe.Dir, "versions")
|
||||
servicePins := make(map[string]imgPin)
|
||||
if _, err := os.Stat(versionsPath); err == nil {
|
||||
log.Debugf("found versions file for %s", recipe.Name)
|
||||
log.Debug(i18n.G("found versions file for %s", recipe.Name))
|
||||
file, err := os.Open(versionsPath)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
@ -97,7 +98,7 @@ You may invoke this command in "wizard" mode and be prompted for input.`,
|
||||
line := scanner.Text()
|
||||
splitLine := strings.Split(line, " ")
|
||||
if splitLine[0] != "pin" || len(splitLine) != 3 {
|
||||
log.Fatalf("malformed version pin specification: %s", line)
|
||||
log.Fatal(i18n.G("malformed version pin specification: %s", line))
|
||||
}
|
||||
pinSlice := strings.Split(splitLine[2], ":")
|
||||
pinTag, err := tagcmp.Parse(pinSlice[1])
|
||||
@ -115,7 +116,7 @@ You may invoke this command in "wizard" mode and be prompted for input.`,
|
||||
}
|
||||
versionsPresent = true
|
||||
} else {
|
||||
log.Debugf("did not find versions file for %s", recipe.Name)
|
||||
log.Debug(i18n.G("did not find versions file for %s", recipe.Name))
|
||||
}
|
||||
|
||||
config, err := recipe.GetComposeConfig(nil)
|
||||
@ -135,26 +136,26 @@ You may invoke this command in "wizard" mode and be prompted for input.`,
|
||||
}
|
||||
|
||||
image := reference.Path(img)
|
||||
log.Debugf("retrieved %s from remote registry for %s", regVersions, image)
|
||||
log.Debug(i18n.G("retrieved %s from remote registry for %s", regVersions, image))
|
||||
image = formatter.StripTagMeta(image)
|
||||
|
||||
switch img.(type) {
|
||||
case reference.NamedTagged:
|
||||
if !tagcmp.IsParsable(img.(reference.NamedTagged).Tag()) {
|
||||
log.Debugf("%s not considered semver-like", img.(reference.NamedTagged).Tag())
|
||||
log.Debug(i18n.G("%s not considered semver-like", img.(reference.NamedTagged).Tag()))
|
||||
}
|
||||
default:
|
||||
log.Warnf("unable to read tag for image %s, is it missing? skipping upgrade for %s", image, service.Name)
|
||||
log.Warn(i18n.G("unable to read tag for image %s, is it missing? skipping upgrade for %s", image, service.Name))
|
||||
continue
|
||||
}
|
||||
|
||||
tag, err := tagcmp.Parse(img.(reference.NamedTagged).Tag())
|
||||
if err != nil {
|
||||
log.Warnf("unable to parse %s, error was: %s, skipping upgrade for %s", image, err.Error(), service.Name)
|
||||
log.Warn(i18n.G("unable to parse %s, error was: %s, skipping upgrade for %s", image, err.Error(), service.Name))
|
||||
continue
|
||||
}
|
||||
|
||||
log.Debugf("parsed %s for %s", tag, service.Name)
|
||||
log.Debug(i18n.G("parsed %s for %s", tag, service.Name))
|
||||
|
||||
var compatible []tagcmp.Tag
|
||||
for _, regVersion := range regVersions {
|
||||
@ -168,12 +169,12 @@ You may invoke this command in "wizard" mode and be prompted for input.`,
|
||||
}
|
||||
}
|
||||
|
||||
log.Debugf("detected potential upgradable tags %s for %s", compatible, service.Name)
|
||||
log.Debug(i18n.G("detected potential upgradable tags %s for %s", compatible, service.Name))
|
||||
|
||||
sort.Sort(tagcmp.ByTagDesc(compatible))
|
||||
|
||||
if len(compatible) == 0 && !allTags {
|
||||
log.Info(fmt.Sprintf("no new versions available for %s, assuming %s is the latest (use -a/--all-tags to see all anyway)", image, tag))
|
||||
log.Info(i18n.G("no new versions available for %s, assuming %s is the latest (use -a/--all-tags to see all anyway)", image, tag))
|
||||
continue // skip on to the next tag and don't update any compose files
|
||||
}
|
||||
|
||||
@ -195,7 +196,7 @@ You may invoke this command in "wizard" mode and be prompted for input.`,
|
||||
}
|
||||
}
|
||||
|
||||
log.Debugf("detected compatible upgradable tags %s for %s", compatibleStrings, service.Name)
|
||||
log.Debug(i18n.G("detected compatible upgradable tags %s for %s", compatibleStrings, service.Name))
|
||||
|
||||
var upgradeTag string
|
||||
_, ok := servicePins[service.Name]
|
||||
@ -212,13 +213,13 @@ You may invoke this command in "wizard" mode and be prompted for input.`,
|
||||
}
|
||||
}
|
||||
if contains {
|
||||
log.Infof("upgrading service %s from %s to %s (pinned tag: %s)", service.Name, tag.String(), upgradeTag, pinnedTagString)
|
||||
log.Info(i18n.G("upgrading service %s from %s to %s (pinned tag: %s)", service.Name, tag.String(), upgradeTag, pinnedTagString))
|
||||
} else {
|
||||
log.Infof("service %s, image %s pinned to %s, no compatible upgrade found", service.Name, servicePins[service.Name].image, pinnedTagString)
|
||||
log.Info(i18n.G("service %s, image %s pinned to %s, no compatible upgrade found", service.Name, servicePins[service.Name].image, pinnedTagString))
|
||||
continue
|
||||
}
|
||||
} else {
|
||||
log.Fatalf("service %s is at version %s, but pinned to %s, please correct your compose.yml file manually!", service.Name, tag.String(), pinnedTag.String())
|
||||
log.Fatal(i18n.G("service %s is at version %s, but pinned to %s, please correct your compose.yml file manually!", service.Name, tag.String(), pinnedTag.String()))
|
||||
continue
|
||||
}
|
||||
} else {
|
||||
@ -235,17 +236,17 @@ You may invoke this command in "wizard" mode and be prompted for input.`,
|
||||
}
|
||||
}
|
||||
if upgradeTag == "" {
|
||||
log.Warnf("not upgrading from %s to %s for %s, because the upgrade type is more serious than what user wants", tag.String(), compatible[0].String(), image)
|
||||
log.Warn(i18n.G("not upgrading from %s to %s for %s, because the upgrade type is more serious than what user wants", tag.String(), compatible[0].String(), image))
|
||||
continue
|
||||
}
|
||||
} else {
|
||||
msg := fmt.Sprintf("upgrade to which tag? (service: %s, image: %s, tag: %s)", service.Name, image, tag)
|
||||
msg := i18n.G("upgrade to which tag? (service: %s, image: %s, tag: %s)", service.Name, image, tag)
|
||||
if !tagcmp.IsParsable(img.(reference.NamedTagged).Tag()) || allTags {
|
||||
tag := img.(reference.NamedTagged).Tag()
|
||||
if !allTags {
|
||||
log.Warn(fmt.Sprintf("unable to determine versioning semantics of %s, listing all tags", tag))
|
||||
log.Warn(i18n.G("unable to determine versioning semantics of %s, listing all tags", tag))
|
||||
}
|
||||
msg = fmt.Sprintf("upgrade to which tag? (service: %s, tag: %s)", service.Name, tag)
|
||||
msg = i18n.G("upgrade to which tag? (service: %s, tag: %s)", service.Name, tag)
|
||||
compatibleStrings = []string{"skip"}
|
||||
for _, regVersion := range regVersions {
|
||||
compatibleStrings = append(compatibleStrings, regVersion)
|
||||
@ -276,7 +277,7 @@ You may invoke this command in "wizard" mode and be prompted for input.`,
|
||||
} else {
|
||||
prompt := &survey.Select{
|
||||
Message: msg,
|
||||
Help: "enter / return to confirm, choose 'skip' to not upgrade this tag, vim mode is enabled",
|
||||
Help: i18n.G("enter / return to confirm, choose 'skip' to not upgrade this tag, vim mode is enabled"),
|
||||
VimMode: true,
|
||||
Options: compatibleStrings,
|
||||
}
|
||||
@ -292,11 +293,11 @@ You may invoke this command in "wizard" mode and be prompted for input.`,
|
||||
log.Fatal(err)
|
||||
}
|
||||
if ok {
|
||||
log.Infof("tag upgraded from %s to %s for %s", tag.String(), upgradeTag, image)
|
||||
log.Info(i18n.G("tag upgraded from %s to %s for %s", tag.String(), upgradeTag, image))
|
||||
}
|
||||
} else {
|
||||
if !internal.NoInput {
|
||||
log.Warnf("not upgrading %s, skipping as requested", image)
|
||||
log.Warn(i18n.G("not upgrading %s, skipping as requested", image))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -314,7 +315,7 @@ You may invoke this command in "wizard" mode and be prompted for input.`,
|
||||
}
|
||||
|
||||
for _, upgrade := range upgradeList {
|
||||
log.Infof("can upgrade service: %s, image: %s, tag: %s ::", upgrade.Service, upgrade.Image, upgrade.Tag)
|
||||
log.Info(i18n.G("can upgrade service: %s, image: %s, tag: %s ::", upgrade.Service, upgrade.Image, upgrade.Tag))
|
||||
for _, utag := range upgrade.UpgradeTags {
|
||||
log.Infof(" %s", utag)
|
||||
}
|
||||
@ -326,7 +327,7 @@ You may invoke this command in "wizard" mode and be prompted for input.`,
|
||||
log.Fatal(err)
|
||||
}
|
||||
if !isClean {
|
||||
log.Infof("%s currently has these unstaged changes 👇", recipe.Name)
|
||||
log.Info(i18n.G("%s currently has these unstaged changes 👇", recipe.Name))
|
||||
if err := gitPkg.DiffUnstaged(recipe.Dir); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
@ -341,41 +342,41 @@ var (
|
||||
func init() {
|
||||
RecipeUpgradeCommand.Flags().BoolVarP(
|
||||
&internal.Major,
|
||||
"major",
|
||||
"x",
|
||||
i18n.G("major"),
|
||||
i18n.G("x"),
|
||||
false,
|
||||
"increase the major part of the version",
|
||||
i18n.G("increase the major part of the version"),
|
||||
)
|
||||
|
||||
RecipeUpgradeCommand.Flags().BoolVarP(
|
||||
&internal.Minor,
|
||||
"minor",
|
||||
"y",
|
||||
i18n.G("minor"),
|
||||
i18n.G("y"),
|
||||
false,
|
||||
"increase the minor part of the version",
|
||||
i18n.G("increase the minor part of the version"),
|
||||
)
|
||||
|
||||
RecipeUpgradeCommand.Flags().BoolVarP(
|
||||
&internal.Patch,
|
||||
"patch",
|
||||
"z",
|
||||
i18n.G("patch"),
|
||||
i18n.G("z"),
|
||||
false,
|
||||
"increase the patch part of the version",
|
||||
i18n.G("increase the patch part of the version"),
|
||||
)
|
||||
|
||||
RecipeUpgradeCommand.Flags().BoolVarP(
|
||||
&internal.MachineReadable,
|
||||
"machine",
|
||||
"m",
|
||||
i18n.G("machine"),
|
||||
i18n.G("m"),
|
||||
false,
|
||||
"print machine-readable output",
|
||||
i18n.G("print machine-readable output"),
|
||||
)
|
||||
|
||||
RecipeUpgradeCommand.Flags().BoolVarP(
|
||||
&allTags,
|
||||
"all-tags",
|
||||
"a",
|
||||
i18n.G("all-tags"),
|
||||
i18n.G("a"),
|
||||
false,
|
||||
"list all tags, not just upgrades",
|
||||
i18n.G("list all tags, not just upgrades"),
|
||||
)
|
||||
}
|
||||
|
@ -7,15 +7,16 @@ import (
|
||||
"coopcloud.tech/abra/cli/internal"
|
||||
"coopcloud.tech/abra/pkg/autocomplete"
|
||||
"coopcloud.tech/abra/pkg/formatter"
|
||||
"coopcloud.tech/abra/pkg/i18n"
|
||||
"coopcloud.tech/abra/pkg/log"
|
||||
recipePkg "coopcloud.tech/abra/pkg/recipe"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var RecipeVersionCommand = &cobra.Command{
|
||||
Use: "versions <recipe> [flags]",
|
||||
Aliases: []string{"v"},
|
||||
Short: "List recipe versions",
|
||||
Use: i18n.G("versions <recipe> [flags]"),
|
||||
Aliases: []string{i18n.G("v")},
|
||||
Short: i18n.G("List recipe versions"),
|
||||
Args: cobra.ExactArgs(1),
|
||||
ValidArgsFunction: func(
|
||||
cmd *cobra.Command,
|
||||
@ -35,7 +36,7 @@ var RecipeVersionCommand = &cobra.Command{
|
||||
|
||||
recipeMeta, ok := catl[recipe.Name]
|
||||
if !ok {
|
||||
warnMessages = append(warnMessages, "retrieved versions from local recipe repository")
|
||||
warnMessages = append(warnMessages, i18n.G("retrieved versions from local recipe repository"))
|
||||
|
||||
recipeVersions, warnMsg, err := recipe.GetRecipeVersions()
|
||||
if err != nil {
|
||||
@ -49,7 +50,7 @@ var RecipeVersionCommand = &cobra.Command{
|
||||
}
|
||||
|
||||
if len(recipeMeta.Versions) == 0 {
|
||||
log.Fatalf("%s has no published versions?", recipe.Name)
|
||||
log.Fatal(i18n.G("%s has no published versions?", recipe.Name))
|
||||
}
|
||||
|
||||
for i := len(recipeMeta.Versions) - 1; i >= 0; i-- {
|
||||
@ -58,7 +59,7 @@ var RecipeVersionCommand = &cobra.Command{
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
table.Headers("SERVICE", "IMAGE", "TAG", "VERSION")
|
||||
table.Headers(i18n.G("SERVICE"), i18n.G("IMAGE"), i18n.G("TAG"), i18n.G("VERSION"))
|
||||
|
||||
for version, meta := range recipeMeta.Versions[i] {
|
||||
var allRows [][]string
|
||||
@ -99,10 +100,10 @@ var RecipeVersionCommand = &cobra.Command{
|
||||
|
||||
if internal.MachineReadable {
|
||||
sort.Slice(allRows, sortServiceByName(allRows))
|
||||
headers := []string{"VERSION", "SERVICE", "NAME", "TAG"}
|
||||
headers := []string{i18n.G("VERSION"), i18n.G("SERVICE"), i18n.G("NAME"), i18n.G("TAG")}
|
||||
out, err := formatter.ToJSON(headers, allRows)
|
||||
if err != nil {
|
||||
log.Fatal("unable to render to JSON: %s", err)
|
||||
log.Fatal(i18n.G("unable to render to JSON: %s", err))
|
||||
}
|
||||
fmt.Println(out)
|
||||
continue
|
||||
@ -127,9 +128,9 @@ func sortServiceByName(versions [][]string) func(i, j int) bool {
|
||||
func init() {
|
||||
RecipeVersionCommand.Flags().BoolVarP(
|
||||
&internal.MachineReadable,
|
||||
"machine",
|
||||
"m",
|
||||
i18n.G("machine"),
|
||||
i18n.G("m"),
|
||||
false,
|
||||
"print machine-readable output",
|
||||
i18n.G("print machine-readable output"),
|
||||
)
|
||||
}
|
||||
|
Reference in New Issue
Block a user