Skip to content

Commit

Permalink
Merge pull request #173 from danielsuguimoto/run_completion
Browse files Browse the repository at this point in the history
feat(run): updagraded cobra version and added scripts completion to run command
  • Loading branch information
fabriciojs authored Oct 20, 2020
2 parents e8bd1b1 + 4f635a4 commit e2dde50
Show file tree
Hide file tree
Showing 19 changed files with 309 additions and 60 deletions.
11 changes: 5 additions & 6 deletions cmd/completion.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,29 +51,28 @@ Bash:
$ source <(kool completion bash)
# To load completions for each session, execute once:
#### To load completions for each session, execute once:
Linux:
$ kool completion bash > /etc/bash_completion.d/kool
MacOS:
$ kool completion bash > /usr/local/etc/bash_completion.d/kool
Zsh:
# If shell completion is not already enabled in your environment you will need
# to enable it. You can execute the following once:
#### If shell completion is not already enabled in your environment you will need to enable it. You can execute the following once:
$ echo "autoload -U compinit; compinit" >> ~/.zshrc
# To load completions for each session, execute once:
#### To load completions for each session, execute once:
$ kool completion zsh > "${fpath[1]}/_kool"
# You will need to start a new shell for this setup to take effect.
#### You will need to start a new shell for this setup to take effect.
Fish:
$ kool completion fish | source
# To load completions for each session, execute once:
#### To load completions for each session, execute once:
$ kool completion fish > ~/.config/fish/completions/kool.fish
`,
DisableFlagsInUseLine: true,
Expand Down
15 changes: 13 additions & 2 deletions cmd/parser/fake_parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package parser

import (
"kool-dev/kool/cmd/builder"
"strings"
)

// FakeParser implements all fake behaviors for using parser in tests.
Expand Down Expand Up @@ -32,9 +33,19 @@ func (f *FakeParser) Parse(script string) (commands []builder.Command, err error
}

// ParseAvailableScripts implements fake ParseAvailableScripts behavior
func (f *FakeParser) ParseAvailableScripts() (scripts []string, err error) {
func (f *FakeParser) ParseAvailableScripts(filter string) (scripts []string, err error) {
f.CalledParseAvailableScripts = true
scripts = f.MockScripts

if filter == "" {
scripts = f.MockScripts
} else {
for _, script := range f.MockScripts {
if strings.HasPrefix(script, filter) {
scripts = append(scripts, script)
}
}
}

err = f.MockParseAvailableScriptsError
return
}
16 changes: 14 additions & 2 deletions cmd/parser/fake_parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,23 @@ func TestFakeParser(t *testing.T) {

f.MockScripts = []string{"script"}

scripts, _ := f.ParseAvailableScripts()
scripts, _ := f.ParseAvailableScripts("")

if !f.CalledParseAvailableScripts || len(scripts) != 1 || scripts[0] != "script" {
t.Error("failed to use mocked ParseAvailableScripts function on FakeParser")
}

scripts, _ = f.ParseAvailableScripts("scr")

if len(scripts) != 1 || scripts[0] != "script" {
t.Error("failed to use mocked ParseAvailableScripts function on FakeParser")
}

scripts, _ = f.ParseAvailableScripts("invalid")

if len(scripts) != 0 {
t.Error("failed to use mocked ParseAvailableScripts function on FakeParser")
}
}

func TestFakeFailedParser(t *testing.T) {
Expand All @@ -50,7 +62,7 @@ func TestFakeFailedParser(t *testing.T) {
t.Error("failed to use mocked failing Parse function on FakeParser")
}

_, err = f.ParseAvailableScripts()
_, err = f.ParseAvailableScripts("")

if !f.CalledParseAvailableScripts || err == nil {
t.Error("failed to use mocked failing ParseAvailableScripts function on FakeParser")
Expand Down
7 changes: 4 additions & 3 deletions cmd/parser/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@ import (
"os"
"path"
"sort"
"strings"
)

// Parser defines the functions required for handling kool.yml files.
type Parser interface {
AddLookupPath(string) error
Parse(string) ([]builder.Command, error)
ParseAvailableScripts() ([]string, error)
ParseAvailableScripts(string) ([]string, error)
}

// DefaultParser implements all default behavior for using kool.yml files.
Expand Down Expand Up @@ -97,7 +98,7 @@ func (p *DefaultParser) Parse(script string) (commands []builder.Command, err er
}

// ParseAvailableScripts parse all available scripts
func (p *DefaultParser) ParseAvailableScripts() (scripts []string, err error) {
func (p *DefaultParser) ParseAvailableScripts(filter string) (scripts []string, err error) {
var (
koolFile string
parsedFile *KoolYaml
Expand All @@ -117,7 +118,7 @@ func (p *DefaultParser) ParseAvailableScripts() (scripts []string, err error) {
}

for script := range parsedFile.Scripts {
if !foundScripts[script] {
if !foundScripts[script] && (filter == "" || strings.HasPrefix(script, filter)) {
scripts = append(scripts, script)
}

Expand Down
33 changes: 30 additions & 3 deletions cmd/parser/parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ func TestDefaultParser(t *testing.T) {
}
}

func TestParserAddLooupPath(t *testing.T) {
func TestParserAddLookupPath(t *testing.T) {
var (
p Parser = NewParser()
err error
Expand Down Expand Up @@ -83,7 +83,7 @@ func TestParserParseAvailableScripts(t *testing.T) {
err error
)

if _, err = p.ParseAvailableScripts(); err == nil {
if _, err = p.ParseAvailableScripts(""); err == nil {
t.Error("expecting 'kool.yml not found' error, got none")
}

Expand All @@ -94,11 +94,38 @@ func TestParserParseAvailableScripts(t *testing.T) {
workDir, _ := os.Getwd()
_ = p.AddLookupPath(path.Join(workDir, "testing_files"))

if scripts, err = p.ParseAvailableScripts(); err != nil {
if scripts, err = p.ParseAvailableScripts(""); err != nil {
t.Errorf("unexpected error; error: %s", err)
}

if len(scripts) != 1 || scripts[0] != "testing" {
t.Error("failed to get all scripts from kool.yml")
}
}

func TestParserParseAvailableScriptsFilter(t *testing.T) {
var (
p Parser = NewParser()
scripts []string
err error
)

workDir, _ := os.Getwd()
_ = p.AddLookupPath(path.Join(workDir, "testing_files"))

if scripts, err = p.ParseAvailableScripts("tes"); err != nil {
t.Errorf("unexpected error; error: %s", err)
}

if len(scripts) != 1 || scripts[0] != "testing" {
t.Error("failed to get filtered scripts from kool.yml")
}

if scripts, err = p.ParseAvailableScripts("invalidFilter"); err != nil {
t.Errorf("unexpected error; error: %s", err)
}

if len(scripts) != 0 {
t.Error("failed to get filtered scripts from kool.yml")
}
}
23 changes: 22 additions & 1 deletion cmd/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,13 @@ func NewRunCommand(run *KoolRun) (runCmd *cobra.Command) {
Short: "Runs a custom command defined at kool.yaml in the working directory or in the kool folder of the user's home directory",
Args: cobra.MinimumNArgs(1),
Run: DefaultCommandRunFunction(run),
ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
if len(args) != 0 {
return nil, cobra.ShellCompDirectiveNoFileComp
}

return compListScripts(toComplete, run), cobra.ShellCompDirectiveNoFileComp
},
}

// after a non-flag arg, stop parsing flags
Expand All @@ -125,7 +132,7 @@ func getRunUsageFunc(run *KoolRun, originalUsageText string) func(*cobra.Command
// look for kool.yml on kool folder within user home directory
_ = run.parser.AddLookupPath(path.Join(run.envStorage.Get("HOME"), "kool"))

if scripts, err = run.parser.ParseAvailableScripts(); err != nil {
if scripts, err = run.parser.ParseAvailableScripts(""); err != nil {
if run.envStorage.IsTrue("KOOL_VERBOSE") {
run.Println("$ got an error trying to add available scripts to command usage template; error:", err.Error())
}
Expand All @@ -146,3 +153,17 @@ func getRunUsageFunc(run *KoolRun, originalUsageText string) func(*cobra.Command
return
}
}

func compListScripts(toComplete string, run *KoolRun) (scripts []string) {
var err error
// look for kool.yml on current working directory
_ = run.parser.AddLookupPath(run.envStorage.Get("PWD"))
// look for kool.yml on kool folder within user home directory
_ = run.parser.AddLookupPath(path.Join(run.envStorage.Get("HOME"), "kool"))

if scripts, err = run.parser.ParseAvailableScripts(toComplete); err != nil {
return nil
}

return
}
45 changes: 45 additions & 0 deletions cmd/run_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -283,3 +283,48 @@ func TestNewRunCommandFailingUsageTemplate(t *testing.T) {
t.Errorf("expecting message '%s', got '%s'", expected, output)
}
}

func TestNewRunCommandCompletion(t *testing.T) {
var scripts []string
f := newFakeKoolRun([]builder.Command{}, nil)
f.parser.(*parser.FakeParser).MockScripts = []string{"testing_script"}
cmd := NewRunCommand(f)

scripts, _ = cmd.ValidArgsFunction(cmd, []string{}, "")

if len(scripts) != 1 || scripts[0] != "testing_script" {
t.Errorf("expecting suggestions [testing_script], got %v", scripts)
}

scripts, _ = cmd.ValidArgsFunction(cmd, []string{}, "tes")

if len(scripts) != 1 || scripts[0] != "testing_script" {
t.Errorf("expecting suggestions [testing_script], got %v", scripts)
}

scripts, _ = cmd.ValidArgsFunction(cmd, []string{}, "invalid")

if len(scripts) != 0 {
t.Errorf("expecting no suggestion, got %v", scripts)
}

scripts, _ = cmd.ValidArgsFunction(cmd, []string{"testing_script"}, "")

if scripts != nil {
t.Errorf("expecting no suggestion, got %v", scripts)
}
}

func TestNewRunCommandFailingCompletion(t *testing.T) {
var scripts []string
f := newFakeKoolRun([]builder.Command{}, nil)
f.parser.(*parser.FakeParser).MockScripts = []string{"testing_script"}
f.parser.(*parser.FakeParser).MockParseAvailableScriptsError = errors.New("parsing error")
cmd := NewRunCommand(f)

scripts, _ = cmd.ValidArgsFunction(cmd, []string{}, "")

if scripts != nil {
t.Errorf("expecting no suggestion, got %v", scripts)
}
}
11 changes: 5 additions & 6 deletions docs/4-Commands/kool-completion.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,29 +10,28 @@ Bash:

$ source <(kool completion bash)

# To load completions for each session, execute once:
#### To load completions for each session, execute once:
Linux:
$ kool completion bash > /etc/bash_completion.d/kool
MacOS:
$ kool completion bash > /usr/local/etc/bash_completion.d/kool

Zsh:

# If shell completion is not already enabled in your environment you will need
# to enable it. You can execute the following once:
#### If shell completion is not already enabled in your environment you will need to enable it. You can execute the following once:

$ echo "autoload -U compinit; compinit" >> ~/.zshrc

# To load completions for each session, execute once:
#### To load completions for each session, execute once:
$ kool completion zsh > "${fpath[1]}/_kool"

# You will need to start a new shell for this setup to take effect.
#### You will need to start a new shell for this setup to take effect.

Fish:

$ kool completion fish | source

# To load completions for each session, execute once:
#### To load completions for each session, execute once:
$ kool completion fish > ~/.config/fish/completions/kool.fish


Expand Down
4 changes: 0 additions & 4 deletions docs/4-Commands/kool-exec.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,6 @@

Execute a command within a running service container

### Synopsis

Execute a command within a running service container

```
kool exec [options] [service] [command] [flags]
```
Expand Down
4 changes: 0 additions & 4 deletions docs/4-Commands/kool-info.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,6 @@

Prints out information about kool setup (like environment variables)

### Synopsis

Prints out information about kool setup (like environment variables)

```
kool info [flags]
```
Expand Down
4 changes: 0 additions & 4 deletions docs/4-Commands/kool-init.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,6 @@

Initialize kool preset in the current working directory

### Synopsis

Initialize kool preset in the current working directory

```
kool init [PRESET] [flags]
```
Expand Down
4 changes: 0 additions & 4 deletions docs/4-Commands/kool-logs.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,6 @@

Displays log output from services.

### Synopsis

Displays log output from services.

```
kool logs [options] [service...] [flags]
```
Expand Down
4 changes: 0 additions & 4 deletions docs/4-Commands/kool-restart.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,6 @@

Restart containers - the same as stop followed by start.

### Synopsis

Restart containers - the same as stop followed by start.

```
kool restart
```
Expand Down
4 changes: 0 additions & 4 deletions docs/4-Commands/kool-run.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,6 @@

Runs a custom command defined at kool.yaml in the working directory or in the kool folder of the user's home directory

### Synopsis

Runs a custom command defined at kool.yaml in the working directory or in the kool folder of the user's home directory

```
kool run [SCRIPT] [flags]
```
Expand Down
4 changes: 0 additions & 4 deletions docs/4-Commands/kool-start.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,6 @@

Start the specified Kool environment containers. If no service is specified, start all.

### Synopsis

Start the specified Kool environment containers. If no service is specified, start all.

```
kool start [SERVICE]
```
Expand Down
Loading

0 comments on commit e2dde50

Please sign in to comment.