Skip to content

Commit 5945705

Browse files
authored
[services] Fix services when using versioned packages (#994)
## Summary This addresses related 3 bugs: * "versioned" packages where not triggering plugins/services. This was solved by updating plugin packages to use `nix.Input` and then using `CanonicalName()` as the triggering name (In short, this means we use `python` instead of `python@3`) * Updated plugins to recognize canonical names in `match` field. (e.g. `apache` plugin should trigger for `apache` and `apacheHttpd`). This was implemented by augmenting the regular expression. Another approach would have been to save the attribute path returned by search and use that instead. Since it only affects a very limited number of plugins and we don't really want to expand usage of `match` too much, I think this is an OK tradeoff. * minor bug: `PackageAttributePath()` in `input.go` was causing legacy packages that don't exist to get resolved (e.g. when doing `devbox add foobar`). This wasn't breaking anything because no packages get added to `devbox.json` but it would leave bad data in lockfile. ## How was it tested? `devbox add apach@2` `devbox add php` `devbox services ls` `devbox add foobar` shows error and doesn't add to lockfile.
1 parent 042d450 commit 5945705

File tree

15 files changed

+83
-40
lines changed

15 files changed

+83
-40
lines changed

devbox.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,4 @@
1717
"version": "1.52.2"
1818
}
1919
}
20-
}
20+
}

internal/impl/devbox.go

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,7 @@ func (d *Devbox) Info(pkg string, markdown bool) error {
327327
return errors.WithStack(err)
328328
}
329329
return plugin.PrintReadme(
330-
pkg,
330+
nix.InputFromString(pkg, d.lockfile),
331331
d.projectDir,
332332
d.writer,
333333
markdown,
@@ -444,7 +444,7 @@ func (d *Devbox) saveCfg() error {
444444
}
445445

446446
func (d *Devbox) Services() (services.Services, error) {
447-
pluginSvcs, err := plugin.GetServices(d.packages(), d.projectDir)
447+
pluginSvcs, err := plugin.GetServices(d.packagesAsInputs(), d.projectDir)
448448
if err != nil {
449449
return nil, err
450450
}
@@ -778,7 +778,7 @@ func (d *Devbox) computeNixEnv(ctx context.Context, usePrintDevEnvCache bool) (m
778778
// We still need to be able to add env variables to non-service binaries
779779
// (e.g. ruby). This would involve understanding what binaries are associated
780780
// to a given plugin.
781-
pluginEnv, err := plugin.Env(d.packages(), d.projectDir, env)
781+
pluginEnv, err := plugin.Env(d.packagesAsInputs(), d.projectDir, env)
782782
if err != nil {
783783
return nil, err
784784
}
@@ -866,7 +866,7 @@ func (d *Devbox) writeScriptsToFiles() error {
866866

867867
// Write all hooks to a file.
868868
written := map[string]struct{}{} // set semantics; value is irrelevant
869-
pluginHooks, err := plugin.InitHooks(d.packages(), d.projectDir)
869+
pluginHooks, err := plugin.InitHooks(d.packagesAsInputs(), d.projectDir)
870870
if err != nil {
871871
return errors.WithStack(err)
872872
}
@@ -950,6 +950,10 @@ func (d *Devbox) packages() []string {
950950
return d.cfg.Packages
951951
}
952952

953+
func (d *Devbox) packagesAsInputs() []*nix.Input {
954+
return nix.InputsFromStrings(d.packages(), d.lockfile)
955+
}
956+
953957
func (d *Devbox) findPackageByName(name string) (string, error) {
954958
results := []string{}
955959
for _, pkg := range d.cfg.Packages {

internal/impl/generate.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ func (d *Devbox) generateShellFiles() error {
6060
}
6161
}
6262

63-
for _, pkg := range d.packages() {
63+
for _, pkg := range d.packagesAsInputs() {
6464
if err := d.pluginManager.CreateFilesAndShowReadme(d.writer, pkg, d.projectDir); err != nil {
6565
return err
6666
}

internal/impl/packages.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,9 @@ func (d *Devbox) Add(ctx context.Context, pkgs ...string) error {
7676
return err
7777
}
7878

79-
for _, pkg := range pkgs {
79+
for _, input := range nix.InputsFromStrings(pkgs, d.lockfile) {
8080
if err := plugin.PrintReadme(
81-
pkg,
81+
input,
8282
d.projectDir,
8383
d.writer,
8484
false, /*markdown*/

internal/lock/lockfile.go

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -79,13 +79,7 @@ func (l *File) Resolve(pkg string) (*Package, error) {
7979
} else {
8080
// These are legacy packages without a version. Resolve to nixpkgs with
8181
// whatever hash is in the devbox.json
82-
locked = &Package{
83-
Resolved: fmt.Sprintf(
84-
"github:NixOS/nixpkgs/%s#%s",
85-
l.NixPkgsCommitHash(),
86-
pkg,
87-
),
88-
}
82+
locked = &Package{Resolved: l.LegacyNixpkgsPath(pkg)}
8983
}
9084
l.Packages[pkg] = locked
9185
if err := l.Update(); err != nil {
@@ -114,6 +108,14 @@ func (l *File) Update() error {
114108
return cuecfg.WriteFile(lockFilePath(l), l)
115109
}
116110

111+
func (l *File) LegacyNixpkgsPath(pkg string) string {
112+
return fmt.Sprintf(
113+
"github:NixOS/nixpkgs/%s#%s",
114+
l.NixPkgsCommitHash(),
115+
pkg,
116+
)
117+
}
118+
117119
func IsVersionedPackage(pkg string) bool {
118120
name, version, found := strings.Cut(pkg, "@")
119121
return found && name != "" && version != ""

internal/lock/resolvers.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,5 @@ type resolver interface {
1616
type Locker interface {
1717
devboxProject
1818
resolver
19+
LegacyNixpkgsPath(string) string
1920
}

internal/nix/input.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,14 @@ type Input struct {
2424
lockfile lock.Locker
2525
}
2626

27+
func InputsFromStrings(names []string, l lock.Locker) []*Input {
28+
inputs := []*Input{}
29+
for _, name := range names {
30+
inputs = append(inputs, InputFromString(name, l))
31+
}
32+
return inputs
33+
}
34+
2735
func InputFromString(s string, l lock.Locker) *Input {
2836
u, _ := url.Parse(s)
2937
if u.Path == "" && u.Opaque != "" && u.Scheme == "path" {
@@ -101,12 +109,14 @@ func (i *Input) URLForInstall() (string, error) {
101109
// packages.x86_64-linux.hello
102110
func (i *Input) PackageAttributePath() (string, error) {
103111
var infos map[string]*Info
104-
if i.IsDevboxPackage() {
112+
if i.isVersioned() {
105113
entry, err := i.lockfile.Resolve(i.String())
106114
if err != nil {
107115
return "", err
108116
}
109117
infos = search(entry.Resolved)
118+
} else if i.IsDevboxPackage() {
119+
infos = search(i.lockfile.LegacyNixpkgsPath(i.String()))
110120
} else {
111121
infos = search(i.String())
112122
}

internal/nix/input_test.go

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -118,19 +118,23 @@ func (l *lockfile) ProjectDir() string {
118118
return l.projectDir
119119
}
120120

121-
func (lockfile) Resolve(pkg string) (*lock.Package, error) {
121+
func (l *lockfile) LegacyNixpkgsPath(pkg string) string {
122+
return fmt.Sprintf(
123+
"github:NixOS/nixpkgs/%s#%s",
124+
nixCommitHash,
125+
pkg,
126+
)
127+
}
128+
129+
func (l *lockfile) Resolve(pkg string) (*lock.Package, error) {
122130
switch {
123131
case strings.Contains(pkg, "path:"):
124132
return &lock.Package{Resolved: pkg}, nil
125133
case strings.Contains(pkg, "github:"):
126134
return &lock.Package{Resolved: pkg}, nil
127135
default:
128136
return &lock.Package{
129-
Resolved: fmt.Sprintf(
130-
"github:NixOS/nixpkgs/%s#%s",
131-
nixCommitHash,
132-
pkg,
133-
),
137+
Resolved: l.LegacyNixpkgsPath(pkg),
134138
}, nil
135139
}
136140
}

internal/plugin/files.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,11 @@ import (
88
"strings"
99

1010
"github.com/pkg/errors"
11+
"go.jetpack.io/devbox/internal/nix"
1112
"go.jetpack.io/devbox/plugins"
1213
)
1314

14-
func getConfigIfAny(pkg, projectDir string) (*config, error) {
15+
func getConfigIfAny(pkg *nix.Input, projectDir string) (*config, error) {
1516
configFiles, err := plugins.BuiltIn.ReadDir(".")
1617
if err != nil {
1718
return nil, errors.WithStack(err)
@@ -27,14 +28,15 @@ func getConfigIfAny(pkg, projectDir string) (*config, error) {
2728
return nil, errors.WithStack(err)
2829
}
2930

31+
name := pkg.CanonicalName()
3032
cfg, err := buildConfig(pkg, projectDir, string(content))
3133
if err != nil {
3234
return nil, errors.WithStack(err)
3335
}
3436
// if match regex is set we use it to check. Otherwise we assume it's a
3537
// perfect match
36-
if (cfg.Match != "" && !regexp.MustCompile(cfg.Match).MatchString(pkg)) ||
37-
(cfg.Match == "" && strings.Split(file.Name(), ".")[0] != pkg) {
38+
if (cfg.Match != "" && !regexp.MustCompile(cfg.Match).MatchString(name)) ||
39+
(cfg.Match == "" && strings.Split(file.Name(), ".")[0] != name) {
3840
continue
3941
}
4042
return cfg, nil

internal/plugin/hooks.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33

44
package plugin
55

6-
func InitHooks(pkgs []string, projectDir string) ([]string, error) {
6+
import "go.jetpack.io/devbox/internal/nix"
7+
8+
func InitHooks(pkgs []*nix.Input, projectDir string) ([]string, error) {
79
hooks := []string{}
810
for _, pkg := range pkgs {
911
c, err := getConfigIfAny(pkg, projectDir)

0 commit comments

Comments
 (0)