Skip to content

Commit b9c5173

Browse files
authored
devpkg: fix empty patch mode (#2278)
Fix a case where an empty patch mode wouldn't default to "auto". This was causing Devbox to skip patching when it should not have. Got rid of the sync.OnceValue function for determining if a package needs to be patched. This was originally done to avoid a call to nix.System(), but that call doesn't happen anymore.
1 parent 9da62f6 commit b9c5173

File tree

4 files changed

+32
-30
lines changed

4 files changed

+32
-30
lines changed

internal/devpkg/narinfo_cache.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -219,8 +219,8 @@ func (p *Package) outputsForOutputName(output string) ([]lock.Output, error) {
219219
// the package to query it from the binary cache.
220220
func (p *Package) isEligibleForBinaryCache() (bool, error) {
221221
defer debug.FunctionTimer().End()
222-
// Patched glibc packages are not in the binary cache.
223-
if p.PatchGlibc() {
222+
// Patched packages are not in the binary cache.
223+
if p.Patch {
224224
return false, nil
225225
}
226226
sysInfo, err := p.sysInfoIfExists()

internal/devpkg/package.go

+26-24
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@
44
package devpkg
55

66
import (
7+
"cmp"
78
"context"
89
"fmt"
910
"io"
11+
"log/slog"
1012
"path/filepath"
1113
"regexp"
1214
"strings"
@@ -81,10 +83,9 @@ type Package struct {
8183
// Outputs is a list of outputs to build from the package's derivation.
8284
outputs outputs
8385

84-
// patch applies a function to the package's derivation that
85-
// patches any ELF binaries to use the latest version of nixpkgs#glibc.
86-
// It's a function to allow deferring nix System call until it's needed.
87-
patch func() bool
86+
// Patch controls if Devbox environments will do additional patching to
87+
// address known issues with the package.
88+
Patch bool
8889

8990
// AllowInsecure are a list of nix packages that are whitelisted to be
9091
// installed even if they are marked as insecure.
@@ -110,7 +111,7 @@ func PackagesFromConfig(packages []configfile.Package, l lock.Locker) []*Package
110111
for _, cfgPkg := range packages {
111112
pkg := newPackage(cfgPkg.VersionedName(), cfgPkg.IsEnabledOnPlatform, l)
112113
pkg.DisablePlugin = cfgPkg.DisablePlugin
113-
pkg.patch = patchGlibcFunc(pkg.CanonicalName(), cfgPkg.Patch)
114+
pkg.Patch = pkgNeedsPatch(pkg.CanonicalName(), cfgPkg.Patch)
114115
pkg.outputs.selectedNames = lo.Uniq(append(pkg.outputs.selectedNames, cfgPkg.Outputs...))
115116
pkg.AllowInsecure = cfgPkg.AllowInsecure
116117
result = append(result, pkg)
@@ -125,7 +126,7 @@ func PackageFromStringWithDefaults(raw string, locker lock.Locker) *Package {
125126
func PackageFromStringWithOptions(raw string, locker lock.Locker, opts devopt.AddOpts) *Package {
126127
pkg := PackageFromStringWithDefaults(raw, locker)
127128
pkg.DisablePlugin = opts.DisablePlugin
128-
pkg.patch = patchGlibcFunc(pkg.CanonicalName(), configfile.PatchMode(opts.Patch))
129+
pkg.Patch = pkgNeedsPatch(pkg.CanonicalName(), configfile.PatchMode(opts.Patch))
129130
pkg.outputs.selectedNames = lo.Uniq(append(pkg.outputs.selectedNames, opts.Outputs...))
130131
pkg.AllowInsecure = opts.AllowInsecure
131132
return pkg
@@ -155,6 +156,7 @@ func newPackage(raw string, isInstallable func() bool, locker lock.Locker) *Pack
155156
pkg.resolve = sync.OnceValue(func() error { return nil })
156157
pkg.setInstallable(parsed, locker.ProjectDir())
157158
pkg.outputs = outputs{selectedNames: strings.Split(parsed.Outputs, ",")}
159+
pkg.Patch = pkgNeedsPatch(pkg.CanonicalName(), configfile.PatchAuto)
158160
return pkg
159161
}
160162

@@ -177,27 +179,31 @@ func resolve(pkg *Package) error {
177179
return nil
178180
}
179181

180-
func patchGlibcFunc(canonicalName string, mode configfile.PatchMode) func() bool {
181-
return sync.OnceValue(func() (patch bool) {
182-
switch mode {
183-
case configfile.PatchAuto:
184-
patch = canonicalName == "python"
185-
case configfile.PatchAlways:
186-
patch = true
187-
case configfile.PatchNever:
188-
patch = false
189-
}
190-
return patch
191-
})
192-
}
193-
194182
func (p *Package) setInstallable(i flake.Installable, projectDir string) {
195183
if i.Ref.Type == flake.TypePath && !filepath.IsAbs(i.Ref.Path) {
196184
i.Ref.Path = filepath.Join(projectDir, i.Ref.Path)
197185
}
198186
p.installable = i
199187
}
200188

189+
func pkgNeedsPatch(canonicalName string, mode configfile.PatchMode) (patch bool) {
190+
mode = cmp.Or(mode, configfile.PatchAuto)
191+
switch mode {
192+
case configfile.PatchAuto:
193+
patch = canonicalName == "python"
194+
case configfile.PatchAlways:
195+
patch = true
196+
case configfile.PatchNever:
197+
patch = false
198+
}
199+
if patch {
200+
slog.Debug("package needs patching", "pkg", canonicalName, "mode", mode)
201+
} else {
202+
slog.Debug("package doesn't need patching", "pkg", canonicalName, "mode", mode)
203+
}
204+
return patch
205+
}
206+
201207
var inputNameRegex = regexp.MustCompile("[^a-zA-Z0-9-]+")
202208

203209
// FlakeInputName generates a name for the input that will be used in the
@@ -249,10 +255,6 @@ func (p *Package) IsInstallable() bool {
249255
return p.isInstallable()
250256
}
251257

252-
func (p *Package) PatchGlibc() bool {
253-
return p.patch != nil && p.patch()
254-
}
255-
256258
// Installables for this package. Installables is a nix concept defined here:
257259
// https://nixos.org/manual/nix/stable/command-ref/new-cli/nix.html#installables
258260
func (p *Package) Installables() ([]string, error) {

internal/shellgen/flake_input.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ func (f *flakeInput) BuildInputsForSymlinkJoin() ([]*SymlinkJoin, error) {
8484
return nil, err
8585
}
8686

87-
if pkg.PatchGlibc() {
87+
if pkg.Patch {
8888
return nil, errors.New("patch_glibc is not yet supported for packages with non-default outputs")
8989
}
9090

@@ -125,7 +125,7 @@ func (f *flakeInput) BuildInputs() ([]string, error) {
125125
if attributePathErr != nil {
126126
err = attributePathErr
127127
}
128-
if pkg.PatchGlibc() {
128+
if pkg.Patch {
129129
// When the package comes from the glibc flake, the
130130
// "legacyPackages" portion of the attribute path
131131
// becomes just "packages" (matching the standard flake
@@ -179,7 +179,7 @@ func flakeInputs(ctx context.Context, packages []*devpkg.Package) []flakeInput {
179179
// Packages that need a glibc patch are assigned to the special
180180
// glibc-patched flake input. This input refers to the
181181
// glibc-patch.nix flake.
182-
if pkg.PatchGlibc() {
182+
if pkg.Patch {
183183
nixpkgsGlibc := flakeInputs.getOrAppend(glibcPatchFlakeRef)
184184
nixpkgsGlibc.Name = "glibc-patch"
185185
nixpkgsGlibc.URL = glibcPatchFlakeRef

internal/shellgen/flake_plan.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ func newGlibcPatchFlake(nixpkgsGlibcRev string, packages []*devpkg.Package) (gli
106106
NixpkgsGlibcFlakeRef: "flake:nixpkgs/" + nixpkgsGlibcRev,
107107
}
108108
for _, pkg := range packages {
109-
if !pkg.PatchGlibc() {
109+
if !pkg.Patch {
110110
continue
111111
}
112112

0 commit comments

Comments
 (0)