From 727b10053ea4871638cf75b763a53e8657b288b6 Mon Sep 17 00:00:00 2001 From: Frank Carey Date: Mon, 21 Nov 2016 15:19:38 -0500 Subject: [PATCH 01/10] Add some tests using bats. --- .ahoy.yml | 4 ++++ circle.yml | 1 + tests/.ahoy.yml | 0 tests/no-ahoy-file.bats | 14 ++++++++++++++ tests/test.bats | 11 +++++++++++ 5 files changed, 30 insertions(+) create mode 100644 tests/.ahoy.yml create mode 100644 tests/no-ahoy-file.bats create mode 100644 tests/test.bats diff --git a/.ahoy.yml b/.ahoy.yml index 8189bea..b1caebb 100644 --- a/.ahoy.yml +++ b/.ahoy.yml @@ -6,6 +6,9 @@ commands: install: cmd: "go install" usage: Build ahoy using go install. + bats: + usage: "Run the bats bash testing command." + cmd: bats tests test: usage: Run automated tests cmd: | @@ -14,6 +17,7 @@ commands: 'go vet' 'go test -v -race ' 'golint -set_exit_status' + 'bats tests' ) for i in "${TESTS[@]}"; do printf "\n=== TEST: $i ===\n\n" diff --git a/circle.yml b/circle.yml index dd7e1c0..bc3a296 100644 --- a/circle.yml +++ b/circle.yml @@ -1,5 +1,6 @@ test: pre: + - npm install -g bats # Make sure this build is using GO > 1.6 for golint to work correctly. # On CircleCI, only the Trusty 14.04 build has a newer version. - go get -u github.com/golang/lint/golint diff --git a/tests/.ahoy.yml b/tests/.ahoy.yml new file mode 100644 index 0000000..e69de29 diff --git a/tests/no-ahoy-file.bats b/tests/no-ahoy-file.bats new file mode 100644 index 0000000..35c66c5 --- /dev/null +++ b/tests/no-ahoy-file.bats @@ -0,0 +1,14 @@ +#!/usr/bin/env bats + +setup() { + mv .ahoy.yml tmp.ahoy.yml +} + +teardown() { + mv tmp.ahoy.yml .ahoy.yml +} + +@test "run ahoy init without a .ahoy.yml file" { + result="$(ahoy init)" + [ "$result" -eq 4 ] +} diff --git a/tests/test.bats b/tests/test.bats new file mode 100644 index 0000000..5683371 --- /dev/null +++ b/tests/test.bats @@ -0,0 +1,11 @@ +#!/usr/bin/env bats + +@test "addition using bc" { + result="$(echo 2+2 | bc)" + [ "$result" -eq 4 ] +} + +@test "addition using dc" { + result="$(echo 2 2+p | dc)" + [ "$result" -eq 4 ] +} From 04794806ac51c3929b9a891fe2d1dcc99b03eace Mon Sep 17 00:00:00 2001 From: Frank Carey Date: Mon, 21 Nov 2016 15:36:44 -0500 Subject: [PATCH 02/10] Add tests for using flags (most fail now). --- testdata/simple.ahoy.yml | 4 ++++ tests/flags.bats | 11 +++++++++++ tests/simple.bats | 6 ++++++ 3 files changed, 21 insertions(+) create mode 100644 testdata/simple.ahoy.yml create mode 100644 tests/flags.bats create mode 100644 tests/simple.bats diff --git a/testdata/simple.ahoy.yml b/testdata/simple.ahoy.yml new file mode 100644 index 0000000..2b28927 --- /dev/null +++ b/testdata/simple.ahoy.yml @@ -0,0 +1,4 @@ +ahoyapi: v2 +commands: + echo: + cmd: echo {{args}} diff --git a/tests/flags.bats b/tests/flags.bats new file mode 100644 index 0000000..cc675ec --- /dev/null +++ b/tests/flags.bats @@ -0,0 +1,11 @@ +#!/usr/bin/env bats + +@test "get the version of ahoy with --version" { + result="$(ahoy -f testdata/simple.ahoy.yml --version)" + [ "$result" == "master" ] +} + +@test "get help instead of running a command with --help" { + result="$(ahoy -f testdata/simple.ahoy.yml --help echo something)" + [ "$result" != "something" ] +} diff --git a/tests/simple.bats b/tests/simple.bats new file mode 100644 index 0000000..8a72c4c --- /dev/null +++ b/tests/simple.bats @@ -0,0 +1,6 @@ +#!/usr/bin/env bats + +@test "run a simple ahoy command: echo" { + result="$(ahoy -f testdata/simple.ahoy.yml echo something)" + [ "$result" == "something" ] +} From fdc57746fe0215b8a209afd5b43ee7b6c4caeace Mon Sep 17 00:00:00 2001 From: Frank Carey Date: Mon, 21 Nov 2016 15:59:22 -0500 Subject: [PATCH 03/10] Setup bats to use a locally compiled version of .ahoy. --- .ahoy.yml | 4 +++- tests/flags.bats | 7 ++++--- tests/no-ahoy-file.bats | 2 +- tests/simple.bats | 9 ++++++++- tests/test.bats | 11 ----------- 5 files changed, 16 insertions(+), 17 deletions(-) delete mode 100644 tests/test.bats diff --git a/.ahoy.yml b/.ahoy.yml index b1caebb..cf331eb 100644 --- a/.ahoy.yml +++ b/.ahoy.yml @@ -8,7 +8,9 @@ commands: usage: Build ahoy using go install. bats: usage: "Run the bats bash testing command." - cmd: bats tests + cmd: | + ahoy build + bats tests test: usage: Run automated tests cmd: | diff --git a/tests/flags.bats b/tests/flags.bats index cc675ec..68a69a4 100644 --- a/tests/flags.bats +++ b/tests/flags.bats @@ -1,11 +1,12 @@ #!/usr/bin/env bats @test "get the version of ahoy with --version" { - result="$(ahoy -f testdata/simple.ahoy.yml --version)" - [ "$result" == "master" ] + run ./ahoy -f testdata/simple.ahoy.yml --version + [ $status -eq 0 ] + [ "$result" == "2.0.0-alpha-23-g0479480" ] } @test "get help instead of running a command with --help" { - result="$(ahoy -f testdata/simple.ahoy.yml --help echo something)" + result="$(./ahoy -f testdata/simple.ahoy.yml --help echo something)" [ "$result" != "something" ] } diff --git a/tests/no-ahoy-file.bats b/tests/no-ahoy-file.bats index 35c66c5..83d4a5c 100644 --- a/tests/no-ahoy-file.bats +++ b/tests/no-ahoy-file.bats @@ -9,6 +9,6 @@ teardown() { } @test "run ahoy init without a .ahoy.yml file" { - result="$(ahoy init)" + result="$(./ahoy init)" [ "$result" -eq 4 ] } diff --git a/tests/simple.bats b/tests/simple.bats index 8a72c4c..3523307 100644 --- a/tests/simple.bats +++ b/tests/simple.bats @@ -1,6 +1,13 @@ #!/usr/bin/env bats +@test "display help text when no arguments are passed." { + run ./ahoy -f testdata/simple.ahoy.yml + # Should throw an error. + [ "${#lines[@]}" -gt 14 ] + [ $status -eq 1 ] +} + @test "run a simple ahoy command: echo" { - result="$(ahoy -f testdata/simple.ahoy.yml echo something)" + result="$(./ahoy -f testdata/simple.ahoy.yml echo something)" [ "$result" == "something" ] } diff --git a/tests/test.bats b/tests/test.bats deleted file mode 100644 index 5683371..0000000 --- a/tests/test.bats +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env bats - -@test "addition using bc" { - result="$(echo 2+2 | bc)" - [ "$result" -eq 4 ] -} - -@test "addition using dc" { - result="$(echo 2 2+p | dc)" - [ "$result" -eq 4 ] -} From ed08bce18132c7764a4a38a51656a16cf676b86c Mon Sep 17 00:00:00 2001 From: Frank Carey Date: Mon, 21 Nov 2016 16:12:51 -0500 Subject: [PATCH 04/10] Ignore the local ahoy binary when built. --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 4f668d4..23c35a4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ # Ignore the items build by sphinx for read the docs. docs/_build +# Ignore the ahoy binary when it's built +ahoy From 172cfeca10d4937ad6defd100b61ca1983f73b4f Mon Sep 17 00:00:00 2001 From: Frank Carey Date: Mon, 21 Nov 2016 18:11:08 -0500 Subject: [PATCH 05/10] Don't panic, but instead just exit with an error. --- ahoy.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ahoy.go b/ahoy.go index 13d74cc..fae07a7 100644 --- a/ahoy.go +++ b/ahoy.go @@ -51,7 +51,7 @@ func logger(errType string, text string) { log.Print(errText) } if errType == "fatal" { - panic(errText) + os.Exit(1) } } From 3444b28f01594cf43aa06841869d781dbadf79f7 Mon Sep 17 00:00:00 2001 From: Frank Carey Date: Mon, 21 Nov 2016 18:12:35 -0500 Subject: [PATCH 06/10] Add some default commands to handle flags when no arguments are set. --- ahoy.go | 32 +++++++++++++++++++++++++++++--- tests/flags.bats | 2 +- tests/no-ahoy-file.bats | 11 +++++++++++ 3 files changed, 41 insertions(+), 4 deletions(-) diff --git a/ahoy.go b/ahoy.go index fae07a7..1746ab8 100644 --- a/ahoy.go +++ b/ahoy.go @@ -1,6 +1,7 @@ package main import ( + "errors" "flag" "fmt" "github.com/codegangsta/cli" @@ -257,11 +258,36 @@ func BashComplete(c *cli.Context) { } } -func setupApp(args []string) *cli.App { - initFlags(args) - //log.Println(sourcefile) +// This is the application wide default action, for when no arguments are passed. +func NoArgsAction(c *cli.Context) { + if c.Bool("help") { + cli.ShowAppHelp(c) + } +} + +// This runs before every command so arguments must be passed. +func BeforeCommand(c *cli.Context) error { + args := c.Args() + if c.Bool("version") { + fmt.Println(version) + return errors.New("don't continue with commands") + } + if c.Bool("help") { + if len(args) > 0 { + cli.ShowCommandHelp(c, args.First()) + return errors.New("don't continue with commands") + } + } + //fmt.Printf("%+v\n", args) + return nil +} + +func setupApp(localArgs []string) *cli.App { + initFlags(localArgs) // cli stuff app = cli.NewApp() + app.Action = NoArgsAction + app.Before = BeforeCommand app.Name = "ahoy" app.Version = version app.Usage = "Creates a configurable cli app for running commands." diff --git a/tests/flags.bats b/tests/flags.bats index 68a69a4..89674a3 100644 --- a/tests/flags.bats +++ b/tests/flags.bats @@ -3,7 +3,7 @@ @test "get the version of ahoy with --version" { run ./ahoy -f testdata/simple.ahoy.yml --version [ $status -eq 0 ] - [ "$result" == "2.0.0-alpha-23-g0479480" ] + [ $(expr "$output" : "[0-9.]\.[0-9.]\.[0-9.]") -ne 0 ] } @test "get help instead of running a command with --help" { diff --git a/tests/no-ahoy-file.bats b/tests/no-ahoy-file.bats index 83d4a5c..a18177a 100644 --- a/tests/no-ahoy-file.bats +++ b/tests/no-ahoy-file.bats @@ -8,6 +8,17 @@ teardown() { mv tmp.ahoy.yml .ahoy.yml } +@test "run ahoy withough a command and without a .ahoy.yml file" { + result="$(./ahoy)" + echo "$result" + [ "$result" -eq 4 ] +} + +@test "run an ahoy command without a .ahoy.yml file" { + result="$(./ahoy something)" + [ "$result" -eq 4 ] +} + @test "run ahoy init without a .ahoy.yml file" { result="$(./ahoy init)" [ "$result" -eq 4 ] From ac4758bef3d0972e0045b7e029a9b384a1041352 Mon Sep 17 00:00:00 2001 From: Frank Carey Date: Mon, 21 Nov 2016 19:10:57 -0500 Subject: [PATCH 07/10] Issue #32: Make init work without an existing .ahoy.yml file. * Clean up the output of the logger and remove the timestamps. * Update the tests when there isn't an .ahoy.yml file. * Update logic for help text situations. --- ahoy.go | 42 ++++++++++++++++++++++++++++++++++------- tests/no-ahoy-file.bats | 16 ++++++++-------- tests/simple.bats | 5 +++-- 3 files changed, 46 insertions(+), 17 deletions(-) diff --git a/ahoy.go b/ahoy.go index 1746ab8..54c6d72 100644 --- a/ahoy.go +++ b/ahoy.go @@ -47,9 +47,12 @@ var version string //Complete command: `go build -ldflags "-X main.version=$VERSION"` func logger(errType string, text string) { errText := "" + // Disable the flags which add date and time for instance. + log.SetFlags(0) + if (errType == "error") || (errType == "fatal") || (verbose == true) { - errText = "AHOY! [" + errType + "] ==> " + text + "\n" - log.Print(errText) + errText = "[" + errType + "] " + text + "\n" + log.Println(errText) } if errType == "fatal" { os.Exit(1) @@ -258,14 +261,31 @@ func BashComplete(c *cli.Context) { } } -// This is the application wide default action, for when no arguments are passed. +// This is the application wide default action, for when no flags or arguments +// are passed or when a command doesn't exist. +// Looks like -f flag still works through here though. func NoArgsAction(c *cli.Context) { - if c.Bool("help") { - cli.ShowAppHelp(c) + args := c.Args() + if len(args) > 0 { + msg := "Command not found for '" + strings.Join(args, " ") + "'" + logger("fatal", msg) + } + + cli.ShowAppHelp(c) + + if sourcefile == "" { + logger("fatal", "No .ahoy.yml found. You can use 'ahoy init' to download an example.") } + + if !c.Bool("help") || !c.Bool("version") { + logger("fatal", "Missing flag or argument.") + } + + // Looks like we never reach here. + fmt.Println("ERROR: NoArg Action ") } -// This runs before every command so arguments must be passed. +// This runs before every command so arguments or flags must be passed func BeforeCommand(c *cli.Context) error { args := c.Args() if c.Bool("version") { @@ -275,8 +295,10 @@ func BeforeCommand(c *cli.Context) error { if c.Bool("help") { if len(args) > 0 { cli.ShowCommandHelp(c, args.First()) - return errors.New("don't continue with commands") + } else { + cli.ShowAppHelp(c) } + return errors.New("don't continue with commands") } //fmt.Printf("%+v\n", args) return nil @@ -297,6 +319,12 @@ func setupApp(localArgs []string) *cli.App { if sourcefile, err := getConfigPath(sourcefile); err == nil { sourcedir = filepath.Dir(sourcefile) + // If we don't have a sourcefile, then just supply the default commands. + if sourcefile == "" && true { + app.Commands = addDefaultCommands(app.Commands) + app.Run(os.Args) + os.Exit(0) + } config, _ := getConfig(sourcefile) app.Commands = getCommands(config) app.Commands = addDefaultCommands(app.Commands) diff --git a/tests/no-ahoy-file.bats b/tests/no-ahoy-file.bats index a18177a..ba7eb5c 100644 --- a/tests/no-ahoy-file.bats +++ b/tests/no-ahoy-file.bats @@ -8,18 +8,18 @@ teardown() { mv tmp.ahoy.yml .ahoy.yml } -@test "run ahoy withough a command and without a .ahoy.yml file" { - result="$(./ahoy)" - echo "$result" - [ "$result" -eq 4 ] +@test "run ahoy without a command and without a .ahoy.yml file" { + run ./ahoy + [ $status -eq 1 ] + [ "${lines[-1]}" == "[fatal] No .ahoy.yml found. You can use 'ahoy init' to download an example." ] } @test "run an ahoy command without a .ahoy.yml file" { - result="$(./ahoy something)" - [ "$result" -eq 4 ] + run ./ahoy something + [ "$output" == "[fatal] Command not found for 'something'" ] } @test "run ahoy init without a .ahoy.yml file" { - result="$(./ahoy init)" - [ "$result" -eq 4 ] + run ./ahoy init + [ "${lines[-1]}" == "example.ahoy.yml downloaded to the current directory. You can customize it to suit your needs!" ] } diff --git a/tests/simple.bats b/tests/simple.bats index 3523307..e796aac 100644 --- a/tests/simple.bats +++ b/tests/simple.bats @@ -3,8 +3,9 @@ @test "display help text when no arguments are passed." { run ./ahoy -f testdata/simple.ahoy.yml # Should throw an error. - [ "${#lines[@]}" -gt 14 ] - [ $status -eq 1 ] + [ $status -ne 0 ] + echo "$output" + [ "${#lines[@]}" -gt 10 ] } @test "run a simple ahoy command: echo" { From ce77a4bfe8afddfab1f50fd0d18d974f2562465f Mon Sep 17 00:00:00 2001 From: Frank Carey Date: Mon, 21 Nov 2016 20:46:06 -0500 Subject: [PATCH 08/10] Update some functions to return errors instead of handling the logging themselves so they can be properly tested without having to use panic(). --- ahoy.go | 30 +++++++++++++++++++----------- ahoy_test.go | 13 +++++-------- 2 files changed, 24 insertions(+), 19 deletions(-) diff --git a/ahoy.go b/ahoy.go index 54c6d72..f62f43d 100644 --- a/ahoy.go +++ b/ahoy.go @@ -61,18 +61,20 @@ func logger(errType string, text string) { func getConfigPath(sourcefile string) (string, error) { var err error + var config = "" // If a specific source file was set, then try to load it directly. if sourcefile != "" { if _, err := os.Stat(sourcefile); err == nil { return sourcefile, err } - logger("fatal", "An ahoy config file was specified using -f to be at "+sourcefile+" but couldn't be found. Check your path.") + err = errors.New("An ahoy config file was specified using -f to be at " + sourcefile + " but couldn't be found. Check your path.") + return config, err } dir, err := os.Getwd() if err != nil { - log.Fatal(err) + return config, err } for dir != "/" && err == nil { ymlpath := filepath.Join(dir, ".ahoy.yml") @@ -88,23 +90,24 @@ func getConfigPath(sourcefile string) (string, error) { } func getConfig(sourcefile string) (Config, error) { - + var config = Config{} yamlFile, err := ioutil.ReadFile(sourcefile) if err != nil { - logger("fatal", "An ahoy config file couldn't be found in your path. You can create an example one by using 'ahoy init'.") + 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 } - var config Config // Extract the yaml file into the config varaible. err = yaml.Unmarshal(yamlFile, &config) if err != nil { - panic(err) + return config, err } // All ahoy files (and imports) must specify the ahoy version. // This is so we can support backwards compatability in the future. if config.AhoyAPI != "v2" { - logger("fatal", "Ahoy only supports API version 'v2', but '"+config.AhoyAPI+"' given in "+sourcefile) + err = errors.New("Ahoy only supports API version 'v2', but '" + config.AhoyAPI + "' given in " + sourcefile) + return config, err } return config, err @@ -261,7 +264,7 @@ func BashComplete(c *cli.Context) { } } -// This is the application wide default action, for when no flags or arguments +// NoArgsAction is the application wide default action, for when no flags or arguments // are passed or when a command doesn't exist. // Looks like -f flag still works through here though. func NoArgsAction(c *cli.Context) { @@ -285,7 +288,7 @@ func NoArgsAction(c *cli.Context) { fmt.Println("ERROR: NoArg Action ") } -// This runs before every command so arguments or flags must be passed +// BeforeCommand runs before every command so arguments or flags must be passed func BeforeCommand(c *cli.Context) error { args := c.Args() if c.Bool("version") { @@ -317,7 +320,9 @@ func setupApp(localArgs []string) *cli.App { app.BashComplete = BashComplete overrideFlags(app) - if sourcefile, err := getConfigPath(sourcefile); err == nil { + if sourcefile, err := getConfigPath(sourcefile); err != nil { + logger("fatal", err.Error()) + } else { sourcedir = filepath.Dir(sourcefile) // If we don't have a sourcefile, then just supply the default commands. if sourcefile == "" && true { @@ -325,7 +330,10 @@ func setupApp(localArgs []string) *cli.App { app.Run(os.Args) os.Exit(0) } - config, _ := getConfig(sourcefile) + config, err := getConfig(sourcefile) + if err != nil { + logger("fatal", err.Error()) + } app.Commands = getCommands(config) app.Commands = addDefaultCommands(app.Commands) if config.Usage != "" { diff --git a/ahoy_test.go b/ahoy_test.go index 8c0ecb9..eef0656 100644 --- a/ahoy_test.go +++ b/ahoy_test.go @@ -238,14 +238,11 @@ func TestGetConfigPath(t *testing.T) { // TODO: Passing directory should return default } -func TestGetConfigPathPanicOnBogusPath(t *testing.T) { - defer func() { - if r := recover(); r == nil { - t.Error("getConfigPath did not fail when passed a bogus path.") - } - }() - - getConfigPath("~/bogus/path") +func TestGetConfigPathErrorOnBogusPath(t *testing.T) { + _, err := getConfigPath("~/bogus/path") + if err == nil { + t.Error("getConfigPath did not fail when passed a bogus path.") + } } func appRun(args []string) (string, error) { From 623e2f0d4fac9818646b84bf944988933df07c1f Mon Sep 17 00:00:00 2001 From: Frank Carey Date: Mon, 21 Nov 2016 20:50:08 -0500 Subject: [PATCH 09/10] go lint apprently doesn't like the following: * error strings should not be capitalized or end with punctuation or a newline --- ahoy.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ahoy.go b/ahoy.go index f62f43d..e656b00 100644 --- a/ahoy.go +++ b/ahoy.go @@ -93,7 +93,7 @@ func getConfig(sourcefile string) (Config, error) { var config = Config{} yamlFile, err := ioutil.ReadFile(sourcefile) 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'.") + 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 } From 6cf6962a14af1b1380e047abb9a350992c430167 Mon Sep 17 00:00:00 2001 From: Frank Carey Date: Mon, 21 Nov 2016 22:17:05 -0500 Subject: [PATCH 10/10] Refactor to use AhoyConf as the place where global config is stored. We were having scope issues with sourcefile. --- .ahoy.yml | 2 +- ahoy.go | 45 ++++++++++++++++++++++++----------------- ahoy_test.go | 4 ++-- flag.go | 2 +- tests/no-ahoy-file.bats | 3 ++- tests/simple.bats | 3 ++- 6 files changed, 35 insertions(+), 24 deletions(-) diff --git a/.ahoy.yml b/.ahoy.yml index cf331eb..023b663 100644 --- a/.ahoy.yml +++ b/.ahoy.yml @@ -9,11 +9,11 @@ commands: bats: usage: "Run the bats bash testing command." cmd: | - ahoy build bats tests test: usage: Run automated tests cmd: | + ahoy build FAIL=false TESTS=( 'go vet' diff --git a/ahoy.go b/ahoy.go index e656b00..fe64aed 100644 --- a/ahoy.go +++ b/ahoy.go @@ -35,25 +35,30 @@ type Command struct { } var app *cli.App -var sourcedir string var sourcefile string var args []string var verbose bool var bashCompletion bool -var version string - //The build version can be set using the go linker flag `-ldflags "-X main.version=$VERSION"` //Complete command: `go build -ldflags "-X main.version=$VERSION"` +var version string + +// AhoyConf stores the global config. +var AhoyConf struct { + srcDir string + srcFile string +} + func logger(errType string, text string) { errText := "" // Disable the flags which add date and time for instance. log.SetFlags(0) - - if (errType == "error") || (errType == "fatal") || (verbose == true) { + if errType != "debug" { errText = "[" + errType + "] " + text + "\n" log.Println(errText) } + if errType == "fatal" { os.Exit(1) } @@ -80,18 +85,19 @@ func getConfigPath(sourcefile string) (string, error) { ymlpath := filepath.Join(dir, ".ahoy.yml") //log.Println(ymlpath) if _, err := os.Stat(ymlpath); err == nil { - //log.Println("found: ", ymlpath ) + logger("debug", "Found .ahoy.yml at "+ymlpath) return ymlpath, err } // Chop off the last part of the path. dir = path.Dir(dir) } + logger("debug", "Can't find a .ahoy.yml file.") return "", err } -func getConfig(sourcefile string) (Config, error) { +func getConfig(file string) (Config, error) { var config = Config{} - yamlFile, err := ioutil.ReadFile(sourcefile) + yamlFile, err := ioutil.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 @@ -124,7 +130,7 @@ func getSubCommands(includes []string) []cli.Command { continue } if include[0] != "/"[0] || include[0] != "~"[0] { - include = filepath.Join(sourcedir, include) + include = filepath.Join(AhoyConf.srcDir, include) } if _, err := os.Stat(include); err != nil { //Skipping files that cannot be loaded allows us to separate @@ -195,13 +201,11 @@ func runCommand(name string, c string) { cReplace := strings.Replace(c, "{{args}}", strings.Join(args, " "), -1) - dir := sourcedir - if verbose { log.Println("===> AHOY", name, "from", sourcefile, ":", cReplace) } cmd := exec.Command("bash", "-c", cReplace) - cmd.Dir = dir + cmd.Dir = AhoyConf.srcDir cmd.Stdout = os.Stdout cmd.Stdin = os.Stdin cmd.Stderr = os.Stderr @@ -245,6 +249,7 @@ func addDefaultCommands(commands []cli.Command) []cli.Command { //TODO Move these to flag.go? func init() { + logger("debug", "init()") flag.StringVar(&sourcefile, "f", "", "specify the sourcefile") flag.BoolVar(&bashCompletion, "generate-bash-completion", false, "") flag.BoolVar(&verbose, "verbose", false, "") @@ -252,6 +257,7 @@ func init() { // BashComplete prints the list of subcommands as the default app completion method func BashComplete(c *cli.Context) { + logger("debug", "BashComplete()") if sourcefile != "" { log.Println(sourcefile) @@ -276,8 +282,8 @@ func NoArgsAction(c *cli.Context) { cli.ShowAppHelp(c) - if sourcefile == "" { - logger("fatal", "No .ahoy.yml found. You can use 'ahoy init' to download an example.") + if AhoyConf.srcFile == "" { + logger("error", "No .ahoy.yml found. You can use 'ahoy init' to download an example.") } if !c.Bool("help") || !c.Bool("version") { @@ -308,6 +314,7 @@ func BeforeCommand(c *cli.Context) error { } func setupApp(localArgs []string) *cli.App { + var err error initFlags(localArgs) // cli stuff app = cli.NewApp() @@ -320,17 +327,18 @@ func setupApp(localArgs []string) *cli.App { app.BashComplete = BashComplete overrideFlags(app) - if sourcefile, err := getConfigPath(sourcefile); err != nil { + AhoyConf.srcFile, err = getConfigPath(sourcefile) + if err != nil { logger("fatal", err.Error()) } else { - sourcedir = filepath.Dir(sourcefile) + AhoyConf.srcDir = filepath.Dir(AhoyConf.srcFile) // If we don't have a sourcefile, then just supply the default commands. - if sourcefile == "" && true { + if AhoyConf.srcFile == "" { app.Commands = addDefaultCommands(app.Commands) app.Run(os.Args) os.Exit(0) } - config, err := getConfig(sourcefile) + config, err := getConfig(AhoyConf.srcFile) if err != nil { logger("fatal", err.Error()) } @@ -366,6 +374,7 @@ VERSION: } func main() { + logger("debug", "main()") app = setupApp(os.Args[1:]) app.Run(os.Args) } diff --git a/ahoy_test.go b/ahoy_test.go index eef0656..b42d9c6 100644 --- a/ahoy_test.go +++ b/ahoy_test.go @@ -40,7 +40,7 @@ func TestGetCommands(t *testing.T) { func TestGetSubCommand(t *testing.T) { // Since we're not running the app directly, sourcedir doesn't get reset, so // we need to reset it ourselves. TODO: Remove these globals somehow. - sourcedir = "" + AhoyConf.srcDir = "" // When empty return empty list of commands. @@ -121,7 +121,7 @@ func TestGetSubCommand(t *testing.T) { }) if len(actual) != 1 { - t.Error("Sourcedir:", sourcedir) + t.Error("Sourcedir:", AhoyConf.srcDir) t.Error("Failed: expect that two commands with the same name get merged into one.", actual) } diff --git a/flag.go b/flag.go index 24ff734..9bd7158 100644 --- a/flag.go +++ b/flag.go @@ -43,7 +43,7 @@ func initFlags(incomingFlags []string) { // Reset the sourcedir for when we're testing. Otherwise the global state // is preserved between the tests. - sourcedir = "" + AhoyConf.srcDir = "" // Grab the global flags first ourselves so we can customize the yaml file loaded. // Flags are only parsed once, so we need to do this before cli has the chance to? diff --git a/tests/no-ahoy-file.bats b/tests/no-ahoy-file.bats index ba7eb5c..60aa2db 100644 --- a/tests/no-ahoy-file.bats +++ b/tests/no-ahoy-file.bats @@ -11,7 +11,8 @@ teardown() { @test "run ahoy without a command and without a .ahoy.yml file" { run ./ahoy [ $status -eq 1 ] - [ "${lines[-1]}" == "[fatal] No .ahoy.yml found. You can use 'ahoy init' to download an example." ] + [ "${lines[-2]}" == "[error] No .ahoy.yml found. You can use 'ahoy init' to download an example." ] + [ "${lines[-1]}" == "[fatal] Missing flag or argument." ] } @test "run an ahoy command without a .ahoy.yml file" { diff --git a/tests/simple.bats b/tests/simple.bats index e796aac..adcab3a 100644 --- a/tests/simple.bats +++ b/tests/simple.bats @@ -1,11 +1,12 @@ #!/usr/bin/env bats -@test "display help text when no arguments are passed." { +@test "display help text and fatal error when no arguments are passed." { run ./ahoy -f testdata/simple.ahoy.yml # Should throw an error. [ $status -ne 0 ] echo "$output" [ "${#lines[@]}" -gt 10 ] + [ "${lines[-1]}" == "[fatal] Missing flag or argument." ] } @test "run a simple ahoy command: echo" {