diff --git a/ahoy.go b/ahoy.go index 379aec3..3809ec5 100644 --- a/ahoy.go +++ b/ahoy.go @@ -1,10 +1,10 @@ package main import ( + "bufio" "errors" "flag" "fmt" - "io/ioutil" "log" "os" "os/exec" @@ -65,6 +65,14 @@ func logger(errType string, text string) { } } +func fileExists(filename string) bool { + info, err := os.Stat(filename) + if os.IsNotExist(err) { + return false + } + return !info.IsDir() +} + func getConfigPath(sourcefile string) (string, error) { var err error var config = "" @@ -92,26 +100,26 @@ func getConfigPath(sourcefile string) (string, error) { // Chop off the last part of the path. dir = path.Dir(dir) } - logger("debug", "Can't find a .ahoy.yml file.") + logger("debug", "Can't find an .ahoy.yml file.") return "", err } func getConfig(file string) (Config, error) { var config = Config{} - yamlFile, err := ioutil.ReadFile(file) + yamlFile, err := os.ReadFile(file) if err != nil { err = errors.New("an ahoy config file couldn't be found in your path. You can create an example one by using 'ahoy init'") return config, err } - // Extract the yaml file into the config varaible. + // Extract the yaml file into the config variable. err = yaml.Unmarshal(yamlFile, &config) if err != nil { return config, err } // All ahoy files (and imports) must specify the ahoy version. - // This is so we can support backwards compatability in the future. + // This is so we can support backwards compatibility in the future. if config.AhoyAPI != "v2" { err = errors.New("Ahoy only supports API version 'v2', but '" + config.AhoyAPI + "' given in " + sourcefile) return config, err @@ -138,8 +146,8 @@ func getSubCommands(includes []string) []cli.Command { include = filepath.Join(AhoyConf.srcDir, include) } if _, err := os.Stat(include); err != nil { - //Skipping files that cannot be loaded allows us to separate - //subcommands into public and private. + // Skipping files that cannot be loaded allows us to separate + // subcommands into public and private. continue } config, _ := getConfig(include) @@ -258,9 +266,40 @@ func addDefaultCommands(commands []cli.Command) []cli.Command { defaultInitCmd := cli.Command{ Name: "init", Usage: "Initialize a new .ahoy.yml config file in the current directory.", + Flags: []cli.Flag{ + cli.BoolFlag{ + Name: "force", + Usage: "force overwriting the .ahoy.yml file in the current directory.", + }, + }, Action: func(c *cli.Context) { + if fileExists(filepath.Join(".", ".ahoy.yml")) { + if c.Bool("force") { + fmt.Println("Warning: '--force' parameter passed, overwriting .ahoy.yml in current directory.") + } else { + fmt.Println("Warning: .ahoy.yml found in current directory.") + fmt.Fprint(os.Stderr, "Are you sure you wish to overwrite it with an example file, y/N ? ") + reader := bufio.NewReader(os.Stdin) + char, _, err := reader.ReadRune() + if err != nil { + fmt.Println(err) + } + // If "y" or "Y", continue and overwrite. + // Anything else, exit. + if char != 'y' && char != 'Y' { + fmt.Println("Abort: exiting without overwriting.") + os.Exit(0) + } + if len(c.Args()) > 0 { + fmt.Println("Ok, overwriting .ahoy.yml in current directory with specified file.") + } else { + fmt.Println("Ok, overwriting .ahoy.yml in current directory with example file.") + } + } + } // Grab the URL or use a default for the initial ahoy file. // Allows users to define their own files to call to init. + // TODO: Make file downloading OS-independent. var wgetURL = "https://raw.githubusercontent.com/ahoy-cli/ahoy/master/examples/examples.ahoy.yml" if len(c.Args()) > 0 { wgetURL = c.Args()[0] @@ -273,7 +312,11 @@ func addDefaultCommands(commands []cli.Command) []cli.Command { fmt.Fprintln(os.Stderr) os.Exit(1) } else { - fmt.Println("example.ahoy.yml downloaded to the current directory. You can customize it to suit your needs!") + if len(c.Args()) > 0 { + fmt.Println("Your specified .ahoy.yml has been downloaded to the current directory.") + } else { + fmt.Println("Example .ahoy.yml downloaded to the current directory. You can customize it to suit your needs!") + } } }, } diff --git a/ahoy_test.go b/ahoy_test.go index 9ef2cc5..998e9a6 100644 --- a/ahoy_test.go +++ b/ahoy_test.go @@ -2,8 +2,9 @@ package main import ( "fmt" - "io/ioutil" + "io" "os" + "path/filepath" "testing" "gopkg.in/yaml.v2" @@ -23,7 +24,7 @@ func TestGetCommands(t *testing.T) { Usage: "Test getSubCommands Usage.", AhoyAPI: "v2", Commands: map[string]Command{ - "test-command": Command{ + "test-command": { Description: "Testing example Command.", Usage: "test-command a", Cmd: "echo a.ahoy.yml", @@ -169,7 +170,7 @@ func TestGetConfig(t *testing.T) { Usage: "Test example usage.", AhoyAPI: "v2", Commands: map[string]Command{ - "test-command": Command{ + "test-command": { Description: "Testing example Command.", Usage: "test-command", Cmd: "echo 'Hello World'", @@ -184,7 +185,7 @@ func TestGetConfig(t *testing.T) { testYaml, err := yaml.Marshal(expected) if err != nil { - t.Error("Something went wrong mashelling the test object.") + t.Error("Something went wrong mashalling the test object.") } testFile.Write([]byte(testYaml)) @@ -210,14 +211,14 @@ func TestGetConfig(t *testing.T) { func TestGetConfigPath(t *testing.T) { // Passinng empty string. pwd, _ := os.Getwd() - expected := pwd + "/.ahoy.yml" + expected := filepath.Join(pwd, ".ahoy.yml") actual, _ := getConfigPath("") if expected != actual { t.Errorf("ahoy docker override-example: expected - %s; actual - %s", string(expected), string(actual)) } // Passing known path works as expected - expected = pwd + "/.ahoy.yml" + expected = filepath.Join(pwd, ".ahoy.yml") actual, _ = getConfigPath(expected) if expected != actual { @@ -244,7 +245,7 @@ func appRun(args []string) (string, error) { w.Close() //@aashil thinks this reads from the command line - out, _ := ioutil.ReadAll(r) + out, _ := io.ReadAll(r) os.Stdout = stdout return string(out), nil } diff --git a/tests/no-ahoy-file.bats b/tests/no-ahoy-file.bats index 60aa2db..6aec00f 100644 --- a/tests/no-ahoy-file.bats +++ b/tests/no-ahoy-file.bats @@ -22,5 +22,13 @@ teardown() { @test "run ahoy init without a .ahoy.yml file" { run ./ahoy init - [ "${lines[-1]}" == "example.ahoy.yml downloaded to the current directory. You can customize it to suit your needs!" ] + [ "${lines[-1]}" == "Example .ahoy.yml downloaded to the current directory. You can customize it to suit your needs!" ] +} + +@test "run ahoy init with a existing .ahoy.yml file in the current directory" { + cp tmp.ahoy.yml .ahoy.yml + run ./ahoy init --force + [ "${lines[0]}" == "Warning: '--force' parameter passed, overwriting .ahoy.yml in current directory." ] + [ "${lines[-1]}" == "Example .ahoy.yml downloaded to the current directory. You can customize it to suit your needs!" ] + rm .ahoy.yml }