Skip to content

Commit

Permalink
generate devpkg.Package from Config
Browse files Browse the repository at this point in the history
  • Loading branch information
savil committed Aug 10, 2023
1 parent 485ec44 commit 9a3354a
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 27 deletions.
24 changes: 14 additions & 10 deletions internal/devconfig/packages.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,20 +36,11 @@ type Packages struct {
func (pkgs *Packages) VersionedNames() []string {
result := make([]string, 0, len(pkgs.Collection))
for _, p := range pkgs.Collection {
name := p.name
if p.Version != "" {
name += "@" + p.Version
}
result = append(result, name)
result = append(result, p.VersionedName())
}
return result
}

func (pkgs *Packages) VersionedNamesForPlatform() ([]string, error) {
// TODO savil. Next PR will update this implementation
return pkgs.VersionedNames(), nil
}

// Add adds a package to the list of packages
func (pkgs *Packages) Add(versionedName string) {
name, version := parseVersionedName(versionedName)
Expand Down Expand Up @@ -159,6 +150,19 @@ func NewPackage(name string, values map[string]any) Package {
}
}

func (p *Package) VersionedName() string {
name := p.name
if p.Version != "" {
name += "@" + p.Version
}
return name
}

func (p *Package) IsEnabledOnPlatform() (bool, error) {
// TODO savil. Next PR will update this implementation
return true, nil
}

func (p *Package) UnmarshalJSON(data []byte) error {
// First, attempt to unmarshal as a version-only string
var version string
Expand Down
29 changes: 28 additions & 1 deletion internal/devpkg/package.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"go.jetpack.io/devbox/internal/boxcli/featureflag"
"go.jetpack.io/devbox/internal/boxcli/usererr"
"go.jetpack.io/devbox/internal/cuecfg"
"go.jetpack.io/devbox/internal/devconfig"
"go.jetpack.io/devbox/internal/lock"
"go.jetpack.io/devbox/internal/nix"
"go.jetpack.io/devbox/internal/vercheck"
Expand Down Expand Up @@ -46,6 +47,9 @@ type Package struct {
// example: github:nixos/nixpkgs/5233fd2ba76a3accb5aaa999c00509a11fd0793c#hello
Raw string

// isInstallable is true if the package may be enabled on the current platform.
isInstallable bool

normalizedPackageAttributePathCache string // memoized value from normalizedPackageAttributePath()
}

Expand All @@ -59,9 +63,26 @@ func PackageFromStrings(rawNames []string, l lock.Locker) []*Package {
return packages
}

func PackagesFromConfig(config *devconfig.Config, l lock.Locker) ([]*Package, error) {
result := []*Package{}
for _, pkg := range config.Packages.Collection {
isInstallable, err := pkg.IsEnabledOnPlatform()
if err != nil {
return nil, err
}
result = append(result, newPackage(pkg.VersionedName(), isInstallable, l))
}
return result, nil
}

// PackageFromString constructs Package from the raw name provided.
// The raw name corresponds to a devbox package from the devbox.json config.
func PackageFromString(raw string, locker lock.Locker) *Package {
// Packages are installable by default.
return newPackage(raw, true /*isInstallable*/, locker)
}

func newPackage(raw string, isInstallable bool, locker lock.Locker) *Package {
// TODO: We should handle this error
// TODO: URL might not be best representation since most packages are not urls
pkgURL, _ := url.Parse(raw)
Expand All @@ -79,7 +100,7 @@ func PackageFromString(raw string, locker lock.Locker) *Package {
pkgURL, _ = url.Parse(normalizedURL)
}

return &Package{URL: *pkgURL, lockfile: locker, Raw: raw}
return &Package{URL: *pkgURL, lockfile: locker, Raw: raw, isInstallable: isInstallable}
}

// isLocal specifies whether this package is a local flake.
Expand Down Expand Up @@ -146,6 +167,12 @@ func (p *Package) URLForFlakeInput() string {
return p.urlWithoutFragment()
}

// IsInstallable returns whether this package is installable. Not to be confused
// with the Installable() method which returns the corresponding nix concept.
func (p *Package) IsInstallable() bool {
return p.isInstallable
}

// Installable for this package. Installable is a nix concept defined here:
// https://nixos.org/manual/nix/stable/command-ref/new-cli/nix.html#installables
func (p *Package) Installable() (string, error) {
Expand Down
61 changes: 45 additions & 16 deletions internal/impl/devbox.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,9 +110,14 @@ func Open(opts *devopt.Opts) (*Devbox, error) {
)
box.lockfile = lock

hasDeprecated, err := box.HasDeprecatedPackages()
if err != nil {
return nil, err
}

if !opts.IgnoreWarnings &&
!legacyPackagesWarningHasBeenShown &&
box.HasDeprecatedPackages() {
hasDeprecated {
legacyPackagesWarningHasBeenShown = true
globalPath, err := GlobalDataPath()
if err != nil {
Expand All @@ -138,7 +143,11 @@ func (d *Devbox) Config() *devconfig.Config {
}

func (d *Devbox) ConfigHash() (string, error) {
pkgHashes := lo.Map(d.ConfigPackages(), func(i *devpkg.Package, _ int) string { return i.Hash() })
pkgs, err := d.ConfigPackages()
if err != nil {
return "", err
}
pkgHashes := lo.Map(pkgs, func(i *devpkg.Package, _ int) string { return i.Hash() })
includeHashes := lo.Map(d.Includes(), func(i plugin.Includable, _ int) string { return i.Hash() })
h, err := d.cfg.Hash()
if err != nil {
Expand Down Expand Up @@ -934,28 +943,41 @@ func (d *Devbox) nixFlakesFilePath() string {

// ConfigPackageNames returns the package names as defined in devbox.json
func (d *Devbox) ConfigPackageNames() []string {
// TODO savil: centralize implementation by calling d.ConfigPackages and getting pkg.Raw
// Skipping for now to avoid propagating the error value.
return d.cfg.Packages.VersionedNames()
}

// InstallablePackageNames returns the names of packages that are to be installed
func (d *Devbox) InstallablePackageNames() ([]string, error) {
// TODO: next PR replaces this implementation
return d.cfg.Packages.VersionedNamesForPlatform()
pkgs, err := d.InstallablePackages()
if err != nil {
return nil, err
}
return lo.Map(pkgs, func(pkg *devpkg.Package, _ int) string {
return pkg.Raw
}), nil
}

// ConfigPackages returns the packages that are defined in devbox.json
// NOTE: the return type is different from devconfig.Packages
func (d *Devbox) ConfigPackages() []*devpkg.Package {
return devpkg.PackageFromStrings(d.ConfigPackageNames(), d.lockfile)
func (d *Devbox) ConfigPackages() ([]*devpkg.Package, error) {
pkgs, err := devpkg.PackagesFromConfig(d.cfg, d.lockfile)
if err != nil {
return nil, err
}
return pkgs, nil
}

// InstallablePackages returns the packages that are to be installed
func (d *Devbox) InstallablePackages() ([]*devpkg.Package, error) {
names, err := d.InstallablePackageNames()
pkgs, err := d.ConfigPackages()
if err != nil {
return nil, err
}
return devpkg.PackageFromStrings(names, d.lockfile), nil
return lo.Filter(pkgs, func(pkg *devpkg.Package, _ int) bool {
return pkg.IsInstallable()
}), nil
}

func (d *Devbox) Includes() []plugin.Includable {
Expand All @@ -968,21 +990,28 @@ func (d *Devbox) Includes() []plugin.Includable {
return includes
}

func (d *Devbox) HasDeprecatedPackages() bool {
for _, pkg := range d.ConfigPackages() {
func (d *Devbox) HasDeprecatedPackages() (bool, error) {
pkgs, err := d.ConfigPackages()
if err != nil {
return false, err
}
for _, pkg := range pkgs {
if pkg.IsLegacy() {
return true
return true, nil
}
}
return false
return false, nil
}

func (d *Devbox) findPackageByName(name string) (string, error) {
pkgs, err := d.ConfigPackages()
if err != nil {
return "", err
}
results := map[string]bool{}
for _, pkg := range d.ConfigPackageNames() {
i := devpkg.PackageFromString(pkg, d.lockfile)
if i.String() == name || i.CanonicalName() == name {
results[i.String()] = true
for _, pkg := range pkgs {
if pkg.String() == name || pkg.CanonicalName() == name {
results[pkg.String()] = true
}
}
if len(results) > 1 {
Expand Down

0 comments on commit 9a3354a

Please sign in to comment.