Skip to content

Commit 3da1423

Browse files
committed
update version constraints
1 parent 74b9fe7 commit 3da1423

8 files changed

Lines changed: 141 additions & 58 deletions

File tree

cmd/kitty/main.go

Lines changed: 10 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,10 @@ import (
1010

1111
"github.com/ImSingee/go-ex/ee"
1212
"github.com/ImSingee/go-ex/pp"
13-
"github.com/ImSingee/semver"
1413
"github.com/spf13/cobra"
15-
"github.com/ysmood/gson"
1614

1715
"github.com/ImSingee/kitty/internal/config"
16+
"github.com/ImSingee/kitty/internal/config/kittyversion"
1817
"github.com/ImSingee/kitty/internal/ext/format"
1918
lintstaged "github.com/ImSingee/kitty/internal/ext/lint-staged"
2019
"github.com/ImSingee/kitty/internal/hooks"
@@ -148,61 +147,22 @@ func mayUseAnotherKitty() error {
148147
}
149148
}
150149

151-
requiredVersion := parseRequiredKittyVersion(c)
150+
requiredVersion := kittyversion.ParseRequired(c)
152151
if requiredVersion == "" {
153152
return nil // no required version
154153
}
155154

156-
// TODO auto download new kitty version
157-
if requiredVersion[0] == '=' {
158-
sv, err := semver.NewVersion(requiredVersion[1:])
159-
if err != nil {
160-
return ee.Wrapf(err, "invalid kitty required version %s", requiredVersion)
161-
}
162-
163-
if !sv.Equal(version.Semver()) {
164-
pp.Println("Please use kitty ", requiredVersion[1:], "to run this command")
165-
pp.Println("Visit https://github.com/ImSingee/kitty/releases/tag/v" + requiredVersion[1:] + " to download")
166-
return ee.Phantom
167-
}
168-
} else {
169-
sv, err := semver.NewVersion(strings.TrimPrefix(requiredVersion, ">"))
170-
if err != nil {
171-
return ee.Wrapf(err, "invalid kitty required version %s", requiredVersion)
172-
}
173-
174-
if version.LessThan(sv) {
175-
pp.Println("Please use kitty ", requiredVersion, "or later to run this command")
176-
pp.Println("Visit https://github.com/ImSingee/kitty/releases to download")
177-
return ee.Phantom
178-
}
179-
}
180-
181-
return nil
182-
}
183-
184-
func parseRequiredKittyVersion(c map[string]gson.JSON) string {
185-
if c == nil {
186-
return ""
155+
ok, err := kittyversion.CurrentSatisfies(requiredVersion)
156+
if err != nil {
157+
return ee.Wrapf(err, "invalid kitty required version %s", requiredVersion)
187158
}
188-
189-
kitty, kittyExists := c["kitty"]
190-
if !kittyExists {
191-
return ""
159+
if !ok {
160+
pp.Println("Please use kitty version matching constraint", requiredVersion, "to run this command")
161+
pp.Println("Visit https://github.com/ImSingee/kitty/releases to download")
162+
return ee.Phantom
192163
}
193164

194-
switch kittyVal := kitty.Val().(type) {
195-
case string:
196-
return kittyVal
197-
case map[string]any:
198-
if v, ok := kittyVal["version"].(string); ok {
199-
return v
200-
}
201-
202-
return ""
203-
default:
204-
return "" // unknown kitty config type
205-
}
165+
return nil
206166
}
207167

208168
func runExtension(name string, args []string) error {

go.mod

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
module github.com/ImSingee/kitty
22

3-
go 1.20
3+
go 1.21
44

55
require (
66
github.com/ImSingee/go-ex v0.4.43
7-
github.com/ImSingee/semver v0.1.0
87
github.com/ImSingee/tt v1.0.4
8+
github.com/Masterminds/semver/v3 v3.4.0
99
github.com/alessio/shellescape v1.4.2
1010
github.com/charmbracelet/bubbletea v0.24.2
1111
github.com/go-git/go-git/v5 v5.9.0

go.sum

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
github.com/ImSingee/go-ex v0.4.43 h1:+w8AGSPOkcBuzuRkAYisjHsR5+d9eMiRZrLTEnfohFw=
22
github.com/ImSingee/go-ex v0.4.43/go.mod h1:CNc3Fqk9GkQfm/1x53vGnQ0BEHH+52siqBJFkVwdy8U=
3-
github.com/ImSingee/semver v0.1.0 h1:h0l6RYP2KK3PKQlvd4TDsvHWThwcjGHm47GtTk9hMR8=
4-
github.com/ImSingee/semver v0.1.0/go.mod h1:oFE1h7iyQ3+khH/BqhWtr03FMSKeWIApAhIrWF/bf+E=
53
github.com/ImSingee/tt v1.0.4 h1:avDmypiAGmTEaRVJ1hweLzggyKRVfuUfLsGrebTrAyQ=
64
github.com/ImSingee/tt v1.0.4/go.mod h1:7O7v+cIBruYWGFObw85DDjH0gNLquen1cJqMR3GOgxw=
5+
github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0=
6+
github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
77
github.com/acomagu/bufpipe v1.0.4 h1:e3H4WUzM3npvo5uv95QuJM3cQspFNtFBzvJ2oNjKIDQ=
88
github.com/acomagu/bufpipe v1.0.4/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4=
99
github.com/alessio/shellescape v1.4.2 h1:MHPfaU+ddJ0/bYWpgIeUnQUqKrlJ1S7BfEYPM4uEoM0=
@@ -34,7 +34,9 @@ github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLf
3434
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
3535
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
3636
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
37+
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
3738
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
39+
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
3840
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
3941
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
4042
github.com/matryer/is v1.2.0 h1:92UTHpy8CDwaJ08GqLDzhhuixiBUUD1p3AU6PHddz4A=
@@ -63,6 +65,7 @@ github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJ
6365
github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis=
6466
github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
6567
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
68+
github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
6669
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
6770
github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I=
6871
github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0=
@@ -86,6 +89,7 @@ golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
8689
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
8790
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
8891
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
92+
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
8993
gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=
9094
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
9195
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package kittyversion
2+
3+
import (
4+
semver "github.com/Masterminds/semver/v3"
5+
"github.com/ysmood/gson"
6+
7+
"github.com/ImSingee/kitty/internal/version"
8+
)
9+
10+
func ParseRequired(c map[string]gson.JSON) string {
11+
if c == nil {
12+
return ""
13+
}
14+
15+
kitty, kittyExists := c["kitty"]
16+
if !kittyExists {
17+
return ""
18+
}
19+
20+
switch kittyVal := kitty.Val().(type) {
21+
case string:
22+
return kittyVal
23+
case map[string]any:
24+
if v, ok := kittyVal["version"].(string); ok {
25+
return v
26+
}
27+
28+
return ""
29+
default:
30+
return ""
31+
}
32+
}
33+
34+
func CurrentSatisfies(requiredVersion string) (bool, error) {
35+
return Satisfies(version.Version(), requiredVersion)
36+
}
37+
38+
func Satisfies(currentVersion string, requiredVersion string) (bool, error) {
39+
if currentVersion == version.DevVersion {
40+
return true, nil
41+
}
42+
43+
constraints, err := semver.NewConstraint(requiredVersion)
44+
if err != nil {
45+
return false, err
46+
}
47+
48+
sv, err := semver.NewVersion(currentVersion)
49+
if err != nil {
50+
return false, err
51+
}
52+
53+
return constraints.Check(sv), nil
54+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package kittyversion
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/assert"
7+
"github.com/stretchr/testify/require"
8+
"github.com/ysmood/gson"
9+
)
10+
11+
func TestParseRequired(t *testing.T) {
12+
t.Run("reads string shorthand", func(t *testing.T) {
13+
config := map[string]gson.JSON{
14+
"kitty": gson.New("0.2.2"),
15+
}
16+
17+
assert.Equal(t, "0.2.2", ParseRequired(config))
18+
})
19+
20+
t.Run("reads version from object", func(t *testing.T) {
21+
config := map[string]gson.JSON{
22+
"kitty": gson.New(map[string]any{
23+
"version": ">=0.2.2",
24+
}),
25+
}
26+
27+
assert.Equal(t, ">=0.2.2", ParseRequired(config))
28+
})
29+
30+
t.Run("ignores unsupported shapes", func(t *testing.T) {
31+
config := map[string]gson.JSON{
32+
"kitty": gson.New([]any{"0.2.2"}),
33+
}
34+
35+
assert.Equal(t, "", ParseRequired(config))
36+
})
37+
}
38+
39+
func TestSatisfies(t *testing.T) {
40+
t.Run("plain version follows semver constraint semantics", func(t *testing.T) {
41+
ok, err := Satisfies("0.2.2", "0.2.2")
42+
require.NoError(t, err)
43+
assert.True(t, ok)
44+
45+
ok, err = Satisfies("0.2.2", "0.2.3")
46+
require.NoError(t, err)
47+
assert.False(t, ok)
48+
})
49+
50+
t.Run("greater than is strict", func(t *testing.T) {
51+
ok, err := Satisfies("0.2.2", ">0.2.2")
52+
require.NoError(t, err)
53+
assert.False(t, ok)
54+
55+
ok, err = Satisfies("0.2.3", ">0.2.2")
56+
require.NoError(t, err)
57+
assert.True(t, ok)
58+
})
59+
60+
t.Run("dev supports everything", func(t *testing.T) {
61+
ok, err := Satisfies("DEV", ">=999.0.0")
62+
require.NoError(t, err)
63+
assert.True(t, ok)
64+
})
65+
}

internal/extension-registry/installer/impl/goinstaller/installer.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import (
99

1010
"github.com/ImSingee/go-ex/ee"
1111
"github.com/ImSingee/go-ex/pp"
12-
"github.com/ImSingee/semver"
12+
semver "github.com/Masterminds/semver/v3"
1313

1414
"github.com/ImSingee/kitty/internal/extension-registry/installer"
1515
eroptions "github.com/ImSingee/kitty/internal/extension-registry/options"

internal/extension-registry/installer/tmpl/tmpl.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import (
66
"text/template"
77

88
"github.com/ImSingee/go-ex/ee"
9-
"github.com/ImSingee/semver"
9+
semver "github.com/Masterminds/semver/v3"
1010

1111
"github.com/ImSingee/kitty/internal/extension-registry/installer"
1212
)

internal/version/version.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package version
33
import (
44
"fmt"
55

6-
"github.com/ImSingee/semver"
6+
semver "github.com/Masterminds/semver/v3"
77
)
88

99
var (
@@ -29,7 +29,7 @@ func Semver() *semver.Version {
2929
if err == nil {
3030
return v
3131
} else {
32-
return semver.NewVersionByParts(0, 0, 0)
32+
return semver.MustParse("0.0.0")
3333
}
3434
}
3535

0 commit comments

Comments
 (0)