Skip to content

Commit

Permalink
poetry2nix: 1.2.1 -> 1.3.0
Browse files Browse the repository at this point in the history
  • Loading branch information
adisbladis committed Jan 13, 2020
1 parent 244c89d commit 386dbd5
Show file tree
Hide file tree
Showing 4 changed files with 225 additions and 120 deletions.
20 changes: 7 additions & 13 deletions pkgs/development/tools/poetry2nix/poetry2nix/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,10 @@ let

getFunctorFn = fn: if builtins.typeOf fn == "set" then fn.__functor else fn;

getAttrDefault = attribute: set: default: (
if builtins.hasAttr attribute set
then builtins.getAttr attribute set
else default
);

# Map SPDX identifiers to license names
spdxLicenses = lib.listToAttrs (lib.filter (pair: pair.name != null) (builtins.map (v: { name = if lib.hasAttr "spdxId" v then v.spdxId else null; value = v; }) (lib.attrValues lib.licenses)));
# Get license by id falling back to input string
getLicenseBySpdxId = spdxId: getAttrDefault spdxId spdxLicenses spdxId;
getLicenseBySpdxId = spdxId: spdxLicenses.${spdxId} or spdxId;

#
# Returns an attrset { python, poetryPackages } for the given lockfile
Expand Down Expand Up @@ -65,7 +59,7 @@ let
# closure as python can only ever have one version of a dependency
baseOverlay = self: super:
let
getDep = depName: if builtins.hasAttr depName self then self."${depName}" else throw "foo";
getDep = depName: self.${depName};

lockPkgs = builtins.listToAttrs (
builtins.map (
Expand All @@ -74,7 +68,7 @@ let
value = self.mkPoetryDep (
pkgMeta // {
inherit pwd;
source = getAttrDefault "source" pkgMeta null;
source = pkgMeta.source or null;
files = lockFiles.${name};
pythonPackages = self;
}
Expand Down Expand Up @@ -159,12 +153,12 @@ let
passedAttrs = builtins.removeAttrs attrs specialAttrs;

getDeps = depAttr: let
deps = getAttrDefault depAttr pyProject.tool.poetry {};
deps = pyProject.tool.poetry.${depAttr} or {};
depAttrs = builtins.map (d: lib.toLower d) (builtins.attrNames deps);
in
builtins.map (dep: py.pkgs."${dep}") depAttrs;

getInputs = attr: getAttrDefault attr attrs [];
getInputs = attr: attrs.${attr} or [];
mkInput = attr: extraInputs: getInputs attr ++ extraInputs;

buildSystemPkgs = poetryLib.getBuildSystemPkgs {
Expand All @@ -189,7 +183,7 @@ let
python = py;
};

postPatch = (getAttrDefault "postPatch" passedAttrs "") + ''
postPatch = (passedAttrs.postPatch or "") + ''
# Tell poetry not to resolve the path dependencies. Any version is
# fine !
yj -tj < pyproject.toml | python ${./pyproject-without-path.py} > pyproject.json
Expand All @@ -199,7 +193,7 @@ let

meta = meta // {
inherit (pyProject.tool.poetry) description homepage;
license = getLicenseBySpdxId (getAttrDefault "license" pyProject.tool.poetry "unknown");
license = getLicenseBySpdxId (pyProject.tool.poetry.license or "unknown");
};

}
Expand Down
34 changes: 18 additions & 16 deletions pkgs/development/tools/poetry2nix/poetry2nix/lib.nix
Original file line number Diff line number Diff line change
Expand Up @@ -30,22 +30,24 @@ let
in
(builtins.foldl' combine initial tokens).state;

fromTOML = toml: if builtins.hasAttr "fromTOML" builtins then builtins.fromTOML toml else
builtins.fromJSON (
builtins.readFile (
pkgs.runCommand "from-toml"
{
inherit toml;
allowSubstitutes = false;
preferLocalBuild = true;
}
''
${pkgs.remarshal}/bin/remarshal \
-if toml \
-i <(echo "$toml") \
-of json \
-o $out
''
fromTOML = builtins.fromTOML or
(
toml: builtins.fromJSON (
builtins.readFile (
pkgs.runCommand "from-toml"
{
inherit toml;
allowSubstitutes = false;
preferLocalBuild = true;
}
''
${pkgs.remarshal}/bin/remarshal \
-if toml \
-i <(echo "$toml") \
-of json \
-o $out
''
)
)
);
readTOML = path: fromTOML (builtins.readFile path);
Expand Down
172 changes: 91 additions & 81 deletions pkgs/development/tools/poetry2nix/poetry2nix/mk-poetry-dep.nix
Original file line number Diff line number Diff line change
Expand Up @@ -16,102 +16,112 @@
, pwd
, supportedExtensions ? lib.importJSON ./extensions.json
, ...
}: let

inherit (poetryLib) isCompatible getManyLinuxDeps fetchFromPypi;
}:

inherit (import ./pep425.nix {
inherit lib python;
inherit (pkgs) stdenv;
}) selectWheel
;
pythonPackages.callPackage (
{ preferWheel ? false
}:

fileCandidates = let
supportedRegex = ("^.*?(" + builtins.concatStringsSep "|" supportedExtensions + ")");
matchesVersion = fname: builtins.match ("^.*" + builtins.replaceStrings [ "." ] [ "\\." ] version + ".*$") fname != null;
hasSupportedExtension = fname: builtins.match supportedRegex fname != null;
isCompatibleEgg = fname: ! lib.strings.hasSuffix ".egg" fname || lib.strings.hasSuffix "py${python.pythonVersion}.egg" fname;
in
builtins.filter (f: matchesVersion f.file && hasSupportedExtension f.file && isCompatibleEgg f.file) files;
let

toPath = s: pwd + "/${s}";
inherit (poetryLib) isCompatible getManyLinuxDeps fetchFromPypi;

isSource = source != null;
isGit = isSource && source.type == "git";
isLocal = isSource && source.type == "directory";
inherit (import ./pep425.nix {
inherit lib python;
inherit (pkgs) stdenv;
}) selectWheel
;

localDepPath = toPath source.url;
pyProject = poetryLib.readTOML (localDepPath + "/pyproject.toml");
fileCandidates = let
supportedRegex = ("^.*?(" + builtins.concatStringsSep "|" supportedExtensions + ")");
matchesVersion = fname: builtins.match ("^.*" + builtins.replaceStrings [ "." ] [ "\\." ] version + ".*$") fname != null;
hasSupportedExtension = fname: builtins.match supportedRegex fname != null;
isCompatibleEgg = fname: ! lib.strings.hasSuffix ".egg" fname || lib.strings.hasSuffix "py${python.pythonVersion}.egg" fname;
in
builtins.filter (f: matchesVersion f.file && hasSupportedExtension f.file && isCompatibleEgg f.file) files;

buildSystemPkgs = poetryLib.getBuildSystemPkgs {
inherit pythonPackages pyProject;
};
toPath = s: pwd + "/${s}";

fileInfo = let
isBdist = f: lib.strings.hasSuffix "whl" f.file;
isSdist = f: ! isBdist f && ! isEgg f;
isEgg = f: lib.strings.hasSuffix ".egg" f.file;
isSource = source != null;
isGit = isSource && source.type == "git";
isLocal = isSource && source.type == "directory";

binaryDist = selectWheel fileCandidates;
sourceDist = builtins.filter isSdist fileCandidates;
eggs = builtins.filter isEgg fileCandidates;
localDepPath = toPath source.url;
pyProject = poetryLib.readTOML (localDepPath + "/pyproject.toml");

lockFileEntry = builtins.head (sourceDist ++ binaryDist ++ eggs);
buildSystemPkgs = poetryLib.getBuildSystemPkgs {
inherit pythonPackages pyProject;
};

_isEgg = isEgg lockFileEntry;
fileInfo = let
isBdist = f: lib.strings.hasSuffix "whl" f.file;
isSdist = f: ! isBdist f && ! isEgg f;
isEgg = f: lib.strings.hasSuffix ".egg" f.file;

in
rec {
inherit (lockFileEntry) file hash;
name = file;
format =
if _isEgg then "egg"
else if lib.strings.hasSuffix ".whl" name then "wheel"
else "setuptools";
kind =
if _isEgg then python.pythonVersion
else if format == "setuptools" then "source"
else (builtins.elemAt (lib.strings.splitString "-" name) 2);
};
binaryDist = selectWheel fileCandidates;
sourceDist = builtins.filter isSdist fileCandidates;
eggs = builtins.filter isEgg fileCandidates;

baseBuildInputs = lib.optional (name != "setuptools_scm" && name != "setuptools-scm") pythonPackages.setuptools_scm;
entries = (if preferWheel then binaryDist ++ sourceDist else sourceDist ++ binaryDist) ++ eggs;

in
lockFileEntry = builtins.head entries;

buildPythonPackage {
pname = name;
version = version;
_isEgg = isEgg lockFileEntry;

doCheck = false; # We never get development deps
dontStrip = true;
format = if isLocal then "pyproject" else if isGit then "setuptools" else fileInfo.format;
in
rec {
inherit (lockFileEntry) file hash;
name = file;
format =
if _isEgg then "egg"
else if lib.strings.hasSuffix ".whl" name then "wheel"
else "setuptools";
kind =
if _isEgg then python.pythonVersion
else if format == "setuptools" then "source"
else (builtins.elemAt (lib.strings.splitString "-" name) 2);
};

nativeBuildInputs = if (!isSource && (getManyLinuxDeps fileInfo.name).str != null) then [ autoPatchelfHook ] else [];
buildInputs = baseBuildInputs ++ (if !isSource then (getManyLinuxDeps fileInfo.name).pkg else []);
baseBuildInputs = lib.optional (name != "setuptools_scm" && name != "setuptools-scm") pythonPackages.setuptools_scm;

propagatedBuildInputs =
let
# Some dependencies like django gets the attribute name django
# but dependencies try to access Django
deps = builtins.map (d: lib.toLower d) (builtins.attrNames dependencies);
in
(builtins.map (n: pythonPackages.${n}) deps) ++ (if isLocal then buildSystemPkgs else []);

meta = {
broken = ! isCompatible python.version python-versions;
license = [];
};

# We need to retrieve kind from the interpreter and the filename of the package
# Interpreters should declare what wheel types they're compatible with (python type + ABI)
# Here we can then choose a file based on that info.
src = if isGit then (
builtins.fetchGit {
inherit (source) url;
rev = source.reference;
}
) else if isLocal then (localDepPath) else fetchFromPypi {
pname = name;
inherit (fileInfo) file hash kind;
};
}

buildPythonPackage {
pname = name;
version = version;

doCheck = false; # We never get development deps
dontStrip = true;
format = if isLocal then "pyproject" else if isGit then "setuptools" else fileInfo.format;

nativeBuildInputs = if (!isSource && (getManyLinuxDeps fileInfo.name).str != null) then [ autoPatchelfHook ] else [];
buildInputs = baseBuildInputs ++ (if !isSource then (getManyLinuxDeps fileInfo.name).pkg else []);

propagatedBuildInputs =
let
# Some dependencies like django gets the attribute name django
# but dependencies try to access Django
deps = builtins.map (d: lib.toLower d) (builtins.attrNames dependencies);
in
(builtins.map (n: pythonPackages.${n}) deps) ++ (if isLocal then buildSystemPkgs else []);

meta = {
broken = ! isCompatible python.version python-versions;
license = [];
};

# We need to retrieve kind from the interpreter and the filename of the package
# Interpreters should declare what wheel types they're compatible with (python type + ABI)
# Here we can then choose a file based on that info.
src = if isGit then (
builtins.fetchGit {
inherit (source) url;
rev = source.reference;
}
) else if isLocal then (localDepPath) else fetchFromPypi {
pname = name;
inherit (fileInfo) file hash kind;
};
}

) {}
Loading

0 comments on commit 386dbd5

Please sign in to comment.