mirror of
https://github.com/vale981/poetry2nix
synced 2025-03-05 09:11:39 -05:00
Initial commit
This commit is contained in:
commit
866b5e1c37
10 changed files with 402 additions and 0 deletions
2
README.org
Normal file
2
README.org
Normal file
|
@ -0,0 +1,2 @@
|
|||
* Convert poetry projects to nix automagically
|
||||
This is under _really_ early development
|
105
default.nix
Normal file
105
default.nix
Normal file
|
@ -0,0 +1,105 @@
|
|||
{
|
||||
pkgs ? import <nixpkgs> { },
|
||||
python ? pkgs.python3,
|
||||
pythonPackages ? python.pkgs,
|
||||
}:
|
||||
|
||||
let
|
||||
|
||||
importTOML = path: builtins.fromTOML (builtins.readFile path);
|
||||
|
||||
# TODO: Because pip (and by extension poetry) supports wheels hashes are a list
|
||||
# This list has determistic but non-distinguishable origins
|
||||
# (we dont know what url the hashes corresponds to)
|
||||
#
|
||||
# Just grabbing the first possible hash only works ~50% of the time
|
||||
getSha256 = pname: poetryLock: builtins.elemAt poetryLock.metadata.hashes."${pname}" 0;
|
||||
|
||||
# Note: Makes a derivation tree
|
||||
mkPoetryDerivation = {
|
||||
pname,
|
||||
depPkgs,
|
||||
pyProject,
|
||||
poetryLock,
|
||||
overrides,
|
||||
}: let
|
||||
pkgMeta = depPkgs."${pname}";
|
||||
version = pkgMeta.version;
|
||||
dependencies =
|
||||
if (builtins.hasAttr "dependencies" pkgMeta)
|
||||
then (builtins.attrNames pkgMeta.dependencies)
|
||||
else [ ];
|
||||
|
||||
drv = pythonPackages.buildPythonPackage {
|
||||
inherit pname version;
|
||||
|
||||
# TODO: It's probably better to model derivations as an attrset that we pick deps from
|
||||
# That way we avoid instantiating the same derivation multiple times
|
||||
propagatedBuildInputs = builtins.map (pname: (mkPoetryDerivation {
|
||||
inherit pname depPkgs pyProject poetryLock overrides;
|
||||
})) dependencies;
|
||||
|
||||
doCheck = false; # We never get development deps
|
||||
|
||||
src = pythonPackages.fetchPypi {
|
||||
inherit pname version;
|
||||
sha256 = getSha256 pname poetryLock;
|
||||
};
|
||||
};
|
||||
|
||||
override =
|
||||
if (builtins.hasAttr pname overrides)
|
||||
then overrides."${pname}"
|
||||
else (drv: drv);
|
||||
|
||||
in override drv;
|
||||
|
||||
mkPoetryPackage = {
|
||||
src,
|
||||
pyproject ? src + "/pyproject.toml",
|
||||
poetrylock ? src + "/poetry.lock",
|
||||
overrides ? import ./overrides.nix {
|
||||
inherit pkgs python pythonPackages;
|
||||
},
|
||||
}: let
|
||||
pyProject = importTOML pyproject;
|
||||
poetryLock = importTOML poetrylock;
|
||||
|
||||
# Turn list of packages from lock-file into attrset for easy lookup
|
||||
depPkgs = builtins.listToAttrs (builtins.map (pkgMeta: {
|
||||
name = pkgMeta.name;
|
||||
value=pkgMeta;
|
||||
}) poetryLock.package);
|
||||
|
||||
# Turn an attrset of name/version pairs into a list of derivations
|
||||
getDeps = deps: let
|
||||
depNames = builtins.filter (depName: depName != "python") (builtins.attrNames deps);
|
||||
in builtins.map (pname: mkPoetryDerivation {
|
||||
inherit pname depPkgs pyProject poetryLock overrides;
|
||||
}) depNames;
|
||||
|
||||
in pythonPackages.buildPythonApplication {
|
||||
pname = pyProject.tool.poetry.name;
|
||||
version = pyProject.tool.poetry.version;
|
||||
|
||||
inherit src;
|
||||
|
||||
format = "pyproject";
|
||||
|
||||
buildInputs = [
|
||||
pythonPackages.poetry
|
||||
];
|
||||
|
||||
propagatedBuildInputs = getDeps pyProject.tool.poetry.dependencies;
|
||||
checkInputs = getDeps pyProject.tool.poetry.dev-dependencies;
|
||||
|
||||
meta = {
|
||||
description = pyProject.tool.poetry.description;
|
||||
licenses = [ pyProject.tool.poetry.license ];
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
in {
|
||||
inherit mkPoetryPackage;
|
||||
}
|
1
example_project/.envrc
Normal file
1
example_project/.envrc
Normal file
|
@ -0,0 +1 @@
|
|||
use nix
|
1
example_project/README.org
Normal file
1
example_project/README.org
Normal file
|
@ -0,0 +1 @@
|
|||
Note that this example project contains a hand-patched lock-file to work around https://github.com/sdispater/poetry/issues/1172
|
5
example_project/default.nix
Normal file
5
example_project/default.nix
Normal file
|
@ -0,0 +1,5 @@
|
|||
with import ../. { };
|
||||
|
||||
mkPoetryPackage {
|
||||
src = ./.;
|
||||
}
|
5
example_project/example_project/__init__.py
Normal file
5
example_project/example_project/__init__.py
Normal file
|
@ -0,0 +1,5 @@
|
|||
import requests
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
print(requests.get('https://example.com').text)
|
200
example_project/poetry.lock
generated
Normal file
200
example_project/poetry.lock
generated
Normal file
|
@ -0,0 +1,200 @@
|
|||
[[package]]
|
||||
category = "dev"
|
||||
description = "Atomic file writes."
|
||||
name = "atomicwrites"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||
version = "1.3.0"
|
||||
|
||||
[[package]]
|
||||
category = "dev"
|
||||
description = "Classes Without Boilerplate"
|
||||
name = "attrs"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||
version = "19.1.0"
|
||||
|
||||
[[package]]
|
||||
category = "main"
|
||||
description = "Python package for providing Mozilla's CA Bundle."
|
||||
name = "certifi"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
version = "2019.6.16"
|
||||
|
||||
[[package]]
|
||||
category = "main"
|
||||
description = "Universal encoding detector for Python 2 and 3"
|
||||
name = "chardet"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
version = "3.0.4"
|
||||
|
||||
[[package]]
|
||||
category = "dev"
|
||||
description = "Cross-platform colored terminal text."
|
||||
marker = "sys_platform == \"win32\""
|
||||
name = "colorama"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||
version = "0.4.1"
|
||||
|
||||
[[package]]
|
||||
category = "main"
|
||||
description = "Internationalized Domain Names in Applications (IDNA)"
|
||||
name = "idna"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||
version = "2.8"
|
||||
|
||||
[[package]]
|
||||
category = "dev"
|
||||
description = "Read metadata from Python packages"
|
||||
name = "importlib-metadata"
|
||||
optional = false
|
||||
python-versions = ">=2.7,!=3.0,!=3.1,!=3.2,!=3.3"
|
||||
version = "0.18"
|
||||
|
||||
[package.dependencies]
|
||||
zipp = ">=0.5"
|
||||
|
||||
[[package]]
|
||||
category = "dev"
|
||||
description = "More routines for operating on iterables, beyond itertools"
|
||||
marker = "python_version > \"2.7\""
|
||||
name = "more-itertools"
|
||||
optional = false
|
||||
python-versions = ">=3.4"
|
||||
version = "7.0.0"
|
||||
|
||||
[[package]]
|
||||
category = "dev"
|
||||
description = "Core utilities for Python packages"
|
||||
name = "packaging"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||
version = "19.0"
|
||||
|
||||
[package.dependencies]
|
||||
pyparsing = ">=2.0.2"
|
||||
six = "*"
|
||||
|
||||
[[package]]
|
||||
category = "dev"
|
||||
description = "plugin and hook calling mechanisms for python"
|
||||
name = "pluggy"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||
version = "0.12.0"
|
||||
|
||||
[package.dependencies]
|
||||
importlib-metadata = ">=0.12"
|
||||
|
||||
[[package]]
|
||||
category = "dev"
|
||||
description = "library with cross-python path, ini-parsing, io, code, log facilities"
|
||||
name = "py"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||
version = "1.8.0"
|
||||
|
||||
[[package]]
|
||||
category = "dev"
|
||||
description = "Python parsing module"
|
||||
name = "pyparsing"
|
||||
optional = false
|
||||
python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"
|
||||
version = "2.4.0"
|
||||
|
||||
[[package]]
|
||||
category = "dev"
|
||||
description = "pytest: simple powerful testing with Python"
|
||||
name = "pytest"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||
version = "4.6.3"
|
||||
|
||||
[package.dependencies]
|
||||
atomicwrites = ">=1.0"
|
||||
attrs = ">=17.4.0"
|
||||
colorama = "*"
|
||||
importlib-metadata = ">=0.12"
|
||||
packaging = "*"
|
||||
pluggy = ">=0.12,<1.0"
|
||||
py = ">=1.5.0"
|
||||
six = ">=1.10.0"
|
||||
wcwidth = "*"
|
||||
|
||||
[package.dependencies.more-itertools]
|
||||
python = ">=2.8"
|
||||
version = ">=4.0.0"
|
||||
|
||||
[[package]]
|
||||
category = "main"
|
||||
description = "Python HTTP for Humans."
|
||||
name = "requests"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
|
||||
version = "2.22.0"
|
||||
|
||||
[package.dependencies]
|
||||
certifi = ">=2017.4.17"
|
||||
chardet = ">=3.0.2,<3.1.0"
|
||||
idna = ">=2.5,<2.9"
|
||||
urllib3 = ">=1.21.1,<1.25.0 || >1.25.0,<1.25.1 || >1.25.1,<1.26"
|
||||
|
||||
[[package]]
|
||||
category = "dev"
|
||||
description = "Python 2 and 3 compatibility utilities"
|
||||
name = "six"
|
||||
optional = false
|
||||
python-versions = ">=2.6, !=3.0.*, !=3.1.*"
|
||||
version = "1.12.0"
|
||||
|
||||
[[package]]
|
||||
category = "main"
|
||||
description = "HTTP library with thread-safe connection pooling, file post, and more."
|
||||
name = "urllib3"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, <4"
|
||||
version = "1.25.3"
|
||||
|
||||
[[package]]
|
||||
category = "dev"
|
||||
description = "Measures number of Terminal column cells of wide-character codes"
|
||||
name = "wcwidth"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
version = "0.1.7"
|
||||
|
||||
[[package]]
|
||||
category = "dev"
|
||||
description = "Backport of pathlib-compatible object wrapper for zip files"
|
||||
name = "zipp"
|
||||
optional = false
|
||||
python-versions = ">=2.7"
|
||||
version = "0.5.1"
|
||||
|
||||
[metadata]
|
||||
content-hash = "81f5e454b0b11af37c64b11a6288cf92768a311f72008b4ff858b804c22d4f6c"
|
||||
python-versions = "^3.7"
|
||||
|
||||
[metadata.hashes]
|
||||
atomicwrites = ["75a9445bac02d8d058d5e1fe689654ba5a6556a1dfd8ce6ec55a0ed79866cfa6", "03472c30eb2c5d1ba9227e4c2ca66ab8287fbfbbda3888aa93dc2e28fc6811b4"]
|
||||
attrs = ["f0b870f674851ecbfbbbd364d6b5cbdff9dcedbc7f3f5e18a6891057f21fe399", "69c0dbf2ed392de1cb5ec704444b08a5ef81680a61cb899dc08127123af36a79"]
|
||||
certifi = ["945e3ba63a0b9f577b1395204e13c3a231f9bc0223888be653286534e5873695", "046832c04d4e752f37383b628bc601a7ea7211496b4638f6514d0e5b9acc4939"]
|
||||
chardet = ["84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae", "fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"]
|
||||
colorama = ["05eed71e2e327246ad6b38c540c4a3117230b19679b875190486ddd2d721422d", "f8ac84de7840f5b9c4e3347b3c1eaa50f7e49c2b07596221daec5edaabbd7c48"]
|
||||
idna = ["c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407", "ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c"]
|
||||
importlib-metadata = ["cb6ee23b46173539939964df59d3d72c3e0c1b5d54b84f1d8a7e912fe43612db", "6dfd58dfe281e8d240937776065dd3624ad5469c835248219bd16cf2e12dbeb7"]
|
||||
more-itertools = ["c3e4748ba1aad8dba30a4886b0b1a2004f9a863837b8654e7059eebf727afa5a", "2112d2ca570bb7c3e53ea1a35cd5df42bb0fd10c45f0fb97178679c3c03d64c7"]
|
||||
packaging = ["0c98a5d0be38ed775798ece1b9727178c4469d9c3b4ada66e8e6b7849f8732af", "9e1cbf8c12b1f1ce0bb5344b8d7ecf66a6f8a6e91bcb0c84593ed6d3ab5c4ab3"]
|
||||
pluggy = ["0825a152ac059776623854c1543d65a4ad408eb3d33ee114dff91e57ec6ae6fc", "b9817417e95936bf75d85d3f8767f7df6cdde751fc40aed3bb3074cbcb77757c"]
|
||||
py = ["dc639b046a6e2cff5bbe40194ad65936d6ba360b52b3c3fe1d08a82dd50b5e53", "64f65755aee5b381cea27766a3a147c3f15b9b6b9ac88676de66ba2ae36793fa"]
|
||||
pyparsing = ["1873c03321fc118f4e9746baf201ff990ceb915f433f23b395f5580d1840cb2a", "9b6323ef4ab914af344ba97510e966d64ba91055d6b9afa6b30799340e89cc03"]
|
||||
pytest = ["4a784f1d4f2ef198fe9b7aef793e9fa1a3b2f84e822d9b3a64a181293a572d45", "926855726d8ae8371803f7b2e6ec0a69953d9c6311fa7c3b6c1b929ff92d27da"]
|
||||
requests = ["11e007a8a2aa0323f5a921e9e6a2d7e4e67d9877e85773fba9ba6419025cbeb4", "9cf5292fcd0f598c671cfc1e0d7d1a7f13bb8085e9a590f48c010551dc6c4b31"]
|
||||
six = ["d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73", "3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c"]
|
||||
urllib3 = ["dbe59173209418ae49d485b87d1681aefa36252ee85884c31346debd19463232", "b246607a25ac80bedac05c6f282e3cdaf3afb65420fd024ac94435cabe6e18d1"]
|
||||
wcwidth = ["3df37372226d6e63e1b1e1eda15c594bca98a22d33a23832a90998faa96bc65e", "f4ebe71925af7b40a864553f761ed559b43544f8f71746c2d756c7fe788ade7c"]
|
||||
zipp = ["ca943a7e809cc12257001ccfb99e3563da9af99d52f261725e96dfe0f9275bc3", "8c1019c6aad13642199fbe458275ad6a84907634cc9f0989877ccc4a2840139d"]
|
17
example_project/pyproject.toml
Normal file
17
example_project/pyproject.toml
Normal file
|
@ -0,0 +1,17 @@
|
|||
[tool.poetry]
|
||||
name = "example_project"
|
||||
version = "0.1.0"
|
||||
description = "An example project to test poetry2nix"
|
||||
authors = ["adisbladis <adisbladis@gmail.com>"]
|
||||
license = "MIT"
|
||||
|
||||
[tool.poetry.dependencies]
|
||||
python = "^3.7"
|
||||
requests = "^2.22"
|
||||
|
||||
[tool.poetry.dev-dependencies]
|
||||
pytest = "^4.6"
|
||||
|
||||
[build-system]
|
||||
requires = ["poetry>=0.12"]
|
||||
build-backend = "poetry.masonry.api"
|
15
example_project/shell.nix
Normal file
15
example_project/shell.nix
Normal file
|
@ -0,0 +1,15 @@
|
|||
with import <nixpkgs> {};
|
||||
|
||||
let
|
||||
# TODO: Stop propagating PYTHONPATH
|
||||
pythonEnv = (python3.withPackages(ps: [
|
||||
ps.poetry
|
||||
])).override (args: {
|
||||
ignoreCollisions = true;
|
||||
});
|
||||
|
||||
in mkShell {
|
||||
buildInputs = [
|
||||
pythonEnv
|
||||
];
|
||||
}
|
51
overrides.nix
Normal file
51
overrides.nix
Normal file
|
@ -0,0 +1,51 @@
|
|||
{
|
||||
pkgs,
|
||||
python,
|
||||
pythonPackages,
|
||||
}:
|
||||
|
||||
{
|
||||
|
||||
pytest = (drv: drv.overrideAttrs(old: {
|
||||
buildInputs = old.buildInputs ++ [
|
||||
pythonPackages.setuptools_scm
|
||||
];
|
||||
}));
|
||||
|
||||
six = (drv: drv.overrideAttrs(old: {
|
||||
buildInputs = old.buildInputs ++ [
|
||||
pythonPackages.setuptools_scm
|
||||
];
|
||||
}));
|
||||
|
||||
py = (drv: drv.overrideAttrs(old: {
|
||||
buildInputs = old.buildInputs ++ [
|
||||
pythonPackages.setuptools_scm
|
||||
];
|
||||
}));
|
||||
|
||||
zipp = (drv: drv.overrideAttrs(old: {
|
||||
buildInputs = old.buildInputs ++ [
|
||||
pythonPackages.setuptools_scm
|
||||
];
|
||||
}));
|
||||
|
||||
importlib-metadata = (drv: drv.overrideAttrs(old: {
|
||||
src = pythonPackages.fetchPypi {
|
||||
pname = "importlib_metadata";
|
||||
version = old.version;
|
||||
sha256 = old.src.outputHash;
|
||||
};
|
||||
|
||||
buildInputs = old.buildInputs ++ [
|
||||
pythonPackages.setuptools_scm
|
||||
];
|
||||
}));
|
||||
|
||||
pluggy = (drv: drv.overrideAttrs(old: {
|
||||
buildInputs = old.buildInputs ++ [
|
||||
pythonPackages.setuptools_scm
|
||||
];
|
||||
}));
|
||||
|
||||
}
|
Loading…
Add table
Reference in a new issue