mirror of
https://github.com/nix-community/dream2nix.git
synced 2024-12-23 14:31:55 +03:00
Add builder for nodejs
- python builder support application - add version to dream.lock - allowBuiltinsFetchers config option - node2nix builder - handle github sources without hash
This commit is contained in:
parent
33c7912037
commit
f685e44d59
17
flake.lock
17
flake.lock
@ -15,6 +15,22 @@
|
|||||||
"type": "indirect"
|
"type": "indirect"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node2nix": {
|
||||||
|
"flake": false,
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1613594272,
|
||||||
|
"narHash": "sha256-fcnPNexhowSkatLSl+0dat5oDaWKH53Pg+VKrE8+x+Q=",
|
||||||
|
"owner": "svanderburg",
|
||||||
|
"repo": "node2nix",
|
||||||
|
"rev": "0c94281ea98f1b17532176106f90f909aa133704",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "svanderburg",
|
||||||
|
"repo": "node2nix",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"npmlock2nix": {
|
"npmlock2nix": {
|
||||||
"flake": false,
|
"flake": false,
|
||||||
"locked": {
|
"locked": {
|
||||||
@ -34,6 +50,7 @@
|
|||||||
"root": {
|
"root": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"nixpkgs": "nixpkgs",
|
"nixpkgs": "nixpkgs",
|
||||||
|
"node2nix": "node2nix",
|
||||||
"npmlock2nix": "npmlock2nix"
|
"npmlock2nix": "npmlock2nix"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
15
flake.nix
15
flake.nix
@ -3,10 +3,11 @@
|
|||||||
|
|
||||||
inputs = {
|
inputs = {
|
||||||
nixpkgs.url = "nixpkgs/nixos-unstable";
|
nixpkgs.url = "nixpkgs/nixos-unstable";
|
||||||
|
node2nix = { url = "github:svanderburg/node2nix"; flake = false; };
|
||||||
npmlock2nix = { url = "github:nix-community/npmlock2nix"; flake = false; };
|
npmlock2nix = { url = "github:nix-community/npmlock2nix"; flake = false; };
|
||||||
};
|
};
|
||||||
|
|
||||||
outputs = { self, nixpkgs, npmlock2nix }:
|
outputs = { self, nixpkgs, node2nix, npmlock2nix }:
|
||||||
let
|
let
|
||||||
|
|
||||||
lib = nixpkgs.lib;
|
lib = nixpkgs.lib;
|
||||||
@ -20,13 +21,16 @@
|
|||||||
overlays = [ self.overlay ];
|
overlays = [ self.overlay ];
|
||||||
});
|
});
|
||||||
|
|
||||||
|
externalSourcesFor = forAllSystems (system: nixpkgsFor."${system}".runCommand "dream2nix-vendored" {} ''
|
||||||
|
mkdir -p $out/{npmlock2nix,node2nix}
|
||||||
|
cp ${npmlock2nix}/{internal.nix,LICENSE} $out/npmlock2nix/
|
||||||
|
cp ${node2nix}/{nix/node-env.nix,LICENSE} $out/node2nix/
|
||||||
|
'');
|
||||||
|
|
||||||
dream2nixFor = forAllSystems (system: import ./src rec {
|
dream2nixFor = forAllSystems (system: import ./src rec {
|
||||||
pkgs = nixpkgsFor."${system}";
|
pkgs = nixpkgsFor."${system}";
|
||||||
|
externalSources = externalSourcesFor."${system}";
|
||||||
inherit lib;
|
inherit lib;
|
||||||
externalSources = pkgs.runCommand "dream2nix-imported" {} ''
|
|
||||||
mkdir -p $out/npmlock2nix
|
|
||||||
cp ${npmlock2nix}/{internal.nix,LICENSE} $out/npmlock2nix/
|
|
||||||
'';
|
|
||||||
});
|
});
|
||||||
|
|
||||||
in
|
in
|
||||||
@ -54,6 +58,7 @@
|
|||||||
];
|
];
|
||||||
shellHook = ''
|
shellHook = ''
|
||||||
export NIX_PATH=nixpkgs=${nixpkgs}
|
export NIX_PATH=nixpkgs=${nixpkgs}
|
||||||
|
export d2nExternalSources=${externalSourcesFor."${system}"}
|
||||||
'';
|
'';
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -3,11 +3,13 @@
|
|||||||
"requests": {
|
"requests": {
|
||||||
"url": "https://download.pypi.org/requests/2.28.0",
|
"url": "https://download.pypi.org/requests/2.28.0",
|
||||||
"hash": "000000000000000000000000000000000000000",
|
"hash": "000000000000000000000000000000000000000",
|
||||||
|
"version": "1.2.3",
|
||||||
"type": "fetchurl"
|
"type": "fetchurl"
|
||||||
},
|
},
|
||||||
"certifi": {
|
"certifi": {
|
||||||
"url": "https://download.pypi.org/certifi/2.0",
|
"url": "https://download.pypi.org/certifi/2.0",
|
||||||
"hash": "000000000000000000000000000000000000000",
|
"hash": "000000000000000000000000000000000000000",
|
||||||
|
"version": "2.3.4",
|
||||||
"type": "fetchurl"
|
"type": "fetchurl"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -32,4 +34,4 @@
|
|||||||
"certifi": "wheel"
|
"certifi": "wheel"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
5
specifications/subsystems/nodejs/dream.lock.example.json
Normal file
5
specifications/subsystems/nodejs/dream.lock.example.json
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"buildSystem": {
|
||||||
|
"nodejsVersion": 14
|
||||||
|
}
|
||||||
|
}
|
@ -13,7 +13,8 @@ with open (os.environ.get("translatorsJsonFile")) as f:
|
|||||||
|
|
||||||
def strip_hashes_from_lock(lock):
|
def strip_hashes_from_lock(lock):
|
||||||
for source in lock['sources'].values():
|
for source in lock['sources'].values():
|
||||||
del source['hash']
|
if 'hash' in source:
|
||||||
|
del source['hash']
|
||||||
|
|
||||||
|
|
||||||
def order_dict(d):
|
def order_dict(d):
|
||||||
@ -75,7 +76,9 @@ def translate(args):
|
|||||||
raise Exception(f"Input path '{path}' does not exist")
|
raise Exception(f"Input path '{path}' does not exist")
|
||||||
|
|
||||||
inputFiles = list(filter(lambda p: os.path.isfile(p), inputPaths))
|
inputFiles = list(filter(lambda p: os.path.isfile(p), inputPaths))
|
||||||
|
inputFiles = list(map(lambda p:os.path.realpath(p), inputFiles))
|
||||||
inputDirectories = list(filter(lambda p: os.path.isdir(p), inputPaths))
|
inputDirectories = list(filter(lambda p: os.path.isdir(p), inputPaths))
|
||||||
|
inputDirectories = list(map(lambda p:os.path.realpath(p), inputDirectories))
|
||||||
|
|
||||||
# determine output directory
|
# determine output directory
|
||||||
if os.path.isdir(args.output):
|
if os.path.isdir(args.output):
|
||||||
@ -162,6 +165,17 @@ def translate(args):
|
|||||||
lock['generic']['translatedBy'] = f"{subsystem}.{trans_type}.{trans_name}"
|
lock['generic']['translatedBy'] = f"{subsystem}.{trans_type}.{trans_name}"
|
||||||
lock['generic']['translatorParams'] = " ".join(sys.argv[2:])
|
lock['generic']['translatorParams'] = " ".join(sys.argv[2:])
|
||||||
|
|
||||||
|
# clean up dependency graph
|
||||||
|
# remove empty entries
|
||||||
|
if 'dependencyGraph' in lock['generic']:
|
||||||
|
for pname, deps in lock['generic']['dependencyGraph'].copy().items():
|
||||||
|
if not deps:
|
||||||
|
del lock['generic']['dependencyGraph'][pname]
|
||||||
|
|
||||||
|
# re-write dream.lock
|
||||||
|
with open(output, 'w') as f:
|
||||||
|
json.dump(lock, f, indent=2)
|
||||||
|
|
||||||
# calculate combined hash if --combined was specified
|
# calculate combined hash if --combined was specified
|
||||||
if args.combined:
|
if args.combined:
|
||||||
|
|
||||||
|
@ -43,6 +43,9 @@ in
|
|||||||
mkdir $target/external
|
mkdir $target/external
|
||||||
cp -r ${externalSources}/* $target/external/
|
cp -r ${externalSources}/* $target/external/
|
||||||
chmod -R +w $target
|
chmod -R +w $target
|
||||||
|
|
||||||
|
echo "Installed dream2nix successfully to '$target'."
|
||||||
|
echo "Please check/modify settings in '$target/config.json'"
|
||||||
''
|
''
|
||||||
) {};
|
) {};
|
||||||
}
|
}
|
||||||
|
@ -9,5 +9,12 @@
|
|||||||
|
|
||||||
simpleBuilder = callPackage ./python/simple-builder {};
|
simpleBuilder = callPackage ./python/simple-builder {};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
nodejs = rec {
|
||||||
|
|
||||||
|
default = node2nix;
|
||||||
|
|
||||||
|
node2nix = callPackage ./nodejs/node2nix {};
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
72
src/builders/nodejs/node2nix/default.nix
Normal file
72
src/builders/nodejs/node2nix/default.nix
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
# builder imported from node2nix
|
||||||
|
|
||||||
|
{
|
||||||
|
externals,
|
||||||
|
node2nix ? externals.node2nix,
|
||||||
|
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
|
||||||
|
{
|
||||||
|
fetchedSources,
|
||||||
|
dreamLock,
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
mainPackageName = dreamLock.generic.mainPackage;
|
||||||
|
|
||||||
|
nodejsVersion = dreamLock.buildSystem.nodejsVersion;
|
||||||
|
|
||||||
|
nodejs =
|
||||||
|
pkgs."nodejs-${builtins.toString nodejsVersion}_x"
|
||||||
|
or (throw "Could not find nodejs version '${nodejsVersion}' in pkgs");
|
||||||
|
|
||||||
|
node2nixEnv = node2nix nodejs;
|
||||||
|
|
||||||
|
# make node2nix compatible sources
|
||||||
|
makeSource = name: {
|
||||||
|
name = lib.head (lib.splitString "#" name);
|
||||||
|
packageName = lib.head (lib.splitString "#" name);
|
||||||
|
version = dreamLock.sources."${name}".version;
|
||||||
|
src = fetchedSources."${name}";
|
||||||
|
dependencies = lib.forEach dreamLock.generic.dependencyGraph."${name}" or [] (dependency:
|
||||||
|
makeSource dependency
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
callNode2Nix = funcName: args:
|
||||||
|
node2nixEnv."${funcName}" rec {
|
||||||
|
name = mainPackageName;
|
||||||
|
packageName = name;
|
||||||
|
version = dreamLock.sources."${mainPackageName}".version;
|
||||||
|
dependencies =
|
||||||
|
lib.forEach
|
||||||
|
(lib.filter
|
||||||
|
(pname: pname != mainPackageName)
|
||||||
|
(lib.attrNames dreamLock.generic.dependencyGraph)
|
||||||
|
)
|
||||||
|
(dependency: makeSource dependency);
|
||||||
|
# buildInputs ? []
|
||||||
|
# npmFlags ? ""
|
||||||
|
# dontNpmInstall ? false
|
||||||
|
# preRebuild ? ""
|
||||||
|
# dontStrip ? true
|
||||||
|
# unpackPhase ? "true"
|
||||||
|
# buildPhase ? "true"
|
||||||
|
# meta ? {}
|
||||||
|
production = true;
|
||||||
|
bypassCache = true;
|
||||||
|
reconstructLock = true;
|
||||||
|
src = fetchedSources."${dreamLock.generic.mainPackage}";
|
||||||
|
}
|
||||||
|
// args;
|
||||||
|
|
||||||
|
in
|
||||||
|
{
|
||||||
|
|
||||||
|
package = callNode2Nix "buildNodePackage" {};
|
||||||
|
|
||||||
|
shell = callNode2Nix "buildNodeShell" {};
|
||||||
|
|
||||||
|
}
|
@ -1,3 +1,5 @@
|
|||||||
|
# A very simple single derivation python builder
|
||||||
|
|
||||||
{
|
{
|
||||||
lib,
|
lib,
|
||||||
pkgs,
|
pkgs,
|
||||||
@ -11,12 +13,29 @@
|
|||||||
|
|
||||||
let
|
let
|
||||||
python = pkgs."${dreamLock.buildSystem.pythonAttr}";
|
python = pkgs."${dreamLock.buildSystem.pythonAttr}";
|
||||||
|
|
||||||
|
buildFunc =
|
||||||
|
if dreamLock.buildSystem.application then
|
||||||
|
python.pkgs.buildPythonApplication
|
||||||
|
else
|
||||||
|
python.pkgs.buildPythonPackage;
|
||||||
|
|
||||||
|
mainPackageName = dreamLock.generic.mainPackage;
|
||||||
|
|
||||||
|
packageName =
|
||||||
|
if mainPackageName == null then
|
||||||
|
if dreamLock.buildSystem.application then
|
||||||
|
"application"
|
||||||
|
else
|
||||||
|
"environment"
|
||||||
|
else
|
||||||
|
mainPackageName;
|
||||||
in
|
in
|
||||||
|
|
||||||
python.pkgs.buildPythonPackage {
|
buildFunc {
|
||||||
name = "python-environment";
|
name = packageName;
|
||||||
format = "";
|
format = "";
|
||||||
src = lib.attrValues fetchedSources;
|
src = fetchedSources."${toString (mainPackageName)}" or null;
|
||||||
buildInputs = pkgs.pythonManylinuxPackages.manylinux1;
|
buildInputs = pkgs.pythonManylinuxPackages.manylinux1;
|
||||||
nativeBuildInputs = [ pkgs.autoPatchelfHook python.pkgs.wheelUnpackHook ];
|
nativeBuildInputs = [ pkgs.autoPatchelfHook python.pkgs.wheelUnpackHook ];
|
||||||
unpackPhase = ''
|
unpackPhase = ''
|
||||||
@ -32,7 +51,7 @@ python.pkgs.buildPythonPackage {
|
|||||||
runHook preInstall
|
runHook preInstall
|
||||||
mkdir -p "$out/${python.sitePackages}"
|
mkdir -p "$out/${python.sitePackages}"
|
||||||
export PYTHONPATH="$out/${python.sitePackages}:$PYTHONPATH"
|
export PYTHONPATH="$out/${python.sitePackages}:$PYTHONPATH"
|
||||||
${python}/bin/python -m pip install ./dist/*.{whl,tar.gz,zip} \
|
${python}/bin/python -m pip install ./dist/*.{whl,tar.gz,zip} $src \
|
||||||
--no-index \
|
--no-index \
|
||||||
--no-warn-script-location \
|
--no-warn-script-location \
|
||||||
--prefix="$out" \
|
--prefix="$out" \
|
||||||
|
3
src/config.json
Normal file
3
src/config.json
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"allowBuiltinFetchers": true
|
||||||
|
}
|
@ -2,8 +2,10 @@
|
|||||||
pkgs ? import <nixpkgs> {},
|
pkgs ? import <nixpkgs> {},
|
||||||
lib ? pkgs.lib,
|
lib ? pkgs.lib,
|
||||||
externalSources ?
|
externalSources ?
|
||||||
if builtins.getEnv "d2nExternalSources" != "" then
|
# if called via CLI, load externals via env
|
||||||
|
if builtins ? getEnv && builtins.getEnv "d2nExternalSources" != "" then
|
||||||
builtins.getEnv "d2nExternalSources"
|
builtins.getEnv "d2nExternalSources"
|
||||||
|
# load from default dircetory
|
||||||
else
|
else
|
||||||
./external,
|
./external,
|
||||||
}:
|
}:
|
||||||
@ -14,24 +16,35 @@ let
|
|||||||
|
|
||||||
callPackage = f: args: pkgs.callPackage f (args // {
|
callPackage = f: args: pkgs.callPackage f (args // {
|
||||||
inherit callPackage;
|
inherit callPackage;
|
||||||
|
inherit externals;
|
||||||
|
inherit externalSources;
|
||||||
inherit utils;
|
inherit utils;
|
||||||
});
|
});
|
||||||
|
|
||||||
externals = {
|
externals = {
|
||||||
npmlock2nix = pkgs.callPackage "${externalSources}/npmlock2nix/internal.nix" {};
|
npmlock2nix = pkgs.callPackage "${externalSources}/npmlock2nix/internal.nix" {};
|
||||||
|
node2nix = nodejs: pkgs.callPackage "${externalSources}/node2nix/node-env.nix" { inherit nodejs; };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
config = builtins.fromJSON (builtins.readFile ./config.json);
|
||||||
|
|
||||||
in
|
in
|
||||||
|
|
||||||
rec {
|
rec {
|
||||||
|
|
||||||
apps = callPackage ./apps { inherit externalSources location translators; };
|
# apps for CLI and installation
|
||||||
|
apps = callPackage ./apps { inherit location translators; };
|
||||||
|
|
||||||
|
# builder implementaitons for all subsystems
|
||||||
builders = callPackage ./builders {};
|
builders = callPackage ./builders {};
|
||||||
|
|
||||||
fetchers = callPackage ./fetchers {};
|
# fetcher implementations
|
||||||
|
fetchers = callPackage ./fetchers {
|
||||||
|
inherit (config) allowBuiltinFetchers;
|
||||||
|
};
|
||||||
|
|
||||||
translators = callPackage ./translators { inherit externalSources externals location; };
|
# the translator modules and utils for all subsystems
|
||||||
|
translators = callPackage ./translators { inherit location; };
|
||||||
|
|
||||||
|
|
||||||
# the location of the dream2nix framework for self references (update scripts, etc.)
|
# the location of the dream2nix framework for self references (update scripts, etc.)
|
||||||
@ -43,7 +56,10 @@ rec {
|
|||||||
let
|
let
|
||||||
buildSystem = dreamLock.generic.buildSystem;
|
buildSystem = dreamLock.generic.buildSystem;
|
||||||
in
|
in
|
||||||
builders."${buildSystem}".default;
|
if ! builders ? "${buildSystem}" then
|
||||||
|
throw "Could not find any builder for subsystem '${buildSystem}'"
|
||||||
|
else
|
||||||
|
builders."${buildSystem}".default;
|
||||||
|
|
||||||
|
|
||||||
# detect if granular or combined fetching must be used
|
# detect if granular or combined fetching must be used
|
||||||
@ -54,24 +70,27 @@ rec {
|
|||||||
fetchers.defaultFetcher;
|
fetchers.defaultFetcher;
|
||||||
|
|
||||||
|
|
||||||
|
# automatically parse dream.lock if passed as file
|
||||||
parseLock = lock:
|
parseLock = lock:
|
||||||
if builtins.isPath lock || builtins.isString lock then
|
if builtins.isPath lock || builtins.isString lock then
|
||||||
builtins.fromJSON (builtins.readFile lock)
|
builtins.fromJSON (builtins.readFile lock)
|
||||||
else
|
else
|
||||||
lock;
|
lock;
|
||||||
|
|
||||||
|
# fetch only sources and do not build
|
||||||
fetchSources =
|
fetchSources =
|
||||||
{
|
{
|
||||||
dreamLock,
|
dreamLock,
|
||||||
builder ? findBuilder (parseLock dreamLock),
|
builder ? findBuilder (parseLock dreamLock),
|
||||||
fetcher ? findFetcher (parseLock dreamLock),
|
fetcher ? findFetcher (parseLock dreamLock),
|
||||||
sourceOverrides ? oldSources: {},
|
sourceOverrides ? oldSources: {},
|
||||||
|
allowBuiltinFetchers ? true,
|
||||||
}:
|
}:
|
||||||
let
|
let
|
||||||
# if generic lock is a file, read and parse it
|
# if generic lock is a file, read and parse it
|
||||||
dreamLock' = (parseLock dreamLock);
|
dreamLock' = (parseLock dreamLock);
|
||||||
fetched = fetcher {
|
fetched = fetcher {
|
||||||
|
inherit allowBuiltinFetchers;
|
||||||
sources = dreamLock'.sources;
|
sources = dreamLock'.sources;
|
||||||
sourcesCombinedHash = dreamLock'.generic.sourcesCombinedHash;
|
sourcesCombinedHash = dreamLock'.generic.sourcesCombinedHash;
|
||||||
};
|
};
|
||||||
@ -98,13 +117,15 @@ rec {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
# automatically build package defined by generic lock
|
# build package defined by dream.lock
|
||||||
|
# TODO: rename to riseAndShine
|
||||||
buildPackage =
|
buildPackage =
|
||||||
{
|
{
|
||||||
dreamLock,
|
dreamLock,
|
||||||
builder ? findBuilder (parseLock dreamLock),
|
builder ? findBuilder (parseLock dreamLock),
|
||||||
fetcher ? findFetcher (parseLock dreamLock),
|
fetcher ? findFetcher (parseLock dreamLock),
|
||||||
sourceOverrides ? oldSources: {},
|
sourceOverrides ? oldSources: {},
|
||||||
|
allowBuiltinFetchers ? true,
|
||||||
}@args:
|
}@args:
|
||||||
let
|
let
|
||||||
# if generic lock is a file, read and parse it
|
# if generic lock is a file, read and parse it
|
||||||
|
@ -11,30 +11,74 @@
|
|||||||
{
|
{
|
||||||
# sources attrset from generic lock
|
# sources attrset from generic lock
|
||||||
sources,
|
sources,
|
||||||
|
allowBuiltinFetchers,
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
|
|
||||||
|
let
|
||||||
|
githubMissingHashErrorText = pname: ''
|
||||||
|
Error: Cannot verify the integrity of the source of '${pname}'
|
||||||
|
It is a github reference with no hash providedand.
|
||||||
|
Solve this problem via any of the wollowing ways:
|
||||||
|
|
||||||
|
- (alternative 1): allow the use of builtin fetchers (which can verify using git rev).
|
||||||
|
```
|
||||||
|
dream2nix.buildPackage {
|
||||||
|
...
|
||||||
|
allowBuiltinFetchers = true;
|
||||||
|
...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- (alternative 2): add a hash to the source via override
|
||||||
|
```
|
||||||
|
dream2nix.buildPackage {
|
||||||
|
...
|
||||||
|
sourceOverrides = oldSources: {
|
||||||
|
"${pname}" = oldSources."${pname}".overrideAttrs (_:{
|
||||||
|
hash = "";
|
||||||
|
})
|
||||||
|
}
|
||||||
|
...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
'';
|
||||||
|
in
|
||||||
|
|
||||||
{
|
{
|
||||||
# attrset: pname -> path of downloaded source
|
# attrset: pname -> path of downloaded source
|
||||||
fetchedSources = lib.mapAttrs (pname: source:
|
fetchedSources = lib.mapAttrs (pname: source:
|
||||||
if source.type == "github" then
|
if source.type == "github" then
|
||||||
fetchFromGitHub {
|
# handle when no hash is provided
|
||||||
inherit (source) url owner repo rev;
|
if ! source ? hash then
|
||||||
sha256 = source.hash or null;
|
if allowBuiltinFetchers then
|
||||||
}
|
builtins.fetchGit {
|
||||||
|
inherit (source) rev;
|
||||||
|
allRefs = true;
|
||||||
|
url = "https://github.com/${source.owner}/${source.repo}";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw githubMissingHashErrorText pname
|
||||||
|
else
|
||||||
|
fetchFromGitHub {
|
||||||
|
inherit (source) url owner repo rev;
|
||||||
|
hash = source.hash or null;
|
||||||
|
}
|
||||||
else if source.type == "gitlab" then
|
else if source.type == "gitlab" then
|
||||||
fetchFromGitLab {
|
fetchFromGitLab {
|
||||||
inherit (source) url owner repo rev;
|
inherit (source) url owner repo rev;
|
||||||
sha256 = source.hash or null;
|
hash = source.hash or null;
|
||||||
}
|
}
|
||||||
else if source.type == "git" then
|
else if source.type == "git" then
|
||||||
fetchgit {
|
fetchgit {
|
||||||
inherit (source) url rev;
|
inherit (source) url rev;
|
||||||
sha256 = source.hash or null;
|
hash = source.hash or null;
|
||||||
}
|
}
|
||||||
else if source.type == "fetchurl" then
|
else if source.type == "fetchurl" then
|
||||||
fetchurl {
|
fetchurl {
|
||||||
inherit (source) url;
|
inherit (source) url;
|
||||||
sha256 = source.hash or null;
|
hash = source.hash or null;
|
||||||
}
|
}
|
||||||
else if source.type == "unknown" then
|
else if source.type == "unknown" then
|
||||||
"unknown"
|
"unknown"
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
{
|
{
|
||||||
callPackage,
|
callPackage,
|
||||||
|
|
||||||
|
# config
|
||||||
|
allowBuiltinFetchers,
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
rec {
|
rec {
|
||||||
|
@ -26,7 +26,12 @@ let
|
|||||||
translateBin = wrapPureTranslator [ subsystem type name ];
|
translateBin = wrapPureTranslator [ subsystem type name ];
|
||||||
};
|
};
|
||||||
in
|
in
|
||||||
translatorWithBin // { inherit subsystem type name; };
|
translatorWithBin // {
|
||||||
|
inherit subsystem type name;
|
||||||
|
translate = args:
|
||||||
|
translator.translate
|
||||||
|
((getSpecialArgsDefaults translator.specialArgs or {}) // args);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
buildSystems = dirNames ./.;
|
buildSystems = dirNames ./.;
|
||||||
@ -45,7 +50,7 @@ let
|
|||||||
bin = pkgs.writeScriptBin "translate" ''
|
bin = pkgs.writeScriptBin "translate" ''
|
||||||
#!${pkgs.bash}/bin/bash
|
#!${pkgs.bash}/bin/bash
|
||||||
|
|
||||||
jsonInputFile=$1
|
jsonInputFile=$(realpath $1)
|
||||||
outputFile=$(${pkgs.jq}/bin/jq '.outputFile' -c -r $jsonInputFile)
|
outputFile=$(${pkgs.jq}/bin/jq '.outputFile' -c -r $jsonInputFile)
|
||||||
export d2nExternalSources=${externalSources}
|
export d2nExternalSources=${externalSources}
|
||||||
|
|
||||||
@ -165,19 +170,21 @@ let
|
|||||||
lib.head (lib.attrValues (lib.head (lib.attrValues (lib.head (lib.attrValues compatTranslators)))))
|
lib.head (lib.attrValues (lib.head (lib.attrValues (lib.head (lib.attrValues compatTranslators)))))
|
||||||
);
|
);
|
||||||
|
|
||||||
|
getSpecialArgsDefaults = specialArgsDef:
|
||||||
|
lib.mapAttrs
|
||||||
|
(name: def:
|
||||||
|
if def.type == "flag" then
|
||||||
|
false
|
||||||
|
else
|
||||||
|
def.default
|
||||||
|
)
|
||||||
|
specialArgsDef;
|
||||||
|
|
||||||
selectTranslatorJSON = args:
|
selectTranslatorJSON = args:
|
||||||
let
|
let
|
||||||
translator = (selectTranslator args);
|
translator = (selectTranslator args);
|
||||||
data = {
|
data = {
|
||||||
SpecialArgsDefaults =
|
SpecialArgsDefaults = getSpecialArgsDefaults (translator.specialArgs or {});
|
||||||
lib.mapAttrs
|
|
||||||
(name: def:
|
|
||||||
if def.type == "flag" then
|
|
||||||
false
|
|
||||||
else
|
|
||||||
def.default
|
|
||||||
)
|
|
||||||
translator.specialArgs or {};
|
|
||||||
inherit (translator) subsystem type name;
|
inherit (translator) subsystem type name;
|
||||||
};
|
};
|
||||||
in
|
in
|
||||||
|
@ -12,23 +12,116 @@
|
|||||||
{
|
{
|
||||||
inputDirectories,
|
inputDirectories,
|
||||||
inputFiles,
|
inputFiles,
|
||||||
|
|
||||||
|
dev,
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
let
|
let
|
||||||
parsed = externals.npmlock2nix.readLockfile (builtins.elemAt inputFiles 0);
|
parsed = externals.npmlock2nix.readLockfile (builtins.elemAt inputFiles 0);
|
||||||
|
|
||||||
|
parseGithubDepedency = dependency:
|
||||||
|
externals.npmlock2nix.parseGitHubRef dependency.version;
|
||||||
|
|
||||||
|
getVersion = dependency:
|
||||||
|
if dependency ? from && dependency ? version then
|
||||||
|
builtins.substring 0 8 (parseGithubDepedency dependency).rev
|
||||||
|
else
|
||||||
|
dependency.version;
|
||||||
|
|
||||||
|
pinVersions = dependencies: parentScopeDeps:
|
||||||
|
lib.mapAttrs
|
||||||
|
(pname: pdata:
|
||||||
|
let
|
||||||
|
selfScopeDeps = parentScopeDeps // (pdata.dependencies or {});
|
||||||
|
in
|
||||||
|
pdata // {
|
||||||
|
depsExact =
|
||||||
|
if ! pdata ? requires then
|
||||||
|
[]
|
||||||
|
else
|
||||||
|
lib.forEach (lib.attrNames pdata.requires) (reqName:
|
||||||
|
"${reqName}#${getVersion selfScopeDeps."${reqName}"}"
|
||||||
|
);
|
||||||
|
dependencies = pinVersions (pdata.dependencies or {}) selfScopeDeps;
|
||||||
|
}
|
||||||
|
)
|
||||||
|
dependencies;
|
||||||
|
|
||||||
|
packageLockWithPinnedVersions = pinVersions parsed.dependencies parsed.dependencies;
|
||||||
|
|
||||||
|
# recursively collect dependencies
|
||||||
|
parseDependencies = dependencies:
|
||||||
|
lib.mapAttrsToList # returns list of lists
|
||||||
|
(pname: pdata:
|
||||||
|
if ! dev && pdata.dev or false then
|
||||||
|
[]
|
||||||
|
else
|
||||||
|
# handle github dependency
|
||||||
|
if pdata ? from && pdata ? version then
|
||||||
|
let
|
||||||
|
githubData = parseGithubDepedency pdata;
|
||||||
|
in
|
||||||
|
[ rec {
|
||||||
|
name = "${pname}#${version}";
|
||||||
|
version = builtins.substring 0 8 githubData.rev;
|
||||||
|
owner = githubData.org;
|
||||||
|
repo = githubData.repo;
|
||||||
|
rev = githubData.rev;
|
||||||
|
type = "github";
|
||||||
|
depsExact = pdata.depsExact;
|
||||||
|
}]
|
||||||
|
# handle http(s) dependency
|
||||||
|
else
|
||||||
|
[rec {
|
||||||
|
name = "${pname}#${version}";
|
||||||
|
version = pdata.version;
|
||||||
|
url = pdata.resolved;
|
||||||
|
type = "fetchurl";
|
||||||
|
hash = pdata.integrity;
|
||||||
|
depsExact = pdata.depsExact;
|
||||||
|
}]
|
||||||
|
++
|
||||||
|
(lib.optionals (pdata ? dependencies)
|
||||||
|
(lib.flatten (parseDependencies pdata.dependencies))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
dependencies;
|
||||||
in
|
in
|
||||||
{
|
rec {
|
||||||
sources = builtins.mapAttrs (pname: pdata:{
|
sources =
|
||||||
url = pdata.resolved;
|
let
|
||||||
type = "fetchurl";
|
lockedSources = lib.listToAttrs (
|
||||||
hash = pdata.integrity;
|
map
|
||||||
}) parsed.dependencies;
|
(dep: lib.nameValuePair
|
||||||
|
dep.name
|
||||||
|
(
|
||||||
|
if dep.type == "github" then
|
||||||
|
{ inherit (dep) type version owner repo rev; }
|
||||||
|
else
|
||||||
|
{ inherit (dep) type version url hash; }
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(lib.flatten (parseDependencies packageLockWithPinnedVersions))
|
||||||
|
);
|
||||||
|
in
|
||||||
|
# if only a package-lock.json is given, the main source is missing
|
||||||
|
lockedSources // {
|
||||||
|
"${parsed.name}" = {
|
||||||
|
type = "unknown";
|
||||||
|
version = parsed.version;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
generic = {
|
generic = {
|
||||||
buildSystem = "nodejs";
|
buildSystem = "nodejs";
|
||||||
producedBy = translatorName;
|
producedBy = translatorName;
|
||||||
mainPackage = null;
|
mainPackage = parsed.name;
|
||||||
dependencyGraph = null;
|
dependencyGraph =
|
||||||
|
lib.listToAttrs
|
||||||
|
(map
|
||||||
|
(dep: lib.nameValuePair dep.name dep.depsExact )
|
||||||
|
(lib.flatten (parseDependencies packageLockWithPinnedVersions))
|
||||||
|
);
|
||||||
sourcesCombinedHash = null;
|
sourcesCombinedHash = null;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -42,10 +135,18 @@
|
|||||||
inputDirectories,
|
inputDirectories,
|
||||||
inputFiles,
|
inputFiles,
|
||||||
}@args:
|
}@args:
|
||||||
builtins.trace (lib.attrValues args)
|
|
||||||
{
|
{
|
||||||
inputDirectories = [];
|
inputDirectories = [];
|
||||||
inputFiles =
|
inputFiles =
|
||||||
lib.filter (f: builtins.match ".*(package-lock\\.json)" f != null) args.inputFiles;
|
lib.filter (f: builtins.match ".*(package-lock\\.json)" f != null) args.inputFiles;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
specialArgs = {
|
||||||
|
|
||||||
|
dev = {
|
||||||
|
description = "include dependencies for development";
|
||||||
|
type = "flag";
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user