Hello! Pierre Neidhardt <m...@ambrevar.xyz> skribis:
> Ideas that are not that good on second thought: > > - Create a profile specification file from CLI options, > like --export PROFILE or --convert MANIFEST. > > The problem is that those are extra steps that the user would have to run > manually. We can save those extra steps by dumping the specification file > automatically into the profile. > > The Plan©: > > On every profile installation, we generate a "specifications.scm" file > alongside > the internal "manifest". One thing to keep in mind, though, is that if the ‘specifications.scm’ is part of the profile, it must be future-proof. That is, the APIs it uses must essentially be guaranteed to remain forever. That’s a very strong constraint. In contrast, versioned data formats like the famous ‘manifest’ file don’t have this problem at all, but they’re less directly usable from the CLI. > Problems: > > - There may be too many provenances, we need to add a CLI flag to > ignore provenance. Like Konrad wrote, just write if there are too many of them. > Proposed format for "specifications.scm": we can reuse > `specifications->manifest`. Each entry is either or string, in which case it > acts as before, or a list, with the following self-explanatory elements: > > (specifications->manifest > '(("my-package" > #:outputs '("out") > #:version "2.3" > #:channel (channel > (name 'guix) > (branch "master") > (url "https://git.savannah.gnu.org/git/guix.git") > (commit > "704719edade1368f798c9301f3a8197a0df5c930"))) > ("my-package2") > "old-style-package")) As a rule of thumb, I think ‘specifications->manifest’ must remain what it is: it should take a specification as is currently defined and return a manifest. I think that if we need a new concept, we should not overload an existing one. We also need to distinguish between APIs, which should use first-class objects (<channel>, etc.), and data formats, which are plain sexps. (The above example is a mixture of both and in fact looks very similar to what’s already in the ‘manifest’ file.) But then again, that means relying on a larger chunk of the API. So, all in all, I think I’d rather see it implemented as ‘guix package --export’ or similar. The generated Scheme file could use all the parts of the current API (and we could adjust the generator as we change the API). So it could generate something similar to the example in the manual (info "(guix) Inferiors"): --8<---------------cut here---------------start------------->8--- (use-modules (guix inferior) (guix channels) (srfi srfi-1)) ;for 'first' (define channels ;; This is the old revision from which we want to ;; extract guile-json. (list (channel (name 'guix) (url "https://git.savannah.gnu.org/git/guix.git") (commit "65956ad3526ba09e1f7a40722c96c6ef7c0936fe")))) (define inferior ;; An inferior representing the above revision. (inferior-for-channels channels)) ;; Now create a manifest with the current "guile" package ;; and the old "guile-json" package. (packages->manifest (list (first (lookup-inferior-packages inferior "guile-json")) (specification->package "guile"))) --8<---------------cut here---------------end--------------->8--- There could also be an option to generate a “symbolic” manifest: one that would install packages of the same name, but not resorting to inferiors. The result would not be a faithful translation of what’s actually in the store, but an approximation thereof that could be useful for people transitioning. In fact it would be easier to start by prototyping this before going further. As far as faithfulness is concerned, we should also keep in mind that we don’t always have all the information needed to reconstruct what’s in a profile. For example, we lack information about the package transformation options that were used (if any), and we lack information about arbitrary user code that might have been used to generate manifest entries. Thus, as we design this, I think we must keep in mind that the result is necessarily an approximation. > A somewhat unrelated propostion: To avoid further confusion between the > internal > "manifest" and the user-facing "--manifest", we could rename the internal > manifest to $profile/internal-maifest. Renaming ‘manifest’ is not really an option because, as we discussed, it’s a contract over time: today’s Guix can interact with a profile created 5 years ago just fine. Thanks for sharing your thoughts! Ludo’.