diff options
author | John Ericson <John.Ericson@Obsidian.Systems> | 2021-02-12 21:51:36 +0000 |
---|---|---|
committer | John Ericson <John.Ericson@Obsidian.Systems> | 2021-04-06 10:25:09 -0400 |
commit | 8499f32fb2e7fdf09e97d0beb1fe78bef5900d93 (patch) | |
tree | 3bddff8d3894439335707652c4e3653a0b751615 /src | |
parent | 4bf3eb27e6e2c0cdac862d188b23342793180999 (diff) |
New "indexed" installable syntax: `<drvPath>!<outputName>`
Being conservative and only doing a single output name for now.
Diffstat (limited to 'src')
-rw-r--r-- | src/libcmd/installables.cc | 42 | ||||
-rw-r--r-- | src/nix/nix.md | 10 |
2 files changed, 51 insertions, 1 deletions
diff --git a/src/libcmd/installables.cc b/src/libcmd/installables.cc index 5d3026c1a..cf7681d0d 100644 --- a/src/libcmd/installables.cc +++ b/src/libcmd/installables.cc @@ -349,6 +349,31 @@ struct InstallableStorePath : Installable } }; +struct InstallableIndexedStorePath : Installable +{ + ref<Store> store; + DerivedPath::Built req; + + InstallableIndexedStorePath(ref<Store> store, DerivedPath::Built && req) + : store(store), req(std::move(req)) + { } + + std::string what() override + { + return req.to_string(*store); + } + + DerivedPathsWithHints toDerivedPathsWithHints() override + { + std::map<std::string, std::optional<StorePath>> outputs; + for (auto & output : req.outputs) + outputs.insert_or_assign(output, std::nullopt); + return { + DerivedPathWithHints { DerivedPathWithHints::Built { req.drvPath, std::move(outputs) } } + }; + } +}; + DerivedPathsWithHints InstallableValue::toDerivedPathsWithHints() { DerivedPathsWithHints res; @@ -638,7 +663,22 @@ std::vector<std::shared_ptr<Installable>> SourceExprCommand::parseInstallables( ex = std::current_exception(); } - if (s.find('/') != std::string::npos) { + auto found = s.rfind('!'); + if (found != std::string::npos) { + try { + result.push_back(std::make_shared<InstallableIndexedStorePath>( + store, + DerivedPath::Built::parse(*store, s))); + continue; + } catch (BadStorePath &) { + } catch (...) { + if (!ex) + ex = std::current_exception(); + } + } + + found = s.find('/'); + if (found != std::string::npos) { try { result.push_back(std::make_shared<InstallableStorePath>(store, store->followLinksToStorePath(s))); continue; diff --git a/src/nix/nix.md b/src/nix/nix.md index d10de7c01..22cc9d476 100644 --- a/src/nix/nix.md +++ b/src/nix/nix.md @@ -94,6 +94,16 @@ the Nix store. Here are the recognised types of installables: If you want to operate on the store derivation itself, pass the `--derivation` flag. +* **Indexed store derivations**: `/nix/store/p7gp6lxdg32h4ka1q398wd9r2zkbbz2v-hello-2.10.drv!out` + + Store derivations can be indexed with a specific output name. This + allows finer control versus just specifying a derivation (without + `--derivation`) and getting all the outputs. + + This is especially useful for (currently unstable) floating content + addressed derivations, which do not have precomputed output paths that + can be used instead. + * **Nix attributes**: `--file /path/to/nixpkgs hello` When the `-f` / `--file` *path* option is given, installables are |