allow r packages to be passed via extra_pkgs

This commit is contained in:
DavHau 2020-10-12 00:17:54 +07:00
parent cd24fad1c9
commit 877d55d06d
3 changed files with 67 additions and 16 deletions

View file

@ -56,6 +56,8 @@ let
in in
trace msg result; trace msg result;
is_src = input: ! input ? passthru;
is_http_url = url: is_http_url = url:
with builtins; with builtins;
if (substring 0 8 url) == "https://" || (substring 0 7 url) == "http://" then true else false; if (substring 0 8 url) == "https://" || (substring 0 7 url) == "http://" then true else false;
@ -259,9 +261,15 @@ let
let let
python_pkg = pkgs."${python_arg}"; python_pkg = pkgs."${python_arg}";
pyver = get_py_ver python_pkg; pyver = get_py_ver python_pkg;
_extra_pkgs = map (p: # and separate pkgs into groups
extra_pkgs_python = map (p:
# check if element is a package built via mach-nix # check if element is a package built via mach-nix
if isAttrs p && hasAttrByPath ["passthru" "_"] p then if p ? pythomModule && ! p ? passthru._ then
throw ''
python packages from nixpkgs cannot be passed via `extra_pkgs`.
Instead, add the package's name to your `requirements` and set `providers.{package} = "nixpkgs"`
''
else if p ? passthru._ then
let let
pkg_pyver = get_py_ver p.pythonModule; pkg_pyver = get_py_ver p.pythonModule;
in in
@ -273,48 +281,68 @@ let
'' ''
else else
p p
# translate sources to python packages
else else
_buildPython "buildPythonPackage" { _buildPython "buildPythonPackage" {
src = p; src = p;
inherit disable_checks pkgs providers pypi_deps_db_commit pypi_deps_db_sha256 python _provider_defaults; inherit disable_checks pkgs providers pypi_deps_db_commit pypi_deps_db_sha256 python _provider_defaults;
} }
) extra_pkgs; ) (filter (p: is_src p || p ? pythonModule) extra_pkgs);
extra_pkgs_attrs = foldl' (a: b: a // b) {} (map (p: { "${p.pname}" = p; }) _extra_pkgs); extra_pkgs_r = filter (p: p ? rCommand) extra_pkgs;
extra_pkgs_as_overrides = [ (pySelf: pySuper: extra_pkgs_attrs) ]; extra_pkgs_other = filter (p: ! (p ? rCommand || p ? pythonModule || is_src p)) extra_pkgs;
extra_pkgs_reqs =
# gather requirements of exra pkgs
extra_pkgs_py_reqs =
map (p: map (p:
if hasAttr "requirements" p then p.requirements if hasAttr "requirements" p then p.requirements
else throw "Packages passed via 'extra_pkgs' must be built via mach-nix.buildPythonPackage" else throw "Packages passed via 'extra_pkgs' must be built via mach-nix.buildPythonPackage"
) _extra_pkgs; ) extra_pkgs_python;
extra_pkgs_r_reqs = if extra_pkgs_r == [] then "" else "rpy2";
# gather overrides necessary by extra_pkgs
extra_pkgs_python_attrs = foldl' (a: b: a // b) {} (map (p: { "${p.pname}" = p; }) extra_pkgs_python);
extra_pkgs_py_overrides = [ (pySelf: pySuper: extra_pkgs_python_attrs) ];
extra_pkgs_r_overrides = simple_overrides {
rpy2.buildInputs.add = extra_pkgs_r;
};
overrides_simple_extra = flatten ( overrides_simple_extra = flatten (
(map simple_overrides ( (map simple_overrides (
map (p: if hasAttr "_" p then p._ else {}) _extra_pkgs map (p: if hasAttr "_" p then p._ else {}) extra_pkgs_python
)) ))
); );
overrides_pre_extra = flatten (map (p: p.passthru.overrides_pre) _extra_pkgs); overrides_pre_extra = flatten (map (p: p.passthru.overrides_pre) extra_pkgs_python);
overrides_post_extra = flatten (map (p: p.passthru.overrides_post) _extra_pkgs); overrides_post_extra = flatten (map (p: p.passthru.overrides_post) extra_pkgs_python);
py = python_pkg.override { packageOverrides = mergeOverrides overrides_pre; }; py = python_pkg.override { packageOverrides = mergeOverrides overrides_pre; };
result = compileOverrides { result = compileOverrides {
inherit disable_checks pkgs providers pypi_deps_db_commit pypi_deps_db_sha256 _provider_defaults; inherit disable_checks pkgs providers pypi_deps_db_commit pypi_deps_db_sha256 _provider_defaults;
overrides = overrides_pre ++ overrides_pre_extra ++ extra_pkgs_as_overrides; overrides = overrides_pre ++ overrides_pre_extra ++ extra_pkgs_py_overrides;
python = py; python = py;
requirements = concat_reqs ([requirements] ++ extra_pkgs_reqs); requirements = concat_reqs ([requirements] ++ extra_pkgs_py_reqs ++ [extra_pkgs_r_reqs]);
}; };
all_overrides = mergeOverrides ( all_overrides = mergeOverrides (
overrides_pre ++ overrides_pre_extra overrides_pre ++ overrides_pre_extra
++ extra_pkgs_as_overrides ++ extra_pkgs_py_overrides
++ [ result.overrides ] ++ [ result.overrides ]
++ (fixes_to_overrides _fixes) ++ (fixes_to_overrides _fixes)
++ overrides_post_extra ++ overrides_post ++ overrides_post_extra ++ overrides_post
++ extra_pkgs_r_overrides
++ overrides_simple_extra ++ (simple_overrides _) ++ overrides_simple_extra ++ (simple_overrides _)
); );
py_final = python_pkg.override { packageOverrides = all_overrides;}; py_final = python_pkg.override { packageOverrides = all_overrides;};
select_pkgs = ps: select_pkgs = ps:
(result.select_pkgs ps) (result.select_pkgs ps)
++ (map (name: ps."${name}") (attrNames extra_pkgs_attrs)); ++ (map (name: ps."${name}") (attrNames extra_pkgs_python_attrs));
py_final_with_pkgs = py_final.withPackages (ps: select_pkgs ps); py_final_with_pkgs = py_final.withPackages (ps: select_pkgs ps);
final_env = pkgs.buildEnv {
name = "mach-nix-python-env";
paths = [
py_final_with_pkgs
extra_pkgs_other
];
};
in let in let
self = py_final_with_pkgs.overrideAttrs (oa: { self = final_env.overrideAttrs (oa: {
passthru = oa.passthru // rec { passthru = oa.passthru // rec {
selectPkgs = select_pkgs; selectPkgs = select_pkgs;
pythonOverrides = all_overrides; pythonOverrides = all_overrides;
@ -362,7 +390,7 @@ rec {
# the main functions # the main functions
mkPython = args: mkPythonBase "mkPython" args; mkPython = args: mkPythonBase "mkPython" args;
mkPythonShell = args: (mkPythonBase "mkPythonShell" args).env; mkPythonShell = args: pkgs.mkShell { buildInputs = (mkPythonBase "mkPythonShell" args) ;};
mkDockerImage = args: (mkPythonBase "mkDockerImage" args).dockerImage; mkDockerImage = args: (mkPythonBase "mkDockerImage" args).dockerImage;
mkOverlay = args: (mkPythonBase "mkOverlay" args).overlay; mkOverlay = args: (mkPythonBase "mkOverlay" args).overlay;
mkNixpkgs = args: (mkPythonBase "mkNixpkgs" args).nixpkgs; mkNixpkgs = args: (mkPythonBase "mkNixpkgs" args).nixpkgs;
@ -387,6 +415,9 @@ rec {
# those are equivalent to the pkgs passed by the user # those are equivalent to the pkgs passed by the user
nixpkgs = pkgs; nixpkgs = pkgs;
# expose R packages
rPackages = pkgs.rPackages;
# this might beuseful for someone # this might beuseful for someone
inherit mergeOverrides; inherit mergeOverrides;
} }

View file

@ -6,6 +6,7 @@ map (file: import file { inherit mach-nix; }) [
./test_dot_in_name.nix ./test_dot_in_name.nix
./test_extra_pkgs.nix ./test_extra_pkgs.nix
./test_extras.nix ./test_extras.nix
./test_r_pkgs.nix
./test_lazy_usage.nix ./test_lazy_usage.nix
./test_passthru_select_pypi_pname.nix ./test_passthru_select_pypi_pname.nix
./test_py38_cp38_wheel.nix ./test_py38_cp38_wheel.nix

19
tests/test_r_pkgs.nix Normal file
View file

@ -0,0 +1,19 @@
with builtins;
{ mach-nix, ... }:
let
pyEnv = mach-nix.mkPython {
requirements = ''
requests
'';
extra_pkgs = with mach-nix.rPackages; [
data_table
];
};
in
if pyEnv ? python.pkgs.requests
&& pyEnv ? python.pkgs.rpy2
&& elem mach-nix.rPackages.data_table pyEnv.python.pkgs.rpy2.buildInputs then
{ inherit pyEnv; }
else
throw "Error"