about summary refs log tree commit diff
diff options
context:
space:
mode:
authorVincent Ambo <tazjin@google.com>2019-12-13T00·07+0000
committerVincent Ambo <mail@tazj.in>2019-12-13T00·39+0000
commitd8ef203f78ba58968d26fb3a749cb32170394500 (patch)
treebfb6332871d4ba2ad005ada84e0a2dd02df2c11d
parent218b81c709248784112ae7bd0646c7fc6773fe5f (diff)
feat(external): Support foreign dependencies in external packages
Users can supply a list of foreign dependencies in calls to
buildGo.external. These are now appropriately inserted into packages
that *need them* and no further, resolving issues with complex
internal recursion in some repositories!
-rw-r--r--external/default.nix27
1 files changed, 22 insertions, 5 deletions
diff --git a/external/default.nix b/external/default.nix
index f9cb542e6f14..49f8bd93149a 100644
--- a/external/default.nix
+++ b/external/default.nix
@@ -9,6 +9,7 @@ let
     fromJSON
     head
     length
+    listToAttrs
     readFile
     replaceStrings
     tail
@@ -48,29 +49,45 @@ let
 
   last = l: elemAt l ((length l) - 1);
 
-  toPackage = self: src: path: entry:
+  toPackage = self: src: path: depMap: entry:
     let
+      localDeps = map (d: lib.attrByPath (d ++ [ "gopkg" ]) (
+        throw "missing local dependency '${lib.concatStringsSep "." d}' in '${path}'"
+      ) self) entry.localDeps;
+
+      foreignDeps = map (d: lib.attrByPath [ d ] (
+        throw "missing foreign dependency '${d}' in '${path}'"
+      ) depMap) entry.foreignDeps;
+
       args = {
         srcs = map (f: src + ("/" + f)) entry.files;
-        deps = map (d: lib.attrByPath (d ++ [ "gopkg" ]) (
-          throw "missing local dependency '${lib.concatStringsSep "." d}' in '${path}'"
-        ) self) entry.localDeps;
+        deps = localDeps ++ foreignDeps;
       };
+
       libArgs = args // {
         name = pathToName entry.name;
         path = lib.concatStringsSep "/" ([ path ] ++ entry.locator);
       };
+
       binArgs = args // {
         name = last ([ path ] ++ entry.locator);
       };
     in if entry.isCommand then (program binArgs) else (package libArgs);
 
 in { src, path, deps ? [] }: let
+  # Build a map of dependencies (from their import paths to their
+  # derivation) so that they can be conditionally imported only in
+  # sub-packages that require them.
+  depMap = listToAttrs (map (d: {
+    name = d.goImportPath;
+    value = d;
+  }) deps);
+
   name = pathToName path;
   analysisOutput = runCommand "${name}-structure.json" {} ''
     ${analyser}/bin/analyser -path ${path} -source ${src} > $out
   '';
   analysis = fromJSON (readFile analysisOutput);
 in lib.fix(self: foldl' lib.recursiveUpdate {} (
-  map (entry: mkset entry.locator (toPackage self src path entry)) analysis
+  map (entry: mkset entry.locator (toPackage self src path depMap entry)) analysis
 ))