summary refs log tree commit diff
path: root/pkgs/development/tools/poetry2nix/poetry2nix/mk-poetry-dep.nix
blob: 256e2d90daaf5e08c9058f11617dc5f56b23ca51 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
{ autoPatchelfHook
, pkgs
, lib
, python
, buildPythonPackage
, pythonPackages
, poetryLib
}:
{ name
, version
, files
, source
, dependencies ? {}
, pythonPackages
, python-versions
, pwd
, supportedExtensions ? lib.importJSON ./extensions.json
, ...
}: let

  inherit (poetryLib) isCompatible getManyLinuxDeps fetchFromPypi;

  inherit (import ./pep425.nix {
    inherit lib python;
    inherit (pkgs) stdenv;
  }) selectWheel
    ;

  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;

  toPath = s: pwd + "/${s}";

  isSource = source != null;
  isGit = isSource && source.type == "git";
  isLocal = isSource && source.type == "directory";

  localDepPath = toPath source.url;
  pyProject = poetryLib.readTOML (localDepPath + "/pyproject.toml");

  buildSystemPkgs = poetryLib.getBuildSystemPkgs {
    inherit pythonPackages pyProject;
  };

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

    binaryDist = selectWheel fileCandidates;
    sourceDist = builtins.filter isSdist fileCandidates;
    eggs = builtins.filter isEgg fileCandidates;

    lockFileEntry = builtins.head (sourceDist ++ binaryDist ++ eggs);

    _isEgg = isEgg lockFileEntry;

  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);
    };

  baseBuildInputs = lib.optional (name != "setuptools_scm" && name != "setuptools-scm") pythonPackages.setuptools_scm;

in

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;
  };
}