Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion examples/flakes/php/my-php-flake/flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
packages = {
# Flakes can export multiple packages. To include specific packages in
# devbox.json you can use url fragments (e.g. path:my-flake#my-package)
php = pkgs.php.withExtensions ({ enabled, all }: enabled ++ (with all; [ ds ]));
php = pkgs.php.withExtensions ({ enabled, all }: enabled ++ (with all; [ ds memcached ]));
hello = pkgs.hello;

# If you only want to export a single package, you can name it default which allows
Expand Down
77 changes: 58 additions & 19 deletions internal/impl/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,28 +42,14 @@ func (d *Devbox) Update(ctx context.Context, pkgs ...string) error {

for _, pkg := range pendingPackagesToUpdate {
if _, _, isVersioned := devpkg.ParseVersionedPackage(pkg.Raw); !isVersioned {
fmt.Fprintf(d.writer, "Skipping %s because it is not a versioned package\n", pkg)
continue
}
existing := d.lockfile.Packages[pkg.Raw]
newEntry, err := searcher.Client().Resolve(pkg.Raw)
if err != nil {
return err
}
if existing != nil && existing.Version != newEntry.Version {
fmt.Fprintf(d.writer, "Updating %s %s -> %s\n", pkg, existing.Version, newEntry.Version)
if err := d.removePackagesFromProfile(ctx, []string{pkg.Raw}); err != nil {
// Warn but continue. TODO(landau): ensurePackagesAreInstalled should
// sync the profile so we don't need to do this manually.
ux.Fwarning(d.writer, "Failed to remove %s from profile: %s\n", pkg, err)
if err = d.attemptToUpgradeFlake(pkg); err != nil {
return err
}
} else if existing == nil {
fmt.Fprintf(d.writer, "Resolved %s to %[1]s %[2]s\n", pkg, newEntry.Resolved)
} else {
fmt.Fprintf(d.writer, "Already up-to-date %s %s\n", pkg, existing.Version)
if err = d.updateDevboxPackage(ctx, pkg); err != nil {
return err
}
}
// Set the new entry after we've removed the old package from the profile
d.lockfile.Packages[pkg.Raw] = newEntry
}

// TODO(landau): Improve output
Expand All @@ -89,3 +75,56 @@ func (d *Devbox) inputsToUpdate(pkgs ...string) ([]*nix.Input, error) {

return nix.InputsFromStrings(pkgsToUpdate, d.lockfile), nil
}

func (d *Devbox) updateDevboxPackage(
ctx context.Context,
pkg *nix.Input,
) error {
existing := d.lockfile.Packages[pkg.Raw]
newEntry, err := searcher.Client().Resolve(pkg.Raw)
if err != nil {
return err
}
if existing != nil && existing.Version != newEntry.Version {
ux.Finfo(d.writer, "Updating %s %s -> %s\n", pkg, existing.Version, newEntry.Version)
if err := d.removePackagesFromProfile(ctx, []string{pkg.Raw}); err != nil {
// Warn but continue. TODO(landau): ensurePackagesAreInstalled should
// sync the profile so we don't need to do this manually.
ux.Fwarning(d.writer, "Failed to remove %s from profile: %s\n", pkg, err)
}
} else if existing == nil {
ux.Finfo(d.writer, "Resolved %s to %[1]s %[2]s\n", pkg, newEntry.Resolved)
} else {
ux.Finfo(d.writer, "Already up-to-date %s %s\n", pkg, existing.Version)
}
// Set the new entry after we've removed the old package from the profile
d.lockfile.Packages[pkg.Raw] = newEntry
return nil
}

// attemptToUpgradeFlake attempts to upgrade a flake using `nix profile upgrade`
// and prints an error if it fails, but does not propagate upgrade errors.
func (d *Devbox) attemptToUpgradeFlake(pkg *nix.Input) error {
profilePath, err := d.profilePath()
if err != nil {
return err
}

ux.Finfo(
d.writer,
"Attempting to upgrade %s using `nix profile upgrade`\n",
pkg.Raw,
)

err = nix.Upgrade(profilePath, pkg, d.lockfile)
if err != nil {
ux.Ferror(
d.writer,
"Failed to upgrade %s using `nix profile upgrade`: %s\n",
pkg.Raw,
err,
)
}

return nil
}
33 changes: 33 additions & 0 deletions internal/nix/upgrade.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package nix

import (
"fmt"
"os"
"os/exec"

"go.jetpack.io/devbox/internal/lock"
"go.jetpack.io/devbox/internal/redact"
)

func Upgrade(ProfileDir string, pkg *Input, lock *lock.File) error {
idx, err := ProfileListIndex(&ProfileListIndexArgs{
Lockfile: lock,
Writer: os.Stderr,
Input: pkg,
ProfileDir: ProfileDir,
})
if err != nil {
return err
}
cmd := exec.Command("nix", "profile", "upgrade",
"--profile", ProfileDir,
fmt.Sprintf("%d", idx),
)
cmd.Args = append(cmd.Args, ExperimentalFlags()...)
out, err := cmd.CombinedOutput()
if err != nil {
return redact.Errorf(
"error running \"nix profile upgrade\": %s: %w", out, err)
}
return nil
}