Hello, Ricardo Wurmus <rek...@elephly.net> skribis:
>>> (define (latest-channel-instances store channels) >>> "Return a list of channel instances corresponding to the latest >>> checkouts of >>> -CHANNELS." >>> - (map (lambda (channel) >>> - (format (current-error-port) >>> - (G_ "Updating channel '~a' from Git repository at >>> '~a'...~%") >>> - (channel-name channel) >>> - (channel-url channel)) >>> - (let-values (((checkout commit) >>> - (latest-repository-commit store (channel-url >>> channel) >>> - #:ref (channel-reference >>> - channel)))) >>> - (channel-instance channel commit checkout))) >>> - channels)) >>> +CHANNELS and the channels on which they depend." >>> + (append-map (lambda (channel) >>> + (format (current-error-port) >>> + (G_ "Updating channel '~a' from Git repository at >>> '~a'...~%") >>> + (channel-name channel) >>> + (channel-url channel)) >>> + (let-values (((checkout commit) >>> + (latest-repository-commit store (channel-url >>> channel) >>> + #:ref >>> (channel-reference >>> + channel)))) >>> + (let ((instance (channel-instance channel commit >>> checkout))) >>> + (cons instance (latest-channel-instances >>> + store >>> + (channel-instance-dependencies >>> instance)))))) >>> + channels)) >> >> What happens if the dependency list contains duplicate channels? This >> might happen if two unrelated channels mutually depend upon a third >> channel. >> >> What happens if the dependency list contains two channels that differ >> only in their branch (or commit), and are the same in every other way? >> This might happen if two unrelated channels mutually depend upon two >> different versions of the same third channel. We should error out in this case because at run time, there can be only one Guile module with a given name. Thus, conflicting dependencies cannot be honored. (Not like Node.js, for better or worse. ;-)) > I was going to write an email about this just now. This is indeed a > problem with this naive implementation. > > For reproducibility a user may want to pin all channels to a certain > commit, but channels that are dependencies are exempt from that > mechanism as they are added to the list of channels to be instantiated > during the run of “guix pull”. > > It should be possible to pin *all* channels, even if they are > dependencies of other channels. One way is to treat all channels and > their dependencies as a unique set where duplicates are replaced with > the most specific description (e.g. those specifying a commit). This > way users could fully specify dependencies, which would then be used > instead of the channel’s declared dependency. Of course it’s easier to pin all channels when they are directly expressed in ~/.config/guix/channels.scm. Say, I need channel A, which depends on B. What we could do is that if B is already in ~/.config/guix/channels.scm, then we take this particular B; if it’s not there, we take the latest version. In terms of the dependency code, it means that dependencies found in .guix-channels file are added if and only if they are not already present in the user-provided channel list. Does that make sense? Thanks! Ludo’.