aboutsummaryrefslogtreecommitdiff
path: root/src/libcmd/installable-derived-path.cc
diff options
context:
space:
mode:
authorJohn Ericson <John.Ericson@Obsidian.Systems>2023-02-03 11:21:47 -0500
committerJohn Ericson <John.Ericson@Obsidian.Systems>2023-02-03 11:26:39 -0500
commit45fa297e4052acef962d9d124241e7abd02f58af (patch)
treedbcf2f8e8023244acc5b7595c44b026d18ee4162 /src/libcmd/installable-derived-path.cc
parentdbe0748f970a86911aae2cb6b603dfb8b541f8d9 (diff)
Factor out `InstallableStorePath` to its own file, dedup
`nix app` had something called `InstallableDerivedPath` which is actually the same thing. We go with the later's name because it has become more correct. I originally did this change (more hurriedly) as part of #6225 --- a mini store-only Nix and a full Nix need to share this code. In the first RFC meeting for https://github.com/NixOS/rfcs/pull/134 we discussed how some splitting of the massive `installables.cc` could begin prior, as that is a good thing anyways. (@edolstra's words, not mine!) This would be one such PR.
Diffstat (limited to 'src/libcmd/installable-derived-path.cc')
-rw-r--r--src/libcmd/installable-derived-path.cc70
1 files changed, 70 insertions, 0 deletions
diff --git a/src/libcmd/installable-derived-path.cc b/src/libcmd/installable-derived-path.cc
new file mode 100644
index 000000000..a9921b901
--- /dev/null
+++ b/src/libcmd/installable-derived-path.cc
@@ -0,0 +1,70 @@
+#include "installable-derived-path.hh"
+#include "derivations.hh"
+
+namespace nix {
+
+std::string InstallableDerivedPath::what() const
+{
+ return derivedPath.to_string(*store);
+}
+
+DerivedPathsWithInfo InstallableDerivedPath::toDerivedPaths()
+{
+ return {{.path = derivedPath, .info = {} }};
+}
+
+std::optional<StorePath> InstallableDerivedPath::getStorePath()
+{
+ return std::visit(overloaded {
+ [&](const DerivedPath::Built & bfd) {
+ return bfd.drvPath;
+ },
+ [&](const DerivedPath::Opaque & bo) {
+ return bo.path;
+ },
+ }, derivedPath.raw());
+}
+
+InstallableDerivedPath InstallableDerivedPath::parse(
+ ref<Store> store,
+ std::string_view prefix,
+ ExtendedOutputsSpec extendedOutputsSpec)
+{
+ auto derivedPath = std::visit(overloaded {
+ // If the user did not use ^, we treat the output more liberally.
+ [&](const ExtendedOutputsSpec::Default &) -> DerivedPath {
+ // First, we accept a symlink chain or an actual store path.
+ auto storePath = store->followLinksToStorePath(prefix);
+ // Second, we see if the store path ends in `.drv` to decide what sort
+ // of derived path they want.
+ //
+ // This handling predates the `^` syntax. The `^*` in
+ // `/nix/store/hash-foo.drv^*` unambiguously means "do the
+ // `DerivedPath::Built` case", so plain `/nix/store/hash-foo.drv` could
+ // also unambiguously mean "do the DerivedPath::Opaque` case".
+ //
+ // Issue #7261 tracks reconsidering this `.drv` dispatching.
+ return storePath.isDerivation()
+ ? (DerivedPath) DerivedPath::Built {
+ .drvPath = std::move(storePath),
+ .outputs = OutputsSpec::All {},
+ }
+ : (DerivedPath) DerivedPath::Opaque {
+ .path = std::move(storePath),
+ };
+ },
+ // If the user did use ^, we just do exactly what is written.
+ [&](const ExtendedOutputsSpec::Explicit & outputSpec) -> DerivedPath {
+ return DerivedPath::Built {
+ .drvPath = store->parseStorePath(prefix),
+ .outputs = outputSpec,
+ };
+ },
+ }, extendedOutputsSpec.raw());
+ return InstallableDerivedPath {
+ store,
+ std::move(derivedPath),
+ };
+}
+
+}