Skip to content

Commit

Permalink
improve searcher.ParseVersionedPackage, and reuse in implemetation of…
Browse files Browse the repository at this point in the history
… devconfig.parseVersionedName
  • Loading branch information
savil committed Aug 8, 2023
1 parent 5396fe2 commit 6e6e9bd
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 22 deletions.
26 changes: 8 additions & 18 deletions internal/devconfig/packages.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ package devconfig

import (
"encoding/json"
"strings"

"github.com/pkg/errors"
orderedmap "github.com/wk8/go-ordered-map/v2"
"go.jetpack.io/devbox/internal/searcher"
"golang.org/x/exp/slices"
)

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

// parseVersionedName parses the name and version from package@version representation
func parseVersionedName(versionedName string) (name, version string) {
// use the last @ symbol as the version delimiter, some packages have @ in the name
atSymbolIndex := strings.LastIndex(versionedName, "@")
if atSymbolIndex != -1 {
// Common case: package@version
if atSymbolIndex != len(versionedName)-1 {
name, version = versionedName[:atSymbolIndex], versionedName[atSymbolIndex+1:]
} else {
// This case handles packages that end with `@` in the name
// example: `emacsPackages.@`
name = versionedName[:atSymbolIndex] + "@"
}
var found bool
name, version, found = searcher.ParseVersionedPackage(versionedName)
if found {
return name, version
} else {
// Case without any @version: package
// Case without any @version in the versionedName
name = versionedName

// We deliberately do not set version to latest so that we don't
// automatically modify the devbox.json file. It should only be modified
// upon `devbox update`.
// version = "latest"
// We deliberately do not set version to `latest`
version = ""
}
return name, version
}
Expand Down
17 changes: 13 additions & 4 deletions internal/searcher/parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,19 @@ import (

// ParseVersionedPackage checks if the given package is a versioned package
// (`[email protected]`) and returns its name and version
func ParseVersionedPackage(pkg string) (string, string, bool) {
lastIndex := strings.LastIndex(pkg, "@")
if lastIndex == -1 {
func ParseVersionedPackage(versionedName string) (name string, version string, found bool) {
// use the last @ symbol as the version delimiter, some packages have @ in the name
atSymbolIndex := strings.LastIndex(versionedName, "@")
if atSymbolIndex == -1 {
return "", "", false
}
return pkg[:lastIndex], pkg[lastIndex+1:], true
if atSymbolIndex == len(versionedName)-1 {
// This case handles packages that end with `@` in the name
// example: `emacsPackages.@`
return "", "", false
}

// Common case: package@version
name, version = versionedName[:atSymbolIndex], versionedName[atSymbolIndex+1:]
return name, version, true
}
66 changes: 66 additions & 0 deletions internal/searcher/parse_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package searcher

import (
"testing"
)

func TestParseVersionedPackage(t *testing.T) {
testCases := []struct {
name string
input string
expectedFound bool
expectedName string
expectedVersion string
}{
{
name: "no-version",
input: "python",
expectedFound: false,
expectedName: "",
expectedVersion: "",
},
{
name: "with-version-latest",
input: "python@latest",
expectedFound: true,
expectedName: "python",
expectedVersion: "latest",
},
{
name: "with-version",
input: "[email protected]",
expectedFound: true,
expectedName: "python",
expectedVersion: "1.2.3",
},
{
name: "with-two-@-signs",
input: "emacsPackages.@@latest",
expectedFound: true,
expectedName: "emacsPackages.@",
expectedVersion: "latest",
},
{
name: "with-trailing-@-sign",
input: "emacsPackages.@",
expectedFound: false,
expectedName: "",
expectedVersion: "",
},
}

for _, testCase := range testCases {
t.Run(testCase.name, func(t *testing.T) {
name, version, found := ParseVersionedPackage(testCase.input)
if found != testCase.expectedFound {
t.Errorf("expected: %v, got: %v", testCase.expectedFound, found)
}
if name != testCase.expectedName {
t.Errorf("expected: %v, got: %v", testCase.expectedName, name)
}
if version != testCase.expectedVersion {
t.Errorf("expected: %v, got: %v", testCase.expectedVersion, version)
}
})
}
}

0 comments on commit 6e6e9bd

Please sign in to comment.