Skip to content

Commit

Permalink
Change, document and test output order
Browse files Browse the repository at this point in the history
  • Loading branch information
layus committed Oct 7, 2024
1 parent d599b4f commit 3edc164
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 14 deletions.
8 changes: 4 additions & 4 deletions src/libcmd/installables.cc
Original file line number Diff line number Diff line change
Expand Up @@ -803,26 +803,26 @@ StorePath Installable::toStorePath(
return *paths.begin();
}

StorePathSet Installable::toDerivations(
StorePaths Installable::toDerivations(
ref<Store> store,
const Installables & installables,
bool useDeriver)
{
StorePathSet drvPaths;
StorePaths drvPaths;

for (const auto & i : installables)
for (const auto & b : i->toDerivedPaths())
std::visit(overloaded {
[&](const DerivedPath::Opaque & bo) {
drvPaths.insert(
drvPaths.push_back(
bo.path.isDerivation()
? bo.path
: useDeriver
? getDeriver(store, *i, bo.path)
: throw Error("argument '%s' did not evaluate to a derivation", i->what()));
},
[&](const DerivedPath::Built & bfd) {
drvPaths.insert(resolveDerivedPath(*store, *bfd.drvPath));
drvPaths.push_back(resolveDerivedPath(*store, *bfd.drvPath));
},
}, b.path.raw());

Expand Down
2 changes: 1 addition & 1 deletion src/libcmd/installables.hh
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ struct Installable
OperateOn operateOn,
ref<Installable> installable);

static std::set<StorePath> toDerivations(
static std::vector<StorePath> toDerivations(
ref<Store> store,
const Installables & installables,
bool useDeriver = false);
Expand Down
10 changes: 6 additions & 4 deletions src/nix/derivation-instantiate.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,20 @@

using namespace nix;

static nlohmann::json storePathSetToJSON(const StorePathSet & paths, Store & store)
static nlohmann::json storePathSetToJSON(const StorePaths & paths, Store & store)
{
auto res = nlohmann::json::object();
nlohmann::json res;
for (auto & path : paths) {
res[store.printStorePath(path)] = nlohmann::json::object();
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 StorePathSet & derivations, LocalFSStore & store)
createOutLinks(const std::filesystem::path & outLink, const StorePaths & derivations, LocalFSStore & store)
{
for (const auto & [_i, drv] : enumerate(derivations)) {
auto i = _i;
Expand Down
50 changes: 48 additions & 2 deletions src/nix/derivation-instantiate.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,53 @@ derivations are printed on standard output.

- `--json`

Dump a JSON object whose keys are the generated store derivations instread of
printing them directly on the output.
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
```

)""
3 changes: 2 additions & 1 deletion src/nix/derivation-show.cc
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ struct CmdShowDerivation : InstallablesCommand

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) {
StorePathSet closure;
Expand Down
20 changes: 18 additions & 2 deletions tests/functional/derivation-instantiate.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ 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
Expand All @@ -23,22 +24,37 @@ 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\":{}}" ]
[ "$drvPathJson" = "[{\"drvPath\":\"$drvPath\"}]" ]
nix-store --delete "$drvPath"

mapfile -t drvPaths < <(nix derivation instantiate --json --out-link multidrv --file check.nix | jq 'keys|.[]' -r)
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

0 comments on commit 3edc164

Please sign in to comment.