mirror of
https://github.com/nix-community/dream2nix.git
synced 2024-12-29 01:14:09 +03:00
add: descriptive comments, remove: some unused bindings
This commit is contained in:
parent
96e8a0e297
commit
ca80e29283
@ -112,12 +112,13 @@
|
||||
dependencyGraph;
|
||||
|
||||
packageVersions =
|
||||
l.zipAttrsWith
|
||||
(name: versions: l.flatten versions)
|
||||
[
|
||||
allDependants
|
||||
allDependencies
|
||||
];
|
||||
l.mapAttrs (name: versions: l.unique versions)
|
||||
(l.zipAttrsWith
|
||||
(name: versions: l.flatten versions)
|
||||
[
|
||||
allDependants
|
||||
allDependencies
|
||||
]);
|
||||
|
||||
cyclicDependencies = lock.cyclicDependencies;
|
||||
|
||||
|
@ -34,11 +34,10 @@
|
||||
}: let
|
||||
l = lib // builtins;
|
||||
b = builtins;
|
||||
inherit (pkgs) stdenv python3 python310Packages makeWrapper jq;
|
||||
|
||||
nodejsVersion = subsystemAttrs.nodejsVersion;
|
||||
|
||||
defaultNodejsVersion = "14";
|
||||
defaultNodejsVersion = l.versions.major pkgs.nodejs.version;
|
||||
|
||||
isMainPackage = name: version:
|
||||
(packages."${name}" or null) == version;
|
||||
@ -50,6 +49,11 @@
|
||||
pkgs."nodejs-${nodejsVersion}_x"
|
||||
or (throw "Could not find nodejs version '${nodejsVersion}' in pkgs");
|
||||
|
||||
nodeSources = pkgs.runCommandLocal "node-sources" {} ''
|
||||
tar --no-same-owner --no-same-permissions -xf ${nodejs.src}
|
||||
mv node-* $out
|
||||
'';
|
||||
|
||||
# e.g.
|
||||
# {
|
||||
# "@babel/core": ["1.0.0","2.0.0"]
|
||||
@ -73,66 +77,81 @@
|
||||
)
|
||||
packageVersions;
|
||||
|
||||
# our builder, written in python. We have huge complexity with how npm builds node_modules
|
||||
nodejsBuilder = python310Packages.buildPythonApplication {
|
||||
pname = "builder";
|
||||
version = "0.1.0";
|
||||
# our builder, written in python. Better handles the complexity with how npm builds node_modules
|
||||
nodejsBuilder = pkgs.python310Packages.buildPythonApplication {
|
||||
name = "builder";
|
||||
src = ./nodejs_builder;
|
||||
format = "pyproject";
|
||||
nativeBuildInputs = with python310Packages; [poetry mypy flake8 black semantic-version];
|
||||
propagatedBuildInputs = with python310Packages; [node-semver];
|
||||
nativeBuildInputs = with pkgs.python310Packages; [poetry mypy flake8 black];
|
||||
doCheck = false;
|
||||
meta = {
|
||||
description = "Custom builder";
|
||||
};
|
||||
};
|
||||
|
||||
# type: resolveChildren :: { name :: String, version :: String, rootVersions :: { ${String} :: {String} }} -> { ${String} :: { version :: String, dependencies :: Self } }
|
||||
# function that resolves local vs global dependencies.
|
||||
# we copy dependencies into the global node_modules scope, if they dont have conflicts there.
|
||||
# otherwise we need to declare the package as 'private'
|
||||
# returns the recursive structure:
|
||||
# {
|
||||
# "pname": {
|
||||
# "version": "1.0.0",
|
||||
# "dependencies": {...},
|
||||
# }
|
||||
# }
|
||||
resolveChildren = {
|
||||
name, #a
|
||||
version, #1.1.2
|
||||
rootVersions,
|
||||
# {
|
||||
# "packageNameA": "1.0.0",
|
||||
# "packageNameB": "2.0.0"
|
||||
# }
|
||||
}: let
|
||||
directDeps = getDependencies name version;
|
||||
|
||||
installLocally = name: version: !(rootVersions ? ${name}) || (rootVersions.${name} != version);
|
||||
|
||||
locallyRequiredDeps = b.filter (d: installLocally d.name d.version) directDeps;
|
||||
|
||||
localDepsAttrs = b.listToAttrs (l.map (dep: l.nameValuePair dep.name dep.version) locallyRequiredDeps);
|
||||
newRootVersions = rootVersions // localDepsAttrs;
|
||||
|
||||
localDeps =
|
||||
l.mapAttrs
|
||||
(
|
||||
name: version: {
|
||||
inherit version;
|
||||
dependencies = resolveChildren {
|
||||
inherit name version;
|
||||
rootVersions = newRootVersions;
|
||||
};
|
||||
}
|
||||
)
|
||||
localDepsAttrs;
|
||||
in
|
||||
localDeps;
|
||||
|
||||
# function that 'builds' a package.
|
||||
# executes
|
||||
# type: mkNodeModule :: String -> String -> Derivation
|
||||
mkNodeModule = name: version: let
|
||||
pname = lib.replaceStrings ["@" "/"] ["__at__" "__slash__"] (name + "@" + version);
|
||||
|
||||
# all direct dependencies of current package
|
||||
deps = getDependencies name version;
|
||||
|
||||
resolveChildren = {
|
||||
name, #a
|
||||
version, #1.1.2
|
||||
rootVersions,
|
||||
# {
|
||||
# "packageNameA": "1.0.0",
|
||||
# "packageNameB": "2.0.0"
|
||||
# }
|
||||
}: let
|
||||
directDeps = getDependencies name version;
|
||||
|
||||
installLocally = name: version: !(rootVersions ? ${name}) || (rootVersions.${name} != version);
|
||||
|
||||
locallyRequiredDeps = b.filter (d: installLocally d.name d.version) directDeps;
|
||||
|
||||
localDepsAttrs = b.listToAttrs (l.map (dep: l.nameValuePair dep.name dep.version) locallyRequiredDeps);
|
||||
newRootVersions = rootVersions // localDepsAttrs;
|
||||
|
||||
localDeps =
|
||||
l.mapAttrs
|
||||
(
|
||||
name: version: {
|
||||
inherit version;
|
||||
dependencies = resolveChildren {
|
||||
inherit name version;
|
||||
rootVersions = newRootVersions;
|
||||
};
|
||||
}
|
||||
)
|
||||
localDepsAttrs;
|
||||
in
|
||||
localDeps;
|
||||
|
||||
# in case of a conflict pick the highest semantic version as root. All other version must then be private if used.
|
||||
# TODO: pick the version that minimizes the tree
|
||||
pickVersion = name: versions: directDepsAttrs.${name} or (l.head (l.sort (a: b: l.compareVersions a b == 1) versions));
|
||||
rootPackages = l.mapAttrs (name: versions: pickVersion name versions) packageVersions;
|
||||
|
||||
packageVersions' = l.mapAttrs (n: v: l.unique v) packageVersions;
|
||||
rootPackages = l.mapAttrs (name: versions: pickVersion name versions) packageVersions';
|
||||
|
||||
# direct dependencies are all direct dependencies parsed from the lockfile at root level.
|
||||
directDeps = getDependencies name version;
|
||||
|
||||
# type: { ${String} :: String } # e.g { "prettier" = "1.2.3"; }
|
||||
directDepsAttrs = l.listToAttrs (b.map (dep: l.nameValuePair dep.name dep.version) directDeps);
|
||||
|
||||
# build the node_modules tree from all known rootPackages
|
||||
# type: { ${String} :: { version :: String, dependencies :: Self } }
|
||||
nodeModulesTree =
|
||||
l.mapAttrs (
|
||||
name: version: let
|
||||
@ -148,22 +167,40 @@
|
||||
|
||||
nmTreeJSON = b.toJSON nodeModulesTree;
|
||||
|
||||
# type: makeDepAttrs :: {
|
||||
# deps :: { ${String} :: { ${String} :: { deps :: Self, derivation :: Derivation } } },
|
||||
# dep :: { name :: String, version :: String }
|
||||
# attributes :: {
|
||||
# derivation :: Derivation,
|
||||
# deps :: { ${String} :: { ${String} :: { deps :: Self, derivation :: Derivation } } } }
|
||||
# }
|
||||
# -> { ${String} :: { ${String} :: { deps :: Self, derivation :: Derivation } } }
|
||||
makeDepAttrs = {
|
||||
deps,
|
||||
dep,
|
||||
attributes,
|
||||
}:
|
||||
deps
|
||||
// {
|
||||
${dep.name} =
|
||||
(deps.${dep.name} or {})
|
||||
// {
|
||||
${dep.version} =
|
||||
(deps.${dep.name}.${dep.version} or {})
|
||||
// attributes;
|
||||
};
|
||||
};
|
||||
|
||||
depsTree = let
|
||||
getDeps = deps: (b.foldl'
|
||||
(
|
||||
deps: dep:
|
||||
deps
|
||||
// {
|
||||
${dep.name} =
|
||||
(deps.${dep.name} or {})
|
||||
// {
|
||||
${dep.version} =
|
||||
(deps.${dep.name}.${dep.version} or {})
|
||||
// {
|
||||
deps = getDeps (getDependencies dep.name dep.version);
|
||||
derivation = allPackages.${dep.name}.${dep.version}.lib;
|
||||
};
|
||||
};
|
||||
makeDepAttrs {
|
||||
inherit deps dep;
|
||||
attributes = {
|
||||
deps = getDeps (getDependencies dep.name dep.version);
|
||||
derivation = allPackages.${dep.name}.${dep.version}.lib;
|
||||
};
|
||||
}
|
||||
)
|
||||
{}
|
||||
@ -172,139 +209,139 @@
|
||||
|
||||
depsTreeJSON = b.toJSON depsTree;
|
||||
|
||||
# Type: src :: Derivation
|
||||
src = getSource name version;
|
||||
|
||||
# produceDerivation makes the mkDerivation overridable by the dream2nix users
|
||||
pkg = produceDerivation name (
|
||||
stdenv.mkDerivation
|
||||
{
|
||||
inherit nmTreeJSON depsTreeJSON;
|
||||
passAsFile = ["nmTreeJSON" "depsTreeJSON"];
|
||||
with pkgs;
|
||||
stdenv.mkDerivation
|
||||
{
|
||||
inherit pname version src nodeSources;
|
||||
inherit nmTreeJSON depsTreeJSON;
|
||||
passAsFile = ["nmTreeJSON" "depsTreeJSON"];
|
||||
|
||||
inherit pname version src;
|
||||
# needed for some current overrides
|
||||
nativeBuildInputs = [makeWrapper];
|
||||
|
||||
nativeBuildInputs = [makeWrapper];
|
||||
buildInputs = [jq nodejs python3];
|
||||
outputs = ["out" "lib" "deps"];
|
||||
buildInputs = [jq nodejs python3];
|
||||
outputs = ["out" "lib" "deps"];
|
||||
|
||||
inherit (pkgs) system;
|
||||
packageName = pname;
|
||||
name = pname;
|
||||
|
||||
packageName = pname;
|
||||
name = pname;
|
||||
installMethod =
|
||||
if isMainPackage name version
|
||||
then "copy"
|
||||
else "symlink";
|
||||
|
||||
installMethod =
|
||||
if isMainPackage name version
|
||||
then "copy"
|
||||
else "symlink";
|
||||
passthru.devShell = import ./devShell.nix {
|
||||
inherit nodejs pkg pkgs;
|
||||
};
|
||||
|
||||
passthru.devShell = import ./devShell.nix {
|
||||
inherit nodejs pkg pkgs;
|
||||
};
|
||||
unpackCmd =
|
||||
if lib.hasSuffix ".tgz" src
|
||||
then "tar --delay-directory-restore -xf $src"
|
||||
else null;
|
||||
|
||||
unpackCmd =
|
||||
if lib.hasSuffix ".tgz" src
|
||||
then "tar --delay-directory-restore -xf $src"
|
||||
else null;
|
||||
preConfigurePhases = ["d2nPatchPhase" "d2nCheckPhase"];
|
||||
|
||||
preConfigurePhases = ["d2nPatchPhase" "d2nCheckPhase"];
|
||||
unpackPhase = import ./unpackPhase.nix {};
|
||||
|
||||
unpackPhase = import ./unpackPhase.nix {};
|
||||
# nodejs expects HOME to be set
|
||||
d2nPatchPhase = ''
|
||||
export HOME=$TMPDIR
|
||||
'';
|
||||
|
||||
# nodejs expects HOME to be set
|
||||
d2nPatchPhase = ''
|
||||
export HOME=$TMPDIR
|
||||
'';
|
||||
|
||||
# pre-checks:
|
||||
# - platform compatibility (os + arch must match)
|
||||
d2nCheckPhase = ''
|
||||
# exit code 3 -> the package is incompatible to the current platform
|
||||
# -> Let the build succeed, but don't create node_modules
|
||||
${nodejsBuilder}/bin/d2nCheck \
|
||||
|| \
|
||||
if [ "$?" == "3" ]; then
|
||||
mkdir -p $out
|
||||
mkdir -p $lib
|
||||
mkdir -p $deps
|
||||
echo "Not compatible with system $system" > $lib/error
|
||||
exit 0
|
||||
else
|
||||
exit 1
|
||||
fi
|
||||
'';
|
||||
|
||||
# create the node_modules folder
|
||||
# - uses symlinks as default
|
||||
# - symlink the .bin
|
||||
# - add PATH to .bin
|
||||
configurePhase = ''
|
||||
runHook preConfigure
|
||||
|
||||
${nodejsBuilder}/bin/d2nNodeModules
|
||||
|
||||
export PATH="$PATH:node_modules/.bin"
|
||||
|
||||
runHook postConfigure
|
||||
'';
|
||||
|
||||
# only build the main package
|
||||
# deps only get unpacked, installed, patched, etc
|
||||
dontBuild = ! (isMainPackage name version);
|
||||
isMain = isMainPackage name version;
|
||||
# Build:
|
||||
# npm run build
|
||||
# custom build commands for:
|
||||
# - electron apps
|
||||
# fallback to npm lifecycle hooks, if no build script is present
|
||||
buildPhase = ''
|
||||
runHook preBuild
|
||||
|
||||
if [ "$(jq '.scripts.build' ./package.json)" != "null" ];
|
||||
then
|
||||
echo "running npm run build...."
|
||||
npm run build
|
||||
fi
|
||||
|
||||
runHook postBuild
|
||||
'';
|
||||
|
||||
# copy node_modules
|
||||
# - symlink .bin
|
||||
# - symlink manual pages
|
||||
# - dream2nix copies node_modules folder if it is the top-level package
|
||||
installPhase = ''
|
||||
runHook preInstall
|
||||
|
||||
|
||||
|
||||
if [ ! -n "$isMain" ];
|
||||
then
|
||||
if [ "$(jq '.scripts.preinstall' ./package.json)" != "null" ]; then
|
||||
npm --production --offline --nodedir=$nodeSources run preinstall
|
||||
# pre-checks:
|
||||
# - platform compatibility (os + arch must match)
|
||||
d2nCheckPhase = ''
|
||||
# exit code 3 -> the package is incompatible to the current platform
|
||||
# -> Let the build succeed, but don't create node_modules
|
||||
${nodejsBuilder}/bin/d2nCheck \
|
||||
|| \
|
||||
if [ "$?" == "3" ]; then
|
||||
mkdir -p $out
|
||||
mkdir -p $lib
|
||||
mkdir -p $deps
|
||||
echo "Not compatible with system $system" > $lib/error
|
||||
exit 0
|
||||
else
|
||||
exit 1
|
||||
fi
|
||||
if [ "$(jq '.scripts.install' ./package.json)" != "null" ]; then
|
||||
npm --production --offline --nodedir=$nodeSources run install
|
||||
'';
|
||||
|
||||
# create the node_modules folder
|
||||
# - uses symlinks as default
|
||||
# - symlink the .bin
|
||||
# - add PATH to .bin
|
||||
configurePhase = ''
|
||||
runHook preConfigure
|
||||
|
||||
${nodejsBuilder}/bin/d2nNodeModules
|
||||
|
||||
export PATH="$PATH:node_modules/.bin"
|
||||
|
||||
runHook postConfigure
|
||||
'';
|
||||
|
||||
# only build the main package
|
||||
# deps only get unpacked, installed, patched, etc
|
||||
dontBuild = ! (isMainPackage name version);
|
||||
isMain = isMainPackage name version;
|
||||
# Build:
|
||||
# npm run build
|
||||
# custom build commands for:
|
||||
# - electron apps
|
||||
# fallback to npm lifecycle hooks, if no build script is present
|
||||
buildPhase = ''
|
||||
runHook preBuild
|
||||
|
||||
if [ "$(jq '.scripts.build' ./package.json)" != "null" ];
|
||||
then
|
||||
echo "running npm run build...."
|
||||
npm run build
|
||||
fi
|
||||
if [ "$(jq '.scripts.postinstall' ./package.json)" != "null" ]; then
|
||||
npm --production --offline --nodedir=$nodeSources run postinstall
|
||||
|
||||
runHook postBuild
|
||||
'';
|
||||
|
||||
# copy node_modules
|
||||
# - symlink .bin
|
||||
# - symlink manual pages
|
||||
# - dream2nix copies node_modules folder if it is the top-level package
|
||||
installPhase = ''
|
||||
runHook preInstall
|
||||
|
||||
if [ ! -n "$isMain" ];
|
||||
then
|
||||
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
|
||||
fi
|
||||
|
||||
# $out
|
||||
# - $out/lib/... -> $lib ...(extracted tgz)
|
||||
# - $out/lib/node_modules -> $deps
|
||||
# - $out/bin
|
||||
# $out
|
||||
# - $out/lib/... -> $lib ...(extracted tgz)
|
||||
# - $out/lib/node_modules -> $deps
|
||||
# - $out/bin
|
||||
|
||||
# $deps
|
||||
# - $deps/node_modules
|
||||
# $deps
|
||||
# - $deps/node_modules
|
||||
|
||||
# $lib
|
||||
# - ... (extracted + install scripts runned)
|
||||
${nodejsBuilder}/bin/d2nMakeOutputs
|
||||
# $lib
|
||||
# - ... (extracted + install scripts runned)
|
||||
${nodejsBuilder}/bin/d2nMakeOutputs
|
||||
|
||||
|
||||
runHook postInstall
|
||||
'';
|
||||
}
|
||||
runHook postInstall
|
||||
'';
|
||||
}
|
||||
);
|
||||
in
|
||||
pkg;
|
||||
|
@ -1,6 +1,6 @@
|
||||
import os
|
||||
from enum import Enum
|
||||
from typing import Any, Optional, TypedDict
|
||||
from typing import Any, Optional
|
||||
from pathlib import Path
|
||||
from .logger import logger
|
||||
from dataclasses import dataclass
|
||||
|
@ -11,8 +11,6 @@ d2nMakeOutputs = 'nodejs_builder.main:makeOutputs'
|
||||
|
||||
[tool.poetry.dependencies]
|
||||
python = "^3.10"
|
||||
semantic-version = "^2.9.0"
|
||||
node-semver = "^0.8.1"
|
||||
|
||||
[tool.poetry.dev-dependencies]
|
||||
mypy = "^0.991"
|
||||
|
Loading…
Reference in New Issue
Block a user