Ludovic Courtès (2014-08-12 23:50 +0400) wrote: [...]
>>> What about introducing a <manifest-transaction> type that would contain >>> a list of packages to install, to remove, and to upgrade, and we could do: >> >> I think only “install” part should contain a list of packages (or >> (PACKAGE OUTPUT) things). Upgrading and removing can be performed on >> obsolete packages, so only a package specification of an installed >> package is known in such cases. Perhaps any pattern (package (with >> "out" output), (package output), name specification) should be accepted. > > The arguments should be the same as (or compatible) for ‘manifest-add’ > and ‘manifest-remove’. > > So the list of packages could be installed could be a list of (PACKAGE > OUTPUT) as you note. > > The list of packages to upgrade could a list of (PACKAGE OUTPUT) as > well, computed by ‘guix package’ or guix.el. (The difficulty here is > that (guix profiles) should not depend on (gnu packages).) > > The list of packages to remove should be a list of <manifest-pattern>. > >> So there will be ‘make-manifest-transaction’ function with #:install, >> #:upgrade, #:remove keys. Do I understand it right? > > Rather, use (define-record-type* <manifest-transaction> ...), so we can > then write: > > (manifest-transaction > (install lst1) > (remove lst2) > ...) > >>> ;; Show what will/would be installed, removed, etc. >>> (show-transaction manifest transaction #:dry-run? bool) >>> >>> ;; Do the installation/removal/upgrades listed in TRANSACTION, and >>> ;; return the new manifest. >>> (manifest-perform-transaction manifest transaction) >> >> So ‘manifest-perform-transaction’ will open connection? If so, >> shouldn't it accept '#:dry-run' and '#:use-substitutes?' keys? > > No, it would just return the new manifest, built by successive calls to > ‘manifest-add’ and ‘manifest-remove’. Very simple. > > The actual profile is still built with ‘profile-derivation’. I realized there could be a problem with (PACKAGE OUTPUT) elements. They should be transformed into manifest entries, but "guix/scripts/package.scm" uses ‘package->manifest-entry*’ for that, so this cannot be performed in (guix profiles) module. Perhaps “install” should just contain a list of manifest entries. WDYT? And manifest-transaction stuff could look like this:
(define-record-type* <manifest-transaction> manifest-transaction make-manifest-transaction manifest-transaction? (install manifest-transaction-install ; list of <manifest-entry> (default '())) (remove manifest-transaction-remove ; list of <manifest-pattern> (default '()))) (define (manifest-perform-transaction manifest transaction) "Perform TRANSACTION on MANIFEST and return new manifest." (let ((install (manifest-transaction-install transaction)) (remove (manifest-transaction-remove transaction))) (manifest-add (manifest-remove manifest remove) install))) (define* (show-transaction manifest transaction #:key dry-run?) "Display what will/would be installed/removed from MANIFEST by TRANSACTION." (let ((install (manifest-transaction-install transaction)) (remove (manifest-matching-entries manifest (manifest-transaction-remove transaction)))) (match remove ((($ <manifest-entry> name version output path _) ..1) (let ((len (length name)) (remove (map (cut format #f " ~a-~a\t~a\t~a" <> <> <> <>) name version output path))) (if dry-run? (format (current-error-port) (N_ "The following package would be removed:~%~{~a~%~}~%" "The following packages would be removed:~%~{~a~%~}~%" len) remove) (format (current-error-port) (N_ "The following package will be removed:~%~{~a~%~}~%" "The following packages will be removed:~%~{~a~%~}~%" len) remove)))) (_ #f)) (match install ((($ <manifest-entry> name version output path _) ..1) (let ((len (length name)) (install (map (cut format #f " ~a-~a\t~a\t~a" <> <> <> <>) name version output path))) (if dry-run? (format (current-error-port) (N_ "The following package would be installed:~%~{~a~%~}~%" "The following packages would be installed:~%~{~a~%~}~%" len) install) (format (current-error-port) (N_ "The following package will be installed:~%~{~a~%~}~%" "The following packages will be installed:~%~{~a~%~}~%" len) install)))) (_ #f))))
(I excluded “upgrade” part as it's the same as “install”, and ‘show-transaction’ is almost the same as ‘show-what-to-remove/install’ from "package.scm".) Also I think "guix.el" should check for freshness too, so ‘check-package-freshness’ should probably be exported.