diff --git a/.travis.yml b/.travis.yml index 229aa86..590f113 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,7 +12,7 @@ install: - go install github.com/golangci/golangci-lint/cmd/golangci-lint - go install github.com/mattn/goveralls -before_script: make lint +before_script: make check-license lint script: - make test coverage diff --git a/cmd/completion.go b/cmd/completion.go index 50ff4db..83c253f 100644 --- a/cmd/completion.go +++ b/cmd/completion.go @@ -58,14 +58,11 @@ __git-ghost_custom_func() { ` ) -func init() { - RootCmd.AddCommand(completionCmd) -} - -var completionCmd = &cobra.Command{ - Use: "completion SHELL", - Short: "output shell completion code for the specified shell (bash or zsh)", - Long: `Write bash or zsh shell completion code to standard output. +func NewCompletionCommand(rootCmd *cobra.Command) *cobra.Command { + return &cobra.Command{ + Use: "completion SHELL", + Short: "output shell completion code for the specified shell (bash or zsh)", + Long: `Write bash or zsh shell completion code to standard output. For bash, ensure you have bash completions installed and enabled. To access completions in your current shell, run @@ -75,21 +72,22 @@ var completionCmd = &cobra.Command{ For zsh, output to a file in a directory referenced by the $fpath shell variable. `, - Args: cobra.ExactArgs(1), - Run: func(cmd *cobra.Command, args []string) { - shell := args[0] - RootCmd.BashCompletionFunction = bashCompletionFunc - availableCompletions := map[string]func(io.Writer) error{ - "bash": RootCmd.GenBashCompletion, - "zsh": RootCmd.GenZshCompletion, - } - completion, ok := availableCompletions[shell] - if !ok { - fmt.Printf("Invalid shell '%s'. The supported shells are bash and zsh.\n", shell) - os.Exit(1) - } - if err := completion(os.Stdout); err != nil { - log.Fatal(err) - } - }, + Args: cobra.ExactArgs(1), + Run: func(cmd *cobra.Command, args []string) { + shell := args[0] + rootCmd.BashCompletionFunction = bashCompletionFunc + availableCompletions := map[string]func(io.Writer) error{ + "bash": rootCmd.GenBashCompletion, + "zsh": rootCmd.GenZshCompletion, + } + completion, ok := availableCompletions[shell] + if !ok { + fmt.Printf("Invalid shell '%s'. The supported shells are bash and zsh.\n", shell) + os.Exit(1) + } + if err := completion(os.Stdout); err != nil { + log.Fatal(err) + } + }, + } } diff --git a/cmd/delete.go b/cmd/delete.go index b25618c..55529b8 100644 --- a/cmd/delete.go +++ b/cmd/delete.go @@ -25,10 +25,6 @@ import ( "github.com/spf13/cobra" ) -func init() { - RootCmd.AddCommand(NewDeleteCommand()) -} - type deleteFlags struct { hashFrom string hashTo string diff --git a/cmd/gc.go b/cmd/gc.go index 4086d26..2442f21 100644 --- a/cmd/gc.go +++ b/cmd/gc.go @@ -20,15 +20,13 @@ import ( "github.com/spf13/cobra" ) -func init() { - RootCmd.AddCommand(gcCmd) -} - -var gcCmd = &cobra.Command{ - Use: "gc", - Short: "gc ghost commits from remote repository.", - Long: "gc ghost commits from remote repository.", - Run: func(cmd *cobra.Command, args []string) { - fmt.Println("gc command") - }, +func NewGCCommand() *cobra.Command { + return &cobra.Command{ + Use: "gc", + Short: "gc ghost commits from remote repository.", + Long: "gc ghost commits from remote repository.", + Run: func(cmd *cobra.Command, args []string) { + fmt.Println("gc command") + }, + } } diff --git a/cmd/list.go b/cmd/list.go index dfe0957..fee3391 100644 --- a/cmd/list.go +++ b/cmd/list.go @@ -27,10 +27,6 @@ import ( "github.com/spf13/cobra" ) -func init() { - RootCmd.AddCommand(NewListCommand()) -} - var outputTypes = []string{"only-from", "only-to"} var regexpOutputPattern = regexp.MustCompile("^(|" + strings.Join(outputTypes, "|") + ")$") diff --git a/cmd/pull.go b/cmd/pull.go index 0b64730..e0845ce 100644 --- a/cmd/pull.go +++ b/cmd/pull.go @@ -25,10 +25,6 @@ import ( "github.com/spf13/cobra" ) -func init() { - RootCmd.AddCommand(NewPullCommand()) -} - type pullFlags struct { // forceApply bool } diff --git a/cmd/push.go b/cmd/push.go index 32ceab3..bc56604 100644 --- a/cmd/push.go +++ b/cmd/push.go @@ -30,10 +30,6 @@ type pushFlags struct { followSymlinks bool } -func init() { - RootCmd.AddCommand(NewPushCommand()) -} - func NewPushCommand() *cobra.Command { var ( flags pushFlags diff --git a/cmd/root.go b/cmd/root.go index 93d81e5..5b25ba0 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -55,59 +55,68 @@ var ( Revision string ) -var RootCmd = &cobra.Command{ - Use: "git-ghost", - Short: "git-ghost", - SilenceErrors: false, - PersistentPreRunE: func(cmd *cobra.Command, args []string) error { - if cmd.Use == "version" { - return nil - } - err := validateEnvironment() - if err != nil { - return err - } - err = globalOpts.SetDefaults() - if err != nil { - return err - } - err = globalOpts.Validate() - if err != nil { - return err - } - switch globalOpts.verbose { - case 0: - log.SetLevel(log.ErrorLevel) - case 1: - log.SetLevel(log.InfoLevel) - case 2: - log.SetLevel(log.DebugLevel) - case 3: - log.SetLevel(log.TraceLevel) - } - return nil - }, -} - var globalOpts globalFlags -func init() { +func NewRootCmd() *cobra.Command { cobra.OnInitialize() - RootCmd.PersistentFlags().StringVar(&globalOpts.srcDir, "src-dir", "", "source directory which you create ghost from (default to PWD env)") - RootCmd.PersistentFlags().StringVar(&globalOpts.ghostWorkDir, "ghost-working-dir", "", "local root directory for git-ghost interacting with ghost repository (default to a temporary directory)") - RootCmd.PersistentFlags().StringVar(&globalOpts.ghostPrefix, "ghost-prefix", "", "prefix of ghost branch name (default to GIT_GHOST_PREFIX env, or ghost)") - RootCmd.PersistentFlags().StringVar(&globalOpts.ghostRepo, "ghost-repo", "", "git remote url for ghosts repository (default to GIT_GHOST_REPO env)") - RootCmd.PersistentFlags().CountVarP(&globalOpts.verbose, "verbose", "v", "verbose mode") - RootCmd.AddCommand(versionCmd) + rootCmd := &cobra.Command{ + Use: "git-ghost", + Short: "git-ghost", + SilenceErrors: false, + PersistentPreRunE: func(cmd *cobra.Command, args []string) error { + if cmd.Use == "version" { + return nil + } + err := validateEnvironment() + if err != nil { + return err + } + err = globalOpts.SetDefaults() + if err != nil { + return err + } + err = globalOpts.Validate() + if err != nil { + return err + } + switch globalOpts.verbose { + case 0: + log.SetLevel(log.ErrorLevel) + case 1: + log.SetLevel(log.InfoLevel) + case 2: + log.SetLevel(log.DebugLevel) + case 3: + log.SetLevel(log.TraceLevel) + } + return nil + }, + } + rootCmd.PersistentFlags().StringVar(&globalOpts.srcDir, "src-dir", "", "source directory which you create ghost from (default to PWD env)") + rootCmd.PersistentFlags().StringVar(&globalOpts.ghostWorkDir, "ghost-working-dir", "", "local root directory for git-ghost interacting with ghost repository (default to a temporary directory)") + rootCmd.PersistentFlags().StringVar(&globalOpts.ghostPrefix, "ghost-prefix", "", "prefix of ghost branch name (default to GIT_GHOST_PREFIX env, or ghost)") + rootCmd.PersistentFlags().StringVar(&globalOpts.ghostRepo, "ghost-repo", "", "git remote url for ghosts repository (default to GIT_GHOST_REPO env)") + rootCmd.PersistentFlags().CountVarP(&globalOpts.verbose, "verbose", "v", "verbose mode") + rootCmd.AddCommand(NewPushCommand()) + rootCmd.AddCommand(NewPullCommand()) + rootCmd.AddCommand(NewShowCommand()) + rootCmd.AddCommand(NewListCommand()) + rootCmd.AddCommand(NewDeleteCommand()) + rootCmd.AddCommand(NewGCCommand()) + rootCmd.AddCommand(NewVersionCommand()) + rootCmd.AddCommand(NewCompletionCommand(rootCmd)) + return rootCmd } -var versionCmd = &cobra.Command{ - Use: "version", - Short: "Print the version number of git-ghost", - Long: `Print the version number of git-ghost`, - Run: func(cmd *cobra.Command, args []string) { - fmt.Printf("git-ghost %s (revision: %s)", Version, Revision) - }, +func NewVersionCommand() *cobra.Command { + return &cobra.Command{ + Use: "version", + Short: "Print the version number of git-ghost", + Long: `Print the version number of git-ghost`, + Run: func(cmd *cobra.Command, args []string) { + fmt.Printf("git-ghost %s (revision: %s)", Version, Revision) + }, + } } func validateEnvironment() errors.GitGhostError { diff --git a/cmd/root_test.go b/cmd/root_test.go new file mode 100644 index 0000000..17dbca8 --- /dev/null +++ b/cmd/root_test.go @@ -0,0 +1,26 @@ +// Copyright 2019 Preferred Networks, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package cmd + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestRootCmd(t *testing.T) { + cmd := NewRootCmd() + assert.NotNil(t, cmd) +} diff --git a/cmd/show.go b/cmd/show.go index ddd55ec..7050309 100644 --- a/cmd/show.go +++ b/cmd/show.go @@ -25,10 +25,6 @@ import ( "github.com/spf13/cobra" ) -func init() { - RootCmd.AddCommand(NewShowCommand()) -} - func NewShowCommand() *cobra.Command { command := &cobra.Command{ Use: "show [from-hash(default=HEAD)] [diff-hash]", diff --git a/golangci.yml b/golangci.yml index 61b800c..55e5555 100644 --- a/golangci.yml +++ b/golangci.yml @@ -1,7 +1,5 @@ run: tests: false - skip-files: - - "pkg/.*_k8s.go$" output: format: colored-line-number print-issued-lines: true diff --git a/main.go b/main.go index 0ad32d9..69014c1 100644 --- a/main.go +++ b/main.go @@ -27,8 +27,9 @@ func init() { } func main() { - // RootCmd prints errors if exists - if err := cmd.RootCmd.Execute(); err != nil { + // rootCmd prints errors if exists + rootCmd := cmd.NewRootCmd() + if err := rootCmd.Execute(); err != nil { os.Exit(-1) } } diff --git a/scripts/license/add.py b/scripts/license/add.py index da9e24c..63cdaa1 100644 --- a/scripts/license/add.py +++ b/scripts/license/add.py @@ -26,12 +26,16 @@ def main(verbose=False): - add(PROJECT_ROOT.glob("*[!vendor]/**/*_k8s.go"), - license_header("//", True), verbose) - add([p for p in PROJECT_ROOT.glob("*[!vendor]/**/*.go") - if p.name[-7:] != "_k8s.go"], license_header("//"), verbose) - add(PROJECT_ROOT.glob("*[!vendor]/**/*.py"), license_header("#"), verbose) - add(PROJECT_ROOT.glob("*[!vendor]/**/*.sh"), license_header("#"), verbose) + add(PROJECT_ROOT.glob("*.go"), license_header("//"), verbose) + add(PROJECT_ROOT.glob("*.py"), license_header("#"), verbose) + add(PROJECT_ROOT.glob("*.sh"), license_header("#"), verbose) + + for p in PROJECT_ROOT.glob("*"): + if p.name == "vendor" or not p.is_dir(): + continue + add(p.glob("**/*.go"), license_header("//"), verbose) + add(p.glob("**/*.py"), license_header("#"), verbose) + add(p.glob("**/*.sh"), license_header("#"), verbose) def add(paths, license_header, verbose): diff --git a/scripts/license/check.py b/scripts/license/check.py index 24deadb..4ebecf4 100644 --- a/scripts/license/check.py +++ b/scripts/license/check.py @@ -16,8 +16,8 @@ Checks whether files have an appropriate license header. """ -from pathlib import Path import subprocess +from pathlib import Path from license_header import license_header, has_license_header @@ -28,17 +28,19 @@ def main(verbose=False): ok = True - ok &= check( - PROJECT_ROOT.glob("./*[!vendor]/**/*_k8s.go"), - license_header("//", modification=True), verbose) - ok &= check( - [p for p in PROJECT_ROOT.glob( - "./*[!vendor]/**/*.go") if p.name[-7:] != "_k8s.go"], - license_header("//"), verbose) - ok &= check( - PROJECT_ROOT.glob("./*[!vendor]/**/*.py"), license_header("#"), verbose) - ok &= check( - PROJECT_ROOT.glob("./*[!vendor]/**/*.sh"), license_header("#"), verbose) + ok &= check(PROJECT_ROOT.glob("*.go"), license_header("//"), verbose) + ok &= check(PROJECT_ROOT.glob("*.py"), license_header("#"), verbose) + ok &= check(PROJECT_ROOT.glob("*.sh"), license_header("#"), verbose) + + for p in PROJECT_ROOT.glob("*"): + if p.name == "vendor" or not p.is_dir(): + continue + ok &= check( + p.glob("**/*.go"), license_header("//"), verbose) + ok &= check( + p.glob("**/*.py"), license_header("#"), verbose) + ok &= check( + p.glob("**/*.sh"), license_header("#"), verbose) return 0 if ok else 1