about summary refs log tree commit diff
path: root/src/nix-copy-closure/nix-copy-closure.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/nix-copy-closure/nix-copy-closure.cc')
-rwxr-xr-xsrc/nix-copy-closure/nix-copy-closure.cc63
1 files changed, 63 insertions, 0 deletions
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..ed43bffbc8c8
--- /dev/null
+++ b/src/nix-copy-closure/nix-copy-closure.cc
@@ -0,0 +1,63 @@
+#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;
+        std::string sshHost;
+        PathSet storePaths;
+
+        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);
+
+        PathSet storePaths2;
+        for (auto & path : storePaths)
+            storePaths2.insert(from->followLinksToStorePath(path));
+
+        PathSet closure;
+        from->computeFSClosure(storePaths2, closure, false, includeOutputs);
+
+        copyPaths(from, to, closure, useSubstitutes);
+    });
+}