mirror of
https://github.com/nix-community/dream2nix.git
synced 2024-09-11 14:35:30 +03:00
Merge pull request #32 from DavHau/dev
conditional overrides + nodejs builder improvements
This commit is contained in:
commit
2db704be87
@ -75,6 +75,7 @@
|
||||
export NIX_PATH=nixpkgs=${nixpkgs}
|
||||
export d2nExternalSources=${externalSourcesFor."${system}"}
|
||||
export dream2nixWithExternals=${dream2nixFor."${system}".dream2nixWithExternals}
|
||||
export d2nExternalSources=$dream2nixWithExternals/external
|
||||
'';
|
||||
});
|
||||
};
|
||||
|
@ -3,6 +3,7 @@
|
||||
pkgs,
|
||||
runCommand,
|
||||
stdenv,
|
||||
writeText,
|
||||
|
||||
# dream2nix inputs
|
||||
builders,
|
||||
@ -25,10 +26,10 @@ let
|
||||
|
||||
b = builtins;
|
||||
|
||||
applyOverrides = utils.applyOverridesToPackageArgs packageOverrides;
|
||||
|
||||
dreamLock = utils.readDreamLock { inherit (args) dreamLock; };
|
||||
|
||||
inherit (dreamLock.generic) mainPackageName mainPackageVersion;
|
||||
|
||||
dependencyGraph = dreamLock.generic.dependencyGraph;
|
||||
|
||||
standAlonePackages =
|
||||
@ -51,7 +52,7 @@ let
|
||||
lib.recursiveUpdate dreamLock
|
||||
{
|
||||
generic.mainPackagenName = name;
|
||||
generic.mainPackagenVersion = Version;
|
||||
generic.mainPackagenVersion = version;
|
||||
|
||||
# re-introduce removed dependencies
|
||||
generic.dependencyGraph."${key}" =
|
||||
@ -63,7 +64,7 @@ let
|
||||
);
|
||||
|
||||
mainPackageKey =
|
||||
"${dreamLock.generic.mainPackageName}#${dreamLock.generic.mainPackageVersion}";
|
||||
"${mainPackageName}#${mainPackageVersion}";
|
||||
|
||||
nodejsVersion = dreamLock.buildSystem.nodejsVersion;
|
||||
|
||||
@ -76,134 +77,170 @@ let
|
||||
mv node-* $out
|
||||
'';
|
||||
|
||||
allPackages = lib.genAttrs (lib.attrNames fetchedSources) makePackage;
|
||||
allPackages =
|
||||
lib.genAttrs
|
||||
(lib.attrNames fetchedSources)
|
||||
(key:
|
||||
let
|
||||
split = lib.splitString "#" key;
|
||||
name = b.elemAt split 0;
|
||||
version = b.elemAt split 1;
|
||||
in
|
||||
makePackage name version);
|
||||
|
||||
makePackage = name: version:
|
||||
let
|
||||
pkgKey = "${name}#${version}";
|
||||
pkg =
|
||||
(stdenv.mkDerivation rec {
|
||||
|
||||
packageName = name;
|
||||
|
||||
pname = utils.sanitizeDerivationName name;
|
||||
|
||||
inherit version;
|
||||
|
||||
src = fetchedSources."${pkgKey}";
|
||||
|
||||
buildInputs = [ nodejs nodejs.python ];
|
||||
|
||||
ignoreScripts = false;
|
||||
|
||||
inherit nodeSources;
|
||||
|
||||
dependencies_json = writeText "dependencies.json"
|
||||
(b.toJSON
|
||||
(lib.listToAttrs
|
||||
(b.map
|
||||
(pKey:
|
||||
let
|
||||
split = lib.splitString "#" pKey;
|
||||
pname = b.elemAt split 0;
|
||||
version = b.elemAt split 1;
|
||||
in
|
||||
lib.nameValuePair pname version)
|
||||
dreamLock.generic.dependencyGraph."${pkgKey}" or [])));
|
||||
|
||||
nodeDeps =
|
||||
lib.forEach
|
||||
(dependencyGraph."${pkgKey}" or [])
|
||||
(depKey:
|
||||
allPackages."${depKey}"
|
||||
)
|
||||
++
|
||||
lib.forEach (dreamLock.generic.dependenciesRemoved."${pkgKey}" or [])
|
||||
(removedDep: standAlonePackages."${pkgKey}");
|
||||
|
||||
dontUnpack = true;
|
||||
|
||||
installPhase = ''
|
||||
runHook preInstall
|
||||
|
||||
nodeModules=$out/lib/node_modules
|
||||
|
||||
mkdir -p $nodeModules
|
||||
|
||||
cd $TMPDIR
|
||||
|
||||
unpackFile ${src}
|
||||
|
||||
# Make the base dir in which the target dependency resides first
|
||||
mkdir -p "$(dirname "$nodeModules/${packageName}")"
|
||||
|
||||
# install source
|
||||
if [ -f "${src}" ]
|
||||
then
|
||||
# Figure out what directory has been unpacked
|
||||
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" "$nodeModules/${packageName}"
|
||||
elif [ -d "${src}" ]
|
||||
then
|
||||
strippedName="$(stripHash ${src})"
|
||||
|
||||
# Restore write permissions
|
||||
chmod -R u+w "$strippedName"
|
||||
|
||||
# Move the extracted directory into the output folder
|
||||
mv "$strippedName" "$nodeModules/${packageName}"
|
||||
fi
|
||||
|
||||
# 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
|
||||
|
||||
# symlink dependency packages into node_modules
|
||||
for dep in $nodeDeps; do
|
||||
if [ -e $dep/lib/node_modules ]; then
|
||||
for module in $(ls $dep/lib/node_modules); do
|
||||
if [[ $module == @* ]]; then
|
||||
for submodule in $(ls $dep/lib/node_modules/$module); do
|
||||
mkdir -p $nodeModules/${packageName}/node_modules/$module
|
||||
echo "ln -s $dep/lib/node_modules/$module/$submodule $nodeModules/${packageName}/node_modules/$module/$submodule"
|
||||
ln -s $dep/lib/node_modules/$module/$submodule $nodeModules/${packageName}/node_modules/$module/$submodule
|
||||
done
|
||||
else
|
||||
mkdir -p $nodeModules/${packageName}/node_modules/
|
||||
echo "ln -s $dep/lib/node_modules/$module $nodeModules/${packageName}/node_modules/$module"
|
||||
ln -s $dep/lib/node_modules/$module $nodeModules/${packageName}/node_modules/$module
|
||||
fi
|
||||
done
|
||||
fi
|
||||
done
|
||||
|
||||
cd "$nodeModules/${packageName}"
|
||||
|
||||
# fix package.json malformed dependency versions
|
||||
python ${./fix-package-lock.py} $dependencies_json package.json
|
||||
|
||||
export HOME=$TMPDIR
|
||||
|
||||
flags=("--offline" "--production" "--nodedir=$nodeSources")
|
||||
if [ -n "$ignoreScripts" ]; then
|
||||
flags+=("--ignore-scripts")
|
||||
fi
|
||||
|
||||
npm "''${flags[@]}" install
|
||||
|
||||
# Create symlink to the deployed executable folder, if applicable
|
||||
if [ -d "$nodeModules/.bin" ]
|
||||
then
|
||||
ln -s $nodeModules/.bin $out/bin
|
||||
fi
|
||||
|
||||
# Create symlinks to the deployed manual page folders, if applicable
|
||||
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
|
||||
|
||||
runHook postInstall
|
||||
'';
|
||||
});
|
||||
in
|
||||
standAlonePackages."${name}#${version}"
|
||||
or
|
||||
(stdenv.mkDerivation (applyOverrides rec {
|
||||
(utils.applyOverridesToPackage packageOverrides pkg name);
|
||||
|
||||
packageName = name;
|
||||
|
||||
pname = lib.straings.sanitizeDerivationName name;
|
||||
|
||||
inherit version;
|
||||
|
||||
src = fetchedSources."${pkgKey}";
|
||||
|
||||
buildInputs = [ nodejs ];
|
||||
|
||||
nodeDeps =
|
||||
lib.forEach
|
||||
(dependencyGraph."${pkgKey}" or [])
|
||||
(depKey:
|
||||
allPackages."${depKey}"
|
||||
)
|
||||
++
|
||||
lib.forEach (dreamLock.generic.dependenciesRemoved."${pkgKey}" or [])
|
||||
(removedDep: standAlonePackages."${pkgKey}");
|
||||
|
||||
dontUnpack = true;
|
||||
|
||||
installPhase = ''
|
||||
runHook preInstall
|
||||
|
||||
nodeModules=$out/lib/node_modules
|
||||
|
||||
mkdir -p $nodeModules
|
||||
|
||||
cd $TMPDIR
|
||||
|
||||
unpackFile ${src}
|
||||
|
||||
# Make the base dir in which the target dependency resides first
|
||||
mkdir -p "$(dirname "$nodeModules/${packageName}")"
|
||||
|
||||
# install source
|
||||
if [ -f "${src}" ]
|
||||
then
|
||||
# Figure out what directory has been unpacked
|
||||
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" "$nodeModules/${packageName}"
|
||||
elif [ -d "${src}" ]
|
||||
then
|
||||
strippedName="$(stripHash ${src})"
|
||||
|
||||
# Restore write permissions
|
||||
chmod -R u+w "$strippedName"
|
||||
|
||||
# Move the extracted directory into the output folder
|
||||
mv "$strippedName" "$nodeModules/${packageName}"
|
||||
fi
|
||||
|
||||
# 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
|
||||
|
||||
# symlink dependency packages into node_modules
|
||||
for dep in $nodeDeps; do
|
||||
if [ -e $dep/lib/node_modules ]; then
|
||||
for module in $(ls $dep/lib/node_modules); do
|
||||
if [[ $module == @* ]]; then
|
||||
for submodule in $(ls $dep/lib/node_modules/$module); do
|
||||
mkdir -p $nodeModules/${packageName}/node_modules/$module
|
||||
echo "ln -s $dep/lib/node_modules/$module/$submodule $nodeModules/${packageName}/node_modules/$module/$submodule"
|
||||
ln -s $dep/lib/node_modules/$module/$submodule $nodeModules/${packageName}/node_modules/$module/$submodule
|
||||
done
|
||||
else
|
||||
mkdir -p $nodeModules/${packageName}/node_modules/
|
||||
echo "ln -s $dep/lib/node_modules/$module $nodeModules/${packageName}/node_modules/$module"
|
||||
ln -s $dep/lib/node_modules/$module $nodeModules/${packageName}/node_modules/$module
|
||||
fi
|
||||
done
|
||||
fi
|
||||
done
|
||||
|
||||
cd "$nodeModules/${packageName}"
|
||||
|
||||
export HOME=$TMPDIR
|
||||
|
||||
npm --offline --production --nodedir=${nodeSources} install
|
||||
|
||||
# Create symlink to the deployed executable folder, if applicable
|
||||
if [ -d "$nodeModules/.bin" ]
|
||||
then
|
||||
ln -s $nodeModules/.bin $out/bin
|
||||
fi
|
||||
|
||||
# Create symlinks to the deployed manual page folders, if applicable
|
||||
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
|
||||
|
||||
runHook postInstall
|
||||
'';
|
||||
}));
|
||||
|
||||
package = makePackage mainPackageKey;
|
||||
package = makePackage mainPackageName mainPackageVersion;
|
||||
|
||||
in
|
||||
{
|
||||
|
||||
inherit package;
|
||||
inherit package allPackages;
|
||||
|
||||
}
|
||||
|
24
src/builders/nodejs/granular/fix-package-lock.py
Normal file
24
src/builders/nodejs/granular/fix-package-lock.py
Normal file
@ -0,0 +1,24 @@
|
||||
import json
|
||||
import sys
|
||||
|
||||
|
||||
with open(sys.argv[1]) as f:
|
||||
actual_deps = json.load(f)
|
||||
|
||||
with open(sys.argv[2]) as f:
|
||||
package_json = json.load(f)
|
||||
|
||||
changed = False
|
||||
if 'dependencies' in package_json:
|
||||
for pname, version in package_json['dependencies'].items():
|
||||
if actual_deps[pname] != package_json['dependencies'][pname]:
|
||||
package_json['dependencies'][pname] = actual_deps[pname]
|
||||
changed = True
|
||||
print(
|
||||
f"WARNING: replacing malformed version '{version}' for dependency '{pname}' in package.json",
|
||||
file=sys.stderr
|
||||
)
|
||||
|
||||
if changed:
|
||||
with open(sys.argv[2], 'w') as f:
|
||||
json.dump(package_json, f, indent=2)
|
@ -43,7 +43,7 @@ let
|
||||
in
|
||||
{
|
||||
inherit packageName version;
|
||||
name = lib.strings.sanitizeDerivationName packageName;
|
||||
name = utils.sanitizeDerivationName packageName;
|
||||
src = fetchedSources."${name}";
|
||||
dependencies =
|
||||
lib.forEach
|
||||
@ -61,7 +61,7 @@ let
|
||||
|
||||
callNode2Nix = funcName: args:
|
||||
node2nixEnv."${funcName}" rec {
|
||||
name = lib.strings.sanitizeDerivationName packageName;
|
||||
name = utils.sanitizeDerivationName packageName;
|
||||
packageName = mainPackageName;
|
||||
version = mainPackageVersion;
|
||||
dependencies = node2nixDependencies;
|
||||
|
@ -28,16 +28,13 @@
|
||||
else
|
||||
lib.elemAt inputFiles 0;
|
||||
|
||||
parsed = externals.npmlock2nix.readLockfile packageLock;
|
||||
parsed = b.fromJSON (b.readFile packageLock);
|
||||
|
||||
identifyGitSource = dependencyObject:
|
||||
# TODO: when integrity is there, and git url is github then use tarball instead
|
||||
# ! (dependencyObject ? integrity) &&
|
||||
utils.identifyGitUrl dependencyObject.version;
|
||||
|
||||
# parseGithubDependency = dependency:
|
||||
# externals.npmlock2nix.parseGitHubRef dependency.version;
|
||||
|
||||
getVersion = dependencyObject:
|
||||
if identifyGitSource dependencyObject then
|
||||
builtins.substring 0 8 (utils.parseGitUrl dependencyObject.version).rev
|
||||
|
@ -106,5 +106,8 @@ rec {
|
||||
+ old.postFetch;
|
||||
});
|
||||
|
||||
sanitizeDerivationName = name:
|
||||
lib.replaceStrings [ "@" "/" ] [ "__at__" "__slash__" ] name;
|
||||
|
||||
|
||||
}
|
||||
|
@ -8,45 +8,61 @@ let
|
||||
|
||||
exampleOverrides = {
|
||||
|
||||
|
||||
hello = {
|
||||
condition = old: if old.version > 3.0.0 then true else false;
|
||||
override = old: {
|
||||
patches = [];
|
||||
};
|
||||
};
|
||||
|
||||
hello = [
|
||||
{
|
||||
description = "patch hello";
|
||||
condition = pkg: if pkg.version > 3.0.0 then true else false;
|
||||
overrideAttrs = old: {
|
||||
patches = [];
|
||||
};
|
||||
override = old: {
|
||||
withPython = false;
|
||||
};
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
applyOverridesToPackageArgs = conditionalOverrides: oldArgs:
|
||||
let
|
||||
applyOverridesToPackage = conditionalOverrides: pkg: pname:
|
||||
if ! conditionalOverrides ? "${pname}" then
|
||||
pkg
|
||||
else
|
||||
|
||||
let
|
||||
|
||||
# if condition is unset, it will be assumed true
|
||||
evalCondition = condAndOverride: oldArgs:
|
||||
if condAndOverride ? condition then
|
||||
condAndOverride.condition oldArgs
|
||||
else
|
||||
true;
|
||||
# if condition is unset, it will be assumed true
|
||||
evalCondition = condOverride: pkg:
|
||||
if condOverride ? condition then
|
||||
condOverride.condition pkg
|
||||
else
|
||||
true;
|
||||
|
||||
# filter the overrides by the package name and applying conditions
|
||||
overridesToApply =
|
||||
(lib.filterAttrs
|
||||
(name: condAndOverride:
|
||||
name == oldArgs.pname && condAndOverride.condition oldArgs)
|
||||
conditionalOverrides);
|
||||
in
|
||||
# filter the overrides by the package name and conditions
|
||||
overridesToApply =
|
||||
(lib.filter
|
||||
(condOverride: evalCondition condOverride pkg)
|
||||
conditionalOverrides."${pname}");
|
||||
|
||||
# apply the overrides to the given args and return teh overridden args
|
||||
lib.recursiveUpdate
|
||||
# helper to apply one conditional override
|
||||
# the condition is not evaluated anymore here
|
||||
applyOneOverride = pkg: condOverride:
|
||||
let
|
||||
overrideFuncs =
|
||||
lib.mapAttrsToList
|
||||
(funcName: func: { inherit funcName func; })
|
||||
(lib.filterAttrs (n: v: lib.hasPrefix "override" n) condOverride);
|
||||
in
|
||||
b.foldl'
|
||||
(pkg: overrideFunc: pkg."${overrideFunc.funcName}" overrideFunc.func)
|
||||
pkg
|
||||
overrideFuncs;
|
||||
in
|
||||
# apply the overrides to the given pkg
|
||||
(lib.foldl
|
||||
(old: condAndOverride: old // (condAndOverride.override old))
|
||||
oldArgs
|
||||
(lib.attrValues overridesToApply))
|
||||
{
|
||||
passthru.appliedConditionalOverrides = lib.attrNames overridesToApply;
|
||||
};
|
||||
(pkg: condOverride: applyOneOverride pkg condOverride)
|
||||
pkg
|
||||
overridesToApply);
|
||||
|
||||
in
|
||||
{
|
||||
inherit applyOverridesToPackageArgs;
|
||||
inherit applyOverridesToPackage;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user