On 23/6/26 22:55, Hugo Buddelmeijer wrote:


On 6/23/26 20:43, Hugo Buddelmeijer wrote:
Hi all,

On 5/10/26 21:51, Hugo Buddelmeijer wrote:
What would be the easiest way to prevent any package from a specific
commit (or generation) to be garbage collected?

Maybe I can make a manifest with "all packages" and then filter out those that are not already in the store.  So the manifest will always build, since it would contain only already built packages.  Not really what a manifest normally should do, but I guess it could work.

In case anyone cares, I realized `guix weather` must be able to get the information I need. (Maybe the scripts should export more of their utility functions.)

Below is my current manifest-store.scm which contains all packages in the store that are part of the current guix generation. So I should be able to make them all live by putting them in a root, and then I can `guix gc` without actually loosing my build progress.

That is, I can now, on e.g. my python-team checkout do
```
guix build -k -m my-favorite-manifest.scm  # Many failures
guix build -m manifest-store.scm -r python-team-root
```
and then `guix gc` for unrelated reasons, keeping my progress.

At least I think I can now do that. Maybe I should also keep a --no-grafts root around. And maybe a root with sources.

The manifest raises many questions, but those answers will arrive in due time. E.g.

- Why is the below so much faster then my earlier attempt?
- What is the difference between `(with-monad %store-monad` and `(with-store store'?
- What is the difference between `lower-object` and `package->derivation`?

(Can I make an arbitrary stack of 'objects' other than packages that I can keep lowering until I finally get to a fixed store item? That would be so cool.)

Also, apparently I already have 5000 out of the 30000 packages in my store. Might as well get all of them if it is only a factor of 6!




```
;;; from guix weather
(define (call-with-progress-reporter reporter proc)
"This is a variant of 'call-with-progress-reporter' that works with monadic
scope."
  (with-monad %store-monad
              (start-progress-reporter! reporter)
              (mlet* %store-monad
                     ((report -> (lambda ()
                                   (progress-reporter-report! reporter)))
                      (result (proc report)))
                     (stop-progress-reporter! reporter)
                     (return result))))

;;; from guix weather
(define (package->derivation/no-grafts obj)
  (mlet* %store-monad ((previous (set-grafting #f))
                       (drv      (package->derivation obj))
                       (_        (set-grafting previous)))
         (return drv)))

(define* (filter-packages-in-store packages)
  "Return the list of outputs of all of PACKAGES."
  (format (current-error-port)
          (G_ "computing ~h package derivations...~%")
          (length packages))

  (call-with-progress-reporter
   (progress-reporter/bar (length packages))
   (lambda (report)
     (foldm %store-monad
            (lambda (package result)
(mlet %store-monad ((drv (package->derivation/no-grafts package)))
                    (report)
                    (match (derivation->output-paths drv)
                      (((names . items) ...)
                       (return
;; Just check the first output; good enough for now.
                        (if (file-exists? (first items))
                            (cons package result)
                            result))))))
            '()
            packages))))

(define packages-all
  (fold-packages
   cons
   '()))

(define packages-in-store
  (with-store store
              ((filter-packages-in-store packages-all) store)))

(packages->manifest packages-in-store)
```


Reply via email to