From fe38f28ba873d4d5c1da5cfcedb486f009329525 Mon Sep 17 00:00:00 2001 From: Yusuf Bera Ertan Date: Thu, 6 Oct 2022 20:42:04 +0300 Subject: [PATCH] wip --- src/default.nix | 2 +- src/fetchers/crates-io/default.nix | 17 +- src/fetchers/git/default.nix | 13 +- src/fetchers/github/default.nix | 15 +- src/fetchers/gitlab/default.nix | 14 +- src/fetchers/http/default.nix | 17 +- src/fetchers/npm/default.nix | 16 +- src/fetchers/path/default.nix | 6 +- src/fetchers/pypi-sdist/default.nix | 15 +- src/lib.nix | 3 +- src/modules/builders/implementation.nix | 2 +- src/modules/discoverers/implementation.nix | 2 +- src/modules/framework.nix | 8 +- .../functions.subsystem-loading/default.nix | 6 - .../functions.subsystem-loading/interface.nix | 35 - ...plementation.nix => subsystem-loading.nix} | 38 +- src/modules/top-level.nix | 11 +- src/modules/translators/implementation.nix | 2 +- .../builders/simple-haskell/default.nix | 18 +- .../translators/cabal-plan/default.nix | 5 +- .../haskell/translators/hackage/default.nix | 61 +- .../translators/stack-lock/default.nix | 12 +- .../builders/granular-nodejs/default.nix | 918 +++++++++--------- .../nodejs/translators/npm/default.nix | 40 +- .../translators/package-json/default.nix | 34 +- .../translators/package-lock/default.nix | 9 +- .../nodejs/translators/yarn-lock/default.nix | 7 +- .../php/builders/granular-php/default.nix | 19 +- .../php/builders/simple-php/default.nix | 21 +- .../php/translators/composer-json/default.nix | 31 +- .../php/translators/composer-lock/default.nix | 9 +- .../php/translators/packagist/default.nix | 35 +- .../python/builders/simple-python/default.nix | 10 +- .../python/translators/pip/default.nix | 33 +- .../racket/builders/simple-racket/default.nix | 14 +- .../translators/racket-impure/default.nix | 34 +- .../builders/build-rust-package/default.nix | 19 +- .../rust/builders/crane/default.nix | 26 +- .../rust/translators/cargo-lock/default.nix | 2 + .../rust/translators/cargo-toml/default.nix | 15 +- 40 files changed, 760 insertions(+), 834 deletions(-) delete mode 100644 src/modules/functions.subsystem-loading/default.nix delete mode 100644 src/modules/functions.subsystem-loading/interface.nix rename src/modules/{functions.subsystem-loading/implementation.nix => subsystem-loading.nix} (73%) diff --git a/src/default.nix b/src/default.nix index 045c7b53..83599c65 100644 --- a/src/default.nix +++ b/src/default.nix @@ -51,7 +51,7 @@ in let }; framework = import ./modules/framework.nix { - inherit apps lib dlib pkgs utils; + inherit apps lib dlib pkgs utils externals externalSources; dream2nixConfig = config; }; diff --git a/src/fetchers/crates-io/default.nix b/src/fetchers/crates-io/default.nix index 4f2e5a7e..960a03c2 100644 --- a/src/fetchers/crates-io/default.nix +++ b/src/fetchers/crates-io/default.nix @@ -1,18 +1,17 @@ -{lib, ...}: { +{ + pkgs, + utils, + ... +}: { inputs = ["pname" "version"]; versionField = "version"; outputs = { - fetchurl, - runCommandLocal, - utils, - ... - }: { pname, version, ... - } @ inp: let + }: let b = builtins; # See https://github.com/rust-lang/crates.io-index/blob/master/config.json#L2 url = "https://crates.io/api/v1/crates/${pname}/${version}/download"; @@ -23,13 +22,13 @@ }); fetched = hash: let - fetched = fetchurl { + fetched = pkgs.fetchurl { inherit url; sha256 = hash; name = "download-${pname}-${version}"; }; in - runCommandLocal "unpack-${pname}-${version}" {} + pkgs.runCommandLocal "unpack-${pname}-${version}" {} '' mkdir -p $out tar --strip-components 1 -xzf ${fetched} -C $out diff --git a/src/fetchers/git/default.nix b/src/fetchers/git/default.nix index ddfa4988..b0fc43b0 100644 --- a/src/fetchers/git/default.nix +++ b/src/fetchers/git/default.nix @@ -1,4 +1,9 @@ -{lib, ...}: let +{ + pkgs, + lib, + utils, + ... +}: let b = builtins; # check if a string is a git ref @@ -14,10 +19,6 @@ in { versionField = "rev"; outputs = { - fetchgit, - utils, - ... - }: { url, rev, submodules ? true, @@ -78,7 +79,7 @@ in { inherit submodules; }) else - fetchgit + pkgs.fetchgit (refAndRev // { inherit url; diff --git a/src/fetchers/github/default.nix b/src/fetchers/github/default.nix index 38350bfc..45478b98 100644 --- a/src/fetchers/github/default.nix +++ b/src/fetchers/github/default.nix @@ -1,4 +1,9 @@ -{lib, ...}: { +{ + pkgs, + lib, + utils, + ... +}: { inputs = [ "owner" "repo" @@ -10,15 +15,11 @@ defaultUpdater = "githubNewestReleaseTag"; outputs = { - fetchFromGitHub, - utils, - ... - }: { owner, repo, rev, ... - } @ inp: let + }: let b = builtins; in { calcHash = algo: @@ -27,7 +28,7 @@ }); fetched = hash: - fetchFromGitHub { + pkgs.fetchFromGitHub { inherit owner repo rev hash; }; }; diff --git a/src/fetchers/gitlab/default.nix b/src/fetchers/gitlab/default.nix index 53d552f5..47962f3d 100644 --- a/src/fetchers/gitlab/default.nix +++ b/src/fetchers/gitlab/default.nix @@ -1,4 +1,8 @@ -{...}: { +{ + pkgs, + utils, + ... +}: { inputs = [ "owner" "repo" @@ -8,15 +12,11 @@ versionField = "rev"; outputs = { - fetchFromGitLab, - utils, - ... - }: { owner, repo, rev, ... - } @ inp: let + }: let b = builtins; in { calcHash = algo: @@ -25,7 +25,7 @@ }); fetched = hash: - fetchFromGitLab { + pkgs.fetchFromGitLab { inherit owner repo rev hash; }; }; diff --git a/src/fetchers/http/default.nix b/src/fetchers/http/default.nix index f6e8a8b1..958ccf7e 100644 --- a/src/fetchers/http/default.nix +++ b/src/fetchers/http/default.nix @@ -1,13 +1,14 @@ -{lib, ...}: { +{ + pkgs, + lib, + utils, + ... +}: { inputs = [ "url" ]; - outputs = { - fetchurl, - utils, - ... - }: {url, ...} @ inp: let + outputs = {url, ...}: let b = builtins; in { calcHash = algo: @@ -19,12 +20,12 @@ drv = if hash != null && lib.stringLength hash == 40 then - fetchurl { + pkgs.fetchurl { inherit url; sha1 = hash; } else - fetchurl { + pkgs.fetchurl { inherit url hash; }; diff --git a/src/fetchers/npm/default.nix b/src/fetchers/npm/default.nix index 495add9b..f46cb7c7 100644 --- a/src/fetchers/npm/default.nix +++ b/src/fetchers/npm/default.nix @@ -1,4 +1,9 @@ -{lib, ...}: let +{ + pkgs, + lib, + utils, + ... +}: let b = builtins; in rec { inputs = ["pname" "version"]; @@ -36,14 +41,9 @@ in rec { # defaultUpdater = ""; outputs = { - python3, - utils, - fetchurl, - ... - }: { pname, version, - } @ inp: let + }: let b = builtins; submodule = lib.last (lib.splitString "/" pname); @@ -56,7 +56,7 @@ in rec { fetched = hash: let source = - (fetchurl { + (pkgs.fetchurl { inherit url; sha256 = hash; }) diff --git a/src/fetchers/path/default.nix b/src/fetchers/path/default.nix index bfef7104..598174af 100644 --- a/src/fetchers/path/default.nix +++ b/src/fetchers/path/default.nix @@ -1,11 +1,9 @@ -{...}: { +{utils, ...}: { inputs = [ "path" ]; - outputs = {utils, ...}: {path, ...} @ inp: let - b = builtins; - in { + outputs = {path, ...}: { calcHash = algo: utils.hashPath "${path}"; fetched = hash: "${path}"; diff --git a/src/fetchers/pypi-sdist/default.nix b/src/fetchers/pypi-sdist/default.nix index 1aee1c7d..a664a7ce 100644 --- a/src/fetchers/pypi-sdist/default.nix +++ b/src/fetchers/pypi-sdist/default.nix @@ -1,4 +1,8 @@ -{...}: { +{ + pkgs, + utils, + ... +}: { inputs = ["pname" "version"]; versionField = "version"; @@ -6,15 +10,10 @@ defaultUpdater = "pypiNewestReleaseVersion"; outputs = { - fetchurl, - python3, - utils, - ... - }: { pname, version, extension ? "tar.gz", - } @ inp: let + }: let b = builtins; firstChar = builtins.substring 0 1 pname; @@ -29,7 +28,7 @@ fetched = hash: let source = - (fetchurl { + (pkgs.fetchurl { inherit url; sha256 = hash; }) diff --git a/src/lib.nix b/src/lib.nix index 9b357f2c..2a995710 100644 --- a/src/lib.nix +++ b/src/lib.nix @@ -90,11 +90,12 @@ dlib = import ./lib {inherit lib config;}; framework = import ./modules/framework.nix { - inherit lib dlib; + inherit lib dlib externalSources; dream2nixConfig = config; apps = throw "apps is not available before nixpkgs is imported"; pkgs = throw "pkgs is not available before nixpkgs is imported"; utils = throw "utils is not available before nixpkgs is imported"; + externals = throw "externals is not available before nixpkgs is imported"; }; initD2N = initDream2nix config; diff --git a/src/modules/builders/implementation.nix b/src/modules/builders/implementation.nix index 50b436ce..50e2ef10 100644 --- a/src/modules/builders/implementation.nix +++ b/src/modules/builders/implementation.nix @@ -9,7 +9,7 @@ debian = "simple-debian"; racket = "simple-racket"; }; - funcs = config.functions.subsystem-loading; + funcs = import ../subsystem-loading.nix config; collectedModules = funcs.collect "builders"; in { config = { diff --git a/src/modules/discoverers/implementation.nix b/src/modules/discoverers/implementation.nix index e9c68ac9..13edcd9c 100644 --- a/src/modules/discoverers/implementation.nix +++ b/src/modules/discoverers/implementation.nix @@ -1,5 +1,5 @@ {config, ...}: let - funcs = config.functions.subsystem-loading; + funcs = import ../subsystem-loading.nix config; collectedModules = funcs.collect "discoverers"; in { config = { diff --git a/src/modules/framework.nix b/src/modules/framework.nix index 5e9c29d1..15cac543 100644 --- a/src/modules/framework.nix +++ b/src/modules/framework.nix @@ -2,13 +2,13 @@ dream2nixConfig, pkgs, dlib, + externals, + externalSources, lib, utils, apps, -}: let - topLevel = import ./top-level.nix { - inherit apps lib dlib utils pkgs dream2nixConfig; - }; +} @ args: let + topLevel = import ./top-level.nix args; evaledModules = lib.evalModules { modules = [topLevel] ++ (dream2nixConfig.modules or []); }; diff --git a/src/modules/functions.subsystem-loading/default.nix b/src/modules/functions.subsystem-loading/default.nix deleted file mode 100644 index e0a7730f..00000000 --- a/src/modules/functions.subsystem-loading/default.nix +++ /dev/null @@ -1,6 +0,0 @@ -{ - imports = [ - ./implementation.nix - ./interface.nix - ]; -} diff --git a/src/modules/functions.subsystem-loading/interface.nix b/src/modules/functions.subsystem-loading/interface.nix deleted file mode 100644 index c4887d70..00000000 --- a/src/modules/functions.subsystem-loading/interface.nix +++ /dev/null @@ -1,35 +0,0 @@ -{config, ...}: let - lib = config.lib; - t = lib.types; -in { - options.functions.subsystem-loading = { - collect = lib.mkOption { - type = t.functionTo t.anything; - description = '' - Discover modules in /src/subsystems/{subsystem}/{module-type}/{module-name} - ''; - }; - import_ = lib.mkOption { - type = t.functionTo t.anything; - description = '' - Imports discovered module files. - Adds name and subsystem attributes to each module derived from the path. - ''; - }; - instantiate = lib.mkOption { - type = t.functionTo t.anything; - description = '' - To keep module implementations simpler, additional generic logic is added - by a loader. - The loader is subsytem specific and needs to be passed as an argument. - ''; - }; - structureBySubsystem = lib.mkOption { - type = t.functionTo t.anything; - description = '' - re-structures the instantiated instances into a deeper attrset like: - {subsytem}.{module-name} = ... - ''; - }; - }; -} diff --git a/src/modules/functions.subsystem-loading/implementation.nix b/src/modules/subsystem-loading.nix similarity index 73% rename from src/modules/functions.subsystem-loading/implementation.nix rename to src/modules/subsystem-loading.nix index 7ca647eb..b8b02b76 100644 --- a/src/modules/functions.subsystem-loading/implementation.nix +++ b/src/modules/subsystem-loading.nix @@ -5,10 +5,12 @@ translators and builders. This recurses through the following directory structure to discover and load modules: /src/subsystems/{subsystem}/{module-type}/{module-name} + +This is not included in `config.functions` because it causes infinite recursion. */ -{config, ...}: let +config: let inherit (config) dlib lib; - subsystemsDir = lib.toString ../../subsystems; + subsystemsDir = lib.toString ../subsystems; subsystems = dlib.dirNames subsystemsDir; collect = moduleDirName: @@ -35,9 +37,12 @@ modules: import_ = collectedModules: lib.mapAttrs - (name: description: - (import description.path config) - // {inherit (description) name subsystem;}) + ( + name: description: let + attrs = {inherit (description) name subsystem;}; + in + (import description.path (config // attrs)) // attrs + ) ( lib.foldl' ( @@ -54,13 +59,6 @@ modules: collectedModules ); - instantiate = importedModules: loader: - lib.mapAttrs - (name: module: - (loader module) - // {inherit (module) name subsystem;}) - importedModules; - structureBySubsystem = instances: lib.foldl lib.recursiveUpdate @@ -69,15 +67,9 @@ modules: (tName: t: {"${t.subsystem}"."${tName}" = t;}) instances); in { - /* - Expose the functions via via the modules system. - */ - config.functions.subsystem-loading = { - inherit - collect - import_ - instantiate - structureBySubsystem - ; - }; + inherit + collect + import_ + structureBySubsystem + ; } diff --git a/src/modules/top-level.nix b/src/modules/top-level.nix index 82fa86b8..1c59d137 100644 --- a/src/modules/top-level.nix +++ b/src/modules/top-level.nix @@ -1,6 +1,8 @@ { apps, dlib, + externals, + externalSources, lib, pkgs, utils, @@ -14,7 +16,6 @@ in { ./functions.default-fetcher ./functions.combined-fetcher ./functions.translators - ./functions.subsystem-loading ./builders ./discoverers ./discoverers.default-discoverer @@ -31,6 +32,12 @@ in { dlib = lib.mkOption { type = t.raw; }; + externals = lib.mkOption { + type = t.raw; + }; + externalSources = lib.mkOption { + type = t.raw; + }; pkgs = lib.mkOption { type = t.raw; }; @@ -42,7 +49,7 @@ in { }; }; config = { - inherit apps dlib pkgs utils dream2nixConfig; + inherit apps dlib externals externalSources pkgs utils dream2nixConfig; lib = lib // builtins; }; } diff --git a/src/modules/translators/implementation.nix b/src/modules/translators/implementation.nix index 49346d78..003c8367 100644 --- a/src/modules/translators/implementation.nix +++ b/src/modules/translators/implementation.nix @@ -1,5 +1,5 @@ {config, ...}: let - funcs = config.functions.subsystem-loading; + funcs = import ../subsystem-loading.nix config; collectedModules = funcs.collect "translators"; in { config = { diff --git a/src/subsystems/haskell/builders/simple-haskell/default.nix b/src/subsystems/haskell/builders/simple-haskell/default.nix index bb6a8fbf..3eabce17 100644 --- a/src/subsystems/haskell/builders/simple-haskell/default.nix +++ b/src/subsystems/haskell/builders/simple-haskell/default.nix @@ -1,17 +1,15 @@ -{lib, ...}: let +{ + pkgs, + utils, + externals, + lib, + ... +}: let l = lib // builtins; in { type = "pure"; build = { - lib, - pkgs, - stdenv, - # dream2nix inputs - externals, - utils, - ... - }: { ### FUNCTIONS # AttrSet -> Bool) -> AttrSet -> [x] getCyclicDependencies, # name: version: -> [ {name=; version=; } ] @@ -37,8 +35,6 @@ in { produceDerivation, ... } @ args: let - b = builtins; - compiler = pkgs .haskell diff --git a/src/subsystems/haskell/translators/cabal-plan/default.nix b/src/subsystems/haskell/translators/cabal-plan/default.nix index 49730cd4..83989461 100644 --- a/src/subsystems/haskell/translators/cabal-plan/default.nix +++ b/src/subsystems/haskell/translators/cabal-plan/default.nix @@ -1,6 +1,7 @@ { dlib, lib, + name, ... }: let l = lib // builtins; @@ -37,7 +38,7 @@ in { l.pathExists "${tree.fullPath}/dist-newstyle/cache/plan.json"; # translate from a given source and a project specification to a dream-lock. - translate = {translatorName, ...}: { + translate = { /* A list of projects returned by `discoverProjects` Example: @@ -189,7 +190,7 @@ in { in dlib.simpleTranslate2.translate ({objectsByKey, ...}: rec { - inherit translatorName; + translatorName = name; # relative path of the project within the source tree. location = project.relPath; diff --git a/src/subsystems/haskell/translators/hackage/default.nix b/src/subsystems/haskell/translators/hackage/default.nix index f8f7cb87..e29f90d8 100644 --- a/src/subsystems/haskell/translators/hackage/default.nix +++ b/src/subsystems/haskell/translators/hackage/default.nix @@ -1,10 +1,9 @@ { - dlib, - lib, + pkgs, + utils, + translators, ... -}: let - l = lib // builtins; -in { +}: { type = "impure"; # A derivation which outputs a single executable at `$out`. @@ -18,24 +17,21 @@ in { # by the input parameter `outFile`. # The output file must contain the dream lock data encoded as json. # See /src/specifications/dream-lock-example.json - translateBin = { - # dream2nix utils - subsystems, - utils, - # nixpkgs dependenies - bash, - coreutils, - curl, - gnutar, - gzip, - haskellPackages, - jq, - moreutils, - nix, - python3, - writeScriptBin, - ... - }: + translateBin = let + inherit + (pkgs) + bash + coreutils + curl + gnutar + gzip + haskellPackages + jq + moreutils + nix + python3 + ; + in utils.writePureShellScript [ bash @@ -86,7 +82,7 @@ in { popd # execute cabal-plan translator - ${subsystems.haskell.translators.cabal-plan.translateBin} $TMPDIR/newJsonInput + ${translators.cabal-plan.translateBin} $TMPDIR/newJsonInput # finalize dream-lock. Add source and export default package # set correct package version under `packages` @@ -105,22 +101,5 @@ in { # - boolean flag (type = "flag") # String arguments contain a default value and examples. Flags do not. extraArgs = { - # Example: boolean option - # Flags always default to 'false' if not specified by the user - noDev = { - description = "Exclude dev dependencies"; - type = "flag"; - }; - - # Example: string option - theAnswer = { - default = "42"; - description = "The Answer to the Ultimate Question of Life"; - examples = [ - "0" - "1234" - ]; - type = "argument"; - }; }; } diff --git a/src/subsystems/haskell/translators/stack-lock/default.nix b/src/subsystems/haskell/translators/stack-lock/default.nix index 711fbb6d..c1411259 100644 --- a/src/subsystems/haskell/translators/stack-lock/default.nix +++ b/src/subsystems/haskell/translators/stack-lock/default.nix @@ -1,6 +1,9 @@ { dlib, lib, + pkgs, + utils, + name, ... }: let l = lib // builtins; @@ -71,12 +74,7 @@ in { (l.attrNames tree.files); # translate from a given source and a project specification to a dream-lock. - translate = { - translatorName, - pkgs, - utils, - ... - }: let + translate = let stackLockUtils = import ./utils.nix {inherit dlib lib pkgs;}; all-cabal-hashes = let all-cabal-hashes' = pkgs.runCommandLocal "all-cabal-hashes" {} '' @@ -231,7 +229,7 @@ in { in dlib.simpleTranslate2.translate ({objectsByKey, ...}: rec { - inherit translatorName; + translatorName = name; # relative path of the project within the source tree. location = project.relPath; diff --git a/src/subsystems/nodejs/builders/granular-nodejs/default.nix b/src/subsystems/nodejs/builders/granular-nodejs/default.nix index c9a8f4a5..ab4dcf0e 100644 --- a/src/subsystems/nodejs/builders/granular-nodejs/default.nix +++ b/src/subsystems/nodejs/builders/granular-nodejs/default.nix @@ -1,511 +1,515 @@ -{...}: { +{ + pkgs, + lib, + ... +}: { type = "pure"; - build = { - jq, - lib, - makeWrapper, - mkShell, - pkgs, - python3, - runCommandLocal, - stdenv, - writeText, - ... - }: { - # Funcs - # AttrSet -> Bool) -> AttrSet -> [x] - getCyclicDependencies, # name: version: -> [ {name=; version=; } ] - getDependencies, # name: version: -> [ {name=; version=; } ] - getSource, # name: version: -> store-path - # Attributes - subsystemAttrs, # attrset - defaultPackageName, # string - defaultPackageVersion, # string - packages, # list - # attrset of pname -> versions, - # where versions is a list of version strings - packageVersions, - # function which applies overrides to a package - # It must be applied by the builder to each individual derivation - # Example: - # produceDerivation name (mkDerivation {...}) - produceDerivation, - nodejs ? null, - ... - } @ args: let - b = builtins; - l = lib // builtins; + build = let + inherit + (pkgs) + jq + makeWrapper + mkShell + python3 + runCommandLocal + stdenv + ; + in + { + # Funcs + # AttrSet -> Bool) -> AttrSet -> [x] + getCyclicDependencies, # name: version: -> [ {name=; version=; } ] + getDependencies, # name: version: -> [ {name=; version=; } ] + getSource, # name: version: -> store-path + # Attributes + subsystemAttrs, # attrset + defaultPackageName, # string + defaultPackageVersion, # string + packages, # list + # attrset of pname -> versions, + # where versions is a list of version strings + packageVersions, + # function which applies overrides to a package + # It must be applied by the builder to each individual derivation + # Example: + # produceDerivation name (mkDerivation {...}) + produceDerivation, + nodejs ? null, + ... + } @ args: let + b = builtins; + l = lib // builtins; - nodejsVersion = subsystemAttrs.nodejsVersion; + nodejsVersion = subsystemAttrs.nodejsVersion; - isMainPackage = name: version: - (args.packages."${name}" or null) == version; + isMainPackage = name: version: + (args.packages."${name}" or null) == version; - nodejs = - if args ? nodejs - then b.toString args.nodejs - else - pkgs."nodejs-${nodejsVersion}_x" - or (throw "Could not find nodejs version '${nodejsVersion}' in pkgs"); + nodejs = + if args ? nodejs + then b.toString args.nodejs + else + pkgs."nodejs-${nodejsVersion}_x" + or (throw "Could not find nodejs version '${nodejsVersion}' in pkgs"); - nodeSources = runCommandLocal "node-sources" {} '' - tar --no-same-owner --no-same-permissions -xf ${nodejs.src} - mv node-* $out - ''; - - allPackages = - lib.mapAttrs - (name: versions: - lib.genAttrs - versions - (version: - makePackage name version)) - packageVersions; - - outputs = rec { - # select only the packages listed in dreamLock as main packages - packages = - b.foldl' - (ps: p: ps // p) - {} - (lib.mapAttrsToList - (name: version: { - "${name}"."${version}" = allPackages."${name}"."${version}"; - }) - args.packages); - - devShells = - {default = devShells.${defaultPackageName};} - // ( - l.mapAttrs - (name: version: allPackages.${name}.${version}.devShell) - args.packages - ); - }; - - # This is only executed for electron based packages. - # Electron ships its own version of node, requiring a rebuild of native - # extensions. - # Theoretically this requires headers for the exact electron version in use, - # but we use the headers from nixpkgs' electron instead which might have a - # different minor version. - # Alternatively the headers can be specified via `electronHeaders`. - # Also a custom electron version can be specified via `electronPackage` - electron-rebuild = '' - # prepare node headers for electron - if [ -n "$electronPackage" ]; then - export electronDist="$electronPackage/lib/electron" - else - export electronDist="$nodeModules/$packageName/node_modules/electron/dist" - fi - local ver - ver="v$(cat $electronDist/version | tr -d '\n')" - mkdir $TMP/$ver - cp $electronHeaders $TMP/$ver/node-$ver-headers.tar.gz - - # calc checksums - cd $TMP/$ver - sha256sum ./* > SHASUMS256.txt - cd - - - # serve headers via http - python -m http.server 45034 --directory $TMP & - - # copy electron distribution - cp -r $electronDist $TMP/electron - chmod -R +w $TMP/electron - - # configure electron toolchain - ${pkgs.jq}/bin/jq ".build.electronDist = \"$TMP/electron\"" package.json \ - | ${pkgs.moreutils}/bin/sponge package.json - - ${pkgs.jq}/bin/jq ".build.linux.target = \"dir\"" package.json \ - | ${pkgs.moreutils}/bin/sponge package.json - - ${pkgs.jq}/bin/jq ".build.npmRebuild = false" package.json \ - | ${pkgs.moreutils}/bin/sponge package.json - - # execute electron-rebuild if available - export headers=http://localhost:45034/ - if command -v electron-rebuild &> /dev/null; then - pushd $electronAppDir - - electron-rebuild -d $headers - popd - fi - ''; - - # Only executed for electron based packages. - # Creates an executable script under /bin starting the electron app - electron-wrap = - if pkgs.stdenv.isLinux - then '' - mkdir -p $out/bin - makeWrapper \ - $electronDist/electron \ - $out/bin/$(basename "$packageName") \ - --add-flags "$(realpath $electronAppDir)" - '' - else '' - mkdir -p $out/bin - makeWrapper \ - $electronDist/Electron.app/Contents/MacOS/Electron \ - $out/bin/$(basename "$packageName") \ - --add-flags "$(realpath $electronAppDir)" + nodeSources = runCommandLocal "node-sources" {} '' + tar --no-same-owner --no-same-permissions -xf ${nodejs.src} + mv node-* $out ''; - # Generates a derivation for a specific package name + version - makePackage = name: version: let - pname = lib.replaceStrings ["@" "/"] ["__at__" "__slash__"] name; + allPackages = + lib.mapAttrs + (name: versions: + lib.genAttrs + versions + (version: + makePackage name version)) + packageVersions; - deps = getDependencies name version; + outputs = rec { + # select only the packages listed in dreamLock as main packages + packages = + b.foldl' + (ps: p: ps // p) + {} + (lib.mapAttrsToList + (name: version: { + "${name}"."${version}" = allPackages."${name}"."${version}"; + }) + args.packages); - nodeDeps = - lib.forEach - deps - (dep: allPackages."${dep.name}"."${dep.version}"); + devShells = + {default = devShells.${defaultPackageName};} + // ( + l.mapAttrs + (name: version: allPackages.${name}.${version}.devShell) + args.packages + ); + }; - passthruDeps = - l.listToAttrs - (l.forEach deps - (dep: - l.nameValuePair - dep.name - allPackages."${dep.name}"."${dep.version}")); - - dependenciesJson = - b.toJSON - (lib.listToAttrs - (b.map - (dep: lib.nameValuePair dep.name dep.version) - deps)); - - electronDep = - if ! isMainPackage name version - then null + # This is only executed for electron based packages. + # Electron ships its own version of node, requiring a rebuild of native + # extensions. + # Theoretically this requires headers for the exact electron version in use, + # but we use the headers from nixpkgs' electron instead which might have a + # different minor version. + # Alternatively the headers can be specified via `electronHeaders`. + # Also a custom electron version can be specified via `electronPackage` + electron-rebuild = '' + # prepare node headers for electron + if [ -n "$electronPackage" ]; then + export electronDist="$electronPackage/lib/electron" else - lib.findFirst - (dep: dep.name == "electron") - null - deps; + export electronDist="$nodeModules/$packageName/node_modules/electron/dist" + fi + local ver + ver="v$(cat $electronDist/version | tr -d '\n')" + mkdir $TMP/$ver + cp $electronHeaders $TMP/$ver/node-$ver-headers.tar.gz - electronVersionMajor = - lib.versions.major electronDep.version; + # calc checksums + cd $TMP/$ver + sha256sum ./* > SHASUMS256.txt + cd - - electronHeaders = - if - (electronDep == null) - # hashes seem unavailable for electron < 4 - || ((l.toInt electronVersionMajor) <= 2) - then null - else pkgs."electron_${electronVersionMajor}".headers; + # serve headers via http + python -m http.server 45034 --directory $TMP & - pkg = produceDerivation name (stdenv.mkDerivation rec { - inherit - dependenciesJson - electronHeaders - nodeDeps - nodeSources - version - ; + # copy electron distribution + cp -r $electronDist $TMP/electron + chmod -R +w $TMP/electron - packageName = name; + # configure electron toolchain + ${pkgs.jq}/bin/jq ".build.electronDist = \"$TMP/electron\"" package.json \ + | ${pkgs.moreutils}/bin/sponge package.json - inherit pname; + ${pkgs.jq}/bin/jq ".build.linux.target = \"dir\"" package.json \ + | ${pkgs.moreutils}/bin/sponge package.json - meta = let - meta = subsystemAttrs.meta; - in - meta - // { - license = l.map (name: l.licenses.${name}) meta.license; + ${pkgs.jq}/bin/jq ".build.npmRebuild = false" package.json \ + | ${pkgs.moreutils}/bin/sponge package.json + + # execute electron-rebuild if available + export headers=http://localhost:45034/ + if command -v electron-rebuild &> /dev/null; then + pushd $electronAppDir + + electron-rebuild -d $headers + popd + fi + ''; + + # Only executed for electron based packages. + # Creates an executable script under /bin starting the electron app + electron-wrap = + if pkgs.stdenv.isLinux + then '' + mkdir -p $out/bin + makeWrapper \ + $electronDist/electron \ + $out/bin/$(basename "$packageName") \ + --add-flags "$(realpath $electronAppDir)" + '' + else '' + mkdir -p $out/bin + makeWrapper \ + $electronDist/Electron.app/Contents/MacOS/Electron \ + $out/bin/$(basename "$packageName") \ + --add-flags "$(realpath $electronAppDir)" + ''; + + # Generates a derivation for a specific package name + version + makePackage = name: version: let + pname = lib.replaceStrings ["@" "/"] ["__at__" "__slash__"] name; + + deps = getDependencies name version; + + nodeDeps = + lib.forEach + deps + (dep: allPackages."${dep.name}"."${dep.version}"); + + passthruDeps = + l.listToAttrs + (l.forEach deps + (dep: + l.nameValuePair + dep.name + allPackages."${dep.name}"."${dep.version}")); + + dependenciesJson = + b.toJSON + (lib.listToAttrs + (b.map + (dep: lib.nameValuePair dep.name dep.version) + deps)); + + electronDep = + if ! isMainPackage name version + then null + else + lib.findFirst + (dep: dep.name == "electron") + null + deps; + + electronVersionMajor = + lib.versions.major electronDep.version; + + electronHeaders = + if + (electronDep == null) + # hashes seem unavailable for electron < 4 + || ((l.toInt electronVersionMajor) <= 2) + then null + else pkgs."electron_${electronVersionMajor}".headers; + + pkg = produceDerivation name (stdenv.mkDerivation rec { + inherit + dependenciesJson + electronHeaders + nodeDeps + nodeSources + version + ; + + packageName = name; + + inherit pname; + + meta = let + meta = subsystemAttrs.meta; + in + meta + // { + license = l.map (name: l.licenses.${name}) meta.license; + }; + + passthru.dependencies = passthruDeps; + + passthru.devShell = import ./devShell.nix { + inherit + mkShell + nodejs + packageName + pkg + ; }; - passthru.dependencies = passthruDeps; + /* + For top-level packages install dependencies as full copies, as this + reduces errors with build tooling that doesn't cope well with + symlinking. + */ + installMethod = + if isMainPackage name version + then "copy" + else "symlink"; - passthru.devShell = import ./devShell.nix { - inherit - mkShell - nodejs - packageName - pkg - ; - }; + electronAppDir = "."; - /* - For top-level packages install dependencies as full copies, as this - reduces errors with build tooling that doesn't cope well with - symlinking. - */ - installMethod = - if isMainPackage name version - then "copy" - else "symlink"; + # only run build on the main package + runBuild = isMainPackage name version; - electronAppDir = "."; + src = getSource name version; - # only run build on the main package - runBuild = isMainPackage name version; + nativeBuildInputs = [makeWrapper]; - src = getSource name version; + buildInputs = [jq nodejs python3]; - nativeBuildInputs = [makeWrapper]; + # prevents running into ulimits + passAsFile = ["dependenciesJson" "nodeDeps"]; - buildInputs = [jq nodejs python3]; + preConfigurePhases = ["d2nLoadFuncsPhase" "d2nPatchPhase"]; - # prevents running into ulimits - passAsFile = ["dependenciesJson" "nodeDeps"]; + # can be overridden to define alternative install command + # (defaults to 'npm run postinstall') + buildScript = null; - preConfigurePhases = ["d2nLoadFuncsPhase" "d2nPatchPhase"]; + # python script to modify some metadata to support installation + # (see comments below on d2nPatchPhase) + fixPackage = "${./fix-package.py}"; - # can be overridden to define alternative install command - # (defaults to 'npm run postinstall') - buildScript = null; + # script to install (symlink or copy) dependencies. + installDeps = "${./install-deps.py}"; - # python script to modify some metadata to support installation - # (see comments below on d2nPatchPhase) - fixPackage = "${./fix-package.py}"; + # python script to link bin entries from package.json + linkBins = "${./link-bins.py}"; - # script to install (symlink or copy) dependencies. - installDeps = "${./install-deps.py}"; + # costs performance and doesn't seem beneficial in most scenarios + dontStrip = true; - # python script to link bin entries from package.json - linkBins = "${./link-bins.py}"; + # declare some useful shell functions + d2nLoadFuncsPhase = '' + # function to resolve symlinks to copies + symlinksToCopies() { + local dir="$1" - # costs performance and doesn't seem beneficial in most scenarios - dontStrip = true; - - # declare some useful shell functions - d2nLoadFuncsPhase = '' - # function to resolve symlinks to copies - symlinksToCopies() { - local dir="$1" - - echo "transforming symlinks to copies..." - for f in $(find -L "$dir" -xtype l); do - if [ -f $f ]; then - continue - fi - echo "copying $f" - chmod +wx $(dirname "$f") - mv "$f" "$f.bak" - mkdir "$f" - if [ -n "$(ls -A "$f.bak/")" ]; then - cp -r "$f.bak"/* "$f/" - chmod -R +w $f - fi - rm "$f.bak" - done - } - ''; - - # TODO: upstream fix to nixpkgs - # example which requires this: - # https://registry.npmjs.org/react-window-infinite-loader/-/react-window-infinite-loader-1.0.7.tgz - unpackCmd = - if lib.hasSuffix ".tgz" src - then "tar --delay-directory-restore -xf $src" - else null; - - unpackPhase = '' - runHook preUnpack - - nodeModules=$out/lib/node_modules - - export sourceRoot="$nodeModules/$packageName" - - # sometimes tarballs do not end with .tar.?? - unpackFallback(){ - local fn="$1" - tar xf "$fn" - } - - unpackCmdHooks+=(unpackFallback) - - unpackFile $src - - # Make the base dir in which the target dependency resides in first - mkdir -p "$(dirname "$sourceRoot")" - - # install source - if [ -f "$src" ] - then - # Figure out what directory has been unpacked - export packageDir="$(find . -maxdepth 1 -type d | tail -1)" - - # Restore write permissions - find "$packageDir" -type d -exec chmod u+x {} \; - chmod -R u+w -- "$packageDir" - - # Move the extracted tarball into the output folder - mv -- "$packageDir" "$sourceRoot" - elif [ -d "$src" ] - then - export strippedName="$(stripHash $src)" - - # Restore write permissions - chmod -R u+w -- "$strippedName" - - # Move the extracted directory into the output folder - mv -- "$strippedName" "$sourceRoot" - fi - - runHook postUnpack - ''; - - # The python script wich is executed in this phase: - # - ensures that the package is compatible to the current system - # - ensures the main version in package.json matches the expected - # - pins dependency versions in package.json - # (some npm commands might otherwise trigger networking) - # - creates symlinks for executables declared in package.json - # Apart from that: - # - Any usage of 'link:' in package.json is replaced with 'file:' - # - If package-lock.json exists, it is deleted, as it might conflict - # with the parent package-lock.json. - d2nPatchPhase = '' - # delete package-lock.json as it can lead to conflicts - rm -f package-lock.json - - # repair 'link:' -> 'file:' - mv $nodeModules/$packageName/package.json $nodeModules/$packageName/package.json.old - cat $nodeModules/$packageName/package.json.old | sed 's!link:!file\:!g' > $nodeModules/$packageName/package.json - rm $nodeModules/$packageName/package.json.old - - # run python script (see comment above): - cp package.json package.json.bak - python $fixPackage \ - || \ - # exit code 3 -> the package is incompatible to the current platform - # -> Let the build succeed, but don't create lib/node_packages - if [ "$?" == "3" ]; then - rm -r $out/* - echo "Not compatible with system $system" > $out/error - exit 0 - else - exit 1 - fi - - # configure typescript - if [ -f ./tsconfig.json ] \ - && node -e 'require("typescript")' &>/dev/null; then - node ${./tsconfig-to-json.js} - ${pkgs.jq}/bin/jq ".compilerOptions.preserveSymlinks = true" tsconfig.json \ - | ${pkgs.moreutils}/bin/sponge tsconfig.json - fi - ''; - - # - installs dependencies into the node_modules directory - # - adds executables of direct node module dependencies to PATH - # - adds the current node module to NODE_PATH - # - sets HOME=$TMPDIR, as this is required by some npm scripts - # TODO: don't install dev dependencies. Load into NODE_PATH instead - configurePhase = '' - runHook preConfigure - - # symlink sub dependencies as well as this imitates npm better - python $installDeps - - echo "Symlinking transitive executables to $nodeModules/.bin" - for dep in ${l.toString nodeDeps}; do - binDir=$dep/lib/node_modules/.bin - if [ -e $binDir ]; then - for bin in $(ls $binDir/); do\ - if [ ! -e $nodeModules/.bin ]; then - mkdir -p $nodeModules/.bin + echo "transforming symlinks to copies..." + for f in $(find -L "$dir" -xtype l); do + if [ -f $f ]; then + continue fi - - # symlink might have been already created by install-deps.py - # if installMethod=copy was selected - if [ ! -L $nodeModules/.bin/$bin ]; then - ln -s $binDir/$bin $nodeModules/.bin/$bin - else - echo "won't overwrite existing symlink $nodeModules/.bin/$bin. current target: $(readlink $nodeModules/.bin/$bin)" + echo "copying $f" + chmod +wx $(dirname "$f") + mv "$f" "$f.bak" + mkdir "$f" + if [ -n "$(ls -A "$f.bak/")" ]; then + cp -r "$f.bak"/* "$f/" + chmod -R +w $f fi + rm "$f.bak" done + } + ''; + + # TODO: upstream fix to nixpkgs + # example which requires this: + # https://registry.npmjs.org/react-window-infinite-loader/-/react-window-infinite-loader-1.0.7.tgz + unpackCmd = + if lib.hasSuffix ".tgz" src + then "tar --delay-directory-restore -xf $src" + else null; + + unpackPhase = '' + runHook preUnpack + + nodeModules=$out/lib/node_modules + + export sourceRoot="$nodeModules/$packageName" + + # sometimes tarballs do not end with .tar.?? + unpackFallback(){ + local fn="$1" + tar xf "$fn" + } + + unpackCmdHooks+=(unpackFallback) + + unpackFile $src + + # Make the base dir in which the target dependency resides in first + mkdir -p "$(dirname "$sourceRoot")" + + # install source + if [ -f "$src" ] + then + # Figure out what directory has been unpacked + export packageDir="$(find . -maxdepth 1 -type d | tail -1)" + + # Restore write permissions + find "$packageDir" -type d -exec chmod u+x {} \; + chmod -R u+w -- "$packageDir" + + # Move the extracted tarball into the output folder + mv -- "$packageDir" "$sourceRoot" + elif [ -d "$src" ] + then + export strippedName="$(stripHash $src)" + + # Restore write permissions + chmod -R u+w -- "$strippedName" + + # Move the extracted directory into the output folder + mv -- "$strippedName" "$sourceRoot" fi - done - # add bin path entries collected by python script - export PATH="$PATH:$nodeModules/.bin" + runHook postUnpack + ''; - # add dependencies to NODE_PATH - export NODE_PATH="$NODE_PATH:$nodeModules/$packageName/node_modules" + # The python script wich is executed in this phase: + # - ensures that the package is compatible to the current system + # - ensures the main version in package.json matches the expected + # - pins dependency versions in package.json + # (some npm commands might otherwise trigger networking) + # - creates symlinks for executables declared in package.json + # Apart from that: + # - Any usage of 'link:' in package.json is replaced with 'file:' + # - If package-lock.json exists, it is deleted, as it might conflict + # with the parent package-lock.json. + d2nPatchPhase = '' + # delete package-lock.json as it can lead to conflicts + rm -f package-lock.json - export HOME=$TMPDIR + # repair 'link:' -> 'file:' + mv $nodeModules/$packageName/package.json $nodeModules/$packageName/package.json.old + cat $nodeModules/$packageName/package.json.old | sed 's!link:!file\:!g' > $nodeModules/$packageName/package.json + rm $nodeModules/$packageName/package.json.old - runHook postConfigure - ''; - - # Runs the install command which defaults to 'npm run postinstall'. - # Allows using custom install command by overriding 'buildScript'. - buildPhase = '' - runHook preBuild - - # execute electron-rebuild - if [ -n "$electronHeaders" ]; then - echo "executing electron-rebuild" - ${electron-rebuild} - fi - - # execute install command - if [ -n "$buildScript" ]; then - if [ -f "$buildScript" ]; then - $buildScript + # run python script (see comment above): + cp package.json package.json.bak + python $fixPackage \ + || \ + # exit code 3 -> the package is incompatible to the current platform + # -> Let the build succeed, but don't create lib/node_packages + if [ "$?" == "3" ]; then + rm -r $out/* + echo "Not compatible with system $system" > $out/error + exit 0 else - eval "$buildScript" + exit 1 fi - # by default, only for top level packages, `npm run build` is executed - elif [ -n "$runBuild" ] && [ "$(jq '.scripts.build' ./package.json)" != "null" ]; then - npm run build - else - if [ "$(jq '.scripts.preinstall' ./package.json)" != "null" ]; then - npm --production --offline --nodedir=$nodeSources run preinstall + + # configure typescript + if [ -f ./tsconfig.json ] \ + && node -e 'require("typescript")' &>/dev/null; then + node ${./tsconfig-to-json.js} + ${pkgs.jq}/bin/jq ".compilerOptions.preserveSymlinks = true" tsconfig.json \ + | ${pkgs.moreutils}/bin/sponge tsconfig.json fi - if [ "$(jq '.scripts.install' ./package.json)" != "null" ]; then - npm --production --offline --nodedir=$nodeSources run install - fi - if [ "$(jq '.scripts.postinstall' ./package.json)" != "null" ]; then - npm --production --offline --nodedir=$nodeSources run postinstall - fi - fi + ''; - runHook postBuild - ''; + # - installs dependencies into the node_modules directory + # - adds executables of direct node module dependencies to PATH + # - adds the current node module to NODE_PATH + # - sets HOME=$TMPDIR, as this is required by some npm scripts + # TODO: don't install dev dependencies. Load into NODE_PATH instead + configurePhase = '' + runHook preConfigure - # Symlinks executables and manual pages to correct directories - installPhase = '' - runHook preInstall + # symlink sub dependencies as well as this imitates npm better + python $installDeps - echo "Symlinking bin entries from package.json" - python $linkBins + echo "Symlinking transitive executables to $nodeModules/.bin" + for dep in ${l.toString nodeDeps}; do + binDir=$dep/lib/node_modules/.bin + if [ -e $binDir ]; then + for bin in $(ls $binDir/); do\ + if [ ! -e $nodeModules/.bin ]; then + mkdir -p $nodeModules/.bin + fi - echo "Symlinking manual pages" - if [ -d "$nodeModules/$packageName/man" ] - then - mkdir -p $out/share - for dir in "$nodeModules/$packageName/man/"* - do - mkdir -p $out/share/man/$(basename "$dir") - for page in "$dir"/* - do - ln -s $page $out/share/man/$(basename "$dir") - done + # symlink might have been already created by install-deps.py + # if installMethod=copy was selected + if [ ! -L $nodeModules/.bin/$bin ]; then + ln -s $binDir/$bin $nodeModules/.bin/$bin + else + echo "won't overwrite existing symlink $nodeModules/.bin/$bin. current target: $(readlink $nodeModules/.bin/$bin)" + fi + done + fi done - fi - # wrap electron app - if [ -n "$electronHeaders" ]; then - echo "Wrapping electron app" - ${electron-wrap} - fi + # add bin path entries collected by python script + export PATH="$PATH:$nodeModules/.bin" - runHook postInstall - ''; - }); + # add dependencies to NODE_PATH + export NODE_PATH="$NODE_PATH:$nodeModules/$packageName/node_modules" + + export HOME=$TMPDIR + + runHook postConfigure + ''; + + # Runs the install command which defaults to 'npm run postinstall'. + # Allows using custom install command by overriding 'buildScript'. + buildPhase = '' + runHook preBuild + + # execute electron-rebuild + if [ -n "$electronHeaders" ]; then + echo "executing electron-rebuild" + ${electron-rebuild} + fi + + # execute install command + if [ -n "$buildScript" ]; then + if [ -f "$buildScript" ]; then + $buildScript + else + eval "$buildScript" + fi + # by default, only for top level packages, `npm run build` is executed + elif [ -n "$runBuild" ] && [ "$(jq '.scripts.build' ./package.json)" != "null" ]; then + npm run build + else + if [ "$(jq '.scripts.preinstall' ./package.json)" != "null" ]; then + npm --production --offline --nodedir=$nodeSources run preinstall + fi + if [ "$(jq '.scripts.install' ./package.json)" != "null" ]; then + npm --production --offline --nodedir=$nodeSources run install + fi + if [ "$(jq '.scripts.postinstall' ./package.json)" != "null" ]; then + npm --production --offline --nodedir=$nodeSources run postinstall + fi + fi + + runHook postBuild + ''; + + # Symlinks executables and manual pages to correct directories + installPhase = '' + runHook preInstall + + echo "Symlinking bin entries from package.json" + python $linkBins + + echo "Symlinking manual pages" + if [ -d "$nodeModules/$packageName/man" ] + then + mkdir -p $out/share + for dir in "$nodeModules/$packageName/man/"* + do + mkdir -p $out/share/man/$(basename "$dir") + for page in "$dir"/* + do + ln -s $page $out/share/man/$(basename "$dir") + done + done + fi + + # wrap electron app + if [ -n "$electronHeaders" ]; then + echo "Wrapping electron app" + ${electron-wrap} + fi + + runHook postInstall + ''; + }); + in + pkg; in - pkg; - in - outputs; + outputs; } diff --git a/src/subsystems/nodejs/translators/npm/default.nix b/src/subsystems/nodejs/translators/npm/default.nix index 157648c9..2d63a7af 100644 --- a/src/subsystems/nodejs/translators/npm/default.nix +++ b/src/subsystems/nodejs/translators/npm/default.nix @@ -1,29 +1,27 @@ { - dlib, - lib, + apps, + utils, + pkgs, + translators, ... }: { type = "impure"; # the input format is specified in /specifications/translator-call-example.json # this script receives a json file including the input paths and specialArgs - translateBin = { - # dream2nix utils - apps, - subsystems, - utils, - # nixpkgs dependencies - bash, - coreutils, - git, - jq, - moreutils, - nodePackages, - openssh, - python3, - writeScriptBin, - ... - }: + translateBin = let + inherit + (pkgs) + bash + coreutils + git + jq + moreutils + nodePackages + openssh + python3 + ; + in utils.writePureShellScript [ bash @@ -64,7 +62,7 @@ popd # call package-lock translator - ${subsystems.nodejs.translators.package-lock.translateBin} $TMPDIR/newJsonInput + ${translators.package-lock.translateBin} $TMPDIR/newJsonInput # get resolved package version export version=$(npm view $candidate version) @@ -78,7 +76,7 @@ # inherit options from package-lock translator extraArgs = - dlib.translators.translators.nodejs.package-lock.extraArgs + translators.package-lock.extraArgs // { npmArgs = { description = "Additional arguments for npm"; diff --git a/src/subsystems/nodejs/translators/package-json/default.nix b/src/subsystems/nodejs/translators/package-json/default.nix index ec8cfc3e..13ec3b79 100644 --- a/src/subsystems/nodejs/translators/package-json/default.nix +++ b/src/subsystems/nodejs/translators/package-json/default.nix @@ -1,26 +1,24 @@ { - dlib, - lib, + utils, + pkgs, + translators, ... }: { type = "impure"; # the input format is specified in /specifications/translator-call-example.json # this script receives a json file including the input paths and specialArgs - translateBin = { - # dream2nix utils - subsystems, - utils, - # nixpkgs dependencies - bash, - coreutils, - git, - jq, - nodePackages, - openssh, - writeScriptBin, - ... - }: + translateBin = let + inherit + (pkgs) + bash + coreutils + git + jq + nodePackages + openssh + ; + in utils.writePureShellScript [ bash @@ -62,12 +60,12 @@ jq ".source = \"$newSource\"" -c -r $jsonInput > $TMPDIR/newJsonInput popd - ${subsystems.nodejs.translators.package-lock.translateBin} $TMPDIR/newJsonInput + ${translators.package-lock.translateBin} $TMPDIR/newJsonInput ''; # inherit options from package-lock translator extraArgs = - dlib.translators.translators.nodejs.package-lock.extraArgs + translators.package-lock.extraArgs // { npmArgs = { description = "Additional arguments for npm"; diff --git a/src/subsystems/nodejs/translators/package-lock/default.nix b/src/subsystems/nodejs/translators/package-lock/default.nix index 940e2b25..7e8c8354 100644 --- a/src/subsystems/nodejs/translators/package-lock/default.nix +++ b/src/subsystems/nodejs/translators/package-lock/default.nix @@ -1,9 +1,10 @@ { dlib, lib, + utils, + name, ... }: let - b = builtins; l = lib // builtins; nodejsUtils = import ../utils.nix {inherit dlib lib;}; @@ -11,10 +12,6 @@ nodejsUtils.getWorkspaceLockFile tree project "package-lock.json"; translate = { - translatorName, - utils, - ... - }: { project, source, tree, @@ -146,7 +143,7 @@ dependenciesByOriginalID, ... }: rec { - inherit translatorName; + translatorName = name; location = relPath; # values diff --git a/src/subsystems/nodejs/translators/yarn-lock/default.nix b/src/subsystems/nodejs/translators/yarn-lock/default.nix index 9536ebbc..8fd0d66d 100644 --- a/src/subsystems/nodejs/translators/yarn-lock/default.nix +++ b/src/subsystems/nodejs/translators/yarn-lock/default.nix @@ -1,6 +1,7 @@ { dlib, lib, + name, ... }: let l = lib // builtins; @@ -10,7 +11,7 @@ getYarnLock = tree: project: nodejsUtils.getWorkspaceLockFile tree project "yarn.lock"; - translate = {translatorName, ...}: { + translate = { project, source, tree, @@ -130,7 +131,9 @@ then "path" else "http"; in rec { - inherit defaultPackage translatorName; + inherit defaultPackage; + + translatorName = name; location = relPath; diff --git a/src/subsystems/php/builders/granular-php/default.nix b/src/subsystems/php/builders/granular-php/default.nix index a301d638..f37619bd 100644 --- a/src/subsystems/php/builders/granular-php/default.nix +++ b/src/subsystems/php/builders/granular-php/default.nix @@ -1,15 +1,12 @@ -{...}: { +{ + lib, + pkgs, + externals, + ... +}: { type = "pure"; build = { - lib, - pkgs, - stdenvNoCC, - # dream2nix inputs - externals, - callPackageDream, - ... - }: { ### FUNCTIONS # AttrSet -> Bool) -> AttrSet -> [x] getCyclicDependencies, # name: version: -> [ {name=; version=; } ] @@ -37,7 +34,7 @@ } @ args: let l = lib // builtins; - inherit (callPackageDream ../../semver.nix {}) satisfies; + inherit (pkgs.callPackage ../../semver.nix {}) satisfies; # php with required extensions php = @@ -142,7 +139,7 @@ then "0.0.0" else version; - pkg = stdenvNoCC.mkDerivation rec { + pkg = pkgs.stdenvNoCC.mkDerivation rec { pname = l.strings.sanitizeDerivationName name; inherit version; diff --git a/src/subsystems/php/builders/simple-php/default.nix b/src/subsystems/php/builders/simple-php/default.nix index 0883a3bb..64923fdf 100644 --- a/src/subsystems/php/builders/simple-php/default.nix +++ b/src/subsystems/php/builders/simple-php/default.nix @@ -1,15 +1,12 @@ -{...}: { +{ + lib, + pkgs, + externals, + ... +}: { type = "pure"; build = { - lib, - pkgs, - stdenvNoCC, - # dream2nix inputs - externals, - callPackageDream, - ... - }: { ### FUNCTIONS # AttrSet -> Bool) -> AttrSet -> [x] getCyclicDependencies, # name: version: -> [ {name=; version=; } ] @@ -37,7 +34,7 @@ } @ args: let l = lib // builtins; - inherit (callPackageDream ../../semver.nix {}) satisfies; + inherit (pkgs.callPackage ../../semver.nix {}) satisfies; # php with required extensions php = @@ -78,7 +75,7 @@ # Unpack dependency cleanDependency = name: version: - stdenvNoCC.mkDerivation rec { + pkgs.stdenvNoCC.mkDerivation rec { pname = "${l.strings.sanitizeDerivationName name}-source"; inherit version; versionString = @@ -140,7 +137,7 @@ then "0.0.0" else version; - pkg = stdenvNoCC.mkDerivation rec { + pkg = pkgs.stdenvNoCC.mkDerivation rec { pname = l.strings.sanitizeDerivationName name; inherit version; diff --git a/src/subsystems/php/translators/composer-json/default.nix b/src/subsystems/php/translators/composer-json/default.nix index 27fd4b3f..8d7ae010 100644 --- a/src/subsystems/php/translators/composer-json/default.nix +++ b/src/subsystems/php/translators/composer-json/default.nix @@ -1,6 +1,7 @@ { - dlib, - lib, + pkgs, + utils, + translators, ... }: { type = "impure"; @@ -16,18 +17,16 @@ # by the input parameter `outFile`. # The output file must contain the dream lock data encoded as json. # See /src/specifications/dream-lock-example.json - translateBin = { - # dream2nix utils - subsystems, - utils, - # nixpkgs dependencies - bash, - coreutils, - moreutils, - jq, - phpPackages, - ... - }: + translateBin = let + inherit + (pkgs) + bash + coreutils + moreutils + jq + phpPackages + ; + in utils.writePureShellScript [ bash @@ -76,9 +75,9 @@ jq ".source = \"$newSource\"" -c -r $jsonInput > $TMPDIR/newJsonInput popd - ${subsystems.php.translators.composer-lock.translateBin} $TMPDIR/newJsonInput + ${translators.composer-lock.translateBin} $TMPDIR/newJsonInput ''; # inherit options from composer-lock translator - extraArgs = dlib.translators.translators.php.composer-lock.extraArgs; + extraArgs = translators.composer-lock.extraArgs; } diff --git a/src/subsystems/php/translators/composer-lock/default.nix b/src/subsystems/php/translators/composer-lock/default.nix index c6241d98..4537caae 100644 --- a/src/subsystems/php/translators/composer-lock/default.nix +++ b/src/subsystems/php/translators/composer-lock/default.nix @@ -1,4 +1,5 @@ { + name, dlib, lib, ... @@ -24,10 +25,6 @@ in { # translate from a given source and a project specification to a dream-lock. translate = { - translatorName, - callPackageDream, - ... - }: { /* A list of projects returned by `discoverProjects` Example: @@ -95,7 +92,7 @@ in { ... } @ args: let inherit - (callPackageDream ../../semver.nix {}) + (import ../../semver.nix {inherit lib;}) satisfies multiSatisfies ; @@ -236,7 +233,7 @@ in { in dlib.simpleTranslate2.translate ({objectsByKey, ...}: rec { - inherit translatorName; + translatorName = name; # relative path of the project within the source tree. location = project.relPath; diff --git a/src/subsystems/php/translators/packagist/default.nix b/src/subsystems/php/translators/packagist/default.nix index 3d4b9fa8..e82b6765 100644 --- a/src/subsystems/php/translators/packagist/default.nix +++ b/src/subsystems/php/translators/packagist/default.nix @@ -1,25 +1,24 @@ { - dlib, - lib, + apps, + utils, + translators, + pkgs, ... }: { type = "impure"; # the input format is specified in /specifications/translator-call-example.json # this script receives a json file including the input paths and specialArgs - translateBin = { - # dream2nix utils - apps, - subsystems, - utils, - # nixpkgs dependencies - coreutils, - curl, - jq, - git, - moreutils, - ... - }: + translateBin = let + inherit + (pkgs) + coreutils + curl + jq + git + moreutils + ; + in utils.writePureShellScript [ coreutils @@ -71,10 +70,10 @@ if [ -f $TMPDIR/source/composer.lock ] then echo 'Translating with composer-lock' - ${subsystems.php.translators.composer-lock.translateBin} $TMPDIR/newJsonInput + ${translators.composer-lock.translateBin} $TMPDIR/newJsonInput else echo 'Translating with composer-json' - ${subsystems.php.translators.composer-json.translateBin} $TMPDIR/newJsonInput + ${translators.composer-json.translateBin} $TMPDIR/newJsonInput fi # add main package source info to dream-lock.json @@ -91,5 +90,5 @@ ''; # inherit options from composer-json translator - extraArgs = dlib.translators.translators.php.composer-json.extraArgs; + extraArgs = translators.composer-json.extraArgs; } diff --git a/src/subsystems/python/builders/simple-python/default.nix b/src/subsystems/python/builders/simple-python/default.nix index fd76c6b3..b0651aec 100644 --- a/src/subsystems/python/builders/simple-python/default.nix +++ b/src/subsystems/python/builders/simple-python/default.nix @@ -1,12 +1,12 @@ # A very simple single derivation python builder -{...}: { +{ + pkgs, + lib, + ... +}: { type = "pure"; build = { - lib, - pkgs, - ... - }: { defaultPackageName, defaultPackageVersion, getSource, diff --git a/src/subsystems/python/translators/pip/default.nix b/src/subsystems/python/translators/pip/default.nix index efbec56a..3987ceaa 100644 --- a/src/subsystems/python/translators/pip/default.nix +++ b/src/subsystems/python/translators/pip/default.nix @@ -1,27 +1,24 @@ { - dlib, - lib, + externalSources, + utils, + pkgs, ... -}: let - b = builtins; -in { +}: { type = "impure"; # the input format is specified in /specifications/translator-call-example.json # this script receives a json file including the input paths and extraArgs - translateBin = { - externalSources, - utils, - bash, - coreutils, - jq, - nix, - python3, - remarshal, - toml2json, - writeScriptBin, - ... - }: + translateBin = let + inherit + (pkgs) + bash + coreutils + jq + nix + remarshal + toml2json + ; + in utils.writePureShellScript [ bash diff --git a/src/subsystems/racket/builders/simple-racket/default.nix b/src/subsystems/racket/builders/simple-racket/default.nix index 07ca79fa..0a32bf15 100644 --- a/src/subsystems/racket/builders/simple-racket/default.nix +++ b/src/subsystems/racket/builders/simple-racket/default.nix @@ -1,14 +1,12 @@ -{...}: { +{ + pkgs, + lib, + externals, + ... +}: { type = "pure"; build = { - lib, - pkgs, - stdenv, - # dream2nix inputs - externals, - ... - }: { ### FUNCTIONS # AttrSet -> Bool) -> AttrSet -> [x] getCyclicDependencies, # name: version: -> [ {name=; version=; } ] diff --git a/src/subsystems/racket/translators/racket-impure/default.nix b/src/subsystems/racket/translators/racket-impure/default.nix index 664f28cc..69433757 100644 --- a/src/subsystems/racket/translators/racket-impure/default.nix +++ b/src/subsystems/racket/translators/racket-impure/default.nix @@ -1,10 +1,8 @@ { - dlib, - lib, + utils, + pkgs, ... -}: let - l = lib // builtins; -in { +}: { type = "impure"; # A derivation which outputs a single executable at `$out`. @@ -18,20 +16,18 @@ in { # by the input parameter `outFile`. # The output file must contain the dream lock data encoded as json. # See /src/specifications/dream-lock-example.json - translateBin = { - # dream2nix utils - utils, - # nixpkgs dependencies - bash, - coreutils, - fetchurl, - jq, - nix, - racket, - runCommandLocal, - writeScriptBin, - ... - }: let + translateBin = let + inherit + (pkgs) + bash + coreutils + fetchurl + jq + nix + racket + runCommandLocal + ; + pruned-racket-catalog = let src = fetchurl { url = "https://github.com/nix-community/pruned-racket-catalog/tarball/9f11e5ea5765c8a732c5e3129ca2b71237ae2bac"; diff --git a/src/subsystems/rust/builders/build-rust-package/default.nix b/src/subsystems/rust/builders/build-rust-package/default.nix index d24313fe..2b45a767 100644 --- a/src/subsystems/rust/builders/build-rust-package/default.nix +++ b/src/subsystems/rust/builders/build-rust-package/default.nix @@ -1,13 +1,13 @@ -{...}: { +{ + lib, + dlib, + pkgs, + externals, + ... +} @ topArgs: { type = "pure"; build = { - lib, - dlib, - pkgs, - callPackageDream, - ... - } @ topArgs: { subsystemAttrs, defaultPackageName, defaultPackageVersion, @@ -68,7 +68,10 @@ }); mkShellForPkg = pkg: - callPackageDream ../devshell.nix {drv = pkg;}; + pkgs.callPackage ../devshell.nix { + inherit externals; + drv = pkg; + }; allPackages = l.mapAttrs diff --git a/src/subsystems/rust/builders/crane/default.nix b/src/subsystems/rust/builders/crane/default.nix index 37905f71..09951697 100644 --- a/src/subsystems/rust/builders/crane/default.nix +++ b/src/subsystems/rust/builders/crane/default.nix @@ -1,12 +1,12 @@ -{...}: { +{ + lib, + pkgs, + externals, + ... +} @ topArgs: { type = "ifd"; + build = { - lib, - pkgs, - externals, - callPackageDream, - ... - } @ topArgs: { subsystemAttrs, defaultPackageName, defaultPackageVersion, @@ -121,12 +121,16 @@ pname (buildPackageWithToolchain defaultToolchain buildArgs); - # TODO: this does not carry over environment variables from the - # dependencies derivation. this could cause confusion for users. mkShellForPkg = pkg: let pkgDeps = pkg.passthru.dependencies; - depsShell = callPackageDream ../devshell.nix {drv = pkgDeps;}; - mainShell = callPackageDream ../devshell.nix {drv = pkg;}; + depsShell = pkgs.callPackage ../devshell.nix { + inherit externals; + drv = pkgDeps; + }; + mainShell = pkgs.callPackage ../devshell.nix { + inherit externals; + drv = pkg; + }; shell = depsShell.combineWith mainShell; in shell; diff --git a/src/subsystems/rust/translators/cargo-lock/default.nix b/src/subsystems/rust/translators/cargo-lock/default.nix index d92bde9a..e9f04afe 100644 --- a/src/subsystems/rust/translators/cargo-lock/default.nix +++ b/src/subsystems/rust/translators/cargo-lock/default.nix @@ -1,4 +1,5 @@ { + name, dlib, lib, ... @@ -180,6 +181,7 @@ in { in dlib.simpleTranslate2.translate ({...}: { + translatorName = name; # relative path of the project within the source tree. location = project.relPath; diff --git a/src/subsystems/rust/translators/cargo-toml/default.nix b/src/subsystems/rust/translators/cargo-toml/default.nix index d22d0a88..3a21d76c 100644 --- a/src/subsystems/rust/translators/cargo-toml/default.nix +++ b/src/subsystems/rust/translators/cargo-toml/default.nix @@ -1,17 +1,22 @@ -framework: { +{ + pkgs, + utils, + translators, + ... +}: { type = "impure"; # the input format is specified in /specifications/translator-call-example.json # this script receives a json file including the input paths and specialArgs translateBin = let inherit - (framework.pkgs) + (pkgs) coreutils jq rustPlatform ; in - framework.utils.writePureShellScript + utils.writePureShellScript [ coreutils jq @@ -41,7 +46,7 @@ framework: { popd if [ $cargoResult -eq 0 ]; then - ${framework.translators.cargo-lock.translateBin} $TMPDIR/newJsonInput + ${translators.cargo-lock.translateBin} $TMPDIR/newJsonInput else echo "cargo failed to generate the lockfile" exit 1 @@ -50,7 +55,7 @@ framework: { # inherit options from cargo-lock translator extraArgs = - framework.translators.cargo-lock.extraArgs + translators.cargo-lock.extraArgs // { cargoArgs = { description = "Additional arguments for Cargo";