about summary refs log tree commit diff
path: root/src/nix-copy-closure
diff options
context:
space:
mode:
authorShea Levy <shea@shealevy.com>2016-08-10T14·44-0400
committerShea Levy <shea@shealevy.com>2017-01-20T14·47-0500
commitbfa41eb6714a7e7c3956389ee063e898bd1f37ff (patch)
tree53238d800afb6fbaa2874c69e2750627e17d4d2e /src/nix-copy-closure
parent8af062f372ae5db6a90700641f15d98505b4a839 (diff)
nix-copy-closure: Implement in C++.
Tests fail currently because the database is not given proper hashes in the VM
Diffstat (limited to 'src/nix-copy-closure')
-rw-r--r--src/nix-copy-closure/local.mk7
-rwxr-xr-xsrc/nix-copy-closure/nix-copy-closure.cc60
2 files changed, 67 insertions, 0 deletions
diff --git a/src/nix-copy-closure/local.mk b/src/nix-copy-closure/local.mk
new file mode 100644
index 000000000000..42bb34dd8201
--- /dev/null
+++ b/src/nix-copy-closure/local.mk
@@ -0,0 +1,7 @@
+programs += nix-copy-closure
+
+nix-copy-closure_DIR := $(d)
+
+nix-copy-closure_LIBS = libmain libutil libformat libstore
+
+nix-copy-closure_SOURCES := $(d)/nix-copy-closure.cc
diff --git a/src/nix-copy-closure/nix-copy-closure.cc b/src/nix-copy-closure/nix-copy-closure.cc
new file mode 100755
index 000000000000..b7e997ca4b0c
--- /dev/null
+++ b/src/nix-copy-closure/nix-copy-closure.cc
@@ -0,0 +1,60 @@
+#include "shared.hh"
+#include "store-api.hh"
+
+using namespace nix;
+
+int main(int argc, char ** argv)
+{
+    return handleExceptions(argv[0], [&]() {
+        initNix();
+        auto gzip = false;
+        auto toMode = true;
+        auto includeOutputs = false;
+        auto dryRun = false;
+        auto useSubstitutes = false;
+        auto sshHost = string{};
+        auto storePaths = PathSet{};
+        parseCmdLine(argc, argv, [&](Strings::iterator & arg, const Strings::iterator & end) {
+            if (*arg == "--help")
+                showManPage("nix-copy-closure");
+            else if (*arg == "--version")
+                printVersion("nix-copy-closure");
+            else if (*arg == "--gzip" || *arg == "--bzip2" || *arg == "--xz") {
+                if (*arg != "--gzip")
+                    printMsg(lvlError, format("Warning: ‘%1%’ is not implemented, falling back to gzip") % *arg);
+                gzip = true;
+            } else if (*arg == "--from")
+                toMode = false;
+            else if (*arg == "--to")
+                toMode = true;
+            else if (*arg == "--include-outputs")
+                includeOutputs = true;
+            else if (*arg == "--show-progress")
+                printMsg(lvlError, "Warning: ‘--show-progress’ is not implemented");
+            else if (*arg == "--dry-run")
+                dryRun = true;
+            else if (*arg == "--use-substitutes" || *arg == "-s")
+                useSubstitutes = true;
+            else if (sshHost.empty())
+                sshHost = *arg;
+            else
+                storePaths.insert(*arg);
+            return true;
+        });
+        if (sshHost.empty())
+            throw UsageError("no host name specified");
+
+        auto remoteUri = "ssh://" + sshHost + (gzip ? "?compress=true" : "");
+        auto to = toMode ? openStore(remoteUri) : openStore();
+        auto from = toMode ? openStore() : openStore(remoteUri);
+        if (includeOutputs) {
+            auto newPaths = PathSet{};
+            for (const auto & p : storePaths) {
+                auto outputs = from->queryDerivationOutputs(p);
+                newPaths.insert(outputs.begin(), outputs.end());
+            }
+            storePaths.insert(newPaths.begin(), newPaths.end());
+        }
+        copyPaths(from, to, Paths(storePaths.begin(), storePaths.end()), useSubstitutes);
+    });
+}