From b2cb288cdd462cbca35ffd3afda9d7ec2d595209 Mon Sep 17 00:00:00 2001
From: Matthew Bauer <mjbauer95@gmail.com>
Date: Fri, 12 Jun 2020 16:36:35 -0500
Subject: [PATCH] Add makeFixedOutputPathFromCA function

This puts what we are already doing into a shared method. It just
needs a path name and a ca and produces a store path.
---
 src/libstore/local-store.cc | 11 +++--------
 src/libstore/store-api.cc   | 31 ++++++++++++++++++-------------
 src/libstore/store-api.hh   |  6 +++++-
 3 files changed, 26 insertions(+), 22 deletions(-)

diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc
index bf005a3b3..9158a52e0 100644
--- a/src/libstore/local-store.cc
+++ b/src/libstore/local-store.cc
@@ -862,15 +862,10 @@ void LocalStore::querySubstitutablePathInfos(const StorePathSet & paths,
         for (auto & path : paths) {
             auto subPath(path.clone());
 
-            auto ca_ = pathsCA.find(printStorePath(path));
+            auto ca = pathsCA.find(printStorePath(path));
             // recompute store path so that we can use a different store root
-            if (ca_ != pathsCA.end()) {
-                auto ca(ca_->second);
-                if (!hasPrefix(ca, "fixed:"))
-                    continue;
-                FileIngestionMethod ingestionMethod { ca.compare(6, 2, "r:") == 0 };
-                Hash hash(std::string(ca, ingestionMethod == FileIngestionMethod::Recursive ? 8 : 6));
-                subPath = makeFixedOutputPath(ingestionMethod, hash, path.name());
+            if (ca != pathsCA.end() && (hasPrefix(ca->second, "fixed:") || hasPrefix(ca->second, "text:"))) {
+                subPath = makeFixedOutputPathFromCA(path.name(), ca->second);
                 if (subPath != path)
                     debug("replaced path '%s' with '%s' for substituter '%s'", printStorePath(path), sub->printStorePath(subPath), sub->getUri());
             } else if (sub->storeDir != storeDir) continue;
diff --git a/src/libstore/store-api.cc b/src/libstore/store-api.cc
index 7cb48b293..bc9a6c4f5 100644
--- a/src/libstore/store-api.cc
+++ b/src/libstore/store-api.cc
@@ -191,6 +191,19 @@ StorePath Store::makeFixedOutputPath(
     }
 }
 
+StorePath Store::makeFixedOutputPathFromCA(std::string_view name, std::string ca,
+    const StorePathSet & references, bool hasSelfReference) const
+{
+    if (hasPrefix(ca, "fixed:")) {
+        FileIngestionMethod ingestionMethod { ca.compare(6, 2, "r:") == 0 };
+        Hash hash(std::string(ca, ingestionMethod == FileIngestionMethod::Recursive ? 8 : 6));
+        return makeFixedOutputPath(ingestionMethod, hash, name, references, hasSelfReference);
+    } else if (hasPrefix(ca, "text:")) {
+        Hash hash(std::string(ca, 5));
+        return makeTextPath(name, hash, references);
+    } else
+        throw Error("'%s' is not a valid ca", ca);
+}
 
 StorePath Store::makeTextPath(std::string_view name, const Hash & hash,
     const StorePathSet & references) const
@@ -583,9 +596,7 @@ void copyStorePath(ref<Store> srcStore, ref<Store> dstStore,
     // recompute store path on the chance dstStore does it differently
     if (info->isContentAddressed(*srcStore)) {
         auto info2 = make_ref<ValidPathInfo>(*info);
-        FileIngestionMethod ingestionMethod { info->ca.compare(6, 2, "r:") == 0 };
-        Hash hash(std::string(info->ca, ingestionMethod == FileIngestionMethod::Recursive ? 8 : 6));
-        info2->path = dstStore->makeFixedOutputPath(ingestionMethod, hash, storePath.name());
+        info2->path = dstStore->makeFixedOutputPathFromCA(info->path.name(), info->ca);
         info = info2;
     }
 
@@ -656,11 +667,8 @@ void copyPaths(ref<Store> srcStore, ref<Store> dstStore, const StorePathSet & st
 
             auto info = srcStore->queryPathInfo(storePath);
             auto storePathForDst = storePath.clone();
-            if (hasPrefix(info->ca, "fixed:"))
-            {
-                FileIngestionMethod ingestionMethod { info->ca.compare(6, 2, "r:") == 0 };
-                Hash hash(std::string(info->ca, ingestionMethod == FileIngestionMethod::Recursive ? 8 : 6));
-                storePathForDst = dstStore->makeFixedOutputPath(ingestionMethod, hash, storePath.name());
+            if (info->isContentAddressed(*srcStore)) {
+                storePathForDst = dstStore->makeFixedOutputPathFromCA(storePath.name(), info->ca);
                 if (storePathForDst != storePath)
                     debug("rewriting path '%s' to '%s' for substituter '%s'", srcStore->printStorePath(storePath), dstStore->printStorePath(storePathForDst), dstStore->getUri());
             }
@@ -684,11 +692,8 @@ void copyPaths(ref<Store> srcStore, ref<Store> dstStore, const StorePathSet & st
             auto info = srcStore->queryPathInfo(storePath);
 
             auto storePathForDst = storePath.clone();
-            if (hasPrefix(info->ca, "fixed:"))
-            {
-                FileIngestionMethod ingestionMethod { info->ca.compare(6, 2, "r:") == 0 };
-                Hash hash(std::string(info->ca, ingestionMethod == FileIngestionMethod::Recursive ? 8 : 6));
-                storePathForDst = dstStore->makeFixedOutputPath(ingestionMethod, hash, storePath.name());
+            if (info->isContentAddressed(*srcStore)) {
+                storePathForDst = dstStore->makeFixedOutputPathFromCA(storePath.name(), info->ca);
                 if (storePathForDst != storePath)
                     debug("rewriting path '%s' to '%s' for substituter '%s'", srcStore->printStorePath(storePath), dstStore->printStorePath(storePathForDst), dstStore->getUri());
             }
diff --git a/src/libstore/store-api.hh b/src/libstore/store-api.hh
index 6f961329c..9412785b4 100644
--- a/src/libstore/store-api.hh
+++ b/src/libstore/store-api.hh
@@ -352,7 +352,11 @@ public:
         bool hasSelfReference = false) const;
 
     StorePath makeTextPath(std::string_view name, const Hash & hash,
-        const StorePathSet & references) const;
+        const StorePathSet & references = {}) const;
+
+    StorePath makeFixedOutputPathFromCA(std::string_view name, std::string ca,
+        const StorePathSet & references = {},
+        bool hasSelfReference = false) const;
 
     /* This is the preparatory part of addToStore(); it computes the
        store path to which srcPath is to be copied.  Returns the store