From 81ea74979ae6243808d45a12a03a18af16ab975e Mon Sep 17 00:00:00 2001 From: matfax Date: Sat, 5 Jan 2019 19:59:22 +0100 Subject: [PATCH] adding option to choose a different tag vector separator --- README.md | 18 ++++++++++++++++++ cmd/tuplip/exec.go | 11 ++++++++++- pkg/tupliplib/lib.go | 27 ++++++++++++++++++++------- pkg/tupliplib/lib_test.go | 12 ++++++++++++ 4 files changed, 60 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index f53e0ee..92254e6 100644 --- a/README.md +++ b/README.md @@ -176,3 +176,21 @@ echo "_:1.2.3" | tuplip exec addLatest 1.2.3 latest ``` + +### vectorSeparator + +`vectorSeparator` sets a different tag vector separator than the default space character. + +#### Example + +```bash +echo "something; fancy" | tuplip exec vectorSeparator=";" +``` + +#### Result + +```bash +something +fancy +fancy-something +``` diff --git a/cmd/tuplip/exec.go b/cmd/tuplip/exec.go index 8c7226e..d2402b0 100644 --- a/cmd/tuplip/exec.go +++ b/cmd/tuplip/exec.go @@ -29,6 +29,14 @@ func (c *ExecCommand) Run(args []string) int { if strings.Contains(lowerArg, "addlatest") { tuplip.AddLatest = true } + if strings.Contains(lowerArg, "vectorseparator") { + sepArg := strings.SplitAfter(arg, "=") + if len(sepArg) < 2 || len(sepArg[1]) == 0 { + fmt.Fprintln(os.Stderr, "warning: the given tag vector separator is invalid, falling back to space") + } else { + tuplip.Separator = sepArg[1] + } + } } return execute(tuplip) } @@ -49,7 +57,8 @@ func (c *ExecCommand) Help() string { "excludeMajor to exclude the major versions from the result set\n" + "excludeMinor to exclude the minor versions from the result set\n" + "excludeBase to exclude the base alias without version suffix from the result set\n" + - "addLatest to add an additional 'latest' tag to the result set\n" + "addLatest to add an additional 'latest' tag to the result set\n" + + "vectorSeparator=% to choose a different tag vector separator than the default space character\n" } // Synopsis gives a short description of the purpose. diff --git a/pkg/tupliplib/lib.go b/pkg/tupliplib/lib.go index 271798c..d6330a6 100644 --- a/pkg/tupliplib/lib.go +++ b/pkg/tupliplib/lib.go @@ -22,20 +22,26 @@ type Tuplip struct { ExcludeBase bool // AddLatest adds an additional 'latest' tag to the result set. AddLatest bool + // Separator to split the separate tag vector aliases. The default separator is single space. + Separator string } -// The separator that separates the alias form the semantic version. +// VersionSeparator is the separator that separates the alias form the semantic version. const VersionSeparator = ":" -// The alias for a wildcard dependency to build a base tag (i.e., semantic version without a prefix). +// WildcardDependency is the alias for a wildcard dependency to build a root tag vector +// (i.e., semantic version without a prefix). const WildcardDependency = "_" -// The separator that separates the digits of a semantic version. +// VersionDot is the separator that separates the digits of a semantic version. const VersionDot = "." -// The separator that separates the sub tags in a Docker tag. +// DockerTagSeparator is the separator that separates the sub tags in a Docker tag. const DockerTagSeparator = "-" +// VectorSeparator is the default tag vector separator. +const VectorSeparator = " " + // buildTag parses a semantic version with the given version digits. Optionally, prefix an alias tag. func (t Tuplip) buildTag(withBase bool, alias string, versionDigits ...uint64) (string, error) { var builder strings.Builder @@ -132,9 +138,16 @@ func (t Tuplip) nonEmpty(input string) bool { return input != "" } -// splitBySeparator separates the input string by an empty char. +// splitBySeparator separates the input string by the chosen character and trims superfluous spaces. func (t Tuplip) splitBySeparator(input string) (result []string) { - return strings.Split(input, " ") + if t.Separator == "" { + t.Separator = VectorSeparator + } + result = strings.Split(input, t.Separator) + for i, el := range result { + result[i] = strings.TrimSpace(el) + } + return } // packInSet packs a set as subset into a new set. @@ -162,7 +175,7 @@ func (t Tuplip) failOnEmpty(inputSet mapset.Set) (mapset.Set, error) { // join joins all subtags (i.e., elements of the given set) to all possible representations by building a cartesian // product of them. The subtags are separated by the given Docker separator. The subtags are ordered alphabetically -// to ensure that a base tag (i.e., a tag without an alias) is mentioned before alias tags. +// to ensure that a root tag vector (i.e., a tag without an alias) is mentioned before alias tags. func (t Tuplip) join(inputSet mapset.Set) (result mapset.Set) { result = mapset.NewSet() inputSlice := inputSet.ToSlice() diff --git a/pkg/tupliplib/lib_test.go b/pkg/tupliplib/lib_test.go index abd44d5..c91fd6e 100644 --- a/pkg/tupliplib/lib_test.go +++ b/pkg/tupliplib/lib_test.go @@ -92,6 +92,12 @@ func TestTuplipStream_FromReader(t *testing.T) { args: args{[]string{"_:2.0.0", "foo"}}, want: []string{"latest", "foo", "2", "2.0", "2.0.0", "2-foo", "2.0-foo", "2.0.0-foo"}, }, + { + name: "Wildcard Unary Tag With Long Version And a Different Separator", + t: Tuplip{Separator: ";"}, + args: args{[]string{" _:2.0.0; foo "}}, + want: []string{"foo", "2", "2.0", "2.0.0", "2-foo", "2.0-foo", "2.0.0-foo"}, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -391,6 +397,12 @@ func TestTuplip_splitBySeparator(t *testing.T) { args: args{"foo boo hoo"}, wantResult: []string{"foo", "boo", "hoo"}, }, + { + name: "Split Tuple With Different Separator", + t: Tuplip{Separator: ","}, + args: args{"foo, boo,hoo"}, + wantResult: []string{"foo", "boo", "hoo"}, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) {