<feed xmlns='http://www.w3.org/2005/Atom'>
<title>guix/tests/derivations.scm, branch kernel-updates</title>
<subtitle>Transactional package manager, declarative GNU/Linux distribution, reproducible deployment tool, and more! https://guix.gnu.org</subtitle>
<link rel='alternate' type='text/html' href='https://git.vineetk.net/guix/'/>
<entry>
<title>tests: Pass ‘User-Agent’ header when downloading from www.gnu.org.</title>
<updated>2026-03-29T20:20:59+00:00</updated>
<author>
<name>Ludovic Courtès</name>
<email>ludo@gnu.org</email>
</author>
<published>2026-03-25T18:03:38+00:00</published>
<link rel='alternate' type='text/html' href='https://git.vineetk.net/guix/commit/?id=0a8acc00599a43763697f8bfc4542ff0b34cf689'/>
<id>0a8acc00599a43763697f8bfc4542ff0b34cf689</id>
<content type='text'>
This test had been failing for a few months in part due to this change at
www.gnu.org.

* tests/derivations.scm ("fixed-output derivation, network access, external host"):
Pass #:headers to ‘http-get’.

Change-Id: Ife54e65b2665704af433df669df0d4010b49884c
Signed-off-by: Ludovic Courtès &lt;ludo@gnu.org&gt;
Merges: #7470
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This test had been failing for a few months in part due to this change at
www.gnu.org.

* tests/derivations.scm ("fixed-output derivation, network access, external host"):
Pass #:headers to ‘http-get’.

Change-Id: Ife54e65b2665704af433df669df0d4010b49884c
Signed-off-by: Ludovic Courtès &lt;ludo@gnu.org&gt;
Merges: #7470
</pre>
</div>
</content>
</entry>
<entry>
<title>derivations: Let ‘map-derivation’ correctly handle directories.</title>
<updated>2026-03-20T21:43:11+00:00</updated>
<author>
<name>Sergio Pastor Pérez</name>
<email>sergio.pastorperez@gmail.com</email>
</author>
<published>2025-03-01T18:06:08+00:00</published>
<link rel='alternate' type='text/html' href='https://git.vineetk.net/guix/commit/?id=cf2a11b9661ed4b83012a533ef355eab4cbc238e'/>
<id>cf2a11b9661ed4b83012a533ef355eab4cbc238e</id>
<content type='text'>
The 'map-derivation' procedure was trying to process directories as files.
When a derivation had a 'module import' directory as input, it threw an
exception since it tried to open it as a file.

* guix/derivations.scm (map-derivation): In ‘sources’, add
‘file-is-directory?’ case.
* tests/derivations.scm ("map-derivation, modules"): New test.

Fixes: https://issues.guix.gnu.org/71941
Change-Id: I9b766f9aaa03ea9307f73e8abb36bc347af4b5e6
Signed-off-by: Ludovic Courtès &lt;ludo@gnu.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The 'map-derivation' procedure was trying to process directories as files.
When a derivation had a 'module import' directory as input, it threw an
exception since it tried to open it as a file.

* guix/derivations.scm (map-derivation): In ‘sources’, add
‘file-is-directory?’ case.
* tests/derivations.scm ("map-derivation, modules"): New test.

Fixes: https://issues.guix.gnu.org/71941
Change-Id: I9b766f9aaa03ea9307f73e8abb36bc347af4b5e6
Signed-off-by: Ludovic Courtès &lt;ludo@gnu.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>daemon: Actually remove unreadable directories.</title>
<updated>2026-02-27T22:54:00+00:00</updated>
<author>
<name>Reepca Russelstein</name>
<email>reepca@russelstein.xyz</email>
</author>
<published>2026-02-15T18:39:34+00:00</published>
<link rel='alternate' type='text/html' href='https://git.vineetk.net/guix/commit/?id=865cb0188c282726008c56319a853c7dd82c4057'/>
<id>865cb0188c282726008c56319a853c7dd82c4057</id>
<content type='text'>
Fixes a regression introduced in 7173c2c0ca.  Additional discussion at
https://codeberg.org/guix/guix/pulls/5977.

* nix/libutil/util.cc (_deletePathAt): chmod directory and retry open when it
  fails with EACCES.  Do this using an O_PATH file descriptor referenced via
  /proc/self/fd whenever possible to avoid it being replaced by a
  non-directory immediately before being chmod'ed.
* nix/libutil/util.hh (deletePath): document TOCTTOU race on non-linux systems
  where hardlinks aren't protected.
* tests/derivations.scm ("unreadable directories in build tree can be
  removed"): new test.

Fixes: guix/guix#5891
Reported-by: Liliana Marie Prikler &lt;liliana.prikler@gmail.com&gt;
Change-Id: I749127fe5254ebabc8387a2f0ef47e3c116bfcc5
Signed-off-by: Ludovic Courtès &lt;ludo@gnu.org&gt;
Merges: #6460
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Fixes a regression introduced in 7173c2c0ca.  Additional discussion at
https://codeberg.org/guix/guix/pulls/5977.

* nix/libutil/util.cc (_deletePathAt): chmod directory and retry open when it
  fails with EACCES.  Do this using an O_PATH file descriptor referenced via
  /proc/self/fd whenever possible to avoid it being replaced by a
  non-directory immediately before being chmod'ed.
* nix/libutil/util.hh (deletePath): document TOCTTOU race on non-linux systems
  where hardlinks aren't protected.
* tests/derivations.scm ("unreadable directories in build tree can be
  removed"): new test.

Fixes: guix/guix#5891
Reported-by: Liliana Marie Prikler &lt;liliana.prikler@gmail.com&gt;
Change-Id: I749127fe5254ebabc8387a2f0ef47e3c116bfcc5
Signed-off-by: Ludovic Courtès &lt;ludo@gnu.org&gt;
Merges: #6460
</pre>
</div>
</content>
</entry>
<entry>
<title>tests: don't use 'file://...' URIs for testing git downloads.</title>
<updated>2025-10-12T20:22:01+00:00</updated>
<author>
<name>Reepca Russelstein</name>
<email>reepca@russelstein.xyz</email>
</author>
<published>2025-09-17T03:08:19+00:00</published>
<link rel='alternate' type='text/html' href='https://git.vineetk.net/guix/commit/?id=55a10ce4e618d334ccc5df71bf94483d7c9966ed'/>
<id>55a10ce4e618d334ccc5df71bf94483d7c9966ed</id>
<content type='text'>
While 'url-fetch*' in (guix download) special-cases these URIs, 'git-fetch'
does not.  Consequently, the recent changes to (guix scripts perform-download)
that disallow these URIs cause tests that use builtin:git-download to fail.

* guix/tests/git.scm (serve-git-repository, call-with-served-git-repository):
  new procedures.
  (with-served-git-repository, with-served-temporary-git-repository): new
  syntax.
* .dir-locals.el (scheme-mode): add indentation information for
  'with-served-git-repository'.
* tests/builders.scm ("git-fetch, file URI"): use git:// URI with
  'with-served-temporary-git-repository'.
* tests/derivations.scm ("'git-download' build-in builder, invalid hash",
  "'git-download' built-in builder, invalid commit", "'git-download' built-in
  builder, not found"): same.
  ("'git-download' built-in builder"): same, and use a nonce in the repo
  contents so that success isn't cached.

Change-Id: Id3e1233bb74d5987faf89c4341e1d37f09c77c80
Signed-off-by: Ludovic Courtès &lt;ludo@gnu.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
While 'url-fetch*' in (guix download) special-cases these URIs, 'git-fetch'
does not.  Consequently, the recent changes to (guix scripts perform-download)
that disallow these URIs cause tests that use builtin:git-download to fail.

* guix/tests/git.scm (serve-git-repository, call-with-served-git-repository):
  new procedures.
  (with-served-git-repository, with-served-temporary-git-repository): new
  syntax.
* .dir-locals.el (scheme-mode): add indentation information for
  'with-served-git-repository'.
* tests/builders.scm ("git-fetch, file URI"): use git:// URI with
  'with-served-temporary-git-repository'.
* tests/derivations.scm ("'git-download' build-in builder, invalid hash",
  "'git-download' built-in builder, invalid commit", "'git-download' built-in
  builder, not found"): same.
  ("'git-download' built-in builder"): same, and use a nonce in the repo
  contents so that success isn't cached.

Change-Id: Id3e1233bb74d5987faf89c4341e1d37f09c77c80
Signed-off-by: Ludovic Courtès &lt;ludo@gnu.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>daemon: Use slirp4netns to provide networking to fixed-output derivations.</title>
<updated>2025-06-24T14:07:57+00:00</updated>
<author>
<name>Reepca Russelstein</name>
<email>reepca@russelstein.xyz</email>
</author>
<published>2025-04-18T06:35:31+00:00</published>
<link rel='alternate' type='text/html' href='https://git.vineetk.net/guix/commit/?id=fb42611b8f27960304db5a1c0d33b8371dcde2a8'/>
<id>fb42611b8f27960304db5a1c0d33b8371dcde2a8</id>
<content type='text'>
Previously, the builder of a fixed-output derivation could communicate with an
external process via an abstract Unix-domain socket.  In particular, it could
send an open file descriptor to the store, granting write access to some of
its output files in the store provided the derivation build fails—the fix for
CVE-2024-27297 did not address this specific case.  It could also send an open
file descriptor to a setuid program, which could then be executed using
execveat to gain the privileges of the build user.

With this change, fixed-output derivations other than “builtin:download”
and “builtin:git-download” always run in a separate network namespace
and have network access provided by a TAP device backed by slirp4netns,
thereby closing the abstract Unix-domain socket channel.

* nix/libstore/globals.hh (Settings)[useHostLoopback, slirp4netns]: new
fields.
* config-daemon.ac (SLIRP4NETNS): new C preprocessor definition.
* nix/libstore/globals.cc (Settings::Settings): initialize them to defaults.
* nix/nix-daemon/guix-daemon.cc (options): add --isolate-host-loopback option.
* doc/guix.texi: document it.
* nix/libstore/build.cc (DerivationGoal)[slirp]: New field.
(setupTap, setupTapAction, waitForSlirpReadyAction, enableRouteLocalnetAction,
 prepareSlirpChrootAction, spawnSlirp4netns, haveGlobalIPv6Address,
 remapIdsTo0Action): New functions.
(initializeUserNamespace): allow the guest UID and GID to be specified.
(DerivationGoal::killChild): When ‘slirp’ is not -1, call ‘kill’.
(DerivationGoal::startBuilder): Unconditionally add CLONE_NEWNET to FLAGS.
When ‘fixedOutput’ is true, spawn ‘slirp4netns’.
When ‘fixedOutput’ and ‘useChroot’ are true, add setupTapAction,
waitForSlirpReadyAction, and enableRouteLocalnetAction to builder setup
phases.
Create a /etc/resolv.conf for fixed-output derivations that directs them to
slirp4netns's dns address.
When settings.useHostLoopback is true, supply fixed-output derivations with a
/etc/hosts that resolves "localhost" to slirp4netns's address for accessing
the host loopback.
* nix/libutil/util.cc (keepOnExec, decodeOctalEscaped, sendFD, receiveFD,
  findProgram): New functions.
* nix/libutil/util.hh (keepOnExec, decodeOctalEscaped, sendFD, receiveFD,
  findProgram): New declarations.
* gnu/packages/package-management.scm (guix): add slirp4netns input for linux
  targets.
* tests/derivations.scm (builder-network-isolated?): new variable.
  ("fixed-output derivation, network access, localhost", "fixed-output
  derivation, network access, external host"):
  skip test case if fixed output derivations are isolated from the network.

Change-Id: Ia3fea2ab7add56df66800071cf15cdafe7bfab96
Signed-off-by: John Kehayias &lt;john.kehayias@protonmail.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Previously, the builder of a fixed-output derivation could communicate with an
external process via an abstract Unix-domain socket.  In particular, it could
send an open file descriptor to the store, granting write access to some of
its output files in the store provided the derivation build fails—the fix for
CVE-2024-27297 did not address this specific case.  It could also send an open
file descriptor to a setuid program, which could then be executed using
execveat to gain the privileges of the build user.

With this change, fixed-output derivations other than “builtin:download”
and “builtin:git-download” always run in a separate network namespace
and have network access provided by a TAP device backed by slirp4netns,
thereby closing the abstract Unix-domain socket channel.

* nix/libstore/globals.hh (Settings)[useHostLoopback, slirp4netns]: new
fields.
* config-daemon.ac (SLIRP4NETNS): new C preprocessor definition.
* nix/libstore/globals.cc (Settings::Settings): initialize them to defaults.
* nix/nix-daemon/guix-daemon.cc (options): add --isolate-host-loopback option.
* doc/guix.texi: document it.
* nix/libstore/build.cc (DerivationGoal)[slirp]: New field.
(setupTap, setupTapAction, waitForSlirpReadyAction, enableRouteLocalnetAction,
 prepareSlirpChrootAction, spawnSlirp4netns, haveGlobalIPv6Address,
 remapIdsTo0Action): New functions.
(initializeUserNamespace): allow the guest UID and GID to be specified.
(DerivationGoal::killChild): When ‘slirp’ is not -1, call ‘kill’.
(DerivationGoal::startBuilder): Unconditionally add CLONE_NEWNET to FLAGS.
When ‘fixedOutput’ is true, spawn ‘slirp4netns’.
When ‘fixedOutput’ and ‘useChroot’ are true, add setupTapAction,
waitForSlirpReadyAction, and enableRouteLocalnetAction to builder setup
phases.
Create a /etc/resolv.conf for fixed-output derivations that directs them to
slirp4netns's dns address.
When settings.useHostLoopback is true, supply fixed-output derivations with a
/etc/hosts that resolves "localhost" to slirp4netns's address for accessing
the host loopback.
* nix/libutil/util.cc (keepOnExec, decodeOctalEscaped, sendFD, receiveFD,
  findProgram): New functions.
* nix/libutil/util.hh (keepOnExec, decodeOctalEscaped, sendFD, receiveFD,
  findProgram): New declarations.
* gnu/packages/package-management.scm (guix): add slirp4netns input for linux
  targets.
* tests/derivations.scm (builder-network-isolated?): new variable.
  ("fixed-output derivation, network access, localhost", "fixed-output
  derivation, network access, external host"):
  skip test case if fixed output derivations are isolated from the network.

Change-Id: Ia3fea2ab7add56df66800071cf15cdafe7bfab96
Signed-off-by: John Kehayias &lt;john.kehayias@protonmail.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>tests: Test network access from fixed-output derivations.</title>
<updated>2025-06-24T14:07:52+00:00</updated>
<author>
<name>Ludovic Courtès</name>
<email>ludo@gnu.org</email>
</author>
<published>2025-04-15T12:38:27+00:00</published>
<link rel='alternate' type='text/html' href='https://git.vineetk.net/guix/commit/?id=a183afa8e251e86d9dc17e8f177deeef0c1d534d'/>
<id>a183afa8e251e86d9dc17e8f177deeef0c1d534d</id>
<content type='text'>
* tests/derivations.scm ("fixed-output derivation, network access, localhost")
("fixed-output derivation, network access, external host"): New tests.

Change-Id: Iec164981a12ffef1bcb6a63ed9c2f1f363c53d80
Signed-off-by: John Kehayias &lt;john.kehayias@protonmail.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
* tests/derivations.scm ("fixed-output derivation, network access, localhost")
("fixed-output derivation, network access, external host"): New tests.

Change-Id: Iec164981a12ffef1bcb6a63ed9c2f1f363c53d80
Signed-off-by: John Kehayias &lt;john.kehayias@protonmail.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>tests: Add missing derivation inputs.</title>
<updated>2025-03-26T16:57:44+00:00</updated>
<author>
<name>Ludovic Courtès</name>
<email>ludo@gnu.org</email>
</author>
<published>2025-02-25T11:24:31+00:00</published>
<link rel='alternate' type='text/html' href='https://git.vineetk.net/guix/commit/?id=f854095b6ffb6ed86c8a66126825b7d41b5ccf96'/>
<id>f854095b6ffb6ed86c8a66126825b7d41b5ccf96</id>
<content type='text'>
These missing inputs go unnoticed when running ‘guix-daemon
--disable-chroot’ but are immediately visible otherwise.

* tests/derivations.scm ("fixed-output derivation"): Add %BASH to #:sources.
("fixed-output derivation: output paths are equal"):
("fixed-output derivation, recursive"):
("derivation with a fixed-output input"):
("derivation with duplicate fixed-output inputs"):
("derivation with equivalent fixed-output inputs"):
("build derivation with coreutils"): Likewise.
* tests/packages.scm (bootstrap-binary): New procedure.
("package-source-derivation, origin, sha512"): Use it instead of
‘search-bootstrap-binary’ and add BASH to #:sources.
("package-source-derivation, origin, sha3-512"): Likewise.

Change-Id: I4c9087df23c47729a3aff15e9e1435b7266e36e2
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
These missing inputs go unnoticed when running ‘guix-daemon
--disable-chroot’ but are immediately visible otherwise.

* tests/derivations.scm ("fixed-output derivation"): Add %BASH to #:sources.
("fixed-output derivation: output paths are equal"):
("fixed-output derivation, recursive"):
("derivation with a fixed-output input"):
("derivation with duplicate fixed-output inputs"):
("derivation with equivalent fixed-output inputs"):
("build derivation with coreutils"): Likewise.
* tests/packages.scm (bootstrap-binary): New procedure.
("package-source-derivation, origin, sha512"): Use it instead of
‘search-bootstrap-binary’ and add BASH to #:sources.
("package-source-derivation, origin, sha3-512"): Likewise.

Change-Id: I4c9087df23c47729a3aff15e9e1435b7266e36e2
</pre>
</div>
</content>
</entry>
<entry>
<title>daemon: Allow running as non-root with unprivileged user namespaces.</title>
<updated>2025-03-26T16:57:43+00:00</updated>
<author>
<name>Ludovic Courtès</name>
<email>ludovic.courtes@inria.fr</email>
</author>
<published>2025-01-22T22:40:24+00:00</published>
<link rel='alternate' type='text/html' href='https://git.vineetk.net/guix/commit/?id=ae18b3d9e6bd0c184505a094851448d08555e23e'/>
<id>ae18b3d9e6bd0c184505a094851448d08555e23e</id>
<content type='text'>
Many thanks to Reepca Russelstein for their review and guidance on these
changes.

* nix/libstore/build.cc (guestUID, guestGID): New variables.
(DerivationGoal)[readiness]: New field.
(initializeUserNamespace): New function.
(DerivationGoal::runChild): When ‘readiness.readSide’ is positive, read
from it.
(DerivationGoal::startBuilder): Call ‘chown’
only when ‘buildUser.enabled()’ is true.  Pass CLONE_NEWUSER to ‘clone’
when ‘buildUser.enabled()’ is false or not running as root.  Retry
‘clone’ without CLONE_NEWUSER upon EPERM.
(DerivationGoal::registerOutputs): Make ‘actualPath’ writable before
‘rename’.
(DerivationGoal::deleteTmpDir): Catch ‘SysError’ around ‘_chown’ call.
* nix/libstore/local-store.cc (LocalStore::createUser): Do nothing if
‘dirs’ already exists.  Warn instead of failing when failing to chown
‘dir’.
* guix/substitutes.scm (%narinfo-cache-directory): Check for
‘_NIX_OPTIONS’ rather than getuid() == 0 to determine the cache
location.
* doc/guix.texi (Build Environment Setup): Reorganize a bit.  Add
section headings “Daemon Running as Root” and “The Isolated Build
Environment”.  Add “Daemon Running Without Privileges” subsection.
Remove paragraph about ‘--disable-chroot’.
(Invoking guix-daemon): Warn against ‘--disable-chroot’ and explain why.
* tests/derivations.scm ("builder is outside the store"): New test.

Reviewed-by: Reepca Russelstein &lt;reepca@russelstein.xyz&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Many thanks to Reepca Russelstein for their review and guidance on these
changes.

* nix/libstore/build.cc (guestUID, guestGID): New variables.
(DerivationGoal)[readiness]: New field.
(initializeUserNamespace): New function.
(DerivationGoal::runChild): When ‘readiness.readSide’ is positive, read
from it.
(DerivationGoal::startBuilder): Call ‘chown’
only when ‘buildUser.enabled()’ is true.  Pass CLONE_NEWUSER to ‘clone’
when ‘buildUser.enabled()’ is false or not running as root.  Retry
‘clone’ without CLONE_NEWUSER upon EPERM.
(DerivationGoal::registerOutputs): Make ‘actualPath’ writable before
‘rename’.
(DerivationGoal::deleteTmpDir): Catch ‘SysError’ around ‘_chown’ call.
* nix/libstore/local-store.cc (LocalStore::createUser): Do nothing if
‘dirs’ already exists.  Warn instead of failing when failing to chown
‘dir’.
* guix/substitutes.scm (%narinfo-cache-directory): Check for
‘_NIX_OPTIONS’ rather than getuid() == 0 to determine the cache
location.
* doc/guix.texi (Build Environment Setup): Reorganize a bit.  Add
section headings “Daemon Running as Root” and “The Isolated Build
Environment”.  Add “Daemon Running Without Privileges” subsection.
Remove paragraph about ‘--disable-chroot’.
(Invoking guix-daemon): Warn against ‘--disable-chroot’ and explain why.
* tests/derivations.scm ("builder is outside the store"): New test.

Reviewed-by: Reepca Russelstein &lt;reepca@russelstein.xyz&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>tests: Remove extraneous 'with-store' in derivations test.</title>
<updated>2025-02-22T14:55:24+00:00</updated>
<author>
<name>Maxim Cournoyer</name>
<email>maxim.cournoyer@gmail.com</email>
</author>
<published>2025-02-17T14:35:07+00:00</published>
<link rel='alternate' type='text/html' href='https://git.vineetk.net/guix/commit/?id=aea511df9333b6b9cd441b11cd221176af0e14b9'/>
<id>aea511df9333b6b9cd441b11cd221176af0e14b9</id>
<content type='text'>
* tests/derivations.scm ("derivation fails but keep going"): Remove extraneous
'with-store'.

Change-Id: If30c2d457504b8524cd167f1a145fbbea61b513c
Signed-off-by: Maxim Cournoyer &lt;maxim.cournoyer@gmail.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
* tests/derivations.scm ("derivation fails but keep going"): Remove extraneous
'with-store'.

Change-Id: If30c2d457504b8524cd167f1a145fbbea61b513c
Signed-off-by: Maxim Cournoyer &lt;maxim.cournoyer@gmail.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>derivations: ‘derivation-build-plan’ returns builds in topological order.</title>
<updated>2024-11-12T22:46:49+00:00</updated>
<author>
<name>Ludovic Courtès</name>
<email>ludo@gnu.org</email>
</author>
<published>2024-10-22T13:01:48+00:00</published>
<link rel='alternate' type='text/html' href='https://git.vineetk.net/guix/commit/?id=c62f8ab11ff915bd834fc1db5dba3449c9b4b474'/>
<id>c62f8ab11ff915bd834fc1db5dba3449c9b4b474</id>
<content type='text'>
That makes ‘derivation-build-plan’ directly usable in cases where one
wants to sequentially build derivations one by one, or to report builds
in the right order in the user interface.

* guix/derivations.scm (derivation-build-plan): Wrap ‘loop’ in
‘traverse’.  Perform a depth-first traversal.  Return the list of builds
in topological order.
* tests/derivations.scm ("derivation-build-plan, topological ordering"):
New test.

Change-Id: I7cd9083f42c4381b4213794a40dbb5b234df966d
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
That makes ‘derivation-build-plan’ directly usable in cases where one
wants to sequentially build derivations one by one, or to report builds
in the right order in the user interface.

* guix/derivations.scm (derivation-build-plan): Wrap ‘loop’ in
‘traverse’.  Perform a depth-first traversal.  Return the list of builds
in topological order.
* tests/derivations.scm ("derivation-build-plan, topological ordering"):
New test.

Change-Id: I7cd9083f42c4381b4213794a40dbb5b234df966d
</pre>
</div>
</content>
</entry>
</feed>
