mirror of
https://github.com/nix-community/dream2nix.git
synced 2024-09-21 03:19:17 +03:00
commit
1dc003e2e5
@ -69,6 +69,7 @@
|
||||
|
||||
shellHook = ''
|
||||
export NIX_PATH=nixpkgs=${nixpkgs}
|
||||
export d2nExternalSources=${externalSourcesFor."${system}"}
|
||||
'';
|
||||
});
|
||||
};
|
||||
|
@ -154,6 +154,23 @@ class PackageCommand(Command):
|
||||
)
|
||||
exit(1)
|
||||
|
||||
# transform flags to bool
|
||||
for argName, argVal in specified_extra_args.copy().items():
|
||||
if translator['specialArgs'][argName]['type'] == 'flag':
|
||||
if argVal.lower() in ('yes', 'y', 'true'):
|
||||
specified_extra_args[argName] = True
|
||||
elif argVal.lower() in ('no', 'n', 'false'):
|
||||
specified_extra_args[argName] = False
|
||||
else:
|
||||
print(
|
||||
f"Invalid value {argVal} for argument {argName}",
|
||||
file=sys.stderr
|
||||
)
|
||||
|
||||
specified_extra_args =\
|
||||
{k: (bool(v) if translator['specialArgs'][k]['type'] == 'flag' else v ) \
|
||||
for k, v in specified_extra_args.items()}
|
||||
|
||||
# on non-interactive session, assume defaults for unspecified extra args
|
||||
if not self.io.is_interactive():
|
||||
specified_extra_args.update(
|
||||
@ -201,6 +218,7 @@ class PackageCommand(Command):
|
||||
)
|
||||
|
||||
# dump translator arguments to json file and execute translator
|
||||
print("Translating upstream metadata")
|
||||
with tempfile.NamedTemporaryFile("w") as input_json_file:
|
||||
json.dump(translator_input, input_json_file, indent=2)
|
||||
input_json_file.seek(0) # flushes write cache
|
||||
|
@ -1,8 +1,9 @@
|
||||
{
|
||||
coreutils,
|
||||
lib,
|
||||
callPackageDream,
|
||||
pkgs,
|
||||
|
||||
callPackageDream,
|
||||
externalSources,
|
||||
externals,
|
||||
dream2nixWithExternals,
|
||||
@ -48,7 +49,7 @@ let
|
||||
bin = pkgs.writeScriptBin "translate" ''
|
||||
#!${pkgs.bash}/bin/bash
|
||||
|
||||
jsonInputFile=$(realpath $1)
|
||||
jsonInputFile=$(${coreutils}/bin/realpath $1)
|
||||
outputFile=$(${pkgs.jq}/bin/jq '.outputFile' -c -r $jsonInputFile)
|
||||
|
||||
nix eval --show-trace --impure --raw --expr "
|
||||
|
@ -77,7 +77,7 @@
|
||||
depsExact = pdata.depsExact;
|
||||
}]
|
||||
# handle http(s) dependency
|
||||
else
|
||||
else
|
||||
[rec {
|
||||
name = "${pname}#${version}";
|
||||
version = pdata.version;
|
||||
@ -125,6 +125,15 @@
|
||||
producedBy = translatorName;
|
||||
mainPackage = parsed.name;
|
||||
dependencyGraph =
|
||||
{
|
||||
"${parsed.name}" =
|
||||
lib.mapAttrsToList
|
||||
(pname: pdata: "${pname}#${getVersion pdata}")
|
||||
(lib.filterAttrs
|
||||
(pname: pdata: ! (pdata.dev or false) || dev)
|
||||
parsed.dependencies);
|
||||
}
|
||||
//
|
||||
lib.listToAttrs
|
||||
(map
|
||||
(dep: lib.nameValuePair dep.name dep.depsExact)
|
||||
|
@ -12,14 +12,31 @@
|
||||
{
|
||||
inputDirectories,
|
||||
inputFiles,
|
||||
|
||||
# extraArgs
|
||||
dev,
|
||||
optional,
|
||||
peer,
|
||||
...
|
||||
}:
|
||||
let
|
||||
b = builtins;
|
||||
yarnLock = "${lib.elemAt inputDirectories 0}/yarn.lock";
|
||||
yarnLock = utils.readTextFile "${lib.elemAt inputDirectories 0}/yarn.lock";
|
||||
packageJSON = b.fromJSON (b.readFile "${lib.elemAt inputDirectories 0}/package.json");
|
||||
parser = import ./parser.nix { inherit lib; inherit (externals) nix-parsec;};
|
||||
parsedLock = lib.foldAttrs (n: a: n // a) {} (parser.parseLock yarnLock).value;
|
||||
tryParse = parser.parseLock yarnLock;
|
||||
|
||||
mainPackageName = packageJSON.name;
|
||||
mainPackageKey = "${mainPackageName}#${packageJSON.version}";
|
||||
|
||||
parsedLock =
|
||||
if tryParse.type == "success" then
|
||||
lib.foldAttrs (n: a: n // a) {} tryParse.value
|
||||
else
|
||||
let
|
||||
failureOffset = tryParse.value.offset;
|
||||
in
|
||||
throw "parser failed at: \n${lib.substring failureOffset 50 tryParse.value.str}";
|
||||
nameFromLockName = lockName:
|
||||
let
|
||||
version = lib.last (lib.splitString "@" lockName);
|
||||
@ -30,14 +47,8 @@
|
||||
name = nameFromLockName dependencyName;
|
||||
in
|
||||
lib.nameValuePair ("${name}#${dependencyAttrs.version}") (
|
||||
if ! lib.hasInfix "@github:" dependencyName then
|
||||
{
|
||||
version = dependencyAttrs.version;
|
||||
hash = dependencyAttrs.integrity;
|
||||
url = lib.head (lib.splitString "#" dependencyAttrs.resolved);
|
||||
type = "fetchurl";
|
||||
}
|
||||
else
|
||||
if lib.hasInfix "@github:" dependencyName
|
||||
|| lib.hasInfix "codeload.github.com/" dependencyAttrs.resolved then
|
||||
let
|
||||
gitUrlInfos = lib.splitString "/" dependencyAttrs.resolved;
|
||||
in
|
||||
@ -47,24 +58,75 @@
|
||||
owner = lib.elemAt gitUrlInfos 3;
|
||||
repo = lib.elemAt gitUrlInfos 4;
|
||||
}
|
||||
else if lib.hasInfix "@link:" dependencyName then
|
||||
{
|
||||
version = dependencyAttrs.version;
|
||||
path = lib.last (lib.splitString "@link:" dependencyName);
|
||||
type = "path";
|
||||
}
|
||||
else
|
||||
{
|
||||
version = dependencyAttrs.version;
|
||||
hash =
|
||||
if dependencyAttrs ? integrity then
|
||||
dependencyAttrs.integrity
|
||||
else
|
||||
throw "Missing integrity for ${dependencyName}";
|
||||
url = lib.head (lib.splitString "#" dependencyAttrs.resolved);
|
||||
type = "fetchurl";
|
||||
}
|
||||
)) parsedLock;
|
||||
dependencyGraph = lib.mapAttrs' (dependencyName: dependencyAttrs:
|
||||
let
|
||||
name = nameFromLockName dependencyName;
|
||||
dependencies = dependencyAttrs.dependencies or [] ++ dependencyAttrs.optionalDependencies or [];
|
||||
graph = lib.forEach dependencies (dependency:
|
||||
builtins.head (
|
||||
lib.mapAttrsToList (name: value:
|
||||
dependencyGraph =
|
||||
(lib.mapAttrs'
|
||||
(dependencyName: dependencyAttrs:
|
||||
let
|
||||
yarnName = "${name}@${value}";
|
||||
version = parsedLock."${yarnName}".version;
|
||||
name = nameFromLockName dependencyName;
|
||||
dependencies =
|
||||
dependencyAttrs.dependencies or []
|
||||
++ (lib.optionals optional (dependencyAttrs.optionalDependencies or []));
|
||||
graph = lib.forEach dependencies (dependency:
|
||||
builtins.head (
|
||||
lib.mapAttrsToList
|
||||
(name: value:
|
||||
let
|
||||
yarnName = "${name}@${value}";
|
||||
version = parsedLock."${yarnName}".version;
|
||||
in
|
||||
"${name}#${version}"
|
||||
)
|
||||
dependency
|
||||
)
|
||||
);
|
||||
in
|
||||
"${name}#${version}"
|
||||
) dependency
|
||||
lib.nameValuePair ("${name}#${dependencyAttrs.version}") graph
|
||||
)
|
||||
);
|
||||
in
|
||||
lib.nameValuePair ("${name}#${dependencyAttrs.version}") graph) parsedLock;
|
||||
parsedLock
|
||||
)
|
||||
//
|
||||
{
|
||||
"${mainPackageName}" =
|
||||
lib.mapAttrsToList
|
||||
(depName: depSemVer:
|
||||
let
|
||||
depYarnKey = "${depName}@${depSemVer}";
|
||||
dependencyAttrs =
|
||||
if ! parsedLock ? "${depYarnKey}" then
|
||||
throw "Cannot find entry for top level dependency: '${depYarnKey}'"
|
||||
else
|
||||
parsedLock."${depYarnKey}";
|
||||
in
|
||||
"${depName}#${dependencyAttrs.version}"
|
||||
)
|
||||
(
|
||||
packageJSON.dependencies or {}
|
||||
//
|
||||
(lib.optionalAttrs dev (packageJSON.devDependencies or {}))
|
||||
//
|
||||
(lib.optionalAttrs peer (packageJSON.peerDependencies or {}))
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
in
|
||||
# TODO: produce dream lock like in /specifications/dream-lock-example.json
|
||||
|
||||
@ -74,7 +136,7 @@
|
||||
generic = {
|
||||
buildSystem = "nodejs";
|
||||
producedBy = translatorName;
|
||||
mainPackage = packageJSON.name;
|
||||
mainPackage = mainPackageName;
|
||||
inherit dependencyGraph;
|
||||
sourcesCombinedHash = null;
|
||||
};
|
||||
@ -112,10 +174,20 @@
|
||||
# String arguments contain a default value and examples. Flags do not.
|
||||
specialArgs = {
|
||||
|
||||
# optionalDependencies = {
|
||||
# description = "Whether to include optional dependencies";
|
||||
# type = "flag";
|
||||
# };
|
||||
dev = {
|
||||
description = "Whether to include development dependencies";
|
||||
type = "flag";
|
||||
};
|
||||
|
||||
optional = {
|
||||
description = "Whether to include optional dependencies";
|
||||
type = "flag";
|
||||
};
|
||||
|
||||
peer = {
|
||||
description = "Whether to include peer dependencies";
|
||||
type = "flag";
|
||||
};
|
||||
|
||||
};
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
#
|
||||
# Load in nix repl and test, e.g.:
|
||||
#
|
||||
# nix-repl> parseConfigFile ./yarn.lock
|
||||
# nix-repl> parseLock ./yarn.lock
|
||||
# { type = "success"; value = ...; }
|
||||
|
||||
{ lib, nix-parsec }:
|
||||
@ -13,22 +13,20 @@ rec {
|
||||
inherit (nix-parsec) parsec;
|
||||
|
||||
# Skip spaces and line comments and newlines
|
||||
spaceComments = nix-parsec.lexer.space
|
||||
(skipWhile1 (c: c == " " || c == "\t" || c == "\n"))
|
||||
(nix-parsec.lexer.skipLineComment "#")
|
||||
fail;
|
||||
skipEmptyLinesAndComments =
|
||||
skipMany (alt
|
||||
(skipWhile1 (c: c == " " || c == "\t" || c == "\n"))
|
||||
(skipThen (string "#") (skipWhile (x: x != "\n")))
|
||||
);
|
||||
|
||||
charInsideQuotes = c: c != "\"";
|
||||
charOutsideQuotes = c: c != "\"" && c != "\n" && c != " " && c != "," && c != ":";
|
||||
unquotedString = takeWhile1 charOutsideQuotes;
|
||||
newLine = string "\n";
|
||||
|
||||
# use the nix-parsec quotedString
|
||||
quotedString = between (string "\"") (string "\"") (takeWhile1 charInsideQuotes);
|
||||
|
||||
# TODO add the relevant fmap to add the attributes
|
||||
version = skipThen (string " version ") (thenSkip quotedString newLine);
|
||||
# TODO instead of nextLine use an exact count of space and newline ?:w
|
||||
resolved = skipThen (string " resolved ") (thenSkip quotedString newLine);
|
||||
integrity = skipThen (string " integrity ") (thenSkip unquotedString newLine);
|
||||
|
||||
@ -47,12 +45,14 @@ rec {
|
||||
dependencyNames = thenSkip (sepBy (alt quotedString unquotedString) (string ", ")) (string ":\n");
|
||||
|
||||
dependencyAttrs = bind version (parsedVersion:
|
||||
bind resolved (parsedResolved:
|
||||
bind (optional resolved) (parsedResolved:
|
||||
bind (optional integrity) (parsedIntegrity:
|
||||
bind (optional dependencies) (parsedDependencies:
|
||||
bind (optional optionalDependencies) (parsedOptionalDependencies:
|
||||
pure (
|
||||
{ version = parsedVersion; resolved = parsedResolved; }
|
||||
{ version = parsedVersion; }
|
||||
//
|
||||
(if parsedResolved == [ ] then { } else { resolved = builtins.head parsedResolved; })
|
||||
//
|
||||
(if parsedIntegrity == [ ] then { } else { integrity = builtins.head parsedIntegrity; })
|
||||
//
|
||||
@ -61,6 +61,7 @@ rec {
|
||||
(if parsedOptionalDependencies == [ ] then { } else { optionalDependencies = builtins.head parsedOptionalDependencies; })
|
||||
)
|
||||
)))));
|
||||
|
||||
namesToAttrsList = namesList: dependencyAttrs: map (dependencyName: lib.nameValuePair dependencyName dependencyAttrs) namesList;
|
||||
|
||||
group =
|
||||
@ -69,8 +70,8 @@ rec {
|
||||
dependencyAttrs);
|
||||
|
||||
configFile =
|
||||
(skipThen spaceComments
|
||||
(skipThen skipEmptyLinesAndComments
|
||||
(thenSkip (sepBy group newLine) eof));
|
||||
|
||||
parseLock = path: nix-parsec.parsec.runParser configFile (builtins.readFile path);
|
||||
parseLock = text: nix-parsec.parsec.runParser configFile text;
|
||||
}
|
||||
|
@ -17,6 +17,8 @@ rec {
|
||||
|
||||
readDreamLock = callPackageDream ./readDreamLock.nix {};
|
||||
|
||||
readTextFile = file: lib.replaceStrings [ "\r\n" ] [ "\n" ] (b.readFile file);
|
||||
|
||||
isFile = path: (builtins.readDir (b.dirOf path))."${b.baseNameOf path}" == "regular";
|
||||
|
||||
isDir = path: (builtins.readDir (b.dirOf path))."${b.baseNameOf path}" == "directory";
|
||||
|
@ -21,8 +21,5 @@ let
|
||||
dependencyGraph = lock.generic.dependencyGraph;
|
||||
|
||||
in
|
||||
lib.recursiveUpdate
|
||||
lock
|
||||
{
|
||||
generic.dependencyGraph."${mainPackage}" = dependencyGraph."${mainPackage}" or lib.attrNames dependencyGraph;
|
||||
}
|
||||
lock
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user