Skip to content

Commit

Permalink
Merge e10ea7e into 4d7176e
Browse files Browse the repository at this point in the history
  • Loading branch information
fabriciojs committed Feb 1, 2021
2 parents 4d7176e + e10ea7e commit 76a3033
Show file tree
Hide file tree
Showing 7 changed files with 80 additions and 6 deletions.
31 changes: 30 additions & 1 deletion cmd/parser/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,31 @@ package parser

import (
"errors"
"kool-dev/kool/cmd/builder"
"fmt"
"os"
"path"
"sort"
"strings"

"kool-dev/kool/cmd/builder"
)

// ErrPossibleTypo implements error interface and can be used
// to determine specific situations of not-found scripts but
// where similar names exist, indicating a possible typo
type ErrPossibleTypo struct {
similars []string
}

// Error formats a default string with the similar names found
func (e *ErrPossibleTypo) Error() string {
if len(e.similars) == 1 {
return fmt.Sprintf("did you mean '%s'?", e.similars[0])
}

return fmt.Sprintf("did you mean one of ['%s']?", strings.Join(e.similars, "', '"))
}

// Parser defines the functions required for handling kool.yml files.
type Parser interface {
AddLookupPath(string) error
Expand Down Expand Up @@ -67,6 +85,7 @@ func (p *DefaultParser) Parse(script string) (commands []builder.Command, err er
parsedFile *KoolYaml
found bool
previouslyFound bool
similarScripts []string
)

if len(p.targetFiles) == 0 {
Expand All @@ -92,8 +111,18 @@ func (p *DefaultParser) Parse(script string) (commands []builder.Command, err er
// in another file! let's warn about that
err = ErrMultipleDefinedScript
}
} else {
// we could not find the intented script so let's check for a typo
if foundSimilar, similars := parsedFile.GetSimilars(script); foundSimilar {
similarScripts = append(similarScripts, similars...)
}
}
}

if err == nil && len(commands) == 0 && similarScripts != nil && len(similarScripts) > 0 {
err = &ErrPossibleTypo{similarScripts}
}

return
}

Expand Down
21 changes: 21 additions & 0 deletions cmd/parser/parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,24 @@ import (
"kool-dev/kool/cmd/builder"
"os"
"path"
"strings"
"testing"
)

func TestErrPossibleTypo(t *testing.T) {
err := &ErrPossibleTypo{[]string{"script1"}}

if !strings.Contains(err.Error(), "script1") {
t.Errorf("unexpected error message: %s", err.Error())
}

err = &ErrPossibleTypo{[]string{"script1", "script2"}}

if !strings.Contains(err.Error(), "script1") || !strings.Contains(err.Error(), "script2") {
t.Errorf("unexpected error message [2]: %s", err.Error())
}
}

func TestDefaultParser(t *testing.T) {
var p Parser = NewParser()

Expand Down Expand Up @@ -67,6 +82,12 @@ func TestParserParse(t *testing.T) {
t.Error("failed to parse testing kool.yml")
}

if _, err = p.Parse("testin"); err == nil {
t.Error("unexpected non-error on typo")
} else if _, foundSimilar := err.(*ErrPossibleTypo); !foundSimilar {
t.Errorf("unexpected error; should be ErrPossibleTypo; got %s", err)
}

if commands, err = p.Parse("invalid"); err != nil {
t.Errorf("unexpected error; error: %s", err)
}
Expand Down
17 changes: 17 additions & 0 deletions cmd/parser/yml.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,14 @@ import (
"kool-dev/kool/cmd/builder"
"os"

"github.com/agnivade/levenshtein"
"gopkg.in/yaml.v2"
)

// SimilarThreshold represents the minimal Levenshteindistance of two
// script names for them to be considered similarss
const SimilarThreshold int = 2

type yamlMarshalFnType func(interface{}) ([]byte, error)

// KoolYaml holds the structure for parsing the custom commands file
Expand Down Expand Up @@ -70,6 +75,18 @@ func (y *KoolYaml) HasScript(script string) (has bool) {
return
}

// GetSimilars checks for scripts with similar name.
func (y *KoolYaml) GetSimilars(script string) (has bool, similars []string) {
var name string
for name = range y.Scripts {
if levenshtein.ComputeDistance(name, script) < SimilarThreshold {
has = true
similars = append(similars, name)
}
}
return
}

// ParseCommands parsed the given script from kool.yml file onto a list
// of commands parsed.
func (y *KoolYaml) ParseCommands(script string) (commands []builder.Command, err error) {
Expand Down
4 changes: 4 additions & 0 deletions cmd/parser/yml_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ func TestParseKoolYaml(t *testing.T) {
return
}

if hasSimilars, similars := parsed.GetSimilars("single-lne"); !hasSimilars || len(similars) != 1 {
t.Errorf("unexpected return on GetSimilars %v - %v", hasSimilars, similars)
}

if cmds, err = parsed.ParseCommands("single-line"); err != nil {
t.Errorf("failed to parse proper single-line; error: %s", err)
return
Expand Down
8 changes: 3 additions & 5 deletions cmd/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,22 +49,20 @@ func NewKoolRun() *KoolRun {
// Execute runs the run logic with incoming arguments.
func (r *KoolRun) Execute(originalArgs []string) (err error) {
var (
script string
args []string
script string = originalArgs[0]
args []string = originalArgs[1:]
)

// look for kool.yml on current working directory
_ = r.parser.AddLookupPath(r.envStorage.Get("PWD"))
// look for kool.yml on kool folder within user home directory
_ = r.parser.AddLookupPath(path.Join(r.envStorage.Get("HOME"), "kool"))

script = originalArgs[0]
args = originalArgs[1:]

if r.commands, err = r.parser.Parse(script); err != nil {
if parser.IsMultipleDefinedScriptError(err) {
// we should just warn the user about multiple finds for the script
r.Warning("Attention: the script was found in more than one kool.yml file")
err = nil
} else {
return
}
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ go 1.14

require (
github.com/AlecAivazis/survey/v2 v2.1.1
github.com/agnivade/levenshtein v1.1.0
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6 // indirect
github.com/blang/semver v3.5.1+incompatible
github.com/creack/pty v1.1.11
Expand Down
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,13 @@ github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tN
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
github.com/agnivade/levenshtein v1.1.0 h1:n6qGwyHG61v3ABce1rPVZklEYRT8NFpCMrpZdBUbYGM=
github.com/agnivade/levenshtein v1.1.0/go.mod h1:veldBMzWxcCG2ZvUTKD2kJNRdCk5hVbJomOvKkmgYbo=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE=
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
Expand Down Expand Up @@ -95,6 +98,7 @@ github.com/daviddengcn/go-colortext v0.0.0-20160507010035-511bcaf42ccd h1:uVsMph
github.com/daviddengcn/go-colortext v0.0.0-20160507010035-511bcaf42ccd/go.mod h1:dv4zxwHi5C/8AeI+4gX4dCWOIvNi7I6JCSX0HvlKPgE=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA=
github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug=
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96 h1:cenwrSVm+Z7QLSV/BsnenAOcDXdX4cMv4wP0B/5QbPg=
Expand Down

0 comments on commit 76a3033

Please sign in to comment.