From c3935eb868358f2a6ebe1b0167d271d9a06379fc Mon Sep 17 00:00:00 2001 From: Luca Lanziani Date: Fri, 18 Aug 2023 23:33:06 +0200 Subject: [PATCH] Feature/get smarter at detecting app name (#81) --- src/cli/build.go | 2 +- src/cli/cli.go | 15 ++++++----- src/cli/delete.go | 2 +- src/cli/deploy.go | 2 +- src/cli/flags.go | 47 ++++++++++++++++++++++----------- src/cli/init.go | 21 ++++++++------- src/cli/init_test.go | 6 ++--- src/cli/onbranch.go | 11 +++++--- src/cli/onmain.go | 11 +++++--- src/cli/push.go | 2 +- src/cli/template.go | 2 +- src/services/git/repo.go | 47 ++++++++++++++++++++++----------- src/services/project/project.go | 10 +++++++ 13 files changed, 114 insertions(+), 64 deletions(-) diff --git a/src/cli/build.go b/src/cli/build.go index 7361138..a2024da 100644 --- a/src/cli/build.go +++ b/src/cli/build.go @@ -21,7 +21,7 @@ func (c CLI) BuildCMD() *cli.Command { return &cli.Command{ Name: "build", Usage: "build a container image from the project directory", - Flags: c.CommandFlags(Build), + Flags: c.CommandFlags([]FlagsType{Build, Shared}), Action: c.Build, Before: c.baseBeforeFunc, } diff --git a/src/cli/cli.go b/src/cli/cli.go index 23f6646..0268858 100644 --- a/src/cli/cli.go +++ b/src/cli/cli.go @@ -43,6 +43,12 @@ func (c *CLI) init(cCtx *cli.Context) error { version := cCtx.String(appVersionFlag) projectDirectory := cCtx.String(projectDirectoryFlag) absProjectDirectory, err := filepath.Abs(cCtx.String(projectDirectoryFlag)) + registry := cCtx.String(repoNameFlag) + dockerFileName := cCtx.String(dockerFileNameFlag) + + if dockerFileName == "" { + dockerFileName = defaults.GeneratedDockerFile + } if err != nil { c.Logger.Warnf("could not get abs of %s", projectDirectory) @@ -67,17 +73,12 @@ func (c *CLI) init(cCtx *cli.Context) error { } dockerImage := docker.DockerImage{ - Registry: cCtx.String(repoNameFlag), + Registry: registry, Name: dockerImageName, Directory: absProjectDirectory, Tag: version, } - dockerFileName := cCtx.String(dockerFileNameFlag) - if dockerFileName == "" { - dockerFileName = defaults.GeneratedDockerFile - } - dockerService, err := docker.New(project, dockerImage, dockerFileName) if err != nil { logger.PrintError("Error creating docker service", err) @@ -103,7 +104,7 @@ func (c CLI) Run(args []string) error { app := &cli.App{ Name: "initium", Usage: "CLI of the Initium project", - Flags: c.CommandFlags(App), + Flags: c.CommandFlags([]FlagsType{App}), Commands: []*cli.Command{ c.BuildCMD(), c.PushCMD(), diff --git a/src/cli/delete.go b/src/cli/delete.go index 1031b8d..632980e 100644 --- a/src/cli/delete.go +++ b/src/cli/delete.go @@ -25,7 +25,7 @@ func (c *CLI) DeleteCMD() *cli.Command { return &cli.Command{ Name: "delete", Usage: "delete the knative service", - Flags: c.CommandFlags(Kubernetes), + Flags: c.CommandFlags([]FlagsType{Kubernetes, Shared}), Action: c.Delete, Before: c.baseBeforeFunc, } diff --git a/src/cli/deploy.go b/src/cli/deploy.go index 03d354f..0794234 100644 --- a/src/cli/deploy.go +++ b/src/cli/deploy.go @@ -27,7 +27,7 @@ func (c CLI) DeployCMD() *cli.Command { return &cli.Command{ Name: "deploy", Usage: "deploy the application as a knative service", - Flags: c.CommandFlags(Kubernetes), + Flags: c.CommandFlags([]FlagsType{Kubernetes, Shared}), Action: c.Deploy, Before: c.baseBeforeFunc, } diff --git a/src/cli/flags.go b/src/cli/flags.go index 4fd5803..8133f94 100644 --- a/src/cli/flags.go +++ b/src/cli/flags.go @@ -8,6 +8,7 @@ import ( "strings" "github.com/nearform/initium-cli/src/services/git" + "github.com/nearform/initium-cli/src/services/project" "github.com/nearform/initium-cli/src/utils/defaults" "github.com/urfave/cli/v2" "gopkg.in/yaml.v2" @@ -22,6 +23,7 @@ const ( Registry FlagsType = "registry" InitGithub FlagsType = "init-github" App FlagsType = "app" + Shared FlagsType = "shared" ) const ( @@ -55,6 +57,13 @@ func init() { registry = fmt.Sprintf("ghcr.io/%s", org) } + appName := "" + guess := project.GuessAppName() + + if guess != nil { + appName = *guess + } + defaultFlags := map[FlagsType]([]cli.Flag){ Build: []cli.Flag{ &cli.StringFlag{ @@ -118,10 +127,25 @@ func init() { }, }, App: []cli.Flag{ + &cli.StringFlag{ + Name: projectDirectoryFlag, + Usage: "The directory in which your Dockerfile lives", + Value: defaults.ProjectDirectory, + EnvVars: []string{"INITIUM_PROJECT_DIRECTORY"}, + }, + &cli.StringFlag{ + Name: configFileFlag, + Usage: "read parameters from config", + Value: defaults.ConfigFile, + EnvVars: []string{"INITIUM_CONFIG_FILE"}, + }, + }, + Shared: []cli.Flag{ &cli.StringFlag{ Name: appNameFlag, Usage: "The name of the app", - Required: true, + Value: appName, + Required: appName == "", EnvVars: []string{"INITIUM_APP_NAME"}, }, &cli.StringFlag{ @@ -130,12 +154,6 @@ func init() { Value: defaults.AppVersion, EnvVars: []string{"INITIUM_VERSION"}, }, - &cli.StringFlag{ - Name: projectDirectoryFlag, - Usage: "The directory in which your Dockerfile lives", - Value: defaults.ProjectDirectory, - EnvVars: []string{"INITIUM_PROJECT_DIRECTORY"}, - }, &cli.StringFlag{ Name: repoNameFlag, Aliases: []string{"repo-name"}, // keep compatibility with old version of the config @@ -149,13 +167,6 @@ func init() { Usage: "The name of the Dockerfile", EnvVars: []string{"INITIUM_DOCKERFILE_NAME"}, }, - &cli.StringFlag{ - Name: configFileFlag, - Usage: "read parameters from config", - Hidden: true, - Value: defaults.ConfigFile, - EnvVars: []string{"INITIUM_CONFIG_FILE"}, - }, }, } @@ -227,6 +238,10 @@ func (c CLI) loadFlagsFromConfig(ctx *cli.Context) error { return nil } -func (c CLI) CommandFlags(command FlagsType) []cli.Flag { - return flags[command] +func (c CLI) CommandFlags(commands []FlagsType) []cli.Flag { + result := []cli.Flag{} + for _, command := range commands { + result = append(result, flags[command]...) + } + return result } diff --git a/src/cli/init.go b/src/cli/init.go index 063ab55..304ff47 100644 --- a/src/cli/init.go +++ b/src/cli/init.go @@ -104,6 +104,13 @@ func (c CLI) InitServiceAccountCMD(ctx *cli.Context) error { } func (c CLI) InitCMD() *cli.Command { + configFlags := c.CommandFlags([]FlagsType{Shared}) + configFlags = append(configFlags, &cli.BoolFlag{ + Name: persistFlag, + Value: false, + Usage: fmt.Sprintf("will write the file content in %s", defaults.ConfigFile), + }) + return &cli.Command{ Name: "init", Usage: "create configuration for the cli [EXPERIMENTAL]", @@ -111,20 +118,14 @@ func (c CLI) InitCMD() *cli.Command { { Name: "github", Usage: "create a github pipeline yaml file", - Flags: c.CommandFlags(InitGithub), + Flags: c.CommandFlags([]FlagsType{InitGithub, Shared}), Action: c.InitGithubCMD, Before: c.baseBeforeFunc, }, { - Name: "config", - Usage: "create a config file with all available flags set to null", - Flags: []cli.Flag{ - &cli.BoolFlag{ - Name: persistFlag, - Value: false, - Usage: fmt.Sprintf("will write the file content in %s", defaults.ConfigFile), - }, - }, + Name: "config", + Usage: "create a config file with all available flags set to null", + Flags: configFlags, Action: c.InitConfigCMD, Before: c.baseBeforeFunc, }, diff --git a/src/cli/init_test.go b/src/cli/init_test.go index bbc290e..aacafca 100644 --- a/src/cli/init_test.go +++ b/src/cli/init_test.go @@ -75,7 +75,7 @@ func TestInitConfig(t *testing.T) { // Command line argument wins over config and Environment variable cli.Writer = new(bytes.Buffer) - if err = cli.Run([]string{"initium", fmt.Sprintf("--config-file=%s", f.Name()), "--app-name=FromParam", "init", "config"}); err != nil { + if err = cli.Run([]string{"initium", fmt.Sprintf("--config-file=%s", f.Name()), "init", "config", "--app-name=FromParam"}); err != nil { t.Error(err) } compareConfig(t, "FromParam", registry, cli.Writer) @@ -98,14 +98,14 @@ func TestRepoNameRetrocompatibiliy(t *testing.T) { } cli.Writer = new(bytes.Buffer) - if err = cli.Run([]string{"initium", fmt.Sprintf("--config-file=%s", f.Name()), "--app-name=FromParam", "init", "config"}); err != nil { + if err = cli.Run([]string{"initium", fmt.Sprintf("--config-file=%s", f.Name()), "init", "config", "--app-name=FromParam"}); err != nil { t.Error(err) } compareConfig(t, "FromParam", "FromFile", cli.Writer) //Override from parameter cli.Writer = new(bytes.Buffer) - if err = cli.Run([]string{"initium", fmt.Sprintf("--config-file=%s", f.Name()), "--app-name=FromParam", "--container-registry=ghcr.io/nearform", "init", "config"}); err != nil { + if err = cli.Run([]string{"initium", fmt.Sprintf("--config-file=%s", f.Name()), "init", "config", "--app-name=FromParam", "--container-registry=ghcr.io/nearform"}); err != nil { t.Error(err) } compareConfig(t, "FromParam", "ghcr.io/nearform", cli.Writer) diff --git a/src/cli/onbranch.go b/src/cli/onbranch.go index 64c64c5..d455654 100644 --- a/src/cli/onbranch.go +++ b/src/cli/onbranch.go @@ -29,10 +29,13 @@ func (c CLI) buildPushDeploy(cCtx *cli.Context) error { } func (c CLI) OnBranchCMD() *cli.Command { - flags := []cli.Flag{} - flags = append(flags, c.CommandFlags(Kubernetes)...) - flags = append(flags, c.CommandFlags(Build)...) - flags = append(flags, c.CommandFlags(Registry)...) + flags := c.CommandFlags([]FlagsType{ + Kubernetes, + Build, + Registry, + Shared, + }) + flags = append(flags, []cli.Flag{ &cli.BoolFlag{ Name: stopOnBuildFlag, diff --git a/src/cli/onmain.go b/src/cli/onmain.go index 98699f0..9099063 100644 --- a/src/cli/onmain.go +++ b/src/cli/onmain.go @@ -6,10 +6,12 @@ import ( ) func (c *CLI) OnMainCMD() *cli.Command { - flags := []cli.Flag{} - flags = append(flags, c.CommandFlags(Kubernetes)...) - flags = append(flags, c.CommandFlags(Build)...) - flags = append(flags, c.CommandFlags(Registry)...) + flags := c.CommandFlags([]FlagsType{ + Kubernetes, + Build, + Registry, + Shared, + }) flags = append(flags, []cli.Flag{ &cli.BoolFlag{ Name: stopOnBuildFlag, @@ -20,6 +22,7 @@ func (c *CLI) OnMainCMD() *cli.Command { Value: false, }, }...) + return &cli.Command{ Name: "onmain", Usage: "deploy the application as a knative service", diff --git a/src/cli/push.go b/src/cli/push.go index 8c1a3ef..29f35bf 100644 --- a/src/cli/push.go +++ b/src/cli/push.go @@ -18,7 +18,7 @@ func (c *CLI) PushCMD() *cli.Command { return &cli.Command{ Name: "push", Usage: "push the container image to a registry", - Flags: c.CommandFlags(Registry), + Flags: c.CommandFlags([]FlagsType{Registry, Shared}), Action: c.Push, Before: c.baseBeforeFunc, } diff --git a/src/cli/template.go b/src/cli/template.go index 0cd0bc6..2736a83 100644 --- a/src/cli/template.go +++ b/src/cli/template.go @@ -23,7 +23,7 @@ func (c *CLI) TemplateCMD() *cli.Command { return &cli.Command{ Name: "template", Usage: "output the docker file used for this project", - Flags: c.CommandFlags(Build), + Flags: c.CommandFlags([]FlagsType{Build}), Action: c.template, Before: c.baseBeforeFunc, } diff --git a/src/services/git/repo.go b/src/services/git/repo.go index 74a9677..6de1b64 100644 --- a/src/services/git/repo.go +++ b/src/services/git/repo.go @@ -8,6 +8,11 @@ import ( git "github.com/go-git/go-git/v5" ) +const ( + httpgithubprefix = "https://github.com/" + gitgithubprefix = "git@github.com:" +) + func initRepo() (*git.Repository, error) { wd, err := os.Getwd() @@ -38,7 +43,7 @@ func GetHash() (string, error) { return headRef.Hash().String(), nil } -func GetGithubOrg() (string, error) { +func getGithubRemote() (string, error) { repo, err := initRepo() if err != nil { @@ -53,25 +58,37 @@ func GetGithubOrg() (string, error) { for _, remote := range c.Remotes { for _, url := range remote.URLs { // HTTPS (https://github.com/organization/repo.git) - if strings.HasPrefix(url, "https://github.com/") { - splitURL := strings.Split(url, "/") - if len(splitURL) > 3 { - return splitURL[3], nil - } + if strings.HasPrefix(url, httpgithubprefix) { + return strings.Replace(url, httpgithubprefix, "", 1), nil } // SSH (git@github.com:organization/repo.git) - if strings.HasPrefix(url, "git@github.com:") { - splitURL := strings.Split(url, ":") - if len(splitURL) > 1 { - splitPath := strings.Split(splitURL[1], "/") - if len(splitPath) > 1 { - return splitPath[0], nil - } - } + if strings.HasPrefix(url, gitgithubprefix) { + return strings.Replace(url, gitgithubprefix, "", 1), nil } } + } + return "", fmt.Errorf("no github remote found") +} + +func GetRepoName() (string, error) { + remote, err := getGithubRemote() + + if err != nil { + return "", err + } + + splitRemote := strings.Split(remote, "/") + return strings.Replace(splitRemote[1], ".git", "", 1), nil +} + +func GetGithubOrg() (string, error) { + remote, err := getGithubRemote() + + if err != nil { + return "", err } - return "", fmt.Errorf("cannot find any remote with github.com") + splitRemote := strings.Split(remote, "/") + return splitRemote[0], nil } diff --git a/src/services/project/project.go b/src/services/project/project.go index eedc8fa..fcadcd6 100644 --- a/src/services/project/project.go +++ b/src/services/project/project.go @@ -8,6 +8,7 @@ import ( "path" "text/template" + "github.com/nearform/initium-cli/src/services/git" "github.com/nearform/initium-cli/src/utils/defaults" ) @@ -36,6 +37,15 @@ type InitOptions struct { ProjectDirectory string } +func GuessAppName() *string { + var name string + name, err := git.GetRepoName() + if err != nil { + return nil + } + return &name +} + func New(name string, directory string, runtimeVersion string, version string, resources fs.FS) Project { return Project{ Name: name,