1
0
Fork 0
mirror of https://github.com/NixOS/nix synced 2024-10-18 00:16:11 -04:00

Compare commits

...

4 commits

Author SHA1 Message Date
Guillaume Maudoux 23122d0346
Merge c5ec55c9f5 into de1289229f 2024-10-16 15:32:33 +00:00
Guillaume Maudoux c5ec55c9f5 nit: clang-tidy 2024-10-08 01:55:02 +02:00
Guillaume Maudoux 3edc164a86 Change, document and test output order 2024-10-07 22:13:08 +02:00
Guillaume Maudoux d599b4f773 Introduce nix derivation instantiate
This is simmilar to `nix-instantiate` with support for installables (and flakes).
2024-10-07 20:39:13 +02:00
9 changed files with 249 additions and 6 deletions

View file

@ -803,18 +803,18 @@ StorePath Installable::toStorePath(
return *paths.begin(); return *paths.begin();
} }
StorePathSet Installable::toDerivations( StorePaths Installable::toDerivations(
ref<Store> store, ref<Store> store,
const Installables & installables, const Installables & installables,
bool useDeriver) bool useDeriver)
{ {
StorePathSet drvPaths; StorePaths drvPaths;
for (const auto & i : installables) for (const auto & i : installables)
for (const auto & b : i->toDerivedPaths()) for (const auto & b : i->toDerivedPaths())
std::visit(overloaded { std::visit(overloaded {
[&](const DerivedPath::Opaque & bo) { [&](const DerivedPath::Opaque & bo) {
drvPaths.insert( drvPaths.push_back(
bo.path.isDerivation() bo.path.isDerivation()
? bo.path ? bo.path
: useDeriver : useDeriver
@ -822,7 +822,7 @@ StorePathSet Installable::toDerivations(
: throw Error("argument '%s' did not evaluate to a derivation", i->what())); : throw Error("argument '%s' did not evaluate to a derivation", i->what()));
}, },
[&](const DerivedPath::Built & bfd) { [&](const DerivedPath::Built & bfd) {
drvPaths.insert(resolveDerivedPath(*store, *bfd.drvPath)); drvPaths.push_back(resolveDerivedPath(*store, *bfd.drvPath));
}, },
}, b.path.raw()); }, b.path.raw());

View file

@ -186,7 +186,7 @@ struct Installable
OperateOn operateOn, OperateOn operateOn,
ref<Installable> installable); ref<Installable> installable);
static std::set<StorePath> toDerivations( static std::vector<StorePath> toDerivations(
ref<Store> store, ref<Store> store,
const Installables & installables, const Installables & installables,
bool useDeriver = false); bool useDeriver = false);

View file

@ -0,0 +1,94 @@
#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 StorePaths & paths, Store & store)
{
nlohmann::json res;
for (auto & path : paths) {
nlohmann::json entry;
entry["drvPath"] = store.printStorePath(path);
res.push_back(entry);
}
return res;
}
// TODO deduplicate with other code also setting such out links.
static void createOutLinks(const std::filesystem::path & outLink, const StorePaths & 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"});

View file

@ -0,0 +1,85 @@
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 list of objects containing at least a `drvPath` field with the
path to the produced store derivation.
# Examples
* Get the store derivation for a single installable, with a gc root
```console
$ nix derivation instantiate github:NixOS/nixpkgs#hello
/nix/store/af3rc6phyv80h7aq4y3d08awnq2ja8fp-hello-2.12.1.drv
$ ls -ld drv
lrwxrwxrwx [...] drv -> /nix/store/af3rc6phyv80h7aq4y3d08awnq2ja8fp-hello-2.12.1.drv
```
* Get the store derivations for multiple installables, in the same order as the
provided arguments.
```console
$ nix derivation instantiate github:NixOS/nixpkgs#{hello,xorg.xclock}
/nix/store/af3rc6phyv80h7aq4y3d08awnq2ja8fp-hello-2.12.1.drv
/nix/store/82w6jak6c7zldgvxyq5nwhclz3yp85zp-xclock-1.1.1.drv
```
* The same, with JSON output. The values also appear in the same order as CLI parameters.
```console
$ nix derivation instantiate github:NixOS/nixpkgs#{xorg.xclock,hello} --json | jq
[
{
"drvPath": "/nix/store/82w6jak6c7zldgvxyq5nwhclz3yp85zp-xclock-1.1.1.drv"
},
{
"drvPath": "/nix/store/af3rc6phyv80h7aq4y3d08awnq2ja8fp-hello-2.12.1.drv"
}
]
```
# Notes
* JSON output format may be extended in the future with other fields.
* Order guarantees will always ensure that the following bash commands output
the same text.
```console
$ nix derivation instantiate [installables]
$ nix derivation instantiate [installables] --json | jq ".[] | .drvPath" -r
```
)""

View file

@ -41,7 +41,8 @@ struct CmdShowDerivation : InstallablesCommand
void run(ref<Store> store, Installables && installables) override void run(ref<Store> store, Installables && installables) override
{ {
auto drvPaths = Installable::toDerivations(store, installables, true); auto drvPathsList = Installable::toDerivations(store, installables, true);
StorePathSet drvPaths(drvPathsList.begin(), drvPathsList.end());
if (recursive) { if (recursive) {
StorePathSet closure; StorePathSet closure;

View file

@ -78,6 +78,7 @@ nix_sources = [config_h] + files(
'config.cc', 'config.cc',
'copy.cc', 'copy.cc',
'derivation-add.cc', 'derivation-add.cc',
'derivation-instantiate.cc',
'derivation-show.cc', 'derivation-show.cc',
'derivation.cc', 'derivation.cc',
'develop.cc', 'develop.cc',

View file

@ -0,0 +1,60 @@
#!/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
rm -f drv
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
rm -f foobar
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\":\"$drvPath\"}]" ]
nix-store --delete "$drvPath"
rm -f multidrv*
mapfile -t drvPaths < <(nix derivation instantiate --json --out-link multidrv --file check.nix | jq '.[]|.drvPath' -r)
roots=(./multidrv*)
[ "${#roots[@]}" -gt 1 ]
[ "${#roots[@]}" -eq "${#drvPaths[@]}" ]
mapfile -t rootedPaths < <(readlink "${roots[@]}")
[ "${rootedPaths[*]}" = "${drvPaths[*]}" ]
rm -f multidrv*
# The order should always be the same in text and json outputs
jsonOutput=$(nix derivation instantiate --no-link --file check.nix --json | jq '.[]|.drvPath' -r)
textOutput=$(nix derivation instantiate --no-link --file check.nix)
[ "$jsonOutput" = "$textOutput" ]
# Test that the order is the same as on the command line, and that repeated
# inputs are present several times in the output, in the correct order
nix derivation instantiate --no-link --file multiple-outputs.nix a b a --json | jq --exit-status '
(.[0].drvPath | match(".*multiple-outputs-a.drv"))
and (.[1].drvPath | match(".*multiple-outputs-b.drv"))
and (.[2].drvPath | match(".*multiple-outputs-a.drv"))
'
nix-collect-garbage

View file

@ -88,6 +88,7 @@ nix_tests = \
why-depends.sh \ why-depends.sh \
derivation-json.sh \ derivation-json.sh \
derivation-advanced-attributes.sh \ derivation-advanced-attributes.sh \
derivation-instantiate.sh \
import-from-derivation.sh \ import-from-derivation.sh \
nix_path.sh \ nix_path.sh \
nars.sh \ nars.sh \

View file

@ -157,6 +157,7 @@ suites = [
'why-depends.sh', 'why-depends.sh',
'derivation-json.sh', 'derivation-json.sh',
'derivation-advanced-attributes.sh', 'derivation-advanced-attributes.sh',
'derivation-instantiate.sh',
'import-from-derivation.sh', 'import-from-derivation.sh',
'nix_path.sh', 'nix_path.sh',
'nars.sh', 'nars.sh',