mirror of
https://github.com/NixOS/nix
synced 2024-10-18 00:16:11 -04:00
Merge c5ec55c9f5
into 806a91f7bf
This commit is contained in:
commit
e1cb69d597
|
@ -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());
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
94
src/nix/derivation-instantiate.cc
Normal file
94
src/nix/derivation-instantiate.cc
Normal 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"});
|
85
src/nix/derivation-instantiate.md
Normal file
85
src/nix/derivation-instantiate.md
Normal 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
|
||||||
|
```
|
||||||
|
|
||||||
|
)""
|
|
@ -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;
|
||||||
|
|
|
@ -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',
|
||||||
|
|
60
tests/functional/derivation-instantiate.sh
Executable file
60
tests/functional/derivation-instantiate.sh
Executable 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
|
|
@ -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 \
|
||||||
|
|
|
@ -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',
|
||||||
|
|
Loading…
Reference in a new issue