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)
```