Skip to content

Commit 6e6e9bd

Browse files
committed
improve searcher.ParseVersionedPackage, and reuse in implemetation of devconfig.parseVersionedName
1 parent 5396fe2 commit 6e6e9bd

File tree

3 files changed

+87
-22
lines changed

3 files changed

+87
-22
lines changed

internal/devconfig/packages.go

Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@ package devconfig
22

33
import (
44
"encoding/json"
5-
"strings"
65

76
"github.com/pkg/errors"
87
orderedmap "github.com/wk8/go-ordered-map/v2"
8+
"go.jetpack.io/devbox/internal/searcher"
99
"golang.org/x/exp/slices"
1010
)
1111

@@ -187,25 +187,15 @@ func (p Package) MarshalJSON() ([]byte, error) {
187187

188188
// parseVersionedName parses the name and version from package@version representation
189189
func parseVersionedName(versionedName string) (name, version string) {
190-
// use the last @ symbol as the version delimiter, some packages have @ in the name
191-
atSymbolIndex := strings.LastIndex(versionedName, "@")
192-
if atSymbolIndex != -1 {
193-
// Common case: package@version
194-
if atSymbolIndex != len(versionedName)-1 {
195-
name, version = versionedName[:atSymbolIndex], versionedName[atSymbolIndex+1:]
196-
} else {
197-
// This case handles packages that end with `@` in the name
198-
// example: `emacsPackages.@`
199-
name = versionedName[:atSymbolIndex] + "@"
200-
}
190+
var found bool
191+
name, version, found = searcher.ParseVersionedPackage(versionedName)
192+
if found {
193+
return name, version
201194
} else {
202-
// Case without any @version: package
195+
// Case without any @version in the versionedName
203196
name = versionedName
204-
205-
// We deliberately do not set version to latest so that we don't
206-
// automatically modify the devbox.json file. It should only be modified
207-
// upon `devbox update`.
208-
// version = "latest"
197+
// We deliberately do not set version to `latest`
198+
version = ""
209199
}
210200
return name, version
211201
}

internal/searcher/parse.go

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,19 @@ import (
99

1010
// ParseVersionedPackage checks if the given package is a versioned package
1111
// (`[email protected]`) and returns its name and version
12-
func ParseVersionedPackage(pkg string) (string, string, bool) {
13-
lastIndex := strings.LastIndex(pkg, "@")
14-
if lastIndex == -1 {
12+
func ParseVersionedPackage(versionedName string) (name string, version string, found bool) {
13+
// use the last @ symbol as the version delimiter, some packages have @ in the name
14+
atSymbolIndex := strings.LastIndex(versionedName, "@")
15+
if atSymbolIndex == -1 {
1516
return "", "", false
1617
}
17-
return pkg[:lastIndex], pkg[lastIndex+1:], true
18+
if atSymbolIndex == len(versionedName)-1 {
19+
// This case handles packages that end with `@` in the name
20+
// example: `emacsPackages.@`
21+
return "", "", false
22+
}
23+
24+
// Common case: package@version
25+
name, version = versionedName[:atSymbolIndex], versionedName[atSymbolIndex+1:]
26+
return name, version, true
1827
}

internal/searcher/parse_test.go

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package searcher
2+
3+
import (
4+
"testing"
5+
)
6+
7+
func TestParseVersionedPackage(t *testing.T) {
8+
testCases := []struct {
9+
name string
10+
input string
11+
expectedFound bool
12+
expectedName string
13+
expectedVersion string
14+
}{
15+
{
16+
name: "no-version",
17+
input: "python",
18+
expectedFound: false,
19+
expectedName: "",
20+
expectedVersion: "",
21+
},
22+
{
23+
name: "with-version-latest",
24+
input: "python@latest",
25+
expectedFound: true,
26+
expectedName: "python",
27+
expectedVersion: "latest",
28+
},
29+
{
30+
name: "with-version",
31+
32+
expectedFound: true,
33+
expectedName: "python",
34+
expectedVersion: "1.2.3",
35+
},
36+
{
37+
name: "with-two-@-signs",
38+
input: "emacsPackages.@@latest",
39+
expectedFound: true,
40+
expectedName: "emacsPackages.@",
41+
expectedVersion: "latest",
42+
},
43+
{
44+
name: "with-trailing-@-sign",
45+
input: "emacsPackages.@",
46+
expectedFound: false,
47+
expectedName: "",
48+
expectedVersion: "",
49+
},
50+
}
51+
52+
for _, testCase := range testCases {
53+
t.Run(testCase.name, func(t *testing.T) {
54+
name, version, found := ParseVersionedPackage(testCase.input)
55+
if found != testCase.expectedFound {
56+
t.Errorf("expected: %v, got: %v", testCase.expectedFound, found)
57+
}
58+
if name != testCase.expectedName {
59+
t.Errorf("expected: %v, got: %v", testCase.expectedName, name)
60+
}
61+
if version != testCase.expectedVersion {
62+
t.Errorf("expected: %v, got: %v", testCase.expectedVersion, version)
63+
}
64+
})
65+
}
66+
}

0 commit comments

Comments
 (0)