(ctx context.Context, mode installMode)
| 625 | } |
| 626 | |
| 627 | func (d *Devbox) packagesToInstallInStore(ctx context.Context, mode installMode) ([]*devpkg.Package, error) { |
| 628 | defer debug.FunctionTimer().End() |
| 629 | // First, get and prepare all the packages that must be installed in this project |
| 630 | // and remove non-nix packages from the list |
| 631 | packages := lo.Filter(d.InstallablePackages(), devpkg.IsNix) |
| 632 | if err := devpkg.FillNarInfoCache(ctx, packages...); err != nil { |
| 633 | return nil, err |
| 634 | } |
| 635 | |
| 636 | // Second, check which packages are not in the nix store |
| 637 | packagesToInstall := []*devpkg.Package{} |
| 638 | storePathsForPackage := map[*devpkg.Package][]string{} |
| 639 | for _, pkg := range packages { |
| 640 | if mode == update && d.isBeingUpdated(pkg) { |
| 641 | packagesToInstall = append(packagesToInstall, pkg) |
| 642 | continue |
| 643 | } |
| 644 | var err error |
| 645 | storePathsForPackage[pkg], err = pkg.GetStorePaths(ctx, d.stderr) |
| 646 | if err != nil { |
| 647 | return nil, err |
| 648 | } |
| 649 | } |
| 650 | |
| 651 | // Batch this for perf |
| 652 | storePathMap, err := nix.StorePathsAreInStore(ctx, lo.Flatten(lo.Values(storePathsForPackage))) |
| 653 | if err != nil { |
| 654 | return nil, err |
| 655 | } |
| 656 | |
| 657 | for pkg, storePaths := range storePathsForPackage { |
| 658 | for _, storePath := range storePaths { |
| 659 | if !storePathMap[storePath] { |
| 660 | packagesToInstall = append(packagesToInstall, pkg) |
| 661 | break |
| 662 | } |
| 663 | } |
| 664 | } |
| 665 | |
| 666 | return lo.Uniq(packagesToInstall), nil |
| 667 | } |
| 668 | |
| 669 | func (d *Devbox) isBeingUpdated(pkg *devpkg.Package) bool { |
| 670 | for _, u := range d.packagesBeingUpdated { |
no test coverage detected