Skip to content

Commit 63093e2

Browse files
authored
[StorePathParts] move to nix package (#1722)
## Summary This should be in the `nix` package Seeking to reduce the code in #1692. ## How was it tested? compiles, and tests should pass
1 parent 1a41adf commit 63093e2

File tree

4 files changed

+90
-79
lines changed

4 files changed

+90
-79
lines changed

internal/devpkg/narinfo_cache.go

Lines changed: 2 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,8 @@ import (
44
"context"
55
"io"
66
"net/http"
7-
"strings"
87
"sync"
98
"time"
10-
"unicode"
119

1210
"github.com/pkg/errors"
1311
"go.jetpack.io/devbox/internal/boxcli/featureflag"
@@ -110,8 +108,8 @@ func (p *Package) fetchNarInfoStatus() (bool, error) {
110108
)
111109
}
112110

113-
pathParts := newStorePathParts(sysInfo.StorePath)
114-
reqURL := BinaryCache + "/" + pathParts.hash + ".narinfo"
111+
pathParts := nix.NewStorePathParts(sysInfo.StorePath)
112+
reqURL := BinaryCache + "/" + pathParts.Hash + ".narinfo"
115113
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
116114
defer cancel()
117115
req, err := http.NewRequestWithContext(ctx, http.MethodHead, reqURL, nil)
@@ -181,35 +179,3 @@ func (p *Package) sysInfoIfExists() (*lock.SystemInfo, error) {
181179
}
182180
return sysInfo, nil
183181
}
184-
185-
// storePath are the constituent parts of
186-
// /nix/store/<hash>-<name>-<version>
187-
//
188-
// This is a helper struct for analyzing the string representation
189-
type storePathParts struct {
190-
hash string
191-
name string
192-
version string
193-
}
194-
195-
// newStorePathParts splits a Nix store path into its hash, name and version
196-
// components in the same way that Nix does.
197-
//
198-
// See https://nixos.org/manual/nix/stable/language/builtins.html#builtins-parseDrvName
199-
func newStorePathParts(path string) storePathParts {
200-
path = strings.TrimPrefix(path, "/nix/store/")
201-
// path is now <hash>-<name>-<version
202-
203-
hash, name := path[:32], path[33:]
204-
dashIndex := 0
205-
for i, r := range name {
206-
if dashIndex != 0 && !unicode.IsLetter(r) {
207-
return storePathParts{hash: hash, name: name[:dashIndex], version: name[i:]}
208-
}
209-
dashIndex = 0
210-
if r == '-' {
211-
dashIndex = i
212-
}
213-
}
214-
return storePathParts{hash: hash, name: name}
215-
}

internal/devpkg/package_test.go

Lines changed: 0 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -181,49 +181,6 @@ func TestHashFromNixPkgsURL(t *testing.T) {
181181
}
182182
}
183183

184-
func TestStorePathParts(t *testing.T) {
185-
testCases := []struct {
186-
storePath string
187-
expected storePathParts
188-
}{
189-
// simple case:
190-
{
191-
storePath: "/nix/store/cvrn84c1hshv2wcds7n1rhydi6lacqns-gnumake-4.4.1",
192-
expected: storePathParts{
193-
hash: "cvrn84c1hshv2wcds7n1rhydi6lacqns",
194-
name: "gnumake",
195-
version: "4.4.1",
196-
},
197-
},
198-
// the package name can have dashes:
199-
{
200-
storePath: "/nix/store/q2xdxsswjqmqcbax81pmazm367s7jzyb-cctools-binutils-darwin-wrapper-973.0.1",
201-
expected: storePathParts{
202-
hash: "q2xdxsswjqmqcbax81pmazm367s7jzyb",
203-
name: "cctools-binutils-darwin-wrapper",
204-
version: "973.0.1",
205-
},
206-
},
207-
// version is optional. This is an artificial example I constructed
208-
{
209-
storePath: "/nix/store/gfxwrd5nggc68pjj3g3jhlldim9rpg0p-coreutils",
210-
expected: storePathParts{
211-
hash: "gfxwrd5nggc68pjj3g3jhlldim9rpg0p",
212-
name: "coreutils",
213-
},
214-
},
215-
}
216-
217-
for _, testCase := range testCases {
218-
t.Run(testCase.storePath, func(t *testing.T) {
219-
parts := newStorePathParts(testCase.storePath)
220-
if parts != testCase.expected {
221-
t.Errorf("Expected %v, got %v", testCase.expected, parts)
222-
}
223-
})
224-
}
225-
}
226-
227184
func TestCanonicalName(t *testing.T) {
228185
tests := []struct {
229186
pkgName string

internal/nix/storepath.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package nix
2+
3+
import (
4+
"strings"
5+
"unicode"
6+
)
7+
8+
// storePath are the constituent parts of
9+
// /nix/store/<hash>-<name>-<version>
10+
//
11+
// This is a helper struct for analyzing the string representation
12+
type StorePathParts struct {
13+
Hash string
14+
Name string
15+
Version string
16+
}
17+
18+
// NewStorePathParts splits a Nix store path into its hash, name and version
19+
// components in the same way that Nix does.
20+
//
21+
// See https://nixos.org/manual/nix/stable/language/builtins.html#builtins-parseDrvName
22+
//
23+
// TODO: store paths can also have `-{output}` suffixes, which need to be handled below.
24+
func NewStorePathParts(path string) StorePathParts {
25+
path = strings.TrimPrefix(path, "/nix/store/")
26+
// path is now <hash>-<name>-<version
27+
28+
hash, name := path[:32], path[33:]
29+
dashIndex := 0
30+
for i, r := range name {
31+
if dashIndex != 0 && !unicode.IsLetter(r) {
32+
return StorePathParts{Hash: hash, Name: name[:dashIndex], Version: name[i:]}
33+
}
34+
dashIndex = 0
35+
if r == '-' {
36+
dashIndex = i
37+
}
38+
}
39+
return StorePathParts{Hash: hash, Name: name}
40+
}

internal/nix/storepath_test.go

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package nix
2+
3+
import (
4+
"testing"
5+
)
6+
7+
func TestStorePathParts(t *testing.T) {
8+
testCases := []struct {
9+
storePath string
10+
expected StorePathParts
11+
}{
12+
// simple case:
13+
{
14+
storePath: "/nix/store/cvrn84c1hshv2wcds7n1rhydi6lacqns-gnumake-4.4.1",
15+
expected: StorePathParts{
16+
Hash: "cvrn84c1hshv2wcds7n1rhydi6lacqns",
17+
Name: "gnumake",
18+
Version: "4.4.1",
19+
},
20+
},
21+
// the package name can have dashes:
22+
{
23+
storePath: "/nix/store/q2xdxsswjqmqcbax81pmazm367s7jzyb-cctools-binutils-darwin-wrapper-973.0.1",
24+
expected: StorePathParts{
25+
Hash: "q2xdxsswjqmqcbax81pmazm367s7jzyb",
26+
Name: "cctools-binutils-darwin-wrapper",
27+
Version: "973.0.1",
28+
},
29+
},
30+
// version is optional. This is an artificial example I constructed
31+
{
32+
storePath: "/nix/store/gfxwrd5nggc68pjj3g3jhlldim9rpg0p-coreutils",
33+
expected: StorePathParts{
34+
Hash: "gfxwrd5nggc68pjj3g3jhlldim9rpg0p",
35+
Name: "coreutils",
36+
},
37+
},
38+
}
39+
40+
for _, testCase := range testCases {
41+
t.Run(testCase.storePath, func(t *testing.T) {
42+
parts := NewStorePathParts(testCase.storePath)
43+
if parts != testCase.expected {
44+
t.Errorf("Expected %v, got %v", testCase.expected, parts)
45+
}
46+
})
47+
}
48+
}

0 commit comments

Comments
 (0)