From 13683f864664419e814c44ced7f381d496e74cd2 Mon Sep 17 00:00:00 2001 From: wuhuizuo Date: Tue, 29 Aug 2023 11:59:40 +0000 Subject: [PATCH 1/4] feat(funcs): add semver functions - semver.Version: new a SemVer struct. - semver.MatchConstraint: match in arg with semver constraint string. refer to: https://github.com/Masterminds/sprig/blob/master/semver.go --- funcs.go | 1 + funcs/semver.go | 40 +++++++++++++++++++++++++++++ funcs/semver_test.go | 60 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 101 insertions(+) create mode 100644 funcs/semver.go create mode 100644 funcs/semver_test.go diff --git a/funcs.go b/funcs.go index 8a665cdd5..efe7d6bcd 100644 --- a/funcs.go +++ b/funcs.go @@ -41,6 +41,7 @@ func CreateFuncs(ctx context.Context, d *data.Data) template.FuncMap { addToMap(f, funcs.CreateCollFuncs(ctx)) addToMap(f, funcs.CreateUUIDFuncs(ctx)) addToMap(f, funcs.CreateRandomFuncs(ctx)) + addToMap(f, funcs.CreateSemverFuncs(ctx)) return f } diff --git a/funcs/semver.go b/funcs/semver.go new file mode 100644 index 000000000..deeb5c922 --- /dev/null +++ b/funcs/semver.go @@ -0,0 +1,40 @@ +package funcs + +import ( + "context" + + "github.com/Masterminds/semver/v3" +) + +// CreateSemverFuncs - +func CreateSemverFuncs(ctx context.Context) map[string]interface{} { + ns := &SemverFuncs{ctx} + return map[string]interface{}{ + "semver": func() interface{} { return ns }, + } +} + +// SemverFuncs - +type SemverFuncs struct { + ctx context.Context +} + +// Semver - +func (SemverFuncs) Semver(version string) (*semver.Version, error) { + return semver.NewVersion(version) +} + +// MatchConstraint - +func (SemverFuncs) MatchConstraint(constraint, in string) (bool, error) { + c, err := semver.NewConstraint(constraint) + if err != nil { + return false, err + } + + v, err := semver.NewVersion(in) + if err != nil { + return false, err + } + + return c.Check(v), nil +} diff --git a/funcs/semver_test.go b/funcs/semver_test.go new file mode 100644 index 000000000..e93ef0ce8 --- /dev/null +++ b/funcs/semver_test.go @@ -0,0 +1,60 @@ +package funcs + +import ( + "context" + "testing" +) + +func TestSemverFuncs_MatchConstraint(t *testing.T) { + tests := []struct { + name string + constraint string + in string + want bool + wantErr bool + }{ + { + name: "mached constraint", + constraint: ">=1.0.0", + in: "v1.1.1", + want: true, + wantErr: false, + }, + { + name: "not matched constraint", + constraint: "<1.0.0", + in: "v1.1.1", + want: false, + wantErr: false, + }, + { + name: "wrong constraint", + constraint: "abc", + in: "v1.1.1", + want: false, + wantErr: true, + }, + { + name: "wrong in", + constraint: ">1.0.0", + in: "va.b.c", + want: false, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + s := SemverFuncs{ + ctx: context.TODO(), + } + got, err := s.MatchConstraint(tt.constraint, tt.in) + if (err != nil) != tt.wantErr { + t.Errorf("SemverFuncs.MatchConstraint() error = %v, wantErr %v", err, tt.wantErr) + return + } + if got != tt.want { + t.Errorf("SemverFuncs.MatchConstraint() = %v, want %v", got, tt.want) + } + }) + } +} From da2a47271bdd544d36e7408d977fd97d09542ed8 Mon Sep 17 00:00:00 2001 From: wuhuizuo Date: Tue, 7 Nov 2023 07:17:33 +0000 Subject: [PATCH 2/4] docs(functions): add documents for semver functions --- docs-src/content/functions/semver.yaml | 49 ++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 docs-src/content/functions/semver.yaml diff --git a/docs-src/content/functions/semver.yaml b/docs-src/content/functions/semver.yaml new file mode 100644 index 000000000..986a7ef2f --- /dev/null +++ b/docs-src/content/functions/semver.yaml @@ -0,0 +1,49 @@ +ns: semver +preamble: | + These functions allow user you to parse a [semantic version](http://semver.org/) string or test it with constraint. + + It's implemented with https://github.com/Masterminds/semver. +funcs: + - name: semver.Semver + description: | + Returns a semantic version struct holding the `input` version string. + + The returned struct are defined at: [`semver.Version`](https://pkg.go.dev/github.com/Masterminds/semver/v3#Version). + pipeline: true + arguments: + - name: input + required: true + description: The input to parse + examples: + - | + $ gomplate -i '{{ semver.Semver "v1.1.1"}}' + 1.1.1 + - | + $ gomplate -i '{{ (semver.Semver "v1.1.1").Major }}' + 1 + - | + $ gomplate -i 'the pre release version is {{ ("v1.1.1" | semver.Semver).SetPrerelease "beta.1" }}' + the pre release version is 1.1.1-beta.1 + - name: semver.MatchConstraint + description: | + Test whether the input version matchs the constraint. + + Ref: https://github.com/Masterminds/semver#checking-version-constraints + pipeline: true + arguments: + - name: constraint + required: true + description: The constraints expression to test. + - name: input + required: true + description: The input semantic version string to test. + examples: + - | + $ gomplate -i '{{ semver.MatchConstraint "> 1.0" "v1.1.1" }}' + true + - | + $ gomplate -i '{{ semver.MatchConstraint "> 1.0, <1.1" "v1.1.1" }}' + false + - | + $ gomplate -i '{{ "v1.1.1" | semver.MatchConstraint "> 1.0" }}' + true From c11a0c4d6278613793f42fee477d71e98d04e8dc Mon Sep 17 00:00:00 2001 From: wuhuizuo Date: Mon, 13 Nov 2023 20:42:38 +0800 Subject: [PATCH 3/4] Update docs-src/content/functions/semver.yaml Co-authored-by: Dave Henderson --- docs-src/content/functions/semver.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs-src/content/functions/semver.yaml b/docs-src/content/functions/semver.yaml index 986a7ef2f..6bb4868fb 100644 --- a/docs-src/content/functions/semver.yaml +++ b/docs-src/content/functions/semver.yaml @@ -2,7 +2,7 @@ ns: semver preamble: | These functions allow user you to parse a [semantic version](http://semver.org/) string or test it with constraint. - It's implemented with https://github.com/Masterminds/semver. + It's implemented with the https://github.com/Masterminds/semver library. funcs: - name: semver.Semver description: | From 6d66920cdb98ea5b22a41e9efbb8ca36beef8dc6 Mon Sep 17 00:00:00 2001 From: wuhuizuo Date: Mon, 13 Nov 2023 12:57:27 +0000 Subject: [PATCH 4/4] fix(funcs,docs,docs-src): fix the reviewing issues --- .../functions/{semver.yaml => semver.yml} | 8 +- docs/content/functions/semver.md | 85 +++++++++++++++++++ funcs/semver.go | 4 +- funcs/semver_test.go | 17 ++-- 4 files changed, 100 insertions(+), 14 deletions(-) rename docs-src/content/functions/{semver.yaml => semver.yml} (86%) create mode 100644 docs/content/functions/semver.md diff --git a/docs-src/content/functions/semver.yaml b/docs-src/content/functions/semver.yml similarity index 86% rename from docs-src/content/functions/semver.yaml rename to docs-src/content/functions/semver.yml index 6bb4868fb..08710afa1 100644 --- a/docs-src/content/functions/semver.yaml +++ b/docs-src/content/functions/semver.yml @@ -24,7 +24,7 @@ funcs: - | $ gomplate -i 'the pre release version is {{ ("v1.1.1" | semver.Semver).SetPrerelease "beta.1" }}' the pre release version is 1.1.1-beta.1 - - name: semver.MatchConstraint + - name: semver.CheckConstraint description: | Test whether the input version matchs the constraint. @@ -39,11 +39,11 @@ funcs: description: The input semantic version string to test. examples: - | - $ gomplate -i '{{ semver.MatchConstraint "> 1.0" "v1.1.1" }}' + $ gomplate -i '{{ semver.CheckConstraint "> 1.0" "v1.1.1" }}' true - | - $ gomplate -i '{{ semver.MatchConstraint "> 1.0, <1.1" "v1.1.1" }}' + $ gomplate -i '{{ semver.CheckConstraint "> 1.0, <1.1" "v1.1.1" }}' false - | - $ gomplate -i '{{ "v1.1.1" | semver.MatchConstraint "> 1.0" }}' + $ gomplate -i '{{ "v1.1.1" | semver.CheckConstraint "> 1.0" }}' true diff --git a/docs/content/functions/semver.md b/docs/content/functions/semver.md new file mode 100644 index 000000000..b94488ff1 --- /dev/null +++ b/docs/content/functions/semver.md @@ -0,0 +1,85 @@ +--- +title: semver functions +menu: + main: + parent: functions +--- + +These functions allow user you to parse a [semantic version](http://semver.org/) string or test it with constraint. + +It's implemented with the https://github.com/Masterminds/semver library. + +## `semver.Semver`_(unreleased)_ +**Unreleased:** _This function is in development, and not yet available in released builds of gomplate._ + +Returns a semantic version struct holding the `input` version string. + +The returned struct are defined at: [`semver.Version`](https://pkg.go.dev/github.com/Masterminds/semver/v3#Version). + +### Usage + +``` +semver.Semver input +``` +``` +input | semver.Semver +``` + +### Arguments + +| name | description | +|------|-------------| +| `input` | _(required)_ The input to parse | + +### Examples + +```console +$ gomplate -i '{{ semver.Semver "v1.1.1"}}' +1.1.1 +``` +```console +$ gomplate -i '{{ (semver.Semver "v1.1.1").Major }}' +1 +``` +```console +$ gomplate -i 'the pre release version is {{ ("v1.1.1" | semver.Semver).SetPrerelease "beta.1" }}' +the pre release version is 1.1.1-beta.1 +``` + +## `semver.CheckConstraint`_(unreleased)_ +**Unreleased:** _This function is in development, and not yet available in released builds of gomplate._ + +Test whether the input version matchs the constraint. + +Ref: https://github.com/Masterminds/semver#checking-version-constraints + +### Usage + +``` +semver.CheckConstraint constraint input +``` +``` +input | semver.CheckConstraint constraint +``` + +### Arguments + +| name | description | +|------|-------------| +| `constraint` | _(required)_ The constraints expression to test. | +| `input` | _(required)_ The input semantic version string to test. | + +### Examples + +```console +$ gomplate -i '{{ semver.CheckConstraint "> 1.0" "v1.1.1" }}' +true +``` +```console +$ gomplate -i '{{ semver.CheckConstraint "> 1.0, <1.1" "v1.1.1" }}' +false +``` +```console +$ gomplate -i '{{ "v1.1.1" | semver.CheckConstraint "> 1.0" }}' +true +``` diff --git a/funcs/semver.go b/funcs/semver.go index deeb5c922..0212c9987 100644 --- a/funcs/semver.go +++ b/funcs/semver.go @@ -24,8 +24,8 @@ func (SemverFuncs) Semver(version string) (*semver.Version, error) { return semver.NewVersion(version) } -// MatchConstraint - -func (SemverFuncs) MatchConstraint(constraint, in string) (bool, error) { +// CheckConstraint - +func (SemverFuncs) CheckConstraint(constraint, in string) (bool, error) { c, err := semver.NewConstraint(constraint) if err != nil { return false, err diff --git a/funcs/semver_test.go b/funcs/semver_test.go index e93ef0ce8..f10aad5cf 100644 --- a/funcs/semver_test.go +++ b/funcs/semver_test.go @@ -3,6 +3,8 @@ package funcs import ( "context" "testing" + + "github.com/stretchr/testify/assert" ) func TestSemverFuncs_MatchConstraint(t *testing.T) { @@ -45,15 +47,14 @@ func TestSemverFuncs_MatchConstraint(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { s := SemverFuncs{ - ctx: context.TODO(), - } - got, err := s.MatchConstraint(tt.constraint, tt.in) - if (err != nil) != tt.wantErr { - t.Errorf("SemverFuncs.MatchConstraint() error = %v, wantErr %v", err, tt.wantErr) - return + ctx: context.Background(), } - if got != tt.want { - t.Errorf("SemverFuncs.MatchConstraint() = %v, want %v", got, tt.want) + got, err := s.CheckConstraint(tt.constraint, tt.in) + if tt.wantErr { + assert.Errorf(t, err, "SemverFuncs.CheckConstraint() error = %v, wantErr %v", err, tt.wantErr) + } else { + assert.NoErrorf(t, err, "SemverFuncs.CheckConstraint() error = %v, wantErr %v", err, tt.wantErr) + assert.Equal(t, tt.want, got) } }) }