Skip to content

Commit

Permalink
Introduce nix derivation instantiate
Browse files Browse the repository at this point in the history
This is simmilar to `nix-instantiate` with support for installables (and flakes).
  • Loading branch information
layus committed Oct 7, 2024
1 parent 26c3fc1 commit d599b4f
Show file tree
Hide file tree
Showing 6 changed files with 179 additions and 0 deletions.
93 changes: 93 additions & 0 deletions src/nix/derivation-instantiate.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
#include "command.hh"
#include "common-args.hh"
#include "store-api.hh"
#include "derivations.hh"
#include "local-fs-store.hh"
#include "progress-bar.hh"

#include <nlohmann/json.hpp>

using namespace nix;

static nlohmann::json storePathSetToJSON(const StorePathSet & paths, Store & store)
{
auto res = nlohmann::json::object();
for (auto & path : paths) {
res[store.printStorePath(path)] = nlohmann::json::object();
}
return res;
}

// TODO deduplicate with other code also setting such out links.
static void
createOutLinks(const std::filesystem::path & outLink, const StorePathSet & derivations, LocalFSStore & store)
{
for (const auto & [_i, drv] : enumerate(derivations)) {
auto i = _i;
auto symlink = outLink;

if (i)
symlink += fmt("-%d", i);
store.addPermRoot(drv, absPath(symlink.string()));
}
}

struct CmdDerivationInstantiate : InstallablesCommand, MixJSON
{
Path outLink = "drv";
bool printOutputPaths = false;

CmdDerivationInstantiate()
{
addFlag(
{.longName = "out-link",
.shortName = 'o',
.description = "Use *path* as prefix for the symlinks to the evaluation results. It defaults to `drv`.",
.labels = {"path"},
.handler = {&outLink},
.completer = completePath});

addFlag({
.longName = "no-link",
.description = "Do not create symlinks to the evaluation results.",
.handler = {&outLink, Path("")},
});
}

std::string description() override
{
return "Force the evaluation of the expression and return the corresponding .drv";
}

std::string doc() override
{
return
#include "derivation-instantiate.md"
;
}

Category category() override
{
return catSecondary;
}

void run(ref<Store> store, Installables && installables) override
{
auto drvPaths = Installable::toDerivations(store, installables, false);

if (outLink != "")
if (auto store2 = store.dynamic_pointer_cast<LocalFSStore>())
createOutLinks(outLink, drvPaths, *store2);

if (json) {
logger->cout("%s", storePathSetToJSON(drvPaths, *store).dump());
} else {
stopProgressBar();
for (auto & path : drvPaths) {
logger->cout(store->printStorePath(path));
}
}
}
};

static auto rCmdDerivationInstantiate = registerCommand2<CmdDerivationInstantiate>({"derivation", "instantiate"});
39 changes: 39 additions & 0 deletions src/nix/derivation-instantiate.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
R""(

# Name

`nix derivation instantiate` - instantiate store derivations

# Synopsis

`nix derivation instantiate`
[`--out-link` *link prefix*]
[`--json`]
[`--no-link`]
*installables…*

# Description

The command `nix derivation instantiate` produces [store derivation]s from
installables. Each top-level expression should evaluate to a derivation, a list
of derivations, or a set of derivations. The paths of the resulting store
derivations are printed on standard output.

[store derivation]: @docroot@/glossary.md#gloss-store-derivation

# Options

- `--out-link` *link prefix*

The prefix used for gc roots.

- `--no-link`

Do not create garbage collector roots for the generated store derivations.

- `--json`

Dump a JSON object whose keys are the generated store derivations instread of
printing them directly on the output.

)""
1 change: 1 addition & 0 deletions src/nix/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ nix_sources = [config_h] + files(
'config.cc',
'copy.cc',
'derivation-add.cc',
'derivation-instantiate.cc',
'derivation-show.cc',
'derivation.cc',
'develop.cc',
Expand Down
44 changes: 44 additions & 0 deletions tests/functional/derivation-instantiate.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#!/usr/bin/env bash

source common.sh

TODO_NixOS

clearStore

drvPath=$(nix derivation instantiate --no-link --file simple.nix)
test -f "$drvPath"
nix-store --delete "$drvPath"
if test -f "$drvPath"; then false; fi

drvPath=$(nix derivation instantiate --file simple.nix)
test -f "$drvPath"
test -e drv
nix-store --gc --print-roots | grep "$drvPath"
nix-store --gc --print-live | grep "$drvPath"
if nix-store --delete "$drvPath"; then false; fi
test -f "$drvPath"
[ "$(nix-store -q --roots "$drvPath")" = "$(realpath --no-symlinks drv) -> $drvPath" ]
rm drv
nix-store --delete "$drvPath"
if test -f "$drvPath"; then false; fi

drvPath=$(nix derivation instantiate --out-link foobar --file simple.nix)
test -e foobar
[ "$(nix-store -q --roots "$drvPath")" = "$(realpath --no-symlinks foobar) -> $drvPath" ]
rm foobar
nix-store --delete "$drvPath"

drvPathJson=$(nix derivation instantiate --json --no-link --file simple.nix)
[ "$drvPathJson" = "{\"$drvPath\":{}}" ]
nix-store --delete "$drvPath"

mapfile -t drvPaths < <(nix derivation instantiate --json --out-link multidrv --file check.nix | jq 'keys|.[]' -r)
roots=(./multidrv*)
[ "${#roots[@]}" -gt 1 ]
[ "${#roots[@]}" -eq "${#drvPaths[@]}" ]
mapfile -t rootedPaths < <(readlink "${roots[@]}")
[ "${rootedPaths[*]}" = "${drvPaths[*]}" ]
rm -f multidrv*

nix-collect-garbage
1 change: 1 addition & 0 deletions tests/functional/local.mk
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ nix_tests = \
why-depends.sh \
derivation-json.sh \
derivation-advanced-attributes.sh \
derivation-instantiate.sh \
import-from-derivation.sh \
nix_path.sh \
nars.sh \
Expand Down
1 change: 1 addition & 0 deletions tests/functional/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ suites = [
'why-depends.sh',
'derivation-json.sh',
'derivation-advanced-attributes.sh',
'derivation-instantiate.sh',
'import-from-derivation.sh',
'nix_path.sh',
'nars.sh',
Expand Down

0 comments on commit d599b4f

Please sign in to comment.