Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(run): updagraded cobra version and added scripts completion to run command #173

Merged
merged 3 commits into from
Oct 20, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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