about summary refs log tree commit diff
path: root/nixpkgs/pkgs/build-support/dart/pub2nix/pubspec-lock.nix
diff options
context:
space:
mode:
Diffstat (limited to 'nixpkgs/pkgs/build-support/dart/pub2nix/pubspec-lock.nix')
-rw-r--r--nixpkgs/pkgs/build-support/dart/pub2nix/pubspec-lock.nix119
1 files changed, 119 insertions, 0 deletions
diff --git a/nixpkgs/pkgs/build-support/dart/pub2nix/pubspec-lock.nix b/nixpkgs/pkgs/build-support/dart/pub2nix/pubspec-lock.nix
new file mode 100644
index 000000000000..e1ab4d7d2359
--- /dev/null
+++ b/nixpkgs/pkgs/build-support/dart/pub2nix/pubspec-lock.nix
@@ -0,0 +1,119 @@
+{ lib
+, callPackage
+, 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 ? { }
+
+  # Functions that create custom package source derivations.
+  #
+  # The function names should match the package names, and the package version,
+  # source, and source files are given in an attribute set argument.
+  #
+  # The passthru of the source derivation should be propagated.
+, customSourceBuilders ? { }
+}:
+
+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;
+
+  # fetchTarball fails with "tarball contains an unexpected number of top-level files". This is a workaround.
+  # https://discourse.nixos.org/t/fetchtarball-with-multiple-top-level-directories-fails/20556
+  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}" { passthru.packageRoot = "."; } ''
+      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;
+    hash = gitHashes.${name} or (throw "A Git hash is required for ${name}! Set to an empty string to obtain it.");
+  }).overrideAttrs ({ passthru ? { }, ... }: {
+    passthru = passthru // {
+      packageRoot = details.description.path;
+    };
+  });
+
+  mkPathDependencySource = name: details:
+    assert lib.assertMsg details.description.relative "Only relative paths are supported - ${name} has an absolue path!";
+    (if lib.isDerivation src then src else (runCommand "pub-${name}-${details.version}" { } ''cp -r '${src}' "$out"'')).overrideAttrs ({ passthru ? { }, ... }: {
+      passthru = passthru // {
+        packageRoot = "${packageRoot}/${details.description.path}";
+      };
+    });
+
+  mkSdkDependencySource = name: details:
+    (sdkSourceBuilders.${details.description} or (throw "No SDK source builder has been given for ${details.description}!")) name;
+
+  addDependencySourceUtils = dependencySource: details: dependencySource.overrideAttrs ({ passthru, ... }: {
+    passthru = passthru // {
+      inherit (details) version;
+    };
+  });
+
+  sourceBuilders = callPackage ../../../development/compilers/dart/package-source-builders { } // customSourceBuilders;
+
+  dependencySources = lib.filterAttrs (name: src: src != null) (builtins.mapAttrs
+    (name: details:
+      (sourceBuilders.${name} or ({ src, ... }: src)) {
+        inherit (details) version source;
+        src = ((addDependencySourceUtils (({
+          "hosted" = mkHostedDependencySource;
+          "git" = mkGitDependencySource;
+          "path" = mkPathDependencySource;
+          "sdk" = mkSdkDependencySource;
+        }.${details.source} name) details)) 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;
+}