about summary refs log tree commit diff
path: root/pkgs/build-support/dart/pub2nix/pubspec-lock.nix
diff options
context:
space:
mode:
Diffstat (limited to 'pkgs/build-support/dart/pub2nix/pubspec-lock.nix')
-rw-r--r--pkgs/build-support/dart/pub2nix/pubspec-lock.nix107
1 files changed, 107 insertions, 0 deletions
diff --git a/pkgs/build-support/dart/pub2nix/pubspec-lock.nix b/pkgs/build-support/dart/pub2nix/pubspec-lock.nix
new file mode 100644
index 0000000000000..07ca54461f5ba
--- /dev/null
+++ b/pkgs/build-support/dart/pub2nix/pubspec-lock.nix
@@ -0,0 +1,107 @@
+{ lib
+, fetchurl
+, fetchgit
+, runCommand
+}:
+
+{
+  # The source directory of the package.
+  src
+
+  # The package subdirectory within src.
+  # Useful if the package references sibling packages with relative paths.
+, packageRoot ? "."
+
+  # The pubspec.lock file, in attribute set form.
+, pubspecLock
+
+  # Hashes for Git dependencies.
+  # Pub does not record these itself, so they must be manually provided.
+, gitHashes ? { }
+
+  # Functions to generate SDK package sources.
+  # The function names should match the SDK names, and the package name is given as an argument.
+, sdkSourceBuilders ? { }
+}:
+
+let
+  dependencyVersions = builtins.mapAttrs (name: details: details.version) pubspecLock.packages;
+
+  dependencyTypes = {
+    "direct main" = "main";
+    "direct dev" = "dev";
+    "direct overridden" = "overridden";
+    "transitive" = "transitive";
+  };
+
+  dependencies = lib.foldlAttrs
+    (dependencies: name: details: dependencies // { ${dependencyTypes.${details.dependency}} = dependencies.${dependencyTypes.${details.dependency}} ++ [ name ]; })
+    (lib.genAttrs (builtins.attrValues dependencyTypes) (dependencyType: [ ]))
+    pubspecLock.packages;
+
+  mkHostedDependencySource = name: details:
+    let
+      archive = fetchurl {
+        name = "pub-${name}-${details.version}.tar.gz";
+        url = "${details.description.url}/packages/${details.description.name}/versions/${details.version}.tar.gz";
+        sha256 = details.description.sha256;
+      };
+    in
+    runCommand "pub-${name}-${details.version}"
+      { } ''
+      mkdir -p "$out"
+      tar xf '${archive}' -C "$out"
+    '';
+
+  mkGitDependencySource = name: details: fetchgit {
+    name = "pub-${name}-${details.version}";
+    url = details.description.url;
+    rev = details.description.resolved-ref;
+    postFetch = ''
+      if [ "$(realpath "$out/${details.description.path}")" != "$(realpath "$out")" ]; then
+        (shopt -s dotglob; mv "$out"/* .)
+        rmdir "$out"
+        mv '${details.description.path}' "$out"
+      fi
+    '';
+    hash = gitHashes.${name} or (throw "A Git hash is required for ${name}! Set to an empty string to obtain it.");
+  };
+
+  mkPathDependencySource = name: details:
+    if builtins.isPath src
+    then
+    # When src is a path, avoid copying it to the store entirely, and allow
+    # non-relative paths.
+      (builtins.path {
+        name = "pub-${name}-${details.version}";
+        path = if details.description.relative then src + "/${packageRoot}" + "/${details.description.path}" else details.description.path;
+      })
+    else
+      assert lib.assertMsg details.description.relative "Only relative paths are supported!";
+      runCommand "pub-${name}-${details.version}" { } ''
+        cp -r '${src}/${packageRoot}/${details.description.path}' "$out"
+      '';
+
+  mkSdkDependencySource = name: details:
+    (sdkSourceBuilders.${details.description} or (throw "No SDK source builder has been given for ${details.description}!")) name;
+
+  dependencySources = lib.filterAttrs (name: src: src != null) (builtins.mapAttrs
+    (name: details: ({
+      "hosted" = mkHostedDependencySource;
+      "git" = mkGitDependencySource;
+      "path" = mkPathDependencySource;
+      "sdk" = mkSdkDependencySource;
+    }.${details.source} name) details)
+    pubspecLock.packages);
+in
+{
+  inherit
+    # An attribute set of dependency categories to package name lists.
+    dependencies
+
+    # An attribute set of package names to their versions.
+    dependencyVersions
+
+    # An attribute set of package names to their sources.
+    dependencySources;
+}