From 97d2648627663d9a35c392e2e05bd64a90cf5aee Mon Sep 17 00:00:00 2001 From: DavHau Date: Wed, 6 Sep 2023 10:32:25 +0200 Subject: [PATCH 01/70] feat(lib/internal): add findCycles.nix --- lib/internal/findCycles.nix | 98 +++++++++++++++++++ .../dream2nix/nodejs-granular-v3/default.nix | 90 ++--------------- 2 files changed, 106 insertions(+), 82 deletions(-) create mode 100644 lib/internal/findCycles.nix diff --git a/lib/internal/findCycles.nix b/lib/internal/findCycles.nix new file mode 100644 index 0000000000..a0d5f53ffc --- /dev/null +++ b/lib/internal/findCycles.nix @@ -0,0 +1,98 @@ +# This is currently only used for legacy modules ported to v1. +# The dream-lock concept might be deprecated together with this module at some +# point. +{lib, ...}: let + l = builtins // lib; + + nameVersionPair = name: version: { + name = name; + version = version; + }; + + findCycles = { + dependencyGraph, + roots, + }: let + depGraphWithFakeRoot = + l.recursiveUpdate + dependencyGraph + { + __fake-entry.__fake-version = + l.mapAttrsToList + nameVersionPair + roots; + }; + + findCycles_ = node: prevNodes: cycles: let + children = + depGraphWithFakeRoot."${node.name}"."${node.version}"; + + cyclicChildren = + l.filter + (child: prevNodes ? "${child.name}#${child.version}") + children; + + nonCyclicChildren = + l.filter + (child: ! prevNodes ? "${child.name}#${child.version}") + children; + + cycles' = + cycles + ++ (l.map (child: { + from = node; + to = child; + }) + cyclicChildren); + + # use set for efficient lookups + prevNodes' = + prevNodes + // {"${node.name}#${node.version}" = null;}; + in + if nonCyclicChildren == [] + then cycles' + else + l.flatten + (l.map + (child: findCycles_ child prevNodes' cycles') + nonCyclicChildren); + + cyclesList = + findCycles_ + ( + nameVersionPair + "__fake-entry" + "__fake-version" + ) + {} + []; + in + l.foldl' + (cycles: cycle: ( + let + existing = + cycles."${cycle.from.name}"."${cycle.from.version}" + or []; + + reverse = + cycles."${cycle.to.name}"."${cycle.to.version}" + or []; + in + # if edge or reverse edge already in cycles, do nothing + if + l.elem cycle.from reverse + || l.elem cycle.to existing + then cycles + else + l.recursiveUpdate + cycles + { + "${cycle.from.name}"."${cycle.from.version}" = + existing ++ [cycle.to]; + } + )) + {} + cyclesList; +in + findCycles diff --git a/modules/dream2nix/nodejs-granular-v3/default.nix b/modules/dream2nix/nodejs-granular-v3/default.nix index 989298048a..b970ac5aac 100644 --- a/modules/dream2nix/nodejs-granular-v3/default.nix +++ b/modules/dream2nix/nodejs-granular-v3/default.nix @@ -13,6 +13,10 @@ inherit (config.deps.stdenv) mkDerivation; }; + findCycles = import ../../../lib/internal/findCycles.nix { + inherit lib; + }; + # pdefs.${name}.${version} :: { # // all dependency entries of that package. # // each dependency is guaranteed to have its own entry in 'pdef' @@ -69,88 +73,10 @@ ) ); - cyclicDependencies = let - depGraphWithFakeRoot = - l.recursiveUpdate - dependencyGraph - { - __fake-entry.__fake-version = - l.mapAttrsToList - nameVersionPair - {${defaultPackageName} = defaultPackageVersion;}; - }; - - findCycles = node: prevNodes: cycles: let - children = - depGraphWithFakeRoot."${node.name}"."${node.version}"; - - cyclicChildren = - l.filter - (child: prevNodes ? "${child.name}#${child.version}") - children; - - nonCyclicChildren = - l.filter - (child: ! prevNodes ? "${child.name}#${child.version}") - children; - - cycles' = - cycles - ++ (l.map (child: { - from = node; - to = child; - }) - cyclicChildren); - - # use set for efficient lookups - prevNodes' = - prevNodes - // {"${node.name}#${node.version}" = null;}; - in - if nonCyclicChildren == [] - then cycles' - else - l.flatten - (l.map - (child: findCycles child prevNodes' cycles') - nonCyclicChildren); - - cyclesList = - findCycles - ( - nameVersionPair - "__fake-entry" - "__fake-version" - ) - {} - []; - in - l.foldl' - (cycles: cycle: ( - let - existing = - cycles."${cycle.from.name}"."${cycle.from.version}" - or []; - - reverse = - cycles."${cycle.to.name}"."${cycle.to.version}" - or []; - in - # if edge or reverse edge already in cycles, do nothing - if - l.elem cycle.from reverse - || l.elem cycle.to existing - then cycles - else - l.recursiveUpdate - cycles - { - "${cycle.from.name}"."${cycle.from.version}" = - existing ++ [cycle.to]; - } - )) - {} - cyclesList; + cyclicDependencies = findCycles { + inherit dependencyGraph; + roots = {${defaultPackageName} = defaultPackageVersion;}; + }; nodejsDeps = lib.mapAttrs From 19f1f0625d6d844fbba9e572c6c0fcb3a3657376 Mon Sep 17 00:00:00 2001 From: Jairo Llopis Date: Fri, 8 Sep 2023 13:04:53 +0100 Subject: [PATCH 02/70] fix: allow locking git dependencies with pip When you had a pip git requirement such as `git+https://github.com/OCA/maintainer-tools`, `fetch_pip_metadata` was failing with: ``` Traceback (most recent call last): File "/nix/store/v28wx7mr5m9wasbnmsij4dqfrgl0d28q-python3.10-fetch_pip_metadata/bin/.fetch_pip_metadata-wrapped", line 9, in sys.exit(fetch_pip_metadata()) File "/nix/store/v28wx7mr5m9wasbnmsij4dqfrgl0d28q-python3.10-fetch_pip_metadata/lib/python3.10/site-packages/fetch_pip_metadata/__init__.py", line 126, in fetch_pip_metadata lock = lock_file_from_report(report, project_root=args.project_root) File "/nix/store/v28wx7mr5m9wasbnmsij4dqfrgl0d28q-python3.10-fetch_pip_metadata/lib/python3.10/site-packages/fetch_pip_metadata/lock_file_from_report.py", line 240, in lock_file_from_report name, package = lock_entry_from_report_entry(install, project_root) File "/nix/store/v28wx7mr5m9wasbnmsij4dqfrgl0d28q-python3.10-fetch_pip_metadata/lib/python3.10/site-packages/fetch_pip_metadata/lock_file_from_report.py", line 154, in lock_entry_from_report_entry info = lock_info(download_info) File "/nix/store/v28wx7mr5m9wasbnmsij4dqfrgl0d28q-python3.10-fetch_pip_metadata/lib/python3.10/site-packages/fetch_pip_metadata/lock_file_from_report.py", line 132, in lock_info_from_vcs sha256 = nix_prefetch_git(url, rev) File "/nix/store/v28wx7mr5m9wasbnmsij4dqfrgl0d28q-python3.10-fetch_pip_metadata/lib/python3.10/site-packages/fetch_pip_metadata/lock_file_from_report.py", line 29, in nix_prefetch_git subprocess.run( File "/nix/store/bc45k1n0pkrdkr3xa6w84w1xhkl1kkyp-python3-3.10.12/lib/python3.10/subprocess.py", line 503, in run with Popen(*popenargs, **kwargs) as process: File "/nix/store/bc45k1n0pkrdkr3xa6w84w1xhkl1kkyp-python3-3.10.12/lib/python3.10/subprocess.py", line 971, in __init__ self._execute_child(args, executable, preexec_fn, close_fds, File "/nix/store/bc45k1n0pkrdkr3xa6w84w1xhkl1kkyp-python3-3.10.12/lib/python3.10/subprocess.py", line 1863, in _execute_child raise child_exception_type(errno_num, err_msg, err_filename) FileNotFoundError: [Errno 2] No such file or directory: 'nix-prefetch-git' Traceback (most recent call last): File "/nix/store/0715rzxpxka6b12x7nl6i25gbxp9m80g-refresh/bin/refresh", line 37, in lock_data = run_refresh_scripts(refresh_scripts) File "/nix/store/0715rzxpxka6b12x7nl6i25gbxp9m80g-refresh/bin/refresh", line 33, in run_refresh_scripts refresh_scripts[name] = run_refresh_script(value["script"]) File "/nix/store/0715rzxpxka6b12x7nl6i25gbxp9m80g-refresh/bin/refresh", line 19, in run_refresh_script subprocess.run( File "/nix/store/bc45k1n0pkrdkr3xa6w84w1xhkl1kkyp-python3-3.10.12/lib/python3.10/subprocess.py", line 526, in run raise CalledProcessError(retcode, process.args, subprocess.CalledProcessError: Command '['/nix/store/2qfpia31lh9dajnf9s6dm0rp5dw109d3-script.sh']' returned non-zero exit status 1. ``` @moduon MT-1075 --- pkgs/fetchPipMetadata/package.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/fetchPipMetadata/package.nix b/pkgs/fetchPipMetadata/package.nix index 76b0f9ac3e..709bff8f9e 100644 --- a/pkgs/fetchPipMetadata/package.nix +++ b/pkgs/fetchPipMetadata/package.nix @@ -12,11 +12,11 @@ nativeBuildInputs = [ gitMinimal python3.pkgs.pytestCheckHook - nix-prefetch-scripts ]; propagatedBuildInputs = with python3.pkgs; [ packaging certifi + nix-prefetch-scripts python-dateutil pip ]; From e079a214872c2047ce31157f590fa00018c5cd77 Mon Sep 17 00:00:00 2001 From: DavHau Date: Sat, 9 Sep 2023 14:29:58 +0200 Subject: [PATCH 03/70] examples: simplify repo examples --- examples/dream2nix-repo-flake/.project-root | 0 examples/dream2nix-repo-flake/flake.nix | 2 +- examples/dream2nix-repo-flake/settings.nix | 5 ----- examples/dream2nix-repo/settings.nix | 5 ----- 4 files changed, 1 insertion(+), 11 deletions(-) delete mode 100644 examples/dream2nix-repo-flake/.project-root delete mode 100644 examples/dream2nix-repo-flake/settings.nix delete mode 100644 examples/dream2nix-repo/settings.nix diff --git a/examples/dream2nix-repo-flake/.project-root b/examples/dream2nix-repo-flake/.project-root deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/examples/dream2nix-repo-flake/flake.nix b/examples/dream2nix-repo-flake/flake.nix index 32005b08cd..7a7a03cb4e 100644 --- a/examples/dream2nix-repo-flake/flake.nix +++ b/examples/dream2nix-repo-flake/flake.nix @@ -18,7 +18,7 @@ packages.${system} = dream2nix.lib.importPackages { projectRoot = ./.; # can be changed to ".git" or "flake.nix" to get rid of .project-root - projectRootFile = ".project-root"; + projectRootFile = "flake.nix"; packagesDir = "/packages"; packageSets.nixpkgs = nixpkgs.legacyPackages.${system}; }; diff --git a/examples/dream2nix-repo-flake/settings.nix b/examples/dream2nix-repo-flake/settings.nix deleted file mode 100644 index 3efdf188be..0000000000 --- a/examples/dream2nix-repo-flake/settings.nix +++ /dev/null @@ -1,5 +0,0 @@ -{config, ...}: { - paths.projectRoot = ./.; - paths.projectRootFile = ".project-root"; - paths.package = "/packages/${config.name}"; -} diff --git a/examples/dream2nix-repo/settings.nix b/examples/dream2nix-repo/settings.nix deleted file mode 100644 index 3efdf188be..0000000000 --- a/examples/dream2nix-repo/settings.nix +++ /dev/null @@ -1,5 +0,0 @@ -{config, ...}: { - paths.projectRoot = ./.; - paths.projectRootFile = ".project-root"; - paths.package = "/packages/${config.name}"; -} From 16b9241e2b08c707b975549a343a558da3bed368 Mon Sep 17 00:00:00 2001 From: DavHau Date: Sat, 9 Sep 2023 15:12:58 +0200 Subject: [PATCH 04/70] modules.drv-parts: add deprecation error --- modules/flake-parts/all-modules.nix | 2 +- modules/flake-parts/drv-parts-deprecated.nix | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 modules/flake-parts/drv-parts-deprecated.nix diff --git a/modules/flake-parts/all-modules.nix b/modules/flake-parts/all-modules.nix index 1aa6b06e67..76825f21c8 100644 --- a/modules/flake-parts/all-modules.nix +++ b/modules/flake-parts/all-modules.nix @@ -46,7 +46,7 @@ in { imports = flakePartsModules; options.flake.modules = mkOption { - type = types.anything; + type = types.lazyAttrsOf types.raw; }; # generates future flake outputs: `modules..` diff --git a/modules/flake-parts/drv-parts-deprecated.nix b/modules/flake-parts/drv-parts-deprecated.nix new file mode 100644 index 0000000000..23e12ac2b6 --- /dev/null +++ b/modules/flake-parts/drv-parts-deprecated.nix @@ -0,0 +1,6 @@ +{ + flake.modules.drv-parts = throw '' + dream2nix.modules.drv-parts is deprecated. + Use dream2nix.modules.dream2nix instead. + ''; +} From 7a7e5bd6617f82d9183231ab8ce6668968d4d47a Mon Sep 17 00:00:00 2001 From: DavHau Date: Sat, 9 Sep 2023 16:23:07 +0200 Subject: [PATCH 05/70] fix(pip): ensure autoPatchelfHook finds python binary dependencies --- modules/dream2nix/pip/default.nix | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/modules/dream2nix/pip/default.nix b/modules/dream2nix/pip/default.nix index ef478fdb94..2593341209 100644 --- a/modules/dream2nix/pip/default.nix +++ b/modules/dream2nix/pip/default.nix @@ -89,6 +89,11 @@ ++ (l.optionals config.deps.stdenv.isLinux [config.deps.autoPatchelfHook]); buildInputs = l.optionals config.deps.stdenv.isLinux [config.deps.manylinux1]; + # This is required for autoPatchelfHook to find .so files from other + # python dependencies, like for example libcublas.so.11 from nvidia-cublas-cu11. + preFixup = '' + addAutoPatchelfSearchPath ${toString (config.mkDerivation.propagatedBuildInputs)} + ''; propagatedBuildInputs = let depsByExtra = extra: targets.${extra}.${config.name} or []; defaultDeps = targets.default.${config.name} or []; From cfac73dbd18e5ce1e1ebf15ce8b0761717b659f1 Mon Sep 17 00:00:00 2001 From: DavHau Date: Mon, 11 Sep 2023 16:26:17 +0200 Subject: [PATCH 06/70] feat(pip): allow pypiSnapshotDate to be null For many users not having a snapshot date is a valid use case. Also many users will expect their lock file to be updated to the latest dependency versions via a nix run .#package.config.lock.refresh. so it can be the default behavior. --- .../single-language/python-package-pillow/default.nix | 1 - modules/dream2nix/pip/interface.nix | 3 ++- pkgs/fetchPipMetadata/script.nix | 6 +++++- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/examples/packages/single-language/python-package-pillow/default.nix b/examples/packages/single-language/python-package-pillow/default.nix index 9ee924a6f7..55be6a8237 100644 --- a/examples/packages/single-language/python-package-pillow/default.nix +++ b/examples/packages/single-language/python-package-pillow/default.nix @@ -40,7 +40,6 @@ }; pip = { - pypiSnapshotDate = "2023-04-02"; requirementsList = ["${config.name}==${config.version}"]; pipFlags = [ "--no-binary" diff --git a/modules/dream2nix/pip/interface.nix b/modules/dream2nix/pip/interface.nix index a6dab43b74..528a960da5 100644 --- a/modules/dream2nix/pip/interface.nix +++ b/modules/dream2nix/pip/interface.nix @@ -23,12 +23,13 @@ in { # user interface pypiSnapshotDate = l.mkOption { - type = t.str; + type = t.nullOr t.str; description = '' maximum release date for packages Choose any date from the past. ''; example = "2023-01-01"; + default = null; }; pipFlags = l.mkOption { type = t.listOf t.str; diff --git a/pkgs/fetchPipMetadata/script.nix b/pkgs/fetchPipMetadata/script.nix index d990a1ee51..63b57542bf 100644 --- a/pkgs/fetchPipMetadata/script.nix +++ b/pkgs/fetchPipMetadata/script.nix @@ -65,7 +65,11 @@ mitmProxy = "${pythonWithMitmproxy}/bin/mitmdump"; # convert pypiSnapshotDate to string and integrate into finalAttrs - pypiSnapshotDate = builtins.toString pypiSnapshotDate; + pypiSnapshotDate = + if pypiSnapshotDate == null + # when the snapshot date is disabled, put it far into the future + then "9999-01-01" + else builtins.toString pypiSnapshotDate; # add some variables to the derivation to integrate them into finalAttrs inherit From ad4cb865693d2b21ad9b48cdd5aa82b2a765d52f Mon Sep 17 00:00:00 2001 From: DavHau Date: Mon, 11 Sep 2023 22:21:54 +0200 Subject: [PATCH 07/70] fix(pip): fix namespace packages collision error --- modules/dream2nix/pip/default.nix | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/modules/dream2nix/pip/default.nix b/modules/dream2nix/pip/default.nix index 2593341209..674f7880e4 100644 --- a/modules/dream2nix/pip/default.nix +++ b/modules/dream2nix/pip/default.nix @@ -147,12 +147,14 @@ in { l.attrValues (l.mapAttrs (name: _: cfg.drvs.${name}.public.out) rootDeps); }; - public.devShell = config.deps.mkShell { - inherit (config.mkDerivation) buildInputs nativeBuildInputs; - packages = [ - (config.deps.python.withPackages - (ps: config.mkDerivation.propagatedBuildInputs)) - ]; - }; + public.devShell = let + pyEnv' = config.deps.python.withPackages (ps: config.mkDerivation.propagatedBuildInputs); + pyEnv = pyEnv'.override (old: { + # namespaced packages are triggering a collision error, but this can be + # safely ignored. They are still set up correctly and can be imported. + ignoreCollisions = true; + }); + in + pyEnv.env; }; } From c5bdcd7e67acfddfea053593e296165d8e1e6d0b Mon Sep 17 00:00:00 2001 From: DavHau Date: Mon, 11 Sep 2023 22:29:36 +0200 Subject: [PATCH 08/70] feat(python): add module WIP-python-pyproject --- .../python-machine-learning/default.nix | 27 ++ .../python-machine-learning/lock.json | 277 ++++++++++++++++++ .../python-machine-learning/pyproject.toml | 14 + .../someproject/__index__.py | 5 + .../WIP-python-pyproject/default.nix | 31 ++ 5 files changed, 354 insertions(+) create mode 100644 examples/packages/single-language/python-machine-learning/default.nix create mode 100644 examples/packages/single-language/python-machine-learning/lock.json create mode 100644 examples/packages/single-language/python-machine-learning/pyproject.toml create mode 100644 examples/packages/single-language/python-machine-learning/someproject/__index__.py create mode 100644 modules/dream2nix/WIP-python-pyproject/default.nix diff --git a/examples/packages/single-language/python-machine-learning/default.nix b/examples/packages/single-language/python-machine-learning/default.nix new file mode 100644 index 0000000000..37c0da3e0b --- /dev/null +++ b/examples/packages/single-language/python-machine-learning/default.nix @@ -0,0 +1,27 @@ +{ + dream2nix, + config, + lib, + ... +}: let + pyproject = + builtins.fromTOML + (builtins.readFile (config.mkDerivation.src + /pyproject.toml)); +in { + imports = [ + dream2nix.modules.dream2nix.WIP-python-pyproject + ]; + + mkDerivation = { + src = ./.; + }; + + pip.drvs.triton.env.pythonRemoveDeps = [ + "torch" + ]; + pip.drvs.triton.mkDerivation.nativeBuildInputs = [ + config.deps.python.pkgs.pythonRelaxDepsHook + ]; + pip.drvs.torch.env.autoPatchelfIgnoreMissingDeps = ["libcuda.so.1"]; + pip.drvs.torch.mkDerivation.dontStrip = true; +} diff --git a/examples/packages/single-language/python-machine-learning/lock.json b/examples/packages/single-language/python-machine-learning/lock.json new file mode 100644 index 0000000000..6f04ac21c9 --- /dev/null +++ b/examples/packages/single-language/python-machine-learning/lock.json @@ -0,0 +1,277 @@ +{ + "fetchPipMetadata": { + "sources": { + "cmake": { + "sha256": "c36eb106dec60198264b25d4bd23cd9ea30b0af9200a143ec1db887c095306f7", + "type": "url", + "url": "https://files.pythonhosted.org/packages/94/87/68536d2dde5acec492742c63bb71f43534eb7d3d83122cce3067c4abca2b/cmake-3.27.4.1-py2.py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", + "version": "3.27.4.1" + }, + "filelock": { + "sha256": "f067e40ccc40f2b48395a80fcbd4728262fab54e232e090a4063ab804179efeb", + "type": "url", + "url": "https://files.pythonhosted.org/packages/52/90/45223db4e1df30ff14e8aebf9a1bf0222da2e7b49e53692c968f36817812/filelock-3.12.3-py3-none-any.whl", + "version": "3.12.3" + }, + "jinja2": { + "sha256": "6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61", + "type": "url", + "url": "https://files.pythonhosted.org/packages/bc/c3/f068337a370801f372f2f8f6bad74a5c140f6fda3d9de154052708dd3c65/Jinja2-3.1.2-py3-none-any.whl", + "version": "3.1.2" + }, + "joblib": { + "sha256": "ef4331c65f239985f3f2220ecc87db222f08fd22097a3dd5698f693875f8cbb9", + "type": "url", + "url": "https://files.pythonhosted.org/packages/10/40/d551139c85db202f1f384ba8bcf96aca2f329440a844f924c8a0040b6d02/joblib-1.3.2-py3-none-any.whl", + "version": "1.3.2" + }, + "lit": { + "sha256": "84623c9c23b6b14763d637f4e63e6b721b3446ada40bf7001d8fee70b8e77a9a", + "type": "url", + "url": "https://files.pythonhosted.org/packages/bf/fa/0b75c53253ebf3ab566be702a9da16f5783862d8c1ae404c907a8830f283/lit-16.0.6.tar.gz", + "version": "16.0.6" + }, + "markupsafe": { + "sha256": "65c1a9bcdadc6c28eecee2c119465aebff8f7a584dd719facdd9e825ec61ab52", + "type": "url", + "url": "https://files.pythonhosted.org/packages/12/b3/d9ed2c0971e1435b8a62354b18d3060b66c8cb1d368399ec0b9baa7c0ee5/MarkupSafe-2.1.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", + "version": "2.1.3" + }, + "mpmath": { + "sha256": "a0b2b9fe80bbcd81a6647ff13108738cfb482d481d826cc0e02f5b35e5c88d2c", + "type": "url", + "url": "https://files.pythonhosted.org/packages/43/e3/7d92a15f894aa0c9c4b49b8ee9ac9850d6e63b03c9c32c0367a13ae62209/mpmath-1.3.0-py3-none-any.whl", + "version": "1.3.0" + }, + "networkx": { + "sha256": "4f33f68cb2afcf86f28a45f43efc27a9386b535d567d2127f8f61d51dec58d36", + "type": "url", + "url": "https://files.pythonhosted.org/packages/a8/05/9d4f9b78ead6b2661d6e8ea772e111fc4a9fbd866ad0c81906c11206b55e/networkx-3.1-py3-none-any.whl", + "version": "3.1" + }, + "numpy": { + "sha256": "f08f2e037bba04e707eebf4bc934f1972a315c883a9e0ebfa8a7756eabf9e357", + "type": "url", + "url": "https://files.pythonhosted.org/packages/71/3c/3b1981c6a1986adc9ee7db760c0c34ea5b14ac3da9ecfcf1ea2a4ec6c398/numpy-1.25.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", + "version": "1.25.2" + }, + "nvidia-cublas-cu11": { + "sha256": "d32e4d75f94ddfb93ea0a5dda08389bcc65d8916a25cb9f37ac89edaeed3bded", + "type": "url", + "url": "https://files.pythonhosted.org/packages/ce/41/fdeb62b5437996e841d83d7d2714ca75b886547ee8017ee2fe6ea409d983/nvidia_cublas_cu11-11.10.3.66-py3-none-manylinux1_x86_64.whl", + "version": "11.10.3.66" + }, + "nvidia-cuda-cupti-cu11": { + "sha256": "e0cfd9854e1f2edaa36ca20d21cd0bdd5dcfca4e3b9e130a082e05b33b6c5895", + "type": "url", + "url": "https://files.pythonhosted.org/packages/e6/9d/dd0cdcd800e642e3c82ee3b5987c751afd4f3fb9cc2752517f42c3bc6e49/nvidia_cuda_cupti_cu11-11.7.101-py3-none-manylinux1_x86_64.whl", + "version": "11.7.101" + }, + "nvidia-cuda-nvrtc-cu11": { + "sha256": "9f1562822ea264b7e34ed5930567e89242d266448e936b85bc97a3370feabb03", + "type": "url", + "url": "https://files.pythonhosted.org/packages/ef/25/922c5996aada6611b79b53985af7999fc629aee1d5d001b6a22431e18fec/nvidia_cuda_nvrtc_cu11-11.7.99-2-py3-none-manylinux1_x86_64.whl", + "version": "11.7.99" + }, + "nvidia-cuda-runtime-cu11": { + "sha256": "cc768314ae58d2641f07eac350f40f99dcb35719c4faff4bc458a7cd2b119e31", + "type": "url", + "url": "https://files.pythonhosted.org/packages/36/92/89cf558b514125d2ebd8344dd2f0533404b416486ff681d5434a5832a019/nvidia_cuda_runtime_cu11-11.7.99-py3-none-manylinux1_x86_64.whl", + "version": "11.7.99" + }, + "nvidia-cudnn-cu11": { + "sha256": "402f40adfc6f418f9dae9ab402e773cfed9beae52333f6d86ae3107a1b9527e7", + "type": "url", + "url": "https://files.pythonhosted.org/packages/dc/30/66d4347d6e864334da5bb1c7571305e501dcb11b9155971421bb7bb5315f/nvidia_cudnn_cu11-8.5.0.96-2-py3-none-manylinux1_x86_64.whl", + "version": "8.5.0.96" + }, + "nvidia-cufft-cu11": { + "sha256": "222f9da70c80384632fd6035e4c3f16762d64ea7a843829cb278f98b3cb7dd81", + "type": "url", + "url": "https://files.pythonhosted.org/packages/74/79/b912a77e38e41f15a0581a59f5c3548d1ddfdda3225936fb67c342719e7a/nvidia_cufft_cu11-10.9.0.58-py3-none-manylinux1_x86_64.whl", + "version": "10.9.0.58" + }, + "nvidia-curand-cu11": { + "sha256": "eecb269c970fa599a2660c9232fa46aaccbf90d9170b96c462e13bcb4d129e2c", + "type": "url", + "url": "https://files.pythonhosted.org/packages/8f/11/af78d54b2420e64a4dd19e704f5bb69dcb5a6a3138b4465d6a48cdf59a21/nvidia_curand_cu11-10.2.10.91-py3-none-manylinux1_x86_64.whl", + "version": "10.2.10.91" + }, + "nvidia-cusolver-cu11": { + "sha256": "72fa7261d755ed55c0074960df5904b65e2326f7adce364cbe4945063c1be412", + "type": "url", + "url": "https://files.pythonhosted.org/packages/3e/77/66149e3153b19312fb782ea367f3f950123b93916a45538b573fe373570a/nvidia_cusolver_cu11-11.4.0.1-2-py3-none-manylinux1_x86_64.whl", + "version": "11.4.0.1" + }, + "nvidia-cusparse-cu11": { + "sha256": "a3389de714db63321aa11fbec3919271f415ef19fda58aed7f2ede488c32733d", + "type": "url", + "url": "https://files.pythonhosted.org/packages/ea/6f/6d032cc1bb7db88a989ddce3f4968419a7edeafda362847f42f614b1f845/nvidia_cusparse_cu11-11.7.4.91-py3-none-manylinux1_x86_64.whl", + "version": "11.7.4.91" + }, + "nvidia-nccl-cu11": { + "sha256": "5e5534257d1284b8e825bc3a182c6f06acd6eb405e9f89d49340e98cd8f136eb", + "type": "url", + "url": "https://files.pythonhosted.org/packages/55/92/914cdb650b6a5d1478f83148597a25e90ea37d739bd563c5096b0e8a5f43/nvidia_nccl_cu11-2.14.3-py3-none-manylinux1_x86_64.whl", + "version": "2.14.3" + }, + "nvidia-nvtx-cu11": { + "sha256": "b22c64eee426a62fc00952b507d6d29cf62b4c9df7a480fcc417e540e05fd5ac", + "type": "url", + "url": "https://files.pythonhosted.org/packages/23/d5/09493ff0e64fd77523afbbb075108f27a13790479efe86b9ffb4587671b5/nvidia_nvtx_cu11-11.7.91-py3-none-manylinux1_x86_64.whl", + "version": "11.7.91" + }, + "pillow": { + "sha256": "a74ba0c356aaa3bb8e3eb79606a87669e7ec6444be352870623025d75a14a2bf", + "type": "url", + "url": "https://files.pythonhosted.org/packages/3d/36/e78f09d510354977e10102dd811e928666021d9c451e05df962d56477772/Pillow-10.0.0-cp310-cp310-manylinux_2_28_x86_64.whl", + "version": "10.0.0" + }, + "scikit-learn": { + "sha256": "ae80c08834a473d08a204d966982a62e11c976228d306a2648c575e3ead12111", + "type": "url", + "url": "https://files.pythonhosted.org/packages/5c/e9/ee572691a3fb05555bcde41826faad29ae4bc1fb07982e7f53d54a176879/scikit_learn-1.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", + "version": "1.3.0" + }, + "scipy": { + "sha256": "d690e1ca993c8f7ede6d22e5637541217fc6a4d3f78b3672a6fe454dbb7eb9a7", + "type": "url", + "url": "https://files.pythonhosted.org/packages/a8/cc/c36f3439f5d47c3b13833ce6687b43a040cc7638c502ac46b41e2d4f3d6f/scipy-1.11.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", + "version": "1.11.2" + }, + "setuptools": { + "sha256": "eff96148eb336377ab11beee0c73ed84f1709a40c0b870298b0d058828761bae", + "type": "url", + "url": "https://files.pythonhosted.org/packages/95/79/6b47c6a872b40743a480687dc0c79ffb4202710789f3e4d54a84fff8b550/setuptools-68.2.1-py3-none-any.whl", + "version": "68.2.1" + }, + "sympy": { + "sha256": "c3588cd4295d0c0f603d0f2ae780587e64e2efeedb3521e46b9bb1d08d184fa5", + "type": "url", + "url": "https://files.pythonhosted.org/packages/d2/05/e6600db80270777c4a64238a98d442f0fd07cc8915be2a1c16da7f2b9e74/sympy-1.12-py3-none-any.whl", + "version": "1.12" + }, + "threadpoolctl": { + "sha256": "2b7818516e423bdaebb97c723f86a7c6b0a83d3f3b0970328d66f4d9104dc032", + "type": "url", + "url": "https://files.pythonhosted.org/packages/81/12/fd4dea011af9d69e1cad05c75f3f7202cdcbeac9b712eea58ca779a72865/threadpoolctl-3.2.0-py3-none-any.whl", + "version": "3.2.0" + }, + "torch": { + "sha256": "8ced00b3ba471856b993822508f77c98f48a458623596a4c43136158781e306a", + "type": "url", + "url": "https://files.pythonhosted.org/packages/8c/4d/17e07377c9c3d1a0c4eb3fde1c7c16b5a0ce6133ddbabc08ceef6b7f2645/torch-2.0.1-cp310-cp310-manylinux1_x86_64.whl", + "version": "2.0.1" + }, + "triton": { + "sha256": "38806ee9663f4b0f7cd64790e96c579374089e58f49aac4a6608121aa55e2505", + "type": "url", + "url": "https://files.pythonhosted.org/packages/ca/31/ff6be541195daf77aa5c72303b2354661a69e717967d44d91eb4f3fdce32/triton-2.0.0-1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", + "version": "2.0.0" + }, + "typing-extensions": { + "sha256": "440d5dd3af93b060174bf433bccd69b0babc3b15b1a8dca43789fd7f61514b36", + "type": "url", + "url": "https://files.pythonhosted.org/packages/ec/6b/63cc3df74987c36fe26157ee12e09e8f9db4de771e0f3404263117e75b95/typing_extensions-4.7.1-py3-none-any.whl", + "version": "4.7.1" + }, + "wheel": { + "sha256": "75909db2664838d015e3d9139004ee16711748a52c8f336b52882266540215d8", + "type": "url", + "url": "https://files.pythonhosted.org/packages/b8/8b/31273bf66016be6ad22bb7345c37ff350276cfd46e389a0c2ac5da9d9073/wheel-0.41.2-py3-none-any.whl", + "version": "0.41.2" + } + }, + "targets": { + "default": { + "cmake": [], + "filelock": [ + "typing-extensions" + ], + "jinja2": [ + "markupsafe" + ], + "joblib": [], + "lit": [], + "markupsafe": [], + "mpmath": [], + "networkx": [], + "numpy": [], + "nvidia-cublas-cu11": [ + "setuptools", + "wheel" + ], + "nvidia-cuda-cupti-cu11": [ + "setuptools", + "wheel" + ], + "nvidia-cuda-nvrtc-cu11": [], + "nvidia-cuda-runtime-cu11": [ + "setuptools", + "wheel" + ], + "nvidia-cudnn-cu11": [ + "nvidia-cublas-cu11" + ], + "nvidia-cufft-cu11": [], + "nvidia-curand-cu11": [ + "setuptools", + "wheel" + ], + "nvidia-cusolver-cu11": [ + "nvidia-cublas-cu11" + ], + "nvidia-cusparse-cu11": [ + "setuptools", + "wheel" + ], + "nvidia-nccl-cu11": [], + "nvidia-nvtx-cu11": [ + "setuptools", + "wheel" + ], + "pillow": [], + "scikit-learn": [ + "joblib", + "numpy", + "scipy", + "threadpoolctl" + ], + "scipy": [ + "numpy" + ], + "setuptools": [], + "sympy": [ + "mpmath" + ], + "threadpoolctl": [], + "torch": [ + "filelock", + "jinja2", + "networkx", + "nvidia-cublas-cu11", + "nvidia-cuda-cupti-cu11", + "nvidia-cuda-nvrtc-cu11", + "nvidia-cuda-runtime-cu11", + "nvidia-cudnn-cu11", + "nvidia-cufft-cu11", + "nvidia-curand-cu11", + "nvidia-cusolver-cu11", + "nvidia-cusparse-cu11", + "nvidia-nccl-cu11", + "nvidia-nvtx-cu11", + "sympy", + "triton", + "typing-extensions" + ], + "triton": [ + "cmake", + "filelock", + "lit" + ], + "typing-extensions": [], + "wheel": [] + } + } + } +} \ No newline at end of file diff --git a/examples/packages/single-language/python-machine-learning/pyproject.toml b/examples/packages/single-language/python-machine-learning/pyproject.toml new file mode 100644 index 0000000000..0263fdab3b --- /dev/null +++ b/examples/packages/single-language/python-machine-learning/pyproject.toml @@ -0,0 +1,14 @@ +[project] +name = "someproject" +version = "0.1.0" + +dependencies = [ + "pillow", + "scikit-learn", + "torch", +] + +[tool.setuptools.packages.find] +include = [ + "someproject", +] diff --git a/examples/packages/single-language/python-machine-learning/someproject/__index__.py b/examples/packages/single-language/python-machine-learning/someproject/__index__.py new file mode 100644 index 0000000000..e7cb4b33f6 --- /dev/null +++ b/examples/packages/single-language/python-machine-learning/someproject/__index__.py @@ -0,0 +1,5 @@ +import PIL +import sklearn +import torch + +print("hello world") diff --git a/modules/dream2nix/WIP-python-pyproject/default.nix b/modules/dream2nix/WIP-python-pyproject/default.nix new file mode 100644 index 0000000000..e69fc3ac2f --- /dev/null +++ b/modules/dream2nix/WIP-python-pyproject/default.nix @@ -0,0 +1,31 @@ +{ + dream2nix, + config, + lib, + ... +}: let + pyproject = + builtins.fromTOML + (builtins.readFile (config.mkDerivation.src + /pyproject.toml)); +in { + imports = [ + dream2nix.modules.dream2nix.pip + ]; + + mkDerivation = { + buildInputs = + pyproject.build-system.requires + or [config.deps.python.pkgs.setuptools]; + }; + + buildPythonPackage = { + format = "pyproject"; + pythonImportsCheck = pyproject.tool.setuptools.packages.find.include or []; + }; + + name = pyproject.project.name; + version = pyproject.project.version; + + pip.requirementsList = pyproject.project.dependencies; + pip.flattenDependencies = true; +} From f80d7426f6666906ba2db0638d6d589debfefb55 Mon Sep 17 00:00:00 2001 From: DavHau Date: Mon, 11 Sep 2023 23:32:53 +0200 Subject: [PATCH 09/70] fix(python-pyproject): remove default for pythonImportsCheck The heuristic was not reliable --- modules/dream2nix/WIP-python-pyproject/default.nix | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/dream2nix/WIP-python-pyproject/default.nix b/modules/dream2nix/WIP-python-pyproject/default.nix index e69fc3ac2f..7234db8046 100644 --- a/modules/dream2nix/WIP-python-pyproject/default.nix +++ b/modules/dream2nix/WIP-python-pyproject/default.nix @@ -20,7 +20,6 @@ in { buildPythonPackage = { format = "pyproject"; - pythonImportsCheck = pyproject.tool.setuptools.packages.find.include or []; }; name = pyproject.project.name; From 08d414a35952a665b8fe3d04d77864c13474fee4 Mon Sep 17 00:00:00 2001 From: DavHau Date: Tue, 12 Sep 2023 00:01:03 +0200 Subject: [PATCH 10/70] feat: community overrides - Add community overrides accessible via dream2nix.overrides.{lang}.{pname} - make the pip module use the overrides for dependencies --- .../python-machine-learning/default.nix | 15 +-------------- modules/dream2nix/pip/default.nix | 2 ++ modules/flake-parts/lib.nix | 1 + modules/flake-parts/overrides.nix | 13 +++++++++++++ overrides/python/torch/default.nix | 8 ++++++++ overrides/python/triton/default.nix | 12 ++++++++++++ 6 files changed, 37 insertions(+), 14 deletions(-) create mode 100644 modules/flake-parts/overrides.nix create mode 100644 overrides/python/torch/default.nix create mode 100644 overrides/python/triton/default.nix diff --git a/examples/packages/single-language/python-machine-learning/default.nix b/examples/packages/single-language/python-machine-learning/default.nix index 37c0da3e0b..0ba7221a9e 100644 --- a/examples/packages/single-language/python-machine-learning/default.nix +++ b/examples/packages/single-language/python-machine-learning/default.nix @@ -3,11 +3,7 @@ config, lib, ... -}: let - pyproject = - builtins.fromTOML - (builtins.readFile (config.mkDerivation.src + /pyproject.toml)); -in { +}: { imports = [ dream2nix.modules.dream2nix.WIP-python-pyproject ]; @@ -15,13 +11,4 @@ in { mkDerivation = { src = ./.; }; - - pip.drvs.triton.env.pythonRemoveDeps = [ - "torch" - ]; - pip.drvs.triton.mkDerivation.nativeBuildInputs = [ - config.deps.python.pkgs.pythonRelaxDepsHook - ]; - pip.drvs.torch.env.autoPatchelfIgnoreMissingDeps = ["libcuda.so.1"]; - pip.drvs.torch.mkDerivation.dontStrip = true; } diff --git a/modules/dream2nix/pip/default.nix b/modules/dream2nix/pip/default.nix index 674f7880e4..5b3faaaed4 100644 --- a/modules/dream2nix/pip/default.nix +++ b/modules/dream2nix/pip/default.nix @@ -31,6 +31,8 @@ imports = [ commonModule dependencyModule + # include community overrides + (dream2nix.overrides.python.${name} or {}) ]; config = { inherit name; diff --git a/modules/flake-parts/lib.nix b/modules/flake-parts/lib.nix index cfcbcf6e33..6db5b1e1e9 100644 --- a/modules/flake-parts/lib.nix +++ b/modules/flake-parts/lib.nix @@ -69,6 +69,7 @@ // { inherit packageSets; dream2nix.modules.dream2nix = self.modules.dream2nix; + dream2nix.overrides = self.overrides; dream2nix.lib.evalModules = self.lib.evalModules; }; } diff --git a/modules/flake-parts/overrides.nix b/modules/flake-parts/overrides.nix new file mode 100644 index 0000000000..88dfbca8f0 --- /dev/null +++ b/modules/flake-parts/overrides.nix @@ -0,0 +1,13 @@ +{self, ...}: let + overridesDir = self + "/overrides"; +in { + flake.overrides = + builtins.mapAttrs + ( + category: _type: + builtins.mapAttrs + (name: _type: overridesDir + "/${category}/${name}") + (builtins.readDir (overridesDir + "/${category}")) + ) + (builtins.readDir overridesDir); +} diff --git a/overrides/python/torch/default.nix b/overrides/python/torch/default.nix new file mode 100644 index 0000000000..7369bef596 --- /dev/null +++ b/overrides/python/torch/default.nix @@ -0,0 +1,8 @@ +{ + config, + lib, + ... +}: { + env.autoPatchelfIgnoreMissingDeps = ["libcuda.so.1"]; + mkDerivation.dontStrip = true; +} diff --git a/overrides/python/triton/default.nix b/overrides/python/triton/default.nix new file mode 100644 index 0000000000..1fa9b324ab --- /dev/null +++ b/overrides/python/triton/default.nix @@ -0,0 +1,12 @@ +{ + config, + lib, + ... +}: { + env.pythonRemoveDeps = [ + "torch" + ]; + mkDerivation.nativeBuildInputs = [ + config.deps.python.pkgs.pythonRelaxDepsHook + ]; +} From 2ab02224162d0dfac69e2d44c5e40e71793d485c Mon Sep 17 00:00:00 2001 From: DavHau Date: Tue, 12 Sep 2023 00:30:00 +0200 Subject: [PATCH 11/70] feat(ui): add .lock attribute This allows updating the lock file via `nix run .#{package}.lock` instead of ` nix run .#{package}.config.lock.refresh` This is better as it's shorter, and the keyword `lock` is widely understood to lock dependencies. --- modules/dream2nix/core/ui/default.nix | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/modules/dream2nix/core/ui/default.nix b/modules/dream2nix/core/ui/default.nix index 117f0696dd..c015527ca3 100644 --- a/modules/dream2nix/core/ui/default.nix +++ b/modules/dream2nix/core/ui/default.nix @@ -5,4 +5,10 @@ config.public.name = config.name; config.public.version = config.version; + config.public.${ + if config ? lock + then "lock" + else null + } = + config.lock.refresh; } From 740b89d71a52d4694fe6827951d0077097fc5652 Mon Sep 17 00:00:00 2001 From: DavHau Date: Tue, 12 Sep 2023 00:38:22 +0200 Subject: [PATCH 12/70] feat(ui): add .drvPath top-level attribute This allows building evaluated dream2nix modules directly via the nix CLI without having to reference `.public` --- modules/dream2nix/core/ui/default.nix | 2 ++ modules/dream2nix/core/ui/interface.nix | 14 ++++++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/modules/dream2nix/core/ui/default.nix b/modules/dream2nix/core/ui/default.nix index c015527ca3..29a8c234f3 100644 --- a/modules/dream2nix/core/ui/default.nix +++ b/modules/dream2nix/core/ui/default.nix @@ -11,4 +11,6 @@ else null } = config.lock.refresh; + config.type = "derivation"; + config.drvPath = config.public.drvPath; } diff --git a/modules/dream2nix/core/ui/interface.nix b/modules/dream2nix/core/ui/interface.nix index e16095f63d..3cbae71932 100644 --- a/modules/dream2nix/core/ui/interface.nix +++ b/modules/dream2nix/core/ui/interface.nix @@ -9,14 +9,14 @@ the `public` attrs, allowing users to reference name and version elsewhere via `${config.name}` instead of `${config.public.name}`. This is not only more convenient but currently also circumvents issues with - infinite recusions that can be triggered by referencing + infinite recursions that can be triggered by referencing `${config.public.name}`. The top-level of `public` contains an entry for each output, and is therefore dynamic. This makes `public` non-lazy as it requires evaluating `outputs` before it can be constructed. If `outputs` depend on the name and version of the package, which it might in IFD scenarios, then name and version itself cannot be read from - `public` without triggering an infinite recusion. + `public` without triggering an infinite recursion. This problem could be circumvented by removing the top-level output attrs from `public` as proposed in https://github.com/NixOS/nix/issues/6507#issuecomment-1474664755 . @@ -32,5 +32,15 @@ type = lib.types.str; description = "The version of the package"; }; + drvPath = lib.mkOption { + type = lib.types.path; + internal = true; + description = "The path to the derivation of the package"; + }; + type = lib.mkOption { + type = lib.types.str; + internal = true; + description = "The type attribute required by nix to identify derivations"; + }; }; } From 8d5178a6652178e260f34f6545b388bc4f157204 Mon Sep 17 00:00:00 2001 From: DavHau Date: Tue, 12 Sep 2023 01:06:44 +0200 Subject: [PATCH 13/70] fix(pip): set dontStrip for all dependencies Stripping is slow on large binary wheels and doesn't provide much benefit as it seems It also prevents some breakages that can occur after stripping. --- modules/dream2nix/pip/default.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/dream2nix/pip/default.nix b/modules/dream2nix/pip/default.nix index 5b3faaaed4..1a29acb1d4 100644 --- a/modules/dream2nix/pip/default.nix +++ b/modules/dream2nix/pip/default.nix @@ -85,6 +85,7 @@ mkDerivation = { src = l.mkDefault (fetchers.${metadata.sources.${config.name}.type} metadata.sources.${config.name}); doCheck = l.mkDefault false; + dontStrip = l.mkDefault true; nativeBuildInputs = [config.deps.unzip] @@ -142,7 +143,6 @@ in { }; mkDerivation = { - dontStrip = l.mkDefault true; propagatedBuildInputs = let rootDeps = lib.filterAttrs (_: x: x == true) cfg.rootDependencies; in From 77eeb06927e94bc196444fcee2d08a20514443a3 Mon Sep 17 00:00:00 2001 From: DavHau Date: Wed, 13 Sep 2023 00:01:25 +0200 Subject: [PATCH 14/70] feat(overlays/torch): add /run/opengl-driver/lib to RPATH This allows resolving libcuda.so.1 --- overrides/python/torch/default.nix | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/overrides/python/torch/default.nix b/overrides/python/torch/default.nix index 7369bef596..e124763775 100644 --- a/overrides/python/torch/default.nix +++ b/overrides/python/torch/default.nix @@ -3,6 +3,15 @@ lib, ... }: { - env.autoPatchelfIgnoreMissingDeps = ["libcuda.so.1"]; + # stripping doesn't reduce the file size much, and it takes a long time mkDerivation.dontStrip = true; + + # this file is patched manually, so ignore it in autoPatchelf + env.autoPatchelfIgnoreMissingDeps = ["libcuda.so.1"]; + # patch the rpath so libcuda.so.1 can be found at /run/opengl-driver/lib + env.cudaPatchPhase = '' + patchelf $out/${config.deps.python.sitePackages}/torch/lib/libcaffe2_nvrtc.so \ + --add-rpath /run/opengl-driver/lib + ''; + mkDerivation.postPhases = ["cudaPatchPhase"]; } From 19bfd98a971770c03eb957a550cfff27e41569c9 Mon Sep 17 00:00:00 2001 From: DavHau Date: Wed, 13 Sep 2023 13:50:19 +0200 Subject: [PATCH 15/70] fix(overlays/torch): use autoAddOpenGLRunpathHook --- overrides/python/torch/default.nix | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/overrides/python/torch/default.nix b/overrides/python/torch/default.nix index e124763775..97676fd378 100644 --- a/overrides/python/torch/default.nix +++ b/overrides/python/torch/default.nix @@ -6,12 +6,15 @@ # stripping doesn't reduce the file size much, and it takes a long time mkDerivation.dontStrip = true; + # use the autoAddOpenGLRunpathHook to add /run/opengl-driver/lib to the RPATH + # of all ELF files + deps = {nixpkgs, ...}: { + inherit (nixpkgs.cudaPackages) autoAddOpenGLRunpathHook; + }; + mkDerivation.nativeBuildInputs = [ + config.deps.autoAddOpenGLRunpathHook + ]; + # this file is patched manually, so ignore it in autoPatchelf env.autoPatchelfIgnoreMissingDeps = ["libcuda.so.1"]; - # patch the rpath so libcuda.so.1 can be found at /run/opengl-driver/lib - env.cudaPatchPhase = '' - patchelf $out/${config.deps.python.sitePackages}/torch/lib/libcaffe2_nvrtc.so \ - --add-rpath /run/opengl-driver/lib - ''; - mkDerivation.postPhases = ["cudaPatchPhase"]; } From 9cc6f02d94f21f0a65a21a78c8c1effac1739bf7 Mon Sep 17 00:00:00 2001 From: DavHau Date: Thu, 14 Sep 2023 10:55:20 +0200 Subject: [PATCH 16/70] feat(lock): lock file invalidation via lock.invalidationData --- .../python-machine-learning/default.nix | 4 + modules/dream2nix/core/lock/default.nix | 32 ++++++- modules/dream2nix/core/lock/interface.nix | 14 +++ modules/dream2nix/pip/default.nix | 88 +++++++++++-------- 4 files changed, 98 insertions(+), 40 deletions(-) diff --git a/examples/packages/single-language/python-machine-learning/default.nix b/examples/packages/single-language/python-machine-learning/default.nix index 0ba7221a9e..1fd0fc7233 100644 --- a/examples/packages/single-language/python-machine-learning/default.nix +++ b/examples/packages/single-language/python-machine-learning/default.nix @@ -11,4 +11,8 @@ mkDerivation = { src = ./.; }; + + # This is not strictly required, but setting it will keep most dependencies + # locked, even when new dependencies are added via pyproject.toml + pip.pypiSnapshotDate = "2023-09-12"; } diff --git a/modules/dream2nix/core/lock/default.nix b/modules/dream2nix/core/lock/default.nix index 76de7911b7..6c212cf805 100644 --- a/modules/dream2nix/core/lock/default.nix +++ b/modules/dream2nix/core/lock/default.nix @@ -16,6 +16,9 @@ then removeLockFileScript else refresh'; + invalidationHashCurrent = l.hashString "sha256" (l.toJSON cfg.invalidationData); + invalidationHashLocked = fileContent.invalidationHash or null; + # script to remove the lock file if no fields are defined removeLockFileScript = config.deps.writePython3Bin "refresh" {} '' import os @@ -71,6 +74,11 @@ lock_data = run_refresh_scripts(refresh_scripts) + # error out if invalidation hash is already present + if "invalidationHash" in lock_data: + raise Exception("invalidationHash already present in lock file") + else: + lock_data["invalidationHash"] = "${invalidationHashCurrent}" # noqa: E501 with open(lock_path, 'w') as out_file: json.dump(lock_data, out_file, indent=2) print(f"lock file written to {out_file.name}") @@ -138,7 +146,20 @@ nix run -L .#${config.name}.config.lock.refresh ''; - errorOutdated = field: '' + errorOutdated = '' + The lock file ${config.paths.package}/${config.paths.lockFile} + for drv-parts module '${config.name}' is outdated. + + To update it without flakes: + + bash -c $(nix-build ${config.lock.refresh.drvPath} --no-link)/bin/refresh + + To update it using flakes: + + nix run -L .#${config.name}.config.lock.refresh + ''; + + errorOutdatedField = field: '' The lock file ${config.paths.package}/${config.paths.lockFile} for drv-parts module '${config.name}' does not contain field `${field}`. @@ -158,7 +179,12 @@ else data; loadField = field: val: - if + # This first check is generic to the whole lock file but put here under + # loadField to make evaluation a bit lazier and not crash if paths.XXX + # is not set + if invalidationHashCurrent != invalidationHashLocked + then throw errorOutdated + else if # load the default value (if specified) whenever the field is not found in # the lock file or the lock file doesn't exist. (cfg.fields.${field}.default != null) @@ -166,7 +192,7 @@ then cfg.fields.${field}.default else if fileContent ? ${field} then fileContent.${field} - else throw (errorOutdated field); + else throw (errorOutdatedField field); loadedContent = l.mapAttrs loadField cfg.fields; in { diff --git a/modules/dream2nix/core/lock/interface.nix b/modules/dream2nix/core/lock/interface.nix index 3fd390c767..f9a5bcf0ce 100644 --- a/modules/dream2nix/core/lock/interface.nix +++ b/modules/dream2nix/core/lock/interface.nix @@ -48,6 +48,20 @@ in { }; }; + invalidationData = l.mkOption { + type = t.anything; + description = '' + Pass any data that should invalidate the lock file when changed. + This is useful for example when the lock file should be regenerated + when the requirements change. + ''; + default = {}; + example = { + pip.requirements = ["requests" "pillow"]; + pip.lockVersion = "2"; + }; + }; + refresh = l.mkOption { type = t.package; description = "Script to refresh the cache file of this package"; diff --git a/modules/dream2nix/pip/default.nix b/modules/dream2nix/pip/default.nix index 1a29acb1d4..7f940247dd 100644 --- a/modules/dream2nix/pip/default.nix +++ b/modules/dream2nix/pip/default.nix @@ -113,50 +113,64 @@ in { ../pip-hotfixes ]; - config = { - deps = {nixpkgs, ...}: - l.mapAttrs (_: l.mkOverride 1002) { - # This is imported directly instead of depending on dream2nix.packages - # with the intention to keep modules independent. - fetchPipMetadataScript = import ../../../pkgs/fetchPipMetadata/script.nix { - inherit lib; - inherit (cfg) pypiSnapshotDate pipFlags pipVersion requirementsList requirementsFiles nativeBuildInputs; - inherit (config.deps) writePureShellScript nix; - inherit (config.paths) findRoot; - inherit (nixpkgs) gitMinimal nix-prefetch-scripts python3 writeText; - pythonInterpreter = "${python}/bin/python"; - }; - setuptools = config.deps.python.pkgs.setuptools; - inherit (nixpkgs) nix fetchgit; - inherit (writers) writePureShellScript; + deps = {nixpkgs, ...}: + l.mapAttrs (_: l.mkOverride 1002) { + # This is imported directly instead of depending on dream2nix.packages + # with the intention to keep modules independent. + fetchPipMetadataScript = import ../../../pkgs/fetchPipMetadata/script.nix { + inherit lib; + inherit (cfg) pypiSnapshotDate pipFlags pipVersion requirementsList requirementsFiles nativeBuildInputs; + inherit (config.deps) writePureShellScript nix; + inherit (config.paths) findRoot; + inherit (nixpkgs) gitMinimal nix-prefetch-scripts python3 writeText; + pythonInterpreter = "${python}/bin/python"; }; - - # Keep package metadata fetched by Pip in our lockfile - lock.fields.fetchPipMetadata = { - script = config.deps.fetchPipMetadataScript; + setuptools = config.deps.python.pkgs.setuptools; + inherit (nixpkgs) nix fetchgit; + inherit (writers) writePureShellScript; }; + # Keep package metadata fetched by Pip in our lockfile + lock.fields.fetchPipMetadata = { + script = config.deps.fetchPipMetadataScript; + }; + + # if any of the invalidationData changes, the lock file will be invalidated + # and the user will be promted to re-generate it. + lock.invalidationData = { pip = { - drvs = drvs; - rootDependencies = - l.genAttrs (targets.default.${config.name} or []) (_: true); + inherit + (config.pip) + pypiSnapshotDate + pipFlags + pipVersion + requirementsList + requirementsFiles + ; + pythonVersion = config.deps.python.version; }; + }; - mkDerivation = { - propagatedBuildInputs = let - rootDeps = lib.filterAttrs (_: x: x == true) cfg.rootDependencies; - in - l.attrValues (l.mapAttrs (name: _: cfg.drvs.${name}.public.out) rootDeps); - }; + pip = { + drvs = drvs; + rootDependencies = + l.genAttrs (targets.default.${config.name} or []) (_: true); + }; - public.devShell = let - pyEnv' = config.deps.python.withPackages (ps: config.mkDerivation.propagatedBuildInputs); - pyEnv = pyEnv'.override (old: { - # namespaced packages are triggering a collision error, but this can be - # safely ignored. They are still set up correctly and can be imported. - ignoreCollisions = true; - }); + mkDerivation = { + propagatedBuildInputs = let + rootDeps = lib.filterAttrs (_: x: x == true) cfg.rootDependencies; in - pyEnv.env; + l.attrValues (l.mapAttrs (name: _: cfg.drvs.${name}.public.out) rootDeps); }; + + public.devShell = let + pyEnv' = config.deps.python.withPackages (ps: config.mkDerivation.propagatedBuildInputs); + pyEnv = pyEnv'.override (old: { + # namespaced packages are triggering a collision error, but this can be + # safely ignored. They are still set up correctly and can be imported. + ignoreCollisions = true; + }); + in + pyEnv.env; } From a68165d109c440d72bc2fd08d6714adba461eb99 Mon Sep 17 00:00:00 2001 From: DavHau Date: Thu, 14 Sep 2023 10:57:03 +0200 Subject: [PATCH 17/70] chore: update lock files --- examples/packages/multi-language/python-nodejs/lock.json | 3 ++- examples/packages/single-language/nodejs-project/lock.json | 3 ++- .../packages/single-language/python-machine-learning/lock.json | 3 ++- .../packages/single-language/python-package-ansible/lock.json | 3 ++- .../single-language/python-package-apache-airflow/lock.json | 3 ++- .../packages/single-language/python-package-odoo/lock.json | 3 ++- .../packages/single-language/python-package-pillow/lock.json | 3 ++- examples/packages/single-language/python-project/lock.json | 3 ++- 8 files changed, 16 insertions(+), 8 deletions(-) diff --git a/examples/packages/multi-language/python-nodejs/lock.json b/examples/packages/multi-language/python-nodejs/lock.json index b6d88be13a..686af6e86d 100644 --- a/examples/packages/multi-language/python-nodejs/lock.json +++ b/examples/packages/multi-language/python-nodejs/lock.json @@ -118,5 +118,6 @@ ] } } - } + }, + "invalidationHash": "88ef7315dd6761484615891a36ac41cef9a468d66b41f78fecada9eee4c2eb7b" } \ No newline at end of file diff --git a/examples/packages/single-language/nodejs-project/lock.json b/examples/packages/single-language/nodejs-project/lock.json index 69f87051d9..75665c40de 100644 --- a/examples/packages/single-language/nodejs-project/lock.json +++ b/examples/packages/single-language/nodejs-project/lock.json @@ -33,5 +33,6 @@ "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==" } } - } + }, + "invalidationHash": "44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a" } \ No newline at end of file diff --git a/examples/packages/single-language/python-machine-learning/lock.json b/examples/packages/single-language/python-machine-learning/lock.json index 6f04ac21c9..3d2792e971 100644 --- a/examples/packages/single-language/python-machine-learning/lock.json +++ b/examples/packages/single-language/python-machine-learning/lock.json @@ -273,5 +273,6 @@ "wheel": [] } } - } + }, + "invalidationHash": "0dde05ce6fe84aa4050708598e01eb4b80bdb95f3d74b895bfb024152a6415ed" } \ No newline at end of file diff --git a/examples/packages/single-language/python-package-ansible/lock.json b/examples/packages/single-language/python-package-ansible/lock.json index 8d9ef60540..97a6a5b3a8 100644 --- a/examples/packages/single-language/python-package-ansible/lock.json +++ b/examples/packages/single-language/python-package-ansible/lock.json @@ -109,5 +109,6 @@ "six": [] } } - } + }, + "invalidationHash": "5c89fed9d7831a0b738a50203de0f8add46cd9f7c96c1a32cd8cc27569184039" } \ No newline at end of file diff --git a/examples/packages/single-language/python-package-apache-airflow/lock.json b/examples/packages/single-language/python-package-apache-airflow/lock.json index 59535e76f7..9ee24bb751 100644 --- a/examples/packages/single-language/python-package-apache-airflow/lock.json +++ b/examples/packages/single-language/python-package-apache-airflow/lock.json @@ -1011,5 +1011,6 @@ ] } } - } + }, + "invalidationHash": "53b88919c16e4602cb847118509df402e5f13158b99da1e16d6038b0242acf4f" } \ No newline at end of file diff --git a/examples/packages/single-language/python-package-odoo/lock.json b/examples/packages/single-language/python-package-odoo/lock.json index 1f3eb4fc03..6317705e1b 100644 --- a/examples/packages/single-language/python-package-odoo/lock.json +++ b/examples/packages/single-language/python-package-odoo/lock.json @@ -506,5 +506,6 @@ ] } } - } + }, + "invalidationHash": "ab37933821f7fe9c689ce6d206aaf64e1c120b7756c502d94de335b7e4ce31df" } \ No newline at end of file diff --git a/examples/packages/single-language/python-package-pillow/lock.json b/examples/packages/single-language/python-package-pillow/lock.json index 1854d70fa4..b5d61d09cb 100644 --- a/examples/packages/single-language/python-package-pillow/lock.json +++ b/examples/packages/single-language/python-package-pillow/lock.json @@ -13,5 +13,6 @@ "pillow": [] } } - } + }, + "invalidationHash": "ab0a30714d5a0794ad6b0376fd8dd1f61a46268c612afbaa8c3d1ca396d21c6c" } \ No newline at end of file diff --git a/examples/packages/single-language/python-project/lock.json b/examples/packages/single-language/python-project/lock.json index 7c5640e4ff..2fdb2ddb0e 100644 --- a/examples/packages/single-language/python-project/lock.json +++ b/examples/packages/single-language/python-project/lock.json @@ -53,5 +53,6 @@ "urllib3": [] } } - } + }, + "invalidationHash": "ddf895d24e90c9aa98175e398910ccffeb68c1f9a886729261695e81b8e1d82c" } \ No newline at end of file From 8d1dbd0e1f914ae42026d5df2f04499128533648 Mon Sep 17 00:00:00 2001 From: DavHau Date: Thu, 14 Sep 2023 11:37:36 +0200 Subject: [PATCH 18/70] fix(lock): remove flakes command from error The suggested copy paste attribute path is often wrong as it depends on the individual repository setup that dream2nix doesn't control. Instead now simply hint to `nix run` the .lock attribute --- modules/dream2nix/core/lock/default.nix | 33 +++++++++---------------- 1 file changed, 11 insertions(+), 22 deletions(-) diff --git a/modules/dream2nix/core/lock/default.nix b/modules/dream2nix/core/lock/default.nix index 6c212cf805..5d1c7af36e 100644 --- a/modules/dream2nix/core/lock/default.nix +++ b/modules/dream2nix/core/lock/default.nix @@ -133,44 +133,33 @@ json.dump(checksum, f, indent=2) ''; - errorMissingFile = '' - The lock file ${config.paths.package}/${config.paths.lockFile} - for drv-parts module '${config.name}' is missing. - - To update it without flakes: + updateHint = '' + To create or update the lock file, run: bash -c $(nix-build ${config.lock.refresh.drvPath} --no-link)/bin/refresh - To update it using flakes: + Alternatively `nix run` the .lock attribute of your package. + ''; + + errorMissingFile = '' + The lock file ${config.paths.package}/${config.paths.lockFile} + for drv-parts module '${config.name}' is missing. - nix run -L .#${config.name}.config.lock.refresh + ${updateHint} ''; errorOutdated = '' The lock file ${config.paths.package}/${config.paths.lockFile} for drv-parts module '${config.name}' is outdated. - To update it without flakes: - - bash -c $(nix-build ${config.lock.refresh.drvPath} --no-link)/bin/refresh - - To update it using flakes: - - nix run -L .#${config.name}.config.lock.refresh + ${updateHint} ''; errorOutdatedField = field: '' The lock file ${config.paths.package}/${config.paths.lockFile} for drv-parts module '${config.name}' does not contain field `${field}`. - To update it without flakes: - - bash -c $(nix-build ${config.lock.refresh.drvPath} --no-link)/bin/refresh - - To update it using flakes: - - nix run -L .#${config.name}.config.lock.refresh - + ${updateHint} ''; fileContent = From 7a07ef5a41aca52210a545d9a75e46d8fb57ceb7 Mon Sep 17 00:00:00 2001 From: DavHau Date: Thu, 14 Sep 2023 13:46:29 +0200 Subject: [PATCH 19/70] refactor(lock): introduce mkLazy This seems like a cleaner way to make the value for lock.content more lazy and not trigger errors because paths.XXX is not set in unit tests --- modules/dream2nix/core/lock/default.nix | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/modules/dream2nix/core/lock/default.nix b/modules/dream2nix/core/lock/default.nix index 5d1c7af36e..4d820a4285 100644 --- a/modules/dream2nix/core/lock/default.nix +++ b/modules/dream2nix/core/lock/default.nix @@ -168,12 +168,7 @@ else data; loadField = field: val: - # This first check is generic to the whole lock file but put here under - # loadField to make evaluation a bit lazier and not crash if paths.XXX - # is not set - if invalidationHashCurrent != invalidationHashLocked - then throw errorOutdated - else if + if # load the default value (if specified) whenever the field is not found in # the lock file or the lock file doesn't exist. (cfg.fields.${field}.default != null) @@ -183,7 +178,16 @@ then fileContent.${field} else throw (errorOutdatedField field); - loadedContent = l.mapAttrs loadField cfg.fields; + loadedContent = + if invalidationHashCurrent != invalidationHashLocked + then throw errorOutdated + else l.mapAttrs loadField cfg.fields; + + # makes a value more lazy to the module system, so it can be overridden + # without the original value being evaluated. + mkLazy = + lib.mkOverride + (lib.modules.defaultOverridePriority or lib.modules.defaultPriority); in { imports = [ ./interface.nix @@ -192,7 +196,7 @@ in { config = { lock.refresh = refresh; - lock.content = loadedContent; + lock.content = mkLazy loadedContent; lock.lib = {inherit computeFODHash;}; From 398fd949e1ecf210e080d175c9ddda53b17f1bf9 Mon Sep 17 00:00:00 2001 From: DavHau Date: Thu, 14 Sep 2023 17:04:06 +0200 Subject: [PATCH 20/70] fix(pip): don't set addAutoPatchelfSearchPath on darwin --- modules/dream2nix/pip/default.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/dream2nix/pip/default.nix b/modules/dream2nix/pip/default.nix index 7f940247dd..54c10f0834 100644 --- a/modules/dream2nix/pip/default.nix +++ b/modules/dream2nix/pip/default.nix @@ -94,7 +94,7 @@ l.optionals config.deps.stdenv.isLinux [config.deps.manylinux1]; # This is required for autoPatchelfHook to find .so files from other # python dependencies, like for example libcublas.so.11 from nvidia-cublas-cu11. - preFixup = '' + preFixup = lib.optionalString config.deps.stdenv.isLinux '' addAutoPatchelfSearchPath ${toString (config.mkDerivation.propagatedBuildInputs)} ''; propagatedBuildInputs = let From 5a729cb75ae914b2e97114e1c0e9280953b7b488 Mon Sep 17 00:00:00 2001 From: Jairo Llopis Date: Wed, 13 Sep 2023 11:11:45 +0100 Subject: [PATCH 21/70] docs: simplify python project example Use `lib.importTOML`, clearer than the previous implementation. Reuse more information from `pyproject`. --- .../single-language/python-project/default.nix | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/examples/packages/single-language/python-project/default.nix b/examples/packages/single-language/python-project/default.nix index 89c9aa04cd..3118078145 100644 --- a/examples/packages/single-language/python-project/default.nix +++ b/examples/packages/single-language/python-project/default.nix @@ -5,17 +5,13 @@ dream2nix, ... }: let - pyproject = lib.pipe (config.mkDerivation.src + /pyproject.toml) [ - builtins.readFile - builtins.fromTOML - ]; + pyproject = lib.importTOML (config.mkDerivation.src + /pyproject.toml); in { imports = [ dream2nix.modules.dream2nix.pip ]; - name = "pyproject-dependencies"; - version = pyproject.project.version; + inherit (pyproject.project) name version; mkDerivation = { src = ./.; @@ -30,7 +26,10 @@ in { pip = { pypiSnapshotDate = "2023-08-27"; - requirementsList = ["setuptools"] ++ pyproject.project.dependencies; + requirementsList = + pyproject.build-system.requires + or [] + ++ pyproject.project.dependencies; flattenDependencies = true; }; } From 599a42d2479d39219f4ce514c59ec45f31e994ff Mon Sep 17 00:00:00 2001 From: Yusuf Bera Ertan Date: Sun, 17 Sep 2023 09:37:51 +0000 Subject: [PATCH 22/70] refactor: update rust-package example to latest changes (#685) --- examples/packages/single-language/rust-package/default.nix | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/examples/packages/single-language/rust-package/default.nix b/examples/packages/single-language/rust-package/default.nix index 3fb448c580..8011839bb2 100644 --- a/examples/packages/single-language/rust-package/default.nix +++ b/examples/packages/single-language/rust-package/default.nix @@ -16,6 +16,7 @@ name = lib.mkForce "ripgrep"; version = lib.mkForce "13.0.0"; + # options defined on top-level will be applied to the main derivation (the derivation that is exposed) mkDerivation = { # define the source root that contains the package we want to build. src = config.deps.fetchFromGitHub { @@ -24,13 +25,14 @@ rev = config.version; sha256 = "sha256-udEh+Re2PeO3DnX4fQThsaT1Y3MBHFfrX5Q5EN2XrF0="; }; - # note: any more options defined here will be applied to both - # `config.mkDerivation` and `config.depsDrv.mkDerivation`. }; rust-crane = { buildProfile = "dev"; buildFlags = ["--verbose"]; runTests = false; + depsDrv = { + # options defined here will be applied to the dependencies derivation + }; }; } From fbefb96a8174f60d672bc6a59222272e42ff09f7 Mon Sep 17 00:00:00 2001 From: DavHau Date: Sun, 17 Sep 2023 15:28:26 +0200 Subject: [PATCH 23/70] templates: remove v1-python template This is already covered in examples and all examples are exported as templates already --- flake.nix | 1 - templates/default.nix | 14 ----- templates/v1-python/default.nix | 33 ------------ .../my-package-x86_64-linux-lock.json | 54 ------------------- templates/v1-python/my-package.nix | 48 ----------------- templates/v1-python/my_package/__init__.py | 12 ----- templates/v1-python/pyproject.toml | 15 ------ templates/v1-python/requirements.txt | 4 -- 8 files changed, 181 deletions(-) delete mode 100644 templates/default.nix delete mode 100644 templates/v1-python/default.nix delete mode 100644 templates/v1-python/my-package-x86_64-linux-lock.json delete mode 100644 templates/v1-python/my-package.nix delete mode 100644 templates/v1-python/my_package/__init__.py delete mode 100644 templates/v1-python/pyproject.toml delete mode 100644 templates/v1-python/requirements.txt diff --git a/flake.nix b/flake.nix index 98f6813f9a..6355e57522 100644 --- a/flake.nix +++ b/flake.nix @@ -150,7 +150,6 @@ in flake-parts.lib.mkFlake {inherit inputs;} { imports = [ - ./templates ./modules/flake-parts/all-modules.nix ./pkgs/fetchPipMetadata/flake-module.nix ]; diff --git a/templates/default.nix b/templates/default.nix deleted file mode 100644 index ea286a05c1..0000000000 --- a/templates/default.nix +++ /dev/null @@ -1,14 +0,0 @@ -{ - lib, - self, - ... -}: let - l = lib // builtins; -in { - flake = { - v1-python = { - description = "Simple dream2nix python project"; - path = ./v1-python; - }; - }; -} diff --git a/templates/v1-python/default.nix b/templates/v1-python/default.nix deleted file mode 100644 index 7b12d406ed..0000000000 --- a/templates/v1-python/default.nix +++ /dev/null @@ -1,33 +0,0 @@ -let - # import dream2nix - dream2nix = import (builtins.fetchTarball "https://github.com/nix-community/dream2nix/tarball/main"); - - # A setup module which is imported for each package. - # This is used to define the location and naming of dream2nix lock files. - # TODO: modify this according to your repo structure - setupModule = {config, ...}: { - # Define the root of your repo. All other paths are relative to it. - lock.projectRoot = ./.; - - # define how a specific lock file should be called - # This definition will produce lock files like: - # my-package-x86_64-linux-lock.json - paths.package = "."; - paths.lockFile = "/${config.name}-${config.deps.stdenv.system}-lock.json"; - }; - - # evaluate package module - my-package = dream2nix.lib.evalModules { - # define external package sets - packageSets = { - nixpkgs = import {}; - }; - - # load the actual package module - modules = [ - ./my-package.nix - setupModule - ]; - }; -in - my-package diff --git a/templates/v1-python/my-package-x86_64-linux-lock.json b/templates/v1-python/my-package-x86_64-linux-lock.json deleted file mode 100644 index 5a8bcccdc3..0000000000 --- a/templates/v1-python/my-package-x86_64-linux-lock.json +++ /dev/null @@ -1,54 +0,0 @@ -{ - "fetchPipMetadata": { - "asgiref": { - "dependencies": [], - "sha256": "71e68008da809b957b7ee4b43dbccff33d1b23519fb8344e33f049897077afac", - "url": "https://files.pythonhosted.org/packages/8f/29/38d10a47b322a77b2d12c2b79c789f52956f733cb701d4d5157c76b5f238/asgiref-3.6.0-py3-none-any.whl", - "version": "3.6.0" - }, - "django": { - "dependencies": [ - "asgiref", - "sqlparse" - ], - "sha256": "ad33ed68db9398f5dfb33282704925bce044bef4261cd4fb59e4e7f9ae505a78", - "url": "https://files.pythonhosted.org/packages/d9/40/6012f98b14b64b4d3dc47b0c2f116fccbd0795ab35515d0c40dac73b81b8/Django-4.2-py3-none-any.whl", - "version": "4.2" - }, - "lxml": { - "dependencies": [], - "sha256": "1ab8f1f932e8f82355e75dda5413a57612c6ea448069d4fb2e217e9a4bed13d4", - "url": "https://files.pythonhosted.org/packages/89/9c/be3ebeb6053c6625c0497f282e0d8acc36c309212d47201e9cb1198ffb54/lxml-4.9.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", - "version": "4.9.2" - }, - "my-package": { - "dependencies": [ - "django", - "lxml", - "psycopg2", - "setuptools" - ], - "sha256": null, - "url": ".", - "version": "0.0.0" - }, - "psycopg2": { - "dependencies": [], - "sha256": "f15158418fd826831b28585e2ab48ed8df2d0d98f502a2b4fe619e7d5ca29011", - "url": "https://files.pythonhosted.org/packages/af/c4/5726cddb53fe52f0e839eb3da04322364f14493217ebd5818cc5e4c948a5/psycopg2-2.9.6.tar.gz", - "version": "2.9.6" - }, - "setuptools": { - "dependencies": [], - "sha256": "23aaf86b85ca52ceb801d32703f12d77517b2556af839621c641fca11287952b", - "url": "https://files.pythonhosted.org/packages/2f/8c/f336a966d4097c7cef6fc699b2ecb83b5fb63fd698198c1b5c7905a74f0f/setuptools-67.7.2-py3-none-any.whl", - "version": "67.7.2" - }, - "sqlparse": { - "dependencies": [], - "sha256": "5430a4fe2ac7d0f93e66f1efc6e1338a41884b7ddf2a350cedd20ccc4d9d28f3", - "url": "https://files.pythonhosted.org/packages/98/5a/66d7c9305baa9f11857f247d4ba761402cea75db6058ff850ed7128957b7/sqlparse-0.4.4-py3-none-any.whl", - "version": "0.4.4" - } - } -} \ No newline at end of file diff --git a/templates/v1-python/my-package.nix b/templates/v1-python/my-package.nix deleted file mode 100644 index 91757b6438..0000000000 --- a/templates/v1-python/my-package.nix +++ /dev/null @@ -1,48 +0,0 @@ -{ - config, - lib, - dream2nix, - ... -}: { - imports = [ - dream2nix.modules.dream2nix.pip - ]; - - name = "my-package"; - version = "1.0"; - - mkDerivation = { - src = ./.; - }; - - deps = {nixpkgs, ...}: { - inherit - (nixpkgs) - postgresql - stdenv - ; - python = nixpkgs.python310; - }; - - buildPythonPackage = { - format = "pyproject"; - }; - - pip = { - pypiSnapshotDate = "2023-05-03"; - - # pass the current directory as a requirement to pip which will then resolve - # all other requirements via the `dependencies` from pyproject.toml. - requirementsList = ["."]; - - # creating the lock file otherwise fails on psycopg2 - nativeBuildInputs = [config.deps.postgresql]; - - # fix some builds via overrides - drvs = { - psycopg2.mkDerivation = { - nativeBuildInputs = [config.deps.postgresql]; - }; - }; - }; -} diff --git a/templates/v1-python/my_package/__init__.py b/templates/v1-python/my_package/__init__.py deleted file mode 100644 index 3e78f602ca..0000000000 --- a/templates/v1-python/my_package/__init__.py +++ /dev/null @@ -1,12 +0,0 @@ -import django -import lxml -import psycopg2 - -__version__ = "1.0" - - -def hello(): - print(f"{__file__}: Hello world!") - print(f"{django.get_version()=}") - print(f"{lxml.__version__=}") - print(f"{psycopg2.__version__=}") diff --git a/templates/v1-python/pyproject.toml b/templates/v1-python/pyproject.toml deleted file mode 100644 index eb64d628d8..0000000000 --- a/templates/v1-python/pyproject.toml +++ /dev/null @@ -1,15 +0,0 @@ -[project] -name = "my_package" -description = "my_package" -requires-python = "~=3.10" -dynamic = ["version", "dependencies"] - -[project.scripts] -hello = "my_package:hello" - -[build-system] -requires = ["setuptools"] -build-backend = "setuptools.build_meta" - -[tool.setuptools.dynamic] -dependencies = {file = ["requirements.txt"]} diff --git a/templates/v1-python/requirements.txt b/templates/v1-python/requirements.txt deleted file mode 100644 index b1da69dfa2..0000000000 --- a/templates/v1-python/requirements.txt +++ /dev/null @@ -1,4 +0,0 @@ -django -lxml -psycopg2 -setuptools From d6f2f567ad1120e0f4327726ae8194bc2f48b783 Mon Sep 17 00:00:00 2001 From: Yusuf Bera Ertan Date: Mon, 18 Sep 2023 00:01:48 +0000 Subject: [PATCH 24/70] fix(rust-crane): actually pull craneSource from config.deps (#688) --- modules/dream2nix/rust-crane/default.nix | 71 ++++++++++++------------ 1 file changed, 37 insertions(+), 34 deletions(-) diff --git a/modules/dream2nix/rust-crane/default.nix b/modules/dream2nix/rust-crane/default.nix index b08b47cecf..95bd0bc16b 100644 --- a/modules/dream2nix/rust-crane/default.nix +++ b/modules/dream2nix/rust-crane/default.nix @@ -79,16 +79,11 @@ crane = import ./crane.nix { inherit lib; - craneSource = config.deps.fetchFromGitHub { - owner = "ipetkov"; - repo = "crane"; - rev = "v0.12.2"; - sha256 = "sha256-looLH5MdY4erLiJw0XwQohGdr0fJL9y6TJY3898RA2U="; - }; inherit (config.deps) stdenv cargo + craneSource jq zstd remarshal @@ -218,32 +213,40 @@ in { }; deps = {nixpkgs, ...}: - (l.mapAttrs (_: l.mkDefault) { - cargo = nixpkgs.cargo; - }) - # maybe it would be better to put these under `options.rust-crane.deps` instead of this `deps` - # since it conflicts with a lot of stuff? - // (l.mapAttrs (_: l.mkOverride 999) { - inherit - (nixpkgs) - stdenv - fetchurl - jq - zstd - remarshal - moreutils - python3Packages - makeSetupHook - runCommandLocal - runCommand - writeText - fetchFromGitHub - libiconv - mkShell - ; - inherit - (nixpkgs.writers) - writePython3 - ; - }); + l.mkMerge [ + (l.mapAttrs (_: l.mkDefault) { + cargo = nixpkgs.cargo; + craneSource = config.deps.fetchFromGitHub { + owner = "ipetkov"; + repo = "crane"; + rev = "v0.12.2"; + sha256 = "sha256-looLH5MdY4erLiJw0XwQohGdr0fJL9y6TJY3898RA2U="; + }; + }) + # maybe it would be better to put these under `options.rust-crane.deps` instead of this `deps` + # since it conflicts with a lot of stuff? + (l.mapAttrs (_: l.mkOverride 999) { + inherit + (nixpkgs) + stdenv + fetchurl + jq + zstd + remarshal + moreutils + python3Packages + makeSetupHook + runCommandLocal + runCommand + writeText + fetchFromGitHub + libiconv + mkShell + ; + inherit + (nixpkgs.writers) + writePython3 + ; + }) + ]; } From 40b65e4598e249af6cc285259c1c0afefbb0f420 Mon Sep 17 00:00:00 2001 From: Yusuf Bera Ertan Date: Mon, 18 Sep 2023 00:08:54 +0000 Subject: [PATCH 25/70] fix(rust-crane): use crane functions from config.deps.crane options (#689) --- modules/dream2nix/rust-crane/default.nix | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/modules/dream2nix/rust-crane/default.nix b/modules/dream2nix/rust-crane/default.nix index 95bd0bc16b..0e624208ad 100644 --- a/modules/dream2nix/rust-crane/default.nix +++ b/modules/dream2nix/rust-crane/default.nix @@ -190,14 +190,14 @@ in { rust-crane.depsDrv = { inherit version; name = pname + depsNameSuffix; - package-func.func = crane.buildDepsOnly; + package-func.func = config.deps.crane.buildDepsOnly; package-func.args = l.mkMerge [ common depsArgs ]; }; - package-func.func = crane.buildPackage; + package-func.func = config.deps.crane.buildPackage; package-func.args = l.mkMerge [common buildArgs]; public = { @@ -215,6 +215,7 @@ in { deps = {nixpkgs, ...}: l.mkMerge [ (l.mapAttrs (_: l.mkDefault) { + inherit crane; cargo = nixpkgs.cargo; craneSource = config.deps.fetchFromGitHub { owner = "ipetkov"; From 26d0103e1a80374d65a3b6e1545902bf4081a6b0 Mon Sep 17 00:00:00 2001 From: DavHau Date: Sun, 17 Sep 2023 21:13:22 +0200 Subject: [PATCH 26/70] update nixpkgs input we now depend on lib.path functions --- flake.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/flake.lock b/flake.lock index 8755f8e256..791d7a1545 100644 --- a/flake.lock +++ b/flake.lock @@ -118,11 +118,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1686501370, - "narHash": "sha256-G0WuM9fqTPRc2URKP9Lgi5nhZMqsfHGrdEbrLvAPJcg=", + "lastModified": 1694767346, + "narHash": "sha256-5uH27SiVFUwsTsqC5rs3kS7pBoNhtoy9QfTP9BmknGk=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "75a5ebf473cd60148ba9aec0d219f72e5cf52519", + "rev": "ace5093e36ab1e95cb9463863491bee90d5a4183", "type": "github" }, "original": { From fbcdc4a0a633e7464a01afe0c28aef622792b323 Mon Sep 17 00:00:00 2001 From: DavHau Date: Sun, 17 Sep 2023 21:20:03 +0200 Subject: [PATCH 27/70] fix(pip): don't invalidate lock file on python minor version updates --- modules/dream2nix/pip/default.nix | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/dream2nix/pip/default.nix b/modules/dream2nix/pip/default.nix index 54c10f0834..e5098e8ee5 100644 --- a/modules/dream2nix/pip/default.nix +++ b/modules/dream2nix/pip/default.nix @@ -147,7 +147,8 @@ in { requirementsList requirementsFiles ; - pythonVersion = config.deps.python.version; + # don't invalidate on bugfix version changes + pythonVersion = lib.init (lib.splitVersion config.deps.python.version); }; }; From 4234e462ce5d3848ae200b20ce9ba647b1a7f6e6 Mon Sep 17 00:00:00 2001 From: DavHau Date: Mon, 18 Sep 2023 11:15:35 +0200 Subject: [PATCH 28/70] chore: re-generate all lock files --- examples/packages/multi-language/python-nodejs/lock.json | 2 +- .../packages/single-language/python-machine-learning/lock.json | 2 +- .../packages/single-language/python-package-ansible/lock.json | 2 +- .../single-language/python-package-apache-airflow/lock.json | 2 +- examples/packages/single-language/python-package-odoo/lock.json | 2 +- .../packages/single-language/python-package-pillow/lock.json | 2 +- examples/packages/single-language/python-project/lock.json | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/examples/packages/multi-language/python-nodejs/lock.json b/examples/packages/multi-language/python-nodejs/lock.json index 686af6e86d..f3ed6f76f8 100644 --- a/examples/packages/multi-language/python-nodejs/lock.json +++ b/examples/packages/multi-language/python-nodejs/lock.json @@ -119,5 +119,5 @@ } } }, - "invalidationHash": "88ef7315dd6761484615891a36ac41cef9a468d66b41f78fecada9eee4c2eb7b" + "invalidationHash": "255d7306e2485fb3c4e4419fc044fed9dade9ea3d0748396036c0e31ea72a03f" } \ No newline at end of file diff --git a/examples/packages/single-language/python-machine-learning/lock.json b/examples/packages/single-language/python-machine-learning/lock.json index 3d2792e971..18d5802959 100644 --- a/examples/packages/single-language/python-machine-learning/lock.json +++ b/examples/packages/single-language/python-machine-learning/lock.json @@ -274,5 +274,5 @@ } } }, - "invalidationHash": "0dde05ce6fe84aa4050708598e01eb4b80bdb95f3d74b895bfb024152a6415ed" + "invalidationHash": "73ea7fe0e9b1f7d10f3140984bfd37279a11627f127cf23ea37cba173487d379" } \ No newline at end of file diff --git a/examples/packages/single-language/python-package-ansible/lock.json b/examples/packages/single-language/python-package-ansible/lock.json index 97a6a5b3a8..93e621c979 100644 --- a/examples/packages/single-language/python-package-ansible/lock.json +++ b/examples/packages/single-language/python-package-ansible/lock.json @@ -110,5 +110,5 @@ } } }, - "invalidationHash": "5c89fed9d7831a0b738a50203de0f8add46cd9f7c96c1a32cd8cc27569184039" + "invalidationHash": "b351dd845e6472bc9f7472fa28c3d17250ef9fc92409930897a33ce429a08bbf" } \ No newline at end of file diff --git a/examples/packages/single-language/python-package-apache-airflow/lock.json b/examples/packages/single-language/python-package-apache-airflow/lock.json index 9ee24bb751..495e98eb8b 100644 --- a/examples/packages/single-language/python-package-apache-airflow/lock.json +++ b/examples/packages/single-language/python-package-apache-airflow/lock.json @@ -1012,5 +1012,5 @@ } } }, - "invalidationHash": "53b88919c16e4602cb847118509df402e5f13158b99da1e16d6038b0242acf4f" + "invalidationHash": "f486aa598f30432e9a6fb7ba8296ace5ff59f06b170cb1a71fdff31cb56c3e11" } \ No newline at end of file diff --git a/examples/packages/single-language/python-package-odoo/lock.json b/examples/packages/single-language/python-package-odoo/lock.json index 6317705e1b..4e745965c2 100644 --- a/examples/packages/single-language/python-package-odoo/lock.json +++ b/examples/packages/single-language/python-package-odoo/lock.json @@ -507,5 +507,5 @@ } } }, - "invalidationHash": "ab37933821f7fe9c689ce6d206aaf64e1c120b7756c502d94de335b7e4ce31df" + "invalidationHash": "5b35c65abebebe7254231b4dda4d54faafd9e6bfc8acb660e8163b9aa32bb5ec" } \ No newline at end of file diff --git a/examples/packages/single-language/python-package-pillow/lock.json b/examples/packages/single-language/python-package-pillow/lock.json index b5d61d09cb..401e09c83c 100644 --- a/examples/packages/single-language/python-package-pillow/lock.json +++ b/examples/packages/single-language/python-package-pillow/lock.json @@ -14,5 +14,5 @@ } } }, - "invalidationHash": "ab0a30714d5a0794ad6b0376fd8dd1f61a46268c612afbaa8c3d1ca396d21c6c" + "invalidationHash": "72c325a060a2f980a1a160ef7af2fb99ce66fdd37229f25566ff4bc9f9c6db00" } \ No newline at end of file diff --git a/examples/packages/single-language/python-project/lock.json b/examples/packages/single-language/python-project/lock.json index 2fdb2ddb0e..e9e7613861 100644 --- a/examples/packages/single-language/python-project/lock.json +++ b/examples/packages/single-language/python-project/lock.json @@ -54,5 +54,5 @@ } } }, - "invalidationHash": "ddf895d24e90c9aa98175e398910ccffeb68c1f9a886729261695e81b8e1d82c" + "invalidationHash": "9d63b829115c1d449d6830377e4a586d684393b9b63a76a1f89f7486b6d0ed33" } \ No newline at end of file From f8626675d4c8698c4a900068600ad908ade860c4 Mon Sep 17 00:00:00 2001 From: DavHau Date: Mon, 18 Sep 2023 11:16:20 +0200 Subject: [PATCH 29/70] fix(php): exclude xml extension This extension leads to a breakage in composer --- modules/dream2nix/php-granular/default.nix | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/modules/dream2nix/php-granular/default.nix b/modules/dream2nix/php-granular/default.nix index d94ecea182..13650152a8 100644 --- a/modules/dream2nix/php-granular/default.nix +++ b/modules/dream2nix/php-granular/default.nix @@ -55,18 +55,30 @@ inherit (import ../../../lib/internal/php-semver.nix {inherit lib;}) satisfies; + selectExtensions = all: + l.attrValues ( + l.filterAttrs + ( + e: _: + #adding xml currently breaks the build of composer + (e != "xml") + && (l.elem e ["xml"]) + ) + all + ); + # php with required extensions php = if satisfies config.deps.php81.version subsystemAttrs.phpSemver then + # config.deps.php81 config.deps.php81.withExtensions ( { all, enabled, }: - l.unique (enabled - ++ (l.attrValues (l.filterAttrs (e: _: l.elem e subsystemAttrs.phpExtensions) all))) + l.unique (enabled ++ selectExtensions all) ) else l.abort '' From 857697085235d6d9e125b2526b948e597ac0a4b1 Mon Sep 17 00:00:00 2001 From: Jairo Llopis Date: Mon, 18 Sep 2023 09:47:31 +0100 Subject: [PATCH 30/70] fix: forward incoming modules when using `importPackages` interface Before this patch, if a user calls `importPackages` and includes custom modules in the call, those would be lost. @moduon MT-1075 --- modules/flake-parts/lib.nix | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/modules/flake-parts/lib.nix b/modules/flake-parts/lib.nix index 6db5b1e1e9..83a4f0b428 100644 --- a/modules/flake-parts/lib.nix +++ b/modules/flake-parts/lib.nix @@ -28,14 +28,17 @@ module: type: self.lib.evalModules (forwardedArgs // { - modules = [ - (packagesDirPath + "/${module}") - { - paths.projectRoot = projectRoot; - paths.projectRootFile = projectRootFile; - paths.package = "/${packagesDir}/${module}"; - } - ]; + modules = + args.modules + or [] + ++ [ + (packagesDirPath + "/${module}") + { + paths.projectRoot = projectRoot; + paths.projectRootFile = projectRootFile; + paths.package = "/${packagesDir}/${module}"; + } + ]; }) ) (builtins.readDir packagesDirPath); From 4eb5478fdd7e00e58bd79af298b09bfc8821daf3 Mon Sep 17 00:00:00 2001 From: DavHau Date: Wed, 20 Sep 2023 21:48:16 +0200 Subject: [PATCH 31/70] feat(paths): allow paths.package to be an absolute path --- ci.nix | 1 + examples/dream2nix-repo-flake/flake.nix | 2 +- examples/dream2nix-repo/default.nix | 6 +- modules/dream2nix/core/paths/interface.nix | 17 +++- modules/dream2nix/php-granular/interface.nix | 2 +- modules/flake-parts/examples.nix | 22 ++++- modules/flake-parts/lib.nix | 8 +- tests/nix-unit/test_paths/default.nix | 84 ++++++++++++++++++++ 8 files changed, 129 insertions(+), 13 deletions(-) create mode 100644 tests/nix-unit/test_paths/default.nix diff --git a/ci.nix b/ci.nix index ea9f600492..9d1c043f9b 100644 --- a/ci.nix +++ b/ci.nix @@ -7,6 +7,7 @@ let dream2nix-repo = import ./examples/dream2nix-repo { dream2nixSource = ./.; + inherit pkgs; }; dream2nix-repo-flake = (import ./examples/dream2nix-repo-flake/flake.nix).outputs { diff --git a/examples/dream2nix-repo-flake/flake.nix b/examples/dream2nix-repo-flake/flake.nix index 7a7a03cb4e..f9d0a65cee 100644 --- a/examples/dream2nix-repo-flake/flake.nix +++ b/examples/dream2nix-repo-flake/flake.nix @@ -19,7 +19,7 @@ projectRoot = ./.; # can be changed to ".git" or "flake.nix" to get rid of .project-root projectRootFile = "flake.nix"; - packagesDir = "/packages"; + packagesDir = ./packages; packageSets.nixpkgs = nixpkgs.legacyPackages.${system}; }; }; diff --git a/examples/dream2nix-repo/default.nix b/examples/dream2nix-repo/default.nix index 73e90d1c3d..1edac055ca 100644 --- a/examples/dream2nix-repo/default.nix +++ b/examples/dream2nix-repo/default.nix @@ -4,16 +4,16 @@ url = "https://github.com/nix-community/dream2nix/tarball/main"; # sha256 = ""; }, + pkgs ? import (import dream2nixSource).inputs.nixpkgs {}, }: let dream2nix = import dream2nixSource; - nixpkgs = import dream2nix.inputs.nixpkgs {}; # all packages defined inside ./packages/ packages = dream2nix.lib.importPackages { projectRoot = ./.; # can be changed to ".git" to get rid of .project-root projectRootFile = ".project-root"; - packagesDir = "/packages"; - packageSets.nixpkgs = nixpkgs; + packagesDir = ./packages; + packageSets.nixpkgs = pkgs; }; in # all packages defined inside ./packages/ diff --git a/modules/dream2nix/core/paths/interface.nix b/modules/dream2nix/core/paths/interface.nix index 4ad7f0bc78..7e7bc01ab3 100644 --- a/modules/dream2nix/core/paths/interface.nix +++ b/modules/dream2nix/core/paths/interface.nix @@ -2,11 +2,13 @@ lib, config, ... -}: { +}: let + cfg = config.paths; +in { options.paths = lib.mapAttrs (_: lib.mkOption) { # mandatory fields projectRoot = { - type = lib.types.path; + type = lib.types.pathInStore; description = '' Path to the root of the project on which dream2nix operates. Must contain the marker file specified by 'paths.projectRootFile' @@ -16,13 +18,22 @@ example = lib.literalExpression "./."; }; package = { - type = lib.types.str; + type = lib.types.either lib.types.path lib.types.str; description = '' Path to the directory containing the definition of the current package. Relative to 'paths.projectRoot'. This helps locating package definitions for lock & update scripts. ''; + apply = path': let + projectRoot = toString cfg.projectRoot; + path = toString path'; + in + if path == projectRoot + then "./." + else if lib.hasPrefix projectRoot path + then lib.path.subpath.normalise "./${lib.removePrefix projectRoot path}" + else lib.path.subpath.normalise "./${path}"; }; # optional fields diff --git a/modules/dream2nix/php-granular/interface.nix b/modules/dream2nix/php-granular/interface.nix index 024c268003..d46ecd6378 100644 --- a/modules/dream2nix/php-granular/interface.nix +++ b/modules/dream2nix/php-granular/interface.nix @@ -20,7 +20,7 @@ in { })); }; composerInstallFlags = { - type = t.listOf t.string; + type = t.listOf t.str; default = []; }; }; diff --git a/modules/flake-parts/examples.nix b/modules/flake-parts/examples.nix index aadd873e7f..5325606c2d 100644 --- a/modules/flake-parts/examples.nix +++ b/modules/flake-parts/examples.nix @@ -30,6 +30,15 @@ packagePath = "/examples/packages/${dirName}/${name}"; }); + importFlake = flakeFile: let + self' = (import flakeFile).outputs { + dream2nix = self; + nixpkgs = inputs.nixpkgs; + self = self'; + }; + in + self'; + # Type: [ {${name} = {module, packagePath} ] allExamples = mapAttrsToList (dirName: _: readExamples dirName) packageCategories; @@ -96,7 +105,16 @@ in { in { # map all modules in /examples to a package output in the flake. checks = - lib.mapAttrs (_: drvModules: makeDrv drvModules) - allModules; + (lib.mapAttrs (_: drvModules: makeDrv drvModules) allModules) + // { + example-repo = + (import (self + /examples/dream2nix-repo) { + dream2nixSource = self; + inherit pkgs; + }) + .hello; + example-repo-flake = + (importFlake (self + /examples/dream2nix-repo-flake/flake.nix)).packages.${system}.hello; + }; }; } diff --git a/modules/flake-parts/lib.nix b/modules/flake-parts/lib.nix index 83a4f0b428..cdcf3f7840 100644 --- a/modules/flake-parts/lib.nix +++ b/modules/flake-parts/lib.nix @@ -13,9 +13,11 @@ packagesDir, ... }: let + projectRoot = toString args.projectRoot; + packagesDir = toString args.packagesDir; packagesDirPath = - if ! builtins.isString packagesDir - then throw "packagesDir must be a string" + if lib.hasPrefix projectRoot packagesDir + then packagesDir else projectRoot + "/${packagesDir}"; forwardedArgs = builtins.removeAttrs args [ "projectRoot" @@ -36,7 +38,7 @@ { paths.projectRoot = projectRoot; paths.projectRootFile = projectRootFile; - paths.package = "/${packagesDir}/${module}"; + paths.package = packagesDir + "/${module}"; } ]; }) diff --git a/tests/nix-unit/test_paths/default.nix b/tests/nix-unit/test_paths/default.nix new file mode 100644 index 0000000000..6a2e374e44 --- /dev/null +++ b/tests/nix-unit/test_paths/default.nix @@ -0,0 +1,84 @@ +{ + pkgs ? import {}, + lib ? import , + dream2nix ? (import (../../../modules + "/flake.nix")).outputs {}, +}: let + eval = module: + (lib.evalModules { + modules = [ + dream2nix.modules.dream2nix.core + module + ]; + specialArgs = { + inherit dream2nix; + packageSets.nixpkgs = pkgs; + }; + }) + .config; +in { + test_package_in_root_1 = let + config = eval { + paths.projectRoot = "${./.}"; + paths.package = "${./.}"; + }; + in { + expr = {inherit (config.paths) projectRoot package;}; + expected = { + projectRoot = "${./.}"; + package = "./."; + }; + }; + + test_package_in_root_2 = let + config = eval { + paths.projectRoot = "${./.}"; + paths.package = "./."; + }; + in { + expr = {inherit (config.paths) projectRoot package;}; + expected = { + projectRoot = "${./.}"; + package = "./."; + }; + }; + + test_package_in_subdir_1 = let + config = eval { + paths.projectRoot = "${./.}"; + paths.package = "${./.}/package"; + }; + in { + expr = {inherit (config.paths) projectRoot package;}; + expected = { + projectRoot = "${./.}"; + package = "./package"; + }; + }; + + test_package_in_subdir_2 = let + config = eval { + paths.projectRoot = "${./.}"; + paths.package = "./package"; + }; + in { + expr = {inherit (config.paths) projectRoot package;}; + expected = { + projectRoot = "${./.}"; + package = "./package"; + }; + }; + + test_package_in_subdir_3 = let + self = /nix/store/some/path; + config = eval { + paths.projectRoot = self; + paths.package = self + /package; + }; + in { + expr = {inherit (config.paths) projectRoot package;}; + expected = { + projectRoot = self; + package = "./package"; + }; + }; +} From e913ec992b8c0aefa4839caff8eda89f09973384 Mon Sep 17 00:00:00 2001 From: DavHau Date: Wed, 20 Sep 2023 22:03:03 +0200 Subject: [PATCH 32/70] ci: remove ./ci.nix --- ci.nix | 24 -------------------- flake.nix | 19 +++++++++------- modules/flake-parts/checks.nix-unit.nix | 29 ++++++++++++++----------- modules/flake-parts/examples.nix | 26 ++++++++++++---------- 4 files changed, 42 insertions(+), 56 deletions(-) delete mode 100644 ci.nix diff --git a/ci.nix b/ci.nix deleted file mode 100644 index 9d1c043f9b..0000000000 --- a/ci.nix +++ /dev/null @@ -1,24 +0,0 @@ -let - b = builtins; - flakeCompatSrc = b.fetchurl "https://raw.githubusercontent.com/edolstra/flake-compat/12c64ca55c1014cdc1b16ed5a804aa8576601ff2/default.nix"; - flake = (import flakeCompatSrc {src = ./.;}).defaultNix; - pkgs = import flake.inputs.nixpkgs {}; - recurseIntoAll = b.mapAttrs (name: val: pkgs.recurseIntoAttrs val); - - dream2nix-repo = import ./examples/dream2nix-repo { - dream2nixSource = ./.; - inherit pkgs; - }; - - dream2nix-repo-flake = (import ./examples/dream2nix-repo-flake/flake.nix).outputs { - self = dream2nix-repo-flake; - dream2nix = flake; - nixpkgs = flake.inputs.nixpkgs; - }; -in - recurseIntoAll { - inherit dream2nix-repo dream2nix-repo-flake; - checks = flake.checks.x86_64-linux; - devShells = flake.devShells.x86_64-linux; - packages = flake.packages.x86_64-linux; - } diff --git a/flake.nix b/flake.nix index 6355e57522..935b6a1724 100644 --- a/flake.nix +++ b/flake.nix @@ -80,14 +80,17 @@ dream2nix-shell = mkShell { devshell.name = "dream2nix-devshell"; - packages = [ - pkgs.alejandra - pkgs.mdbook - inputs'.nix-unit.packages.nix-unit - (pkgs.python3.withPackages (ps: [ - pkgs.python3.pkgs.black - ])) - ]; + packages = + [ + pkgs.alejandra + pkgs.mdbook + (pkgs.python3.withPackages (ps: [ + pkgs.python3.pkgs.black + ])) + ] + ++ (l.optionals pkgs.stdenv.isLinux [ + inputs'.nix-unit.packages.nix-unit + ]); commands = [ diff --git a/modules/flake-parts/checks.nix-unit.nix b/modules/flake-parts/checks.nix-unit.nix index 885d9f0d67..e3b024d1c7 100644 --- a/modules/flake-parts/checks.nix-unit.nix +++ b/modules/flake-parts/checks.nix-unit.nix @@ -3,18 +3,21 @@ perSystem = { pkgs, inputs', + lib, + system, ... - }: { - # map all modules in /examples to a package output in the flake. - checks.nix-unit = pkgs.runCommand "nix-unit-tests" {} '' - export NIX_PATH=nixpkgs=${pkgs.path} - for test in ${self}/tests/nix-unit/*; do - echo -e "Executing tests from file $test" - ${inputs'.nix-unit.packages.nix-unit}/bin/nix-unit \ - "$test" \ - --eval-store $(realpath .) - done - touch $out - ''; - }; + }: + lib.optionalAttrs (system == "x86_64-linux") { + # map all modules in /examples to a package output in the flake. + checks.nix-unit = pkgs.runCommand "nix-unit-tests" {} '' + export NIX_PATH=nixpkgs=${pkgs.path} + for test in ${self}/tests/nix-unit/*; do + echo -e "Executing tests from file $test" + ${inputs'.nix-unit.packages.nix-unit}/bin/nix-unit \ + "$test" \ + --eval-store $(realpath .) + done + touch $out + ''; + }; } diff --git a/modules/flake-parts/examples.nix b/modules/flake-parts/examples.nix index 5325606c2d..977f6374f9 100644 --- a/modules/flake-parts/examples.nix +++ b/modules/flake-parts/examples.nix @@ -105,16 +105,20 @@ in { in { # map all modules in /examples to a package output in the flake. checks = - (lib.mapAttrs (_: drvModules: makeDrv drvModules) allModules) - // { - example-repo = - (import (self + /examples/dream2nix-repo) { - dream2nixSource = self; - inherit pkgs; - }) - .hello; - example-repo-flake = - (importFlake (self + /examples/dream2nix-repo-flake/flake.nix)).packages.${system}.hello; - }; + lib.optionalAttrs + (system == "x86_64-linux") + ( + (lib.mapAttrs (_: drvModules: makeDrv drvModules) allModules) + // { + example-repo = + (import (self + /examples/dream2nix-repo) { + dream2nixSource = self; + inherit pkgs; + }) + .hello; + example-repo-flake = + (importFlake (self + /examples/dream2nix-repo-flake/flake.nix)).packages.${system}.hello; + } + ); }; } From 0d3146539a0c57cbe9c49b8d3b1852d04394cec6 Mon Sep 17 00:00:00 2001 From: DavHau Date: Thu, 21 Sep 2023 14:34:04 +0200 Subject: [PATCH 33/70] fix(paths): don't force projectRoot to be in store --- modules/dream2nix/core/paths/interface.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/dream2nix/core/paths/interface.nix b/modules/dream2nix/core/paths/interface.nix index 7e7bc01ab3..76cb65ac3f 100644 --- a/modules/dream2nix/core/paths/interface.nix +++ b/modules/dream2nix/core/paths/interface.nix @@ -8,7 +8,7 @@ in { options.paths = lib.mapAttrs (_: lib.mkOption) { # mandatory fields projectRoot = { - type = lib.types.pathInStore; + type = lib.types.path; description = '' Path to the root of the project on which dream2nix operates. Must contain the marker file specified by 'paths.projectRootFile' From 56308a22eff5cb81941a22ee68f743a0527e5491 Mon Sep 17 00:00:00 2001 From: Jairo Llopis Date: Tue, 19 Sep 2023 13:17:09 +0100 Subject: [PATCH 34/70] feat: output pyEnv for pip derivations In case you're building a python environment instead of a package, this output is very handy. --- modules/dream2nix/pip/default.nix | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/modules/dream2nix/pip/default.nix b/modules/dream2nix/pip/default.nix index e5098e8ee5..2079496b50 100644 --- a/modules/dream2nix/pip/default.nix +++ b/modules/dream2nix/pip/default.nix @@ -165,13 +165,14 @@ in { l.attrValues (l.mapAttrs (name: _: cfg.drvs.${name}.public.out) rootDeps); }; - public.devShell = let + public.pyEnv = let pyEnv' = config.deps.python.withPackages (ps: config.mkDerivation.propagatedBuildInputs); - pyEnv = pyEnv'.override (old: { + in + pyEnv'.override (old: { # namespaced packages are triggering a collision error, but this can be # safely ignored. They are still set up correctly and can be imported. ignoreCollisions = true; }); - in - pyEnv.env; + + public.devShell = config.public.pyEnv.env; } From 16552e5813ef8bc9407d33d0a2afaf3a68aca618 Mon Sep 17 00:00:00 2001 From: Jairo Llopis Date: Wed, 20 Sep 2023 13:24:49 +0100 Subject: [PATCH 35/70] feat: allow to split buildInputs in python derivations Follow-up of https://github.com/nix-community/dream2nix/pull/676#discussion_r1326998054, now dependencies marked as buildInputs won't be included as propagatedBuildInputs for python derivations. --- modules/dream2nix/pip/default.nix | 17 +++++++++++++-- modules/dream2nix/pip/interface.nix | 32 +++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 2 deletions(-) diff --git a/modules/dream2nix/pip/default.nix b/modules/dream2nix/pip/default.nix index 2079496b50..49a1dc24ff 100644 --- a/modules/dream2nix/pip/default.nix +++ b/modules/dream2nix/pip/default.nix @@ -11,6 +11,8 @@ # filter out ignored dependencies targets = cfg.targets; + isRootDrv = drv: cfg.rootDependencies.${drv.name} or false; + isBuildInput = drv: cfg.buildDependencies.${drv.name} or false; writers = import ../../../pkgs/writers { inherit lib; @@ -159,10 +161,21 @@ in { }; mkDerivation = { + buildInputs = let + rootDeps = + lib.filterAttrs + (name: value: isRootDrv value && isBuildInput value) + cfg.drvs; + in + l.map (drv: drv.public.out) (l.attrValues rootDeps); + propagatedBuildInputs = let - rootDeps = lib.filterAttrs (_: x: x == true) cfg.rootDependencies; + rootDeps = + lib.filterAttrs + (name: value: isRootDrv value && !isBuildInput value) + cfg.drvs; in - l.attrValues (l.mapAttrs (name: _: cfg.drvs.${name}.public.out) rootDeps); + l.map (drv: drv.public.out) (l.attrValues rootDeps); }; public.pyEnv = let diff --git a/modules/dream2nix/pip/interface.nix b/modules/dream2nix/pip/interface.nix index 528a960da5..b1c43dbe21 100644 --- a/modules/dream2nix/pip/interface.nix +++ b/modules/dream2nix/pip/interface.nix @@ -59,6 +59,38 @@ in { list of requirements.txt files ''; }; + buildDependencies = l.mkOption { + type = t.attrsOf t.bool; + default = { + cython = true; + flit-core = true; + flit-scm = true; + hatch-fancy-pypi-readme = true; + hatch-nodejs-version = true; + hatch-vcs = true; + hatchling = true; + pbr = true; + pdm-pep517 = true; + poetry-core = true; + poetry-dynamic-versioning = true; + setuptools = true; + setuptools-odoo = true; + setuptools-scm = true; + versioneer = true; + wheel = true; + }; + description = '' + python packages to be added only as buildInputs. + These should be somehow installable from `requirementsList` or + `requirementsFiles` too; listing them here doesn't do that automatically. + ''; + example = lib.literalExpression '' + { + setuptools-scm = false; # To disable the default + easy_install = true; # To select easy_install as a buildInput + } + ''; + }; buildExtras = l.mkOption { type = t.listOf t.str; From 25e07594f4d2a49946a0767bb8aa4709a5ad753e Mon Sep 17 00:00:00 2001 From: Jairo Llopis Date: Mon, 18 Sep 2023 12:03:46 +0100 Subject: [PATCH 36/70] fix: improve handling of local python dependencies MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The pip locker [sometimes created a URL without hash][1] to reflect that there was a local source. This produced the following error when trying to evaluate that derivation: … from call site at /nix/store/qdzdi6qvrqxfqxhi3j70d5dsl9f5jpby-source/modules/dream2nix/pip/default.nix:86:28: 85| mkDerivation = { 86| src = l.mkDefault (fetchers.${metadata.sources.${config.name}.type} metadata.sources.${config.name}); | ^ 87| doCheck = l.mkDefault false; … while calling 'url' at /nix/store/qdzdi6qvrqxfqxhi3j70d5dsl9f5jpby-source/modules/dream2nix/pip/default.nix:57:11: 56| fetchers = { 57| url = info: l.fetchurl {inherit (info) url sha256;}; | ^ 58| git = info: config.deps.fetchgit {inherit (info) url sha256 rev;}; error: value is null while a string was expected Of course, one cannot call `builtins.fetchurl` without a `sha256` argument. Now, local dependencies are specified exactly like that in the lock file. Now, we'll fetch nothing when dealing with local dependencies. Also, their evaluation when generating `preFixup` attribute is delayed until build time. This was a bigger problem due to the previous bug, but in any case it should still help to reduce evaluation overhead. FWIW, sometimes local sources might not really exit in the derivation source tree until build time. For example, when building aggregated sources with meta-repo management tools such as Mr. Chef. [1]: https://github.com/nix-community/dream2nix/blob/40b65e4598e249af6cc285259c1c0afefbb0f420/pkgs/fetchPipMetadata/src/fetch_pip_metadata/lock_file_from_report.py#L72C28-L72C28 --- .gitignore | 3 +- .../python-local-dependencies/default.nix | 39 +++++++++++++++++++ .../python-local-dependencies/lock.json | 25 ++++++++++++ .../subpkg1/pyproject.toml | 10 +++++ .../subpkg1/subpkg1.py | 1 + .../subpkg2/pyproject.toml | 7 ++++ .../subpkg2/subpkg2.py | 2 + modules/dream2nix/pip/default.nix | 3 +- .../lock_file_from_report.py | 5 +-- .../src/tests/test_lock_info_from_path.py | 5 +-- 10 files changed, 92 insertions(+), 8 deletions(-) create mode 100644 examples/packages/single-language/python-local-dependencies/default.nix create mode 100644 examples/packages/single-language/python-local-dependencies/lock.json create mode 100644 examples/packages/single-language/python-local-dependencies/subpkg1/pyproject.toml create mode 100644 examples/packages/single-language/python-local-dependencies/subpkg1/subpkg1.py create mode 100644 examples/packages/single-language/python-local-dependencies/subpkg2/pyproject.toml create mode 100644 examples/packages/single-language/python-local-dependencies/subpkg2/subpkg2.py diff --git a/.gitignore b/.gitignore index f6841bc7c1..61d8e51f4b 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,5 @@ /.pre-commit-config.yaml result interpreter -__pycache__ \ No newline at end of file +__pycache__ +*.egg-info \ No newline at end of file diff --git a/examples/packages/single-language/python-local-dependencies/default.nix b/examples/packages/single-language/python-local-dependencies/default.nix new file mode 100644 index 0000000000..74baa01468 --- /dev/null +++ b/examples/packages/single-language/python-local-dependencies/default.nix @@ -0,0 +1,39 @@ +{ + config, + lib, + dream2nix, + ... +}: let + pyproject = lib.importTOML ./subpkg1/pyproject.toml; + buildWithSetuptools = { + buildPythonPackage.format = "pyproject"; + mkDerivation.buildInputs = [config.deps.python.pkgs.setuptools]; + }; +in rec { + imports = [ + dream2nix.modules.dream2nix.pip + buildWithSetuptools + ]; + + inherit (pyproject.project) name version; + + mkDerivation.src = lib.concatStringsSep "/" [ + config.paths.projectRoot + config.paths.package + "subpkg1" + ]; + + buildPythonPackage.pythonImportsCheck = [ + "subpkg1" + "subpkg2" + ]; + + pip = { + pypiSnapshotDate = "2023-09-19"; + requirementsList = [ + "${config.paths.package}/subpkg1" + "${config.paths.package}/subpkg2" + ]; + drvs.subpkg2 = buildWithSetuptools; + }; +} diff --git a/examples/packages/single-language/python-local-dependencies/lock.json b/examples/packages/single-language/python-local-dependencies/lock.json new file mode 100644 index 0000000000..766d309fa0 --- /dev/null +++ b/examples/packages/single-language/python-local-dependencies/lock.json @@ -0,0 +1,25 @@ +{ + "fetchPipMetadata": { + "sources": { + "subpkg1": { + "path": "examples/packages/single-language/python-local-dependencies/subpkg1", + "type": "local", + "version": "0.0.1" + }, + "subpkg2": { + "path": "examples/packages/single-language/python-local-dependencies/subpkg2", + "type": "local", + "version": "0.0.2" + } + }, + "targets": { + "default": { + "subpkg1": [ + "subpkg2" + ], + "subpkg2": [] + } + } + }, + "invalidationHash": "226b1267f23fd3705dd88929c9eb630aececd273204130ad42f13a4f7b8e35ca" +} \ No newline at end of file diff --git a/examples/packages/single-language/python-local-dependencies/subpkg1/pyproject.toml b/examples/packages/single-language/python-local-dependencies/subpkg1/pyproject.toml new file mode 100644 index 0000000000..0ab6886b2a --- /dev/null +++ b/examples/packages/single-language/python-local-dependencies/subpkg1/pyproject.toml @@ -0,0 +1,10 @@ +[build-system] +requires = [ "setuptools" ] +build-backend = "setuptools.build_meta" + +[project] +name = "subpkg1" +version = "0.0.1" +dependencies = [ + "subpkg2" +] diff --git a/examples/packages/single-language/python-local-dependencies/subpkg1/subpkg1.py b/examples/packages/single-language/python-local-dependencies/subpkg1/subpkg1.py new file mode 100644 index 0000000000..aeb4f68e16 --- /dev/null +++ b/examples/packages/single-language/python-local-dependencies/subpkg1/subpkg1.py @@ -0,0 +1 @@ +from subpkg2 import where diff --git a/examples/packages/single-language/python-local-dependencies/subpkg2/pyproject.toml b/examples/packages/single-language/python-local-dependencies/subpkg2/pyproject.toml new file mode 100644 index 0000000000..08d3bccee5 --- /dev/null +++ b/examples/packages/single-language/python-local-dependencies/subpkg2/pyproject.toml @@ -0,0 +1,7 @@ +[build-system] +requires = [ "setuptools" ] +build-backend = "setuptools.build_meta" + +[project] +name = "subpkg2" +version = "0.0.2" diff --git a/examples/packages/single-language/python-local-dependencies/subpkg2/subpkg2.py b/examples/packages/single-language/python-local-dependencies/subpkg2/subpkg2.py new file mode 100644 index 0000000000..d88795a8fd --- /dev/null +++ b/examples/packages/single-language/python-local-dependencies/subpkg2/subpkg2.py @@ -0,0 +1,2 @@ +def where(): + print(__name__) diff --git a/modules/dream2nix/pip/default.nix b/modules/dream2nix/pip/default.nix index 49a1dc24ff..5443c0b4b9 100644 --- a/modules/dream2nix/pip/default.nix +++ b/modules/dream2nix/pip/default.nix @@ -58,6 +58,7 @@ fetchers = { url = info: l.fetchurl {inherit (info) url sha256;}; git = info: config.deps.fetchgit {inherit (info) url sha256 rev;}; + local = info: "${config.paths.projectRoot}/${info.path}"; }; commonModule = {config, ...}: { @@ -97,7 +98,7 @@ # This is required for autoPatchelfHook to find .so files from other # python dependencies, like for example libcublas.so.11 from nvidia-cublas-cu11. preFixup = lib.optionalString config.deps.stdenv.isLinux '' - addAutoPatchelfSearchPath ${toString (config.mkDerivation.propagatedBuildInputs)} + addAutoPatchelfSearchPath $propagatedBuildInputs ''; propagatedBuildInputs = let depsByExtra = extra: targets.${extra}.${config.name} or []; diff --git a/pkgs/fetchPipMetadata/src/fetch_pip_metadata/lock_file_from_report.py b/pkgs/fetchPipMetadata/src/fetch_pip_metadata/lock_file_from_report.py index 952eead3a2..a80f838403 100644 --- a/pkgs/fetchPipMetadata/src/fetch_pip_metadata/lock_file_from_report.py +++ b/pkgs/fetchPipMetadata/src/fetch_pip_metadata/lock_file_from_report.py @@ -67,9 +67,8 @@ def lock_info_from_path(full_path, project_root: Path): # See whether the path is relative to our local repo if project_root in full_path.parents or project_root == full_path: return { - "type": "url", - "url": str(full_path.relative_to(project_root)), - "sha256": None, + "type": "local", + "path": str(full_path.relative_to(project_root)), } # Otherwise, we require it is in /nix/store and just the "top-level" diff --git a/pkgs/fetchPipMetadata/src/tests/test_lock_info_from_path.py b/pkgs/fetchPipMetadata/src/tests/test_lock_info_from_path.py index 2260e38cc0..c400cbf4b3 100644 --- a/pkgs/fetchPipMetadata/src/tests/test_lock_info_from_path.py +++ b/pkgs/fetchPipMetadata/src/tests/test_lock_info_from_path.py @@ -6,9 +6,8 @@ def test_path_in_repo_root(git_repo_path): assert l.lock_info_from_path(git_repo_path / "foo", git_repo_path) == { - "type": "url", - "url": "foo", - "sha256": None, + "type": "local", + "path": "foo", } From 6dbd59e4a47bd916a655c4425a3e730c6aeae033 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Sep 2023 21:16:13 +0000 Subject: [PATCH 37/70] chore(deps): bump actions/checkout from 4.0.0 to 4.1.0 Bumps [actions/checkout](https://github.com/actions/checkout) from 4.0.0 to 4.1.0. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/3df4ab11eba7bda6032a0b82a6bb43b11571feac...8ade135a41bc03ea155e62e844d188df1ea18608) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/pages.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml index 283b1c6bdf..c8670b5f10 100644 --- a/.github/workflows/pages.yml +++ b/.github/workflows/pages.yml @@ -10,7 +10,7 @@ jobs: deploy: runs-on: ubuntu-latest steps: - - uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4.0.0 + - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0 - name: Install nix uses: cachix/install-nix-action@6a9a9e84a173d90b3ffb42c5ddaf9ea033fad011 # v23 From c78d39119a736124f9f246c9419fc9cc9533ed1a Mon Sep 17 00:00:00 2001 From: Frederik Rietdijk Date: Thu, 28 Sep 2023 19:19:40 +0200 Subject: [PATCH 38/70] wip pdm init --- .../dream2nix-repo-flake-groups/flake.nix | 83 +++++++++ examples/dream2nix-repo-flake-pdm/.gitignore | 3 + examples/dream2nix-repo-flake-pdm/flake.nix | 35 ++++ examples/dream2nix-repo-flake-pdm/pdm.lock | 147 ++++++++++++++++ .../dream2nix-repo-flake-pdm/pyproject.toml | 19 +++ flake.lock | 6 +- modules/default.nix | 17 +- modules/dream2nix/_template/default.nix | 7 +- modules/dream2nix/_template/interface.nix | 5 +- modules/dream2nix/groups/default.nix | 9 + modules/dream2nix/groups/group.nix | 47 ++++++ modules/dream2nix/groups/interface.nix | 29 ++++ modules/dream2nix/python-pdm/default.nix | 27 +++ modules/dream2nix/python-pdm/interface.nix | 27 +++ modules/dream2nix/python-pdm/lib.nix | 147 ++++++++++++++++ .../python-pdm/sourceSelectorOption.nix | 14 ++ modules/flake-parts/checks.nix-unit.nix | 36 ++-- modules/flake.lock | 44 +++++ modules/flake.nix | 8 + tests/nix-unit/fixtures.nix | 17 ++ tests/nix-unit/test_groups/default.nix | 38 +++++ .../nix-unit/test_python-pdm-lib/default.nix | 159 ++++++++++++++++++ tests/nix-unit/test_python-pdm/default.nix | 31 ++++ 23 files changed, 934 insertions(+), 21 deletions(-) create mode 100644 examples/dream2nix-repo-flake-groups/flake.nix create mode 100644 examples/dream2nix-repo-flake-pdm/.gitignore create mode 100644 examples/dream2nix-repo-flake-pdm/flake.nix create mode 100644 examples/dream2nix-repo-flake-pdm/pdm.lock create mode 100644 examples/dream2nix-repo-flake-pdm/pyproject.toml create mode 100644 modules/dream2nix/groups/default.nix create mode 100644 modules/dream2nix/groups/group.nix create mode 100644 modules/dream2nix/groups/interface.nix create mode 100644 modules/dream2nix/python-pdm/default.nix create mode 100644 modules/dream2nix/python-pdm/interface.nix create mode 100644 modules/dream2nix/python-pdm/lib.nix create mode 100644 modules/dream2nix/python-pdm/sourceSelectorOption.nix create mode 100644 modules/flake.lock create mode 100644 tests/nix-unit/fixtures.nix create mode 100644 tests/nix-unit/test_groups/default.nix create mode 100644 tests/nix-unit/test_python-pdm-lib/default.nix create mode 100644 tests/nix-unit/test_python-pdm/default.nix diff --git a/examples/dream2nix-repo-flake-groups/flake.nix b/examples/dream2nix-repo-flake-groups/flake.nix new file mode 100644 index 0000000000..e495dca7df --- /dev/null +++ b/examples/dream2nix-repo-flake-groups/flake.nix @@ -0,0 +1,83 @@ +{ + description = "My flake with dream2nix packages"; + + inputs = { + dream2nix.url = "github:nix-community/dream2nix"; + nixpkgs.url = "nixpkgs/nixos-unstable"; + }; + + outputs = inputs @ { + self, + dream2nix, + nixpkgs, + ... + }: let + system = "x86_64-linux"; + lib = nixpkgs.lib; + in { + # all packages defined inside ./packages/ + packages = let + module = { + config, + lib, + dream2nix, + ... + }: { + imports = [ + dream2nix.modules.dream2nix.groups + ]; + + # Overrides for all package sets + overrides = {}; + + # We can define various package sets + groups = { + non-overridden-set = { + overrides = lib.mkForce {}; + }; + # By default, a set has a packages attribute. + # Additional modules can add support for creating environments. + python-set = { + overrides = {}; + devShell = {}; + packages = {}; + }; + nodejs-set = { + # ... + }; + + final-set = { + imports = [ + dream2nix.modules.dream2nix.packages + dream2nix.modules.dream2nix.python-packages + dream2nix.modules.dream2nix.symlinked-env + dream2nix.modules.dream2nix.dev-shell + ]; + packages = { + inherit + (config.groups.python-set) + requests + aiohttp + ; + }; + symlinked-env = {type = "derivation";}; + dev-shell = {type = "derivation";}; + # populated automatically + public.symlinked-env = {type = "derivation";}; + public.dev-shell = {type = "derivation";}; + }; + }; + }; + evaled = lib.evalModules {modules = [module];}; + packages = evaled.config.groups.python-set.public.packages; + env = evaled.config.packages-sets.python-set.public.env; + symlinkedEnv = evaled.config.packge-sets.final-set.public.symlinked-env; + in { + inherit + (packages) + hello + torch + ; + }; + }; +} diff --git a/examples/dream2nix-repo-flake-pdm/.gitignore b/examples/dream2nix-repo-flake-pdm/.gitignore new file mode 100644 index 0000000000..e40cfd13d2 --- /dev/null +++ b/examples/dream2nix-repo-flake-pdm/.gitignore @@ -0,0 +1,3 @@ +__pypackages__ +.pdm-build +.pdm-python diff --git a/examples/dream2nix-repo-flake-pdm/flake.nix b/examples/dream2nix-repo-flake-pdm/flake.nix new file mode 100644 index 0000000000..7b315a596c --- /dev/null +++ b/examples/dream2nix-repo-flake-pdm/flake.nix @@ -0,0 +1,35 @@ +{ + description = "My flake with dream2nix packages"; + + inputs = { + dream2nix.url = "github:nix-community/dream2nix"; + nixpkgs.url = "nixpkgs/nixos-unstable"; + }; + + outputs = inputs @ { + self, + dream2nix, + nixpkgs, + ... + }: let + system = "x86_64-linux"; + lib = nixpkgs.lib; + module = { + config, + lib, + dream2nix, + ... + }: { + imports = [ + dream2nix.modules.dream2nix.python-pdm + ]; + pdm.lockfile = ./pdm.lock; + pdm.pyproject = ./pyproject.toml; + pdm.pythonInterpreter = nixpkgs.legacyPackages.python3; + }; + evaled = lib.evalModules {modules = [module];}; + defaultPackage = evaled.config.groups.default.public.packages.my-package; + in { + packages.${system}.default = defaultPackage; + }; +} diff --git a/examples/dream2nix-repo-flake-pdm/pdm.lock b/examples/dream2nix-repo-flake-pdm/pdm.lock new file mode 100644 index 0000000000..1ad321b23e --- /dev/null +++ b/examples/dream2nix-repo-flake-pdm/pdm.lock @@ -0,0 +1,147 @@ +# This file is @generated by PDM. +# It is not intended for manual editing. + +[[package]] +name = "certifi" +version = "2023.7.22" +requires_python = ">=3.6" +summary = "Python package for providing Mozilla's CA Bundle." + +[[package]] +name = "charset-normalizer" +version = "3.2.0" +requires_python = ">=3.7.0" +summary = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." + +[[package]] +name = "idna" +version = "3.4" +requires_python = ">=3.5" +summary = "Internationalized Domain Names in Applications (IDNA)" + +[[package]] +name = "pi" +version = "0.1.2" +summary = "Simpler python package installation" + +[[package]] +name = "requests" +version = "2.31.0" +requires_python = ">=3.7" +summary = "Python HTTP for Humans." +dependencies = [ + "certifi>=2017.4.17", + "charset-normalizer<4,>=2", + "idna<4,>=2.5", + "urllib3<3,>=1.21.1", +] + +[[package]] +name = "urllib3" +version = "2.0.5" +requires_python = ">=3.7" +summary = "HTTP library with thread-safe connection pooling, file post, and more." + +[metadata] +lock_version = "4.2" +cross_platform = true +groups = ["default", "dev"] +content_hash = "sha256:6b124fd8499d7ddefb13cb60a64760b0601a8db060263247076bc4f4309cd6cd" + +[metadata.files] +"certifi 2023.7.22" = [ + {url = "https://files.pythonhosted.org/packages/4c/dd/2234eab22353ffc7d94e8d13177aaa050113286e93e7b40eae01fbf7c3d9/certifi-2023.7.22-py3-none-any.whl", hash = "sha256:92d6037539857d8206b8f6ae472e8b77db8058fec5937a1ef3f54304089edbb9"}, + {url = "https://files.pythonhosted.org/packages/98/98/c2ff18671db109c9f10ed27f5ef610ae05b73bd876664139cf95bd1429aa/certifi-2023.7.22.tar.gz", hash = "sha256:539cc1d13202e33ca466e88b2807e29f4c13049d6d87031a3c110744495cb082"}, +] +"charset-normalizer 3.2.0" = [ + {url = "https://files.pythonhosted.org/packages/08/f7/3f36bb1d0d74846155c7e3bf1477004c41243bb510f9082e785809787735/charset_normalizer-3.2.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:09393e1b2a9461950b1c9a45d5fd251dc7c6f228acab64da1c9c0165d9c7765c"}, + {url = "https://files.pythonhosted.org/packages/09/79/1b7af063e7c57a51aab7f2aaccd79bb8a694dfae668e8aa79b0b045b17bc/charset_normalizer-3.2.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:855eafa5d5a2034b4621c74925d89c5efef61418570e5ef9b37717d9c796419c"}, + {url = "https://files.pythonhosted.org/packages/0d/dd/e598cc4e4052aa0779d4c6d5e9840d21ed238834944ccfbc6b33f792c426/charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:e6a5bf2cba5ae1bb80b154ed68a3cfa2fa00fde979a7f50d6598d3e17d9ac20c"}, + {url = "https://files.pythonhosted.org/packages/0f/16/8d50877a7215d31f024245a0acbda9e484dd70a21794f3109a6d8eaeba99/charset_normalizer-3.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:46fb8c61d794b78ec7134a715a3e564aafc8f6b5e338417cb19fe9f57a5a9bf2"}, + {url = "https://files.pythonhosted.org/packages/13/de/10c14aa51375b90ed62232935e6c8997756178e6972c7695cdf0500a60ad/charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f87f746ee241d30d6ed93969de31e5ffd09a2961a051e60ae6bddde9ec3583aa"}, + {url = "https://files.pythonhosted.org/packages/16/36/72dcb89fbd0ff89c556ed4a2cc79fc1b262dcc95e9082d8a5911744dadc9/charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:70c610f6cbe4b9fce272c407dd9d07e33e6bf7b4aa1b7ffb6f6ded8e634e3592"}, + {url = "https://files.pythonhosted.org/packages/19/9f/552f15cb1dade9332d6f0208fa3e6c21bb3eecf1c89862413ed8a3c75900/charset_normalizer-3.2.0-cp37-cp37m-win_amd64.whl", hash = "sha256:c0b21078a4b56965e2b12f247467b234734491897e99c1d51cee628da9786959"}, + {url = "https://files.pythonhosted.org/packages/1b/2c/7376d101efdec15e61e9861890cf107c6ce3cceba89eb87cc416ee0528cd/charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:c8063cf17b19661471ecbdb3df1c84f24ad2e389e326ccaf89e3fb2484d8dd7e"}, + {url = "https://files.pythonhosted.org/packages/23/59/8011a01cd8b904d08d86b4a49f407e713d20ee34155300dc698892a29f8b/charset_normalizer-3.2.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1920d4ff15ce893210c1f0c0e9d19bfbecb7983c76b33f046c13a8ffbd570252"}, + {url = "https://files.pythonhosted.org/packages/27/19/49de2049561eca73233ba0ed7a843c184d364ef3b8886969a48d6793c830/charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:3b1613dd5aee995ec6d4c69f00378bbd07614702a315a2cf6c1d21461fe17c23"}, + {url = "https://files.pythonhosted.org/packages/28/ec/cda85baa366071c48593774eb59a5031793dd974fa26f4982829e971df6b/charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f25c229a6ba38a35ae6e25ca1264621cc25d4d38dca2942a7fce0b67a4efe918"}, + {url = "https://files.pythonhosted.org/packages/2a/53/cf0a48de1bdcf6ff6e1c9a023f5f523dfe303e4024f216feac64b6eb7f67/charset-normalizer-3.2.0.tar.gz", hash = "sha256:3bb3d25a8e6c0aedd251753a79ae98a093c7e7b471faa3aa9a93a81431987ace"}, + {url = "https://files.pythonhosted.org/packages/2e/29/dc806e009ddb357371458de3e93cfde78ea6e5c995df008fb6b048769457/charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f30b48dd7fa1474554b0b0f3fdfdd4c13b5c737a3c6284d3cdc424ec0ffff3a"}, + {url = "https://files.pythonhosted.org/packages/2e/56/faee2b51d73e9675b4766366d925f17c253797e5839c28e1c720ec9dfbfc/charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a38856a971c602f98472050165cea2cdc97709240373041b69030be15047691f"}, + {url = "https://files.pythonhosted.org/packages/31/e9/ae16eca3cf24a15ebfb1e36d755c884a91d61ed40de5e612de6555827729/charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:72814c01533f51d68702802d74f77ea026b5ec52793c791e2da806a3844a46c3"}, + {url = "https://files.pythonhosted.org/packages/3d/91/47454b64516f83c5affdcdb0398bff540185d2c37b687410d67507006624/charset_normalizer-3.2.0-cp38-cp38-win32.whl", hash = "sha256:1000fba1057b92a65daec275aec30586c3de2401ccdcd41f8a5c1e2c87078706"}, + {url = "https://files.pythonhosted.org/packages/45/60/1b2113fe172ac66ac4d210034e937ebe0be30bcae9a7a4d2ae5ad3c018b3/charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b0dac0ff919ba34d4df1b6131f59ce95b08b9065233446be7e459f95554c0dc8"}, + {url = "https://files.pythonhosted.org/packages/47/03/2cde6c5fba0115e8726272aabfca33b9d84d377cc11c4bab092fa9617d7a/charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5e86d77b090dbddbe78867a0275cb4df08ea195e660f1f7f13435a4649e954e5"}, + {url = "https://files.pythonhosted.org/packages/47/71/2ce8dca3e8cf1f65c36b6317cf68382bb259966e3a208da6e5550029ab79/charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:45de3f87179c1823e6d9e32156fb14c1927fcc9aba21433f088fdfb555b77c10"}, + {url = "https://files.pythonhosted.org/packages/49/60/87a026215ed77184c413ebb85bafa6c0a998bdc0d1e03b894fa326f2b0f9/charset_normalizer-3.2.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e1c8a2f4c69e08e89632defbfabec2feb8a8d99edc9f89ce33c4b9e36ab63037"}, + {url = "https://files.pythonhosted.org/packages/4a/46/a22af93e707f0d3c3865a2c21b4363c778239f5a6405aadd220992ac3058/charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c4fb39a81950ec280984b3a44f5bd12819953dc5fa3a7e6fa7a80db5ee853952"}, + {url = "https://files.pythonhosted.org/packages/4d/ce/8ce85a7d61bbfb5e49094040642f1558b3cf6cf2ad91bbb3616a967dea38/charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c4983bf937209c57240cff65906b18bb35e64ae872da6a0db937d7b4af845dd7"}, + {url = "https://files.pythonhosted.org/packages/59/8e/62651b09599938e5e6d068ea723fd22d3f8c14d773c3c11c58e5e7d1eab7/charset_normalizer-3.2.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9bd9b3b31adcb054116447ea22caa61a285d92e94d710aa5ec97992ff5eb7cf3"}, + {url = "https://files.pythonhosted.org/packages/5a/60/eeb158f11b0dee921d3e44bf37971271060b234ee60b14fa16ccc1947cbe/charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f058f6963fd82eb143c692cecdc89e075fa0828db2e5b291070485390b2f1c9c"}, + {url = "https://files.pythonhosted.org/packages/5c/f2/f3faa20684729d3910af2ee142e30432c7a46a817eadeeab87366ed87bbb/charset_normalizer-3.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:48021783bdf96e3d6de03a6e39a1171ed5bd7e8bb93fc84cc649d11490f87cea"}, + {url = "https://files.pythonhosted.org/packages/5d/28/f69dac79bf3986a52bc2f7dc561360c2c9c88cb0270738d86ee5a3d8a0ba/charset_normalizer-3.2.0-cp37-cp37m-win32.whl", hash = "sha256:a401b4598e5d3f4a9a811f3daf42ee2291790c7f9d74b18d75d6e21dda98a1a1"}, + {url = "https://files.pythonhosted.org/packages/5f/52/e8ca03368aeecdd5c0057bd1f8ef189796d232b152e3de4244bb5a72d135/charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e03b8895a6990c9ab2cdcd0f2fe44088ca1c65ae592b8f795c3294af00a461c3"}, + {url = "https://files.pythonhosted.org/packages/63/f9/14ffa4b88c1b42837dfa488b0943b7bd7f54f5b63135bf97e5001f6957e7/charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a7647ebdfb9682b7bb97e2a5e7cb6ae735b1c25008a70b906aecca294ee96cf4"}, + {url = "https://files.pythonhosted.org/packages/6b/b2/9d0c8fe83572a37bd66150399e289d8e96d62eca359ffa67c021b4120887/charset_normalizer-3.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:8b2c760cfc7042b27ebdb4a43a4453bd829a5742503599144d54a032c5dc7e9e"}, + {url = "https://files.pythonhosted.org/packages/6b/b7/f042568ee89c378b457f73fda1642fd3b795df79c285520e4ec8a74c8b09/charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:baacc6aee0b2ef6f3d308e197b5d7a81c0e70b06beae1f1fcacffdbd124fe0e3"}, + {url = "https://files.pythonhosted.org/packages/6f/14/8e317fa69483a2823ea358a77e243c37f23f536a7add1b605460269593b5/charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9e608aafdb55eb9f255034709e20d5a83b6d60c054df0802fa9c9883d0a937aa"}, + {url = "https://files.pythonhosted.org/packages/79/55/9aef5046a1765acacf28f80994f5a964ab4f43ab75208b1265191a11004b/charset_normalizer-3.2.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1a100c6d595a7f316f1b6f01d20815d916e75ff98c27a01ae817439ea7726329"}, + {url = "https://files.pythonhosted.org/packages/7b/c6/7f75892d87d7afcf8ed909f3e74de1bc61abd9d77cd9aab1f449430856c5/charset_normalizer-3.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:203f0c8871d5a7987be20c72442488a0b8cfd0f43b7973771640fc593f56321f"}, + {url = "https://files.pythonhosted.org/packages/80/75/eadff07a61d5602b6b19859d464bc0983654ae79114ef8aa15797b02271c/charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2dee8e57f052ef5353cf608e0b4c871aee320dd1b87d351c28764fc0ca55f9f4"}, + {url = "https://files.pythonhosted.org/packages/81/a0/96317ce912b512b7998434eae5e24b28bcc5f1680ad85348e31e1ca56332/charset_normalizer-3.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7c70087bfee18a42b4040bb9ec1ca15a08242cf5867c58726530bdf3945672ed"}, + {url = "https://files.pythonhosted.org/packages/85/52/77ab28e0eb07f12a02732c55abfc3be481bd46c91d5ade76a8904dfb59a4/charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:c1c76a1743432b4b60ab3358c937a3fe1341c828ae6194108a94c69028247f22"}, + {url = "https://files.pythonhosted.org/packages/89/f5/88e9dd454756fea555198ddbe6fa40d6408ec4f10ad4f0a911e0b7e471e4/charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eef9df1eefada2c09a5e7a40991b9fc6ac6ef20b1372abd48d2794a316dc0449"}, + {url = "https://files.pythonhosted.org/packages/8b/b4/e6da7d4c044852d7a08ba945868eaefa32e8c43665e746f420ef14bdb130/charset_normalizer-3.2.0-cp39-cp39-win32.whl", hash = "sha256:6c409c0deba34f147f77efaa67b8e4bb83d2f11c8806405f76397ae5b8c0d1c9"}, + {url = "https://files.pythonhosted.org/packages/8b/c4/62b920ec8f4ec7b55cd29db894ced9a649214fd506295ac19fb786fe3c6f/charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:c04a46716adde8d927adb9457bbe39cf473e1e2c2f5d0a16ceb837e5d841ad4f"}, + {url = "https://files.pythonhosted.org/packages/8e/a2/77cf1f042a4697822070fd5f3f5f58fd0e3ee798d040e3863eac43e3a2e5/charset_normalizer-3.2.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:4957669ef390f0e6719db3613ab3a7631e68424604a7b448f079bee145da6e09"}, + {url = "https://files.pythonhosted.org/packages/91/6e/db0e545302bf93b6dbbdc496dd192c7f8e8c3bb1584acba069256d8b51d4/charset_normalizer-3.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:681eb3d7e02e3c3655d1b16059fbfb605ac464c834a0c629048a30fad2b27489"}, + {url = "https://files.pythonhosted.org/packages/91/e6/8fa919fc84a106e9b04109de62bdf8526899e2754a64da66e1cd50ac1faa/charset_normalizer-3.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f779d3ad205f108d14e99bb3859aa7dd8e9c68874617c72354d7ecaec2a054ac"}, + {url = "https://files.pythonhosted.org/packages/94/fc/53e12f67fff7a127fe2998de3469a9856c6c7cf67f18dc5f417df3e5e60f/charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:3bb7fda7260735efe66d5107fb7e6af6a7c04c7fce9b2514e04b7a74b06bf5dd"}, + {url = "https://files.pythonhosted.org/packages/95/d2/6f25fddfbe31448ceea236e03b70d2bbd647d4bc9148bf9665307794c4f2/charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d62e51710986674142526ab9f78663ca2b0726066ae26b78b22e0f5e571238dd"}, + {url = "https://files.pythonhosted.org/packages/95/d3/ed29b2d14ec9044a223dcf7c439fa550ef9c6d06c9372cd332374d990559/charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:cd6dbe0238f7743d0efe563ab46294f54f9bc8f4b9bcf57c3c666cc5bc9d1299"}, + {url = "https://files.pythonhosted.org/packages/95/ee/8bb03c3518a228dc5956d1b4f46d8258639ff118881fba456b72b06561cf/charset_normalizer-3.2.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c57921cda3a80d0f2b8aec7e25c8aa14479ea92b5b51b6876d975d925a2ea346"}, + {url = "https://files.pythonhosted.org/packages/97/f6/0bae7bdfb07ca42bf5e3e37dbd0cce02d87dd6e87ea85dff43106dfc1f48/charset_normalizer-3.2.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:95eb302ff792e12aba9a8b8f8474ab229a83c103d74a750ec0bd1c1eea32e669"}, + {url = "https://files.pythonhosted.org/packages/99/23/7262c6a7c8a8c2ec783886166a432985915f67277bc44020d181e5c04584/charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:7a4826ad2bd6b07ca615c74ab91f32f6c96d08f6fcc3902ceeedaec8cdc3bcd6"}, + {url = "https://files.pythonhosted.org/packages/9c/71/bf12b8e0d6e1d84ed29c3e16ea1efc47ae96487bde823130d12139c434a0/charset_normalizer-3.2.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:6339d047dab2780cc6220f46306628e04d9750f02f983ddb37439ca47ced7149"}, + {url = "https://files.pythonhosted.org/packages/9c/74/10a518cd27c2c595768f70ddbd7d05c9acb01b26033f79433105ccc73308/charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41b25eaa7d15909cf3ac4c96088c1f266a9a93ec44f87f1d13d4a0e86c81b982"}, + {url = "https://files.pythonhosted.org/packages/a1/5c/c4ae954751f285c6170c3ef4de04492f88ddb29d218fefbdcbd9fb32ba5c/charset_normalizer-3.2.0-cp311-cp311-win32.whl", hash = "sha256:f2a1d0fd4242bd8643ce6f98927cf9c04540af6efa92323e9d3124f57727bfc1"}, + {url = "https://files.pythonhosted.org/packages/a4/65/057bf29660aae6ade0816457f8db4e749e5c0bfa2366eb5f67db9912fa4c/charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:193cbc708ea3aca45e7221ae58f0fd63f933753a9bfb498a3b474878f12caaad"}, + {url = "https://files.pythonhosted.org/packages/ad/0d/9aa61083c35dc21e75a97c0ee53619daf0e5b4fd3b8b4d8bb5e7e56ed302/charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4b749b9cc6ee664a3300bb3a273c1ca8068c46be705b6c31cf5d276f8628a94"}, + {url = "https://files.pythonhosted.org/packages/af/3d/57e7e401f8db6dd0c56e366d69dc7366173fc549bcd533dea15f2a805000/charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2efb1bd13885392adfda4614c33d3b68dee4921fd0ac1d3988f8cbb7d589e72a"}, + {url = "https://files.pythonhosted.org/packages/af/6f/b9b1613a5b672004f08ef3c02242b07406ff36164725ff15207737601de5/charset_normalizer-3.2.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0b87549028f680ca955556e3bd57013ab47474c3124dc069faa0b6545b6c9710"}, + {url = "https://files.pythonhosted.org/packages/b6/2a/03e909cad170b0df5ce8b731fecbc872b7b922a1d38da441b5062a89e53f/charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:3170c9399da12c9dc66366e9d14da8bf7147e1e9d9ea566067bbce7bb74bd9c2"}, + {url = "https://files.pythonhosted.org/packages/bc/85/ef25d4ba14c7653c3020a1c6e1a7413e6791ef36a0ac177efa605fc2c737/charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:246de67b99b6851627d945db38147d1b209a899311b1305dd84916f2b88526c6"}, + {url = "https://files.pythonhosted.org/packages/bf/a0/188f223c7d8b924fb9b554b9d27e0e7506fd5bf9cfb6dbacb2dfd5832b53/charset_normalizer-3.2.0-py3-none-any.whl", hash = "sha256:8e098148dd37b4ce3baca71fb394c81dc5d9c7728c95df695d2dca218edf40e6"}, + {url = "https://files.pythonhosted.org/packages/c1/92/4e30c977d2dc49ca7f84a053ccefd86097a9d1a220f3e1d1f9932561a992/charset_normalizer-3.2.0-cp310-cp310-win32.whl", hash = "sha256:04e57ab9fbf9607b77f7d057974694b4f6b142da9ed4a199859d9d4d5c63fe96"}, + {url = "https://files.pythonhosted.org/packages/cb/dd/dce14328e6abe0f475e606131298b4c8f628abd62a4e6f27fdfa496b9efe/charset_normalizer-3.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:7095f6fbfaa55defb6b733cfeb14efaae7a29f0b59d8cf213be4e7ca0b857b80"}, + {url = "https://files.pythonhosted.org/packages/cb/e7/5e43745003bf1f90668c7be23fc5952b3a2b9c2558f16749411c18039b36/charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:89f1b185a01fe560bc8ae5f619e924407efca2191b56ce749ec84982fc59a32a"}, + {url = "https://files.pythonhosted.org/packages/cb/f9/a652e1b495345000bb7f0e2a960a82ca941db55cb6de158d542918f8b52b/charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a386ebe437176aab38c041de1260cd3ea459c6ce5263594399880bbc398225b2"}, + {url = "https://files.pythonhosted.org/packages/d3/d8/50a33f82bdf25e71222a55cef146310e3e9fe7d5790be5281d715c012eae/charset_normalizer-3.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e857a2232ba53ae940d3456f7533ce6ca98b81917d47adc3c7fd55dad8fab858"}, + {url = "https://files.pythonhosted.org/packages/e8/74/077cb06aed5d41118a5803e842943311032ab2fb94cf523be620c5be9911/charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:bf420121d4c8dce6b889f0e8e4ec0ca34b7f40186203f06a946fa0276ba54029"}, + {url = "https://files.pythonhosted.org/packages/e8/ad/ac491a1cf960ec5873c1b0e4fd4b90b66bfed4a1063933612f2da8189eb8/charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:ccd16eb18a849fd8dcb23e23380e2f0a354e8daa0c984b8a732d9cfaba3a776d"}, + {url = "https://files.pythonhosted.org/packages/ec/a7/96835706283d63fefbbbb4f119d52f195af00fc747e67cc54397c56312c8/charset_normalizer-3.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a103b3a7069b62f5d4890ae1b8f0597618f628b286b03d4bc9195230b154bfa9"}, + {url = "https://files.pythonhosted.org/packages/ed/21/03b4a3533b7a845ee31ed4542ca06debdcf7f12c099ae3dd6773c275b0df/charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f7560358a6811e52e9c4d142d497f1a6e10103d3a6881f18d04dbce3729c0e2c"}, + {url = "https://files.pythonhosted.org/packages/ee/ff/997d61ca61efe90662181f494c8e9fdac14e32de26cc6cb7c7a3fe96c862/charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:ee4006268ed33370957f55bf2e6f4d263eaf4dc3cfc473d1d90baff6ed36ce4a"}, + {url = "https://files.pythonhosted.org/packages/f0/24/7e6c604d80a8eb4378cb075647e65b7905f06645243b43c79fe4b7487ed7/charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94aea8eff76ee6d1cdacb07dd2123a68283cb5569e0250feab1240058f53b623"}, + {url = "https://files.pythonhosted.org/packages/f1/f2/ef1479e741a7ed166b8253987071b2cf2d2b727fc8fa081520e3f7c97e44/charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:db901e2ac34c931d73054d9797383d0f8009991e723dab15109740a63e7f902a"}, + {url = "https://files.pythonhosted.org/packages/f2/e8/d9651a0afd4ee792207b24bd1d438ed750f1c0f29df62bd73d24ded428f9/charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:1249cbbf3d3b04902ff081ffbb33ce3377fa6e4c7356f759f3cd076cc138d020"}, + {url = "https://files.pythonhosted.org/packages/f4/39/b024eb6c2a2b8136f1f48fd2f2eee22ed98fbfe3cd7ddf81dad2b8dd3c1b/charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2f4ac36d8e2b4cc1aa71df3dd84ff8efbe3bfb97ac41242fbcfc053c67434f46"}, + {url = "https://files.pythonhosted.org/packages/f5/50/410da81fd67eb1becef9d633f6aae9f6e296f60126cfc3d19631f7919f76/charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:aaf63899c94de41fe3cf934601b0f7ccb6b428c6e4eeb80da72c58eab077b19a"}, + {url = "https://files.pythonhosted.org/packages/f9/0d/514be8597d7a96243e5467a37d337b9399cec117a513fcf9328405d911c0/charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8700f06d0ce6f128de3ccdbc1acaea1ee264d2caa9ca05daaf492fde7c2a7200"}, + {url = "https://files.pythonhosted.org/packages/fd/17/0a1dba835ec37a3cc025f5c49653effb23f8cd391dea5e60a5696d639a92/charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:8c2f5e83493748286002f9369f3e6607c565a6a90425a3a1fef5ae32a36d749d"}, +] +"idna 3.4" = [ + {url = "https://files.pythonhosted.org/packages/8b/e1/43beb3d38dba6cb420cefa297822eac205a277ab43e5ba5d5c46faf96438/idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"}, + {url = "https://files.pythonhosted.org/packages/fc/34/3030de6f1370931b9dbb4dad48f6ab1015ab1d32447850b9fc94e60097be/idna-3.4-py3-none-any.whl", hash = "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"}, +] +"pi 0.1.2" = [ + {url = "https://files.pythonhosted.org/packages/c5/49/b6bf523a86a63dd364ae0fb6df85645961af166855cf038b361a31d5d504/pi-0.1.2.tar.gz", hash = "sha256:8d503a790317f7fbce7469c4160e44b1c76492571b2b0c0596636a1794800f75"}, +] +"requests 2.31.0" = [ + {url = "https://files.pythonhosted.org/packages/70/8e/0e2d847013cb52cd35b38c009bb167a1a26b2ce6cd6965bf26b47bc0bf44/requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f"}, + {url = "https://files.pythonhosted.org/packages/9d/be/10918a2eac4ae9f02f6cfe6414b7a155ccd8f7f9d4380d62fd5b955065c3/requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"}, +] +"urllib3 2.0.5" = [ + {url = "https://files.pythonhosted.org/packages/37/dc/399e63f5d1d96bb643404ee830657f4dfcf8503f5ba8fa3c6d465d0c57fe/urllib3-2.0.5-py3-none-any.whl", hash = "sha256:ef16afa8ba34a1f989db38e1dbbe0c302e4289a47856990d0682e374563ce35e"}, + {url = "https://files.pythonhosted.org/packages/51/13/62cb4a0af89fdf72db4a0ead8026e724c7f3cbf69706d84a4eff439be853/urllib3-2.0.5.tar.gz", hash = "sha256:13abf37382ea2ce6fb744d4dad67838eec857c9f4f57009891805e0b5e123594"}, +] diff --git a/examples/dream2nix-repo-flake-pdm/pyproject.toml b/examples/dream2nix-repo-flake-pdm/pyproject.toml new file mode 100644 index 0000000000..e79196ef21 --- /dev/null +++ b/examples/dream2nix-repo-flake-pdm/pyproject.toml @@ -0,0 +1,19 @@ + +[project] +name = "my-project" +version = "0.1.0" +description = "" +dependencies = [ + "requests>=2.31.0", +] +requires-python = ">=3.10" +readme = "README.md" +license = {text = "MIT"} +[project.optional-dependencies] +dev = [ + "pi>=0.1.2", +] + +[build-system] +requires = ["pdm-backend"] +build-backend = "pdm.backend" diff --git a/flake.lock b/flake.lock index 791d7a1545..356a077a79 100644 --- a/flake.lock +++ b/flake.lock @@ -103,11 +103,11 @@ "treefmt-nix": "treefmt-nix" }, "locked": { - "lastModified": 1690289081, - "narHash": "sha256-PCXQAQt8+i2pkUym9P1JY4JGoeZJLzzxWBhprHDdItM=", + "lastModified": 1694670962, + "narHash": "sha256-HvMq0TJGYSx37zHm4j2d+JUZx4/6X7xKEt/0DeCiwjQ=", "owner": "adisbladis", "repo": "nix-unit", - "rev": "a9d6f33e50d4dcd9cfc0c92253340437bbae282b", + "rev": "3ed2378bddad85257fc508a291408f9ed9673d01", "type": "github" }, "original": { diff --git a/modules/default.nix b/modules/default.nix index e7ebb61d18..3fc972bc28 100644 --- a/modules/default.nix +++ b/modules/default.nix @@ -1 +1,16 @@ -(import ./flake.nix).outputs {} +# This file provides backward compatibility to nix < 2.4 clients +let + flake = + import + ( + let + lock = builtins.fromJSON (builtins.readFile ./flake.lock); + in + fetchTarball { + url = "https://github.com/edolstra/flake-compat/archive/${lock.nodes.flake-compat.locked.rev}.tar.gz"; + sha256 = lock.nodes.flake-compat.locked.narHash; + } + ) + {src = ./.;}; +in + flake.defaultNix diff --git a/modules/dream2nix/_template/default.nix b/modules/dream2nix/_template/default.nix index 94ae1213f0..22604185aa 100644 --- a/modules/dream2nix/_template/default.nix +++ b/modules/dream2nix/_template/default.nix @@ -2,9 +2,10 @@ config, lib, ... -}: let - l = lib // builtins; -in { +}: { + imports = [ + ./interface.nix + ]; config = { }; } diff --git a/modules/dream2nix/_template/interface.nix b/modules/dream2nix/_template/interface.nix index 6674b1e420..116ba48f1a 100644 --- a/modules/dream2nix/_template/interface.nix +++ b/modules/dream2nix/_template/interface.nix @@ -3,10 +3,9 @@ lib, ... }: let - l = lib // builtins; - t = l.types; + t = lib.types; in { - options = l.mapAttrs (_: l.mkOption) { + options = lib.mapAttrs (_: lib.mkOption) { # put options here }; } diff --git a/modules/dream2nix/groups/default.nix b/modules/dream2nix/groups/default.nix new file mode 100644 index 0000000000..c57356ed48 --- /dev/null +++ b/modules/dream2nix/groups/default.nix @@ -0,0 +1,9 @@ +{ + config, + lib, + ... +}: { + imports = [ + ./interface.nix + ]; +} diff --git a/modules/dream2nix/groups/group.nix b/modules/dream2nix/groups/group.nix new file mode 100644 index 0000000000..e70c6af88c --- /dev/null +++ b/modules/dream2nix/groups/group.nix @@ -0,0 +1,47 @@ +{commonModule}: { + lib, + dream2nix, + config, + ... +}: let + t = lib.types; + packageType = t.deferredModuleWith { + staticModules = [ + dream2nix.modules.dream2nix.core + commonModule + ]; + }; +in { + options = { + overrides = lib.mkOption { + type = lib.attrs; + description = '' + A set of package overrides + ''; + }; + packages = lib.mkOption { + type = t.lazyAttrsOf packageType; + description = '' + The package configurations to evaluate + ''; + }; + packagesEval = lib.mkOption { + type = t.lazyAttrsOf (t.submoduleWith {modules = [];}); + description = '' + The evaluated dream2nix package modules + ''; + internal = true; + }; + public = lib.mkOption { + type = t.lazyAttrsOf t.package; + description = '' + The evaluated packages ready to consume + ''; + readOnly = true; + }; + }; + config = { + packagesEval = config.packages; + public = lib.mapAttrs (name: pkg: pkg.public) config.packagesEval; + }; +} diff --git a/modules/dream2nix/groups/interface.nix b/modules/dream2nix/groups/interface.nix new file mode 100644 index 0000000000..3d9faa4480 --- /dev/null +++ b/modules/dream2nix/groups/interface.nix @@ -0,0 +1,29 @@ +{ + config, + lib, + dream2nix, + specialArgs, + ... +}: let + t = lib.types; + groupType = t.submoduleWith { + modules = [(import ./group.nix {inherit (config) commonModule;})]; + inherit specialArgs; + }; +in { + options = { + groups = lib.mkOption { + type = t.lazyAttrsOf groupType; + description = '' + A set of packages + ''; + }; + commonModule = lib.mkOption { + type = t.deferredModule; + description = '' + Common configuration for all packages in all groups + ''; + default = {}; + }; + }; +} diff --git a/modules/dream2nix/python-pdm/default.nix b/modules/dream2nix/python-pdm/default.nix new file mode 100644 index 0000000000..6473e9fd66 --- /dev/null +++ b/modules/dream2nix/python-pdm/default.nix @@ -0,0 +1,27 @@ +{ + config, + lib, + dream2nix, + ... +}: let + t = lib.types; + pyproject-nix = import (dream2nix.inputs.pyproject-nix + "/lib") {inherit lib;}; + interpreterVersion = config.pythonInterpreter.pythonVersion; + + lock-data = lib.importTOML config.pdm.lock-file; + pyproject-data = lib.importTOML config.pdm.pyproject; + + pyproject-parsed = pyproject-nix.project.loadPyproject { + pyproject = pyproject-data; + }; +in { + imports = [ + dream2nix.modules.groups + ./interface.nix + ]; + pdm.debugData = pyproject-parsed; + commonModule = { + options.sourceSelector = import ./sourceSeelctorOption.nix {}; + config.sourceSelector = lib.mkOptionDefault config.pdm.sourceSelector; + }; +} diff --git a/modules/dream2nix/python-pdm/interface.nix b/modules/dream2nix/python-pdm/interface.nix new file mode 100644 index 0000000000..835d2d3b36 --- /dev/null +++ b/modules/dream2nix/python-pdm/interface.nix @@ -0,0 +1,27 @@ +{ + config, + lib, + dream2nix, + ... +}: let + l = lib // builtins; + t = l.types; +in { + options.pdm = { + lockfile = l.mkOption { + type = t.path; + }; + pyproject = l.mkOption { + type = t.path; + }; + pythonInterpreter = l.mkOption { + type = t.package; + }; + + debugData = l.mkOption { + type = t.raw; + }; + + sourceSelector = import ./sourceSelectorOption.nix {inherit lib;}; + }; +} diff --git a/modules/dream2nix/python-pdm/lib.nix b/modules/dream2nix/python-pdm/lib.nix new file mode 100644 index 0000000000..4c97ee5d92 --- /dev/null +++ b/modules/dream2nix/python-pdm/lib.nix @@ -0,0 +1,147 @@ +{ + lib, + libpyproject, +}: rec { + isUsableFilename = { + environ, + filename, + }: let + is_wheel = libpyproject.pep427.isWheelFileName filename; + func = + if is_wheel + then isUsableWheelFilename + else isUsableSdistFilename; + in + func {inherit environ filename;}; + + valid_sdist_extensions = [".tar.gz" ".zip"]; + + # Check that the given filename is a valid sdist for our environment. + # Note that sdist is not environment-dependent, so all we care aboutis the extension. + isUsableSdistFilename = { + environ, # Not needed + filename, + }: let + isValidSuffix = suffix: lib.strings.hasSuffix suffix filename; + is_valid = lib.lists.any isValidSuffix valid_sdist_extensions; + in + is_valid; + + # matchUniversalWheelFileName = lib.match "([^-]+)-([^-]+)(-([[:digit:]][^-]*))?-([^-]+)-([^-]+)-(.+).[tar.gz|zip]"; + # name: matchUniversalWheelFileName name != null; + + isValidUniversalWheelFilename = {filename}: let + parsed_filename = libpyproject.pep427.parseFileName filename; + is_valid = parsed_filename.languageTag == "py3" && parsed_filename.abiTag == "none" && parsed_filename.platformTags == ["any"]; + in + is_valid; + + # Check that the given filenameis a valid wheel for our environment. + isUsableWheelFilename = { + environ, + filename, + }: let + parsed_filename = libpyproject.pep427.parseFileName filename; + is_valid_build = true; + is_valid_implementation = true; + is_valid_abi = true; + is_valid_platform = true; + is_valid = is_valid_build && is_valid_implementation && is_valid_abi && is_valid_platform; + in + is_valid; + + # Select single item matching the extension. + # If multiple items have the extension, raise. + # If no items match, return null. + selectExtension = names: ext: let + selected = lib.findSingle (name: lib.hasSuffix ext name) null "multiple" names; + in + if selected == "multiple" + then throw "Multiple names found with extension ${ext}" + else selected; + + # Select a single sdist from a list of filenames. + # If multiple sdist we choose the preferred sdist. + # If no valid sdist present we return null. + selectSdist = filenames: let + # sdists = lib.filter (filename: isUsableSdistFilename {environ = {}; inherit filename;}) filenames; + select = selectExtension filenames; + selection = map select valid_sdist_extensions; + selected = lib.findFirst (name: name != null) null selection; + in + selected; + + # Select a single wheel from a list of filenames + # This assumes filtering on usable wheels has already been performed. + selectWheel = filenames: lib.findFirst (x: lib.hasSuffix ".whl" x) null filenames; + + # Source selectors. + # Prefer to select a wheel from a list of filenames. + # Filenames should already have been filtered on environment usability. + preferWheelSelector = filenames: let + wheel = selectWheel filenames; + sdist = selectSdist filenames; + in + if wheel != null + then wheel + else if sdist != null + then sdist + else null; + + preferSdistSelector = filenames: let + wheel = selectWheel filenames; + sdist = selectSdist filenames; + in + if sdist != null + then sdist + else if wheel != null + then wheel + else null; + + # Parse lockfile data. + # Returns a set with package name as key + # and as value the version, sources and dependencies + # The packages are not yet divided into groups. + parseLockData = {lock-data}: let + # TODO: validate against lock file version. + func = item: let + value = { + inherit (item) version; + requires_python = item.requires_python or null; # check already here against Python version? + sources = lock-data.metadata.files."${item.name} ${item.version}"; + # In the future we could add additional meta data fields + # such as summary + }; + in + lib.nameValuePair item.name value; + in + lib.listToAttrs (map func lock-data.package); + + # } + # # Function that parses pyproject.toml and pdm.lock + # # and returns the package sets that are described. + # { pyproject-data + # , pdm-lock-data + # , lib # nixpkgs.lib + # , lib-pyproject + # }: let + # # Collect the attributes for a given package name. + # get-pkg-attrs-from-lock = pkgname: let + # # Collect version, python constraint and dependencies. + # package = lib.findSingle (pkg: pkg.name == pkgname) pkgname; + # # Collect source + # get-source = { + # version, + # }: + # attrs = pdm-lock-data. + # in { + # } + # get-group-pkgnames = groupname: + # # Collect group attributes for a given group name. + # get-group-attrs = groupname: let + # in { } + # groups = pdm-lock-data.metadata.groups; + # # Whether the project defines a library or only optional groups. + # providesLibrary = lib.elem "default" groups; + # in { } +} diff --git a/modules/dream2nix/python-pdm/sourceSelectorOption.nix b/modules/dream2nix/python-pdm/sourceSelectorOption.nix new file mode 100644 index 0000000000..4a108217a2 --- /dev/null +++ b/modules/dream2nix/python-pdm/sourceSelectorOption.nix @@ -0,0 +1,14 @@ +{lib}: +lib.mkOption { + type = lib.types.functionTo lib.types.str; + description = '' + A selector function which picks a source for a specific dependency + Python dependencies can have multiple possible sources, like for example: + - requests-2.31.0.tar.gz + - requests-2.31.0-py3-none-any.whl + The selector receives a list of possible sources and should return either a single source or null. + ''; + example = lib.literalExpression '' + fnames: lib.findFirst (fname: lib.hasSuffix "none-any.whl") none fnames + ''; +} diff --git a/modules/flake-parts/checks.nix-unit.nix b/modules/flake-parts/checks.nix-unit.nix index e3b024d1c7..57761ca94c 100644 --- a/modules/flake-parts/checks.nix-unit.nix +++ b/modules/flake-parts/checks.nix-unit.nix @@ -6,18 +6,32 @@ lib, system, ... - }: + }: let + modulesFlake = import "${self}/modules"; + inputs = lib.mapAttrs (name: input: "${input.outPath}") modulesFlake.inputs; + inputsFile = builtins.toFile "inputs.json" (builtins.toJSON inputs); + in lib.optionalAttrs (system == "x86_64-linux") { # map all modules in /examples to a package output in the flake. - checks.nix-unit = pkgs.runCommand "nix-unit-tests" {} '' - export NIX_PATH=nixpkgs=${pkgs.path} - for test in ${self}/tests/nix-unit/*; do - echo -e "Executing tests from file $test" - ${inputs'.nix-unit.packages.nix-unit}/bin/nix-unit \ - "$test" \ - --eval-store $(realpath .) - done - touch $out - ''; + checks.nix-unit = + pkgs.runCommand "nix-unit-tests" { + nativeBuildInputs = [ + pkgs.nix + ]; + } '' + export NIX_PATH=nixpkgs=${pkgs.path} + export HOME=$(realpath .) + for test in ${self}/tests/nix-unit/*; do + if [ -f "$test" ]; then + continue + fi + echo -e "Executing tests from file $test" + ${inputs'.nix-unit.packages.nix-unit}/bin/nix-unit \ + "$test" \ + --eval-store $(realpath .) \ + --arg inputs 'builtins.fromJSON (builtins.readFile ${inputsFile})' + done + touch $out + ''; }; } diff --git a/modules/flake.lock b/modules/flake.lock new file mode 100644 index 0000000000..3c5591d05c --- /dev/null +++ b/modules/flake.lock @@ -0,0 +1,44 @@ +{ + "nodes": { + "flake-compat": { + "flake": false, + "locked": { + "lastModified": 1673956053, + "narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, + "pyproject-nix": { + "flake": false, + "locked": { + "lastModified": 1694075710, + "narHash": "sha256-B2EzHfVwk6RlW6KGXh/85DkffI8QIaD7ugm119Xz5Hs=", + "owner": "adisbladis", + "repo": "pyproject.nix", + "rev": "c66dab8e7bce2a13c10baeebfe8fe63c51df62c3", + "type": "github" + }, + "original": { + "owner": "adisbladis", + "repo": "pyproject.nix", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-compat": "flake-compat", + "pyproject-nix": "pyproject-nix" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/modules/flake.nix b/modules/flake.nix index 54596fdba4..f29fa3181a 100644 --- a/modules/flake.nix +++ b/modules/flake.nix @@ -1,6 +1,14 @@ { description = "(modules only) dream2nix: Automate reproducible packaging for various language ecosystems"; + inputs = { + flake-compat.url = "github:edolstra/flake-compat"; + flake-compat.flake = false; + + pyproject-nix.url = "github:adisbladis/pyproject.nix"; + pyproject-nix.flake = false; + }; + outputs = _: let modulesDir = ./.; diff --git a/tests/nix-unit/fixtures.nix b/tests/nix-unit/fixtures.nix new file mode 100644 index 0000000000..16794f7e35 --- /dev/null +++ b/tests/nix-unit/fixtures.nix @@ -0,0 +1,17 @@ +{dream2nix}: { + basic-derivation = { + # select builtins.derivation as a backend for this package + imports = [ + dream2nix.modules.dream2nix.builtins-derivation + ]; + + name = "test"; + + # set options + builtins-derivation = { + builder = "/bin/sh"; + args = ["-c" "echo $name > $out"]; + system = "x86_64-linux"; + }; + }; +} diff --git a/tests/nix-unit/test_groups/default.nix b/tests/nix-unit/test_groups/default.nix new file mode 100644 index 0000000000..d1c1d792ae --- /dev/null +++ b/tests/nix-unit/test_groups/default.nix @@ -0,0 +1,38 @@ +{ + pkgs ? import {}, + lib ? import , + dream2nix ? (import (../../../modules + "/flake.nix")).outputs {}, +}: let + fixtures = import ../fixtures.nix {inherit dream2nix;}; + eval = module: + (lib.evalModules { + modules = [ + dream2nix.modules.dream2nix.groups + module + ]; + specialArgs = { + inherit dream2nix; + packageSets.nixpkgs = pkgs; + }; + }) + .config; +in { + test_groups_simple = let + config = eval { + groups.my-group.packages.hello = {...}: fixtures.basic-derivation; + }; + in { + expr = config.groups.my-group.public.hello ? drvPath; + expected = true; + }; + + test_groups_commonModule = let + config = eval { + groups.my-group.packages.hello = {...}: fixtures.basic-derivation; + commonModule = {name = lib.mkForce "hello-mod";}; + }; + in { + expr = "${config.groups.my-group.public.hello.name}"; + expected = "hello-mod"; + }; +} diff --git a/tests/nix-unit/test_python-pdm-lib/default.nix b/tests/nix-unit/test_python-pdm-lib/default.nix new file mode 100644 index 0000000000..72d8eea3fd --- /dev/null +++ b/tests/nix-unit/test_python-pdm-lib/default.nix @@ -0,0 +1,159 @@ +{ + pkgs ? import {}, + lib ? import , + dream2nix ? (import (../../../modules + "/default.nix")), + inputs ? dream2nix.inputs, +}: let + libpdm = (import ../../../modules/dream2nix/python-pdm/lib.nix) { + inherit lib libpyproject; + }; + pyproject-nix = inputs.pyproject-nix; + libpyproject = import (pyproject-nix + "/lib") {inherit lib;}; + + testIsUsableSdistFilename = filename: let + environ = libpyproject.pep508.mkEnviron pkgs.python3; + in + libpdm.isUsableSdistFilename {inherit environ filename;}; + + # test_data = { + # "sdist" = "certifi-2023.7.22.tar.gz"; + # "" + # }; + + tests_isUsableFilename = let + testIsUsableWheelFilename = filename: let + environ = libpyproject.pep508.mkEnviron pkgs.python3; + in + libpdm.isUsableWheelFilename {inherit environ filename;}; + in { + test_isUsableFilename__sdist = { + expr = testIsUsableSdistFilename "certifi-2023.7.22.tar.gz"; + expected = true; + }; + + test_isUsableFilename__wheel_universal = { + expr = testIsUsableWheelFilename "certifi-2023.7.22-py3-none-any.whl"; + expected = true; + }; + }; + + tests_isValidUniversalWheel = let + testIsValidUniversalWheelFilename = filename: + libpdm.isValidUniversalWheelFilename {inherit filename;}; + in { + test_isValidUniversalWheelFilename__wheel_universal = { + expr = testIsValidUniversalWheelFilename "certifi-2023.7.22-py3-none-any.whl"; + expected = true; + }; + + test_isValidUniversalWheelFilename__wheel_not_universal = { + expr = testIsValidUniversalWheelFilename "certifi-2023.7.22-py3-abi3-any.whl"; + expected = false; + }; + }; + + tests_selectExtension = let + names = [ + "certifi-2023.7.22-py3-abi3-any.whl" + "certifi-2023.7.22.tar.gz" + "certifi-2023.7.22.zip" + "certifi-2023.7.22.zip" + ]; + in { + test_selectExtension__tar_gz = { + expr = libpdm.selectExtension names ".tar.gz"; + expected = "certifi-2023.7.22.tar.gz"; + }; + test_selectExtension__zip = let + extension = ".zip"; + in { + expr = libpdm.selectExtension names extension; + expectedError.type = "ThrownError"; + expectedError.msg = "Multiple names found with extension ${extension}"; + }; + }; + + tests_selectSdist = let + names = [ + "certifi-2023.7.22-py3-abi3-any.whl" + "certifi-2023.7.22.tar.gz" + "certifi-2023.7.22.zip" + "certifi-2023.7.22.zip" + ]; + in { + test_selectSdist__tar_gz = { + expr = libpdm.selectSdist names; + expected = "certifi-2023.7.22.tar.gz"; + }; + test_selectSdist__no_sdist = let + names = [ + "certifi-2023.7.22-py3-abi3-any.whl" + ]; + in { + expr = libpdm.selectSdist names; + expected = null; + }; + test_selectSdist__order = let + names = [ + "certifi-2023.7.22.zip" + "certifi-2023.7.22.tar.gz" + ]; + in { + expr = libpdm.selectSdist names; + expected = "certifi-2023.7.22.tar.gz"; + }; + }; + + tests_preferWheelSelector = { + test_preferWheelSelector__has_wheel = let + names = [ + "certifi-2023.7.22-py3-abi3-any.whl" + "certifi-2023.7.22.tar.gz" + "certifi-2023.7.22.zip" + ]; + in { + expr = libpdm.preferWheelSelector names; + expected = "certifi-2023.7.22-py3-abi3-any.whl"; + }; + test_preferWheelSelector__only_sdist = let + names = [ + "certifi-2023.7.22.zip" + "certifi-2023.7.22.tar.gz" + ]; + in { + expr = libpdm.preferWheelSelector names; + expected = "certifi-2023.7.22.tar.gz"; + }; + }; + tests_preferSdistSelector = { + test_preferSdistSelector__has_sdist = let + names = [ + "certifi-2023.7.22-py3-abi3-any.whl" + "certifi-2023.7.22.tar.gz" + "certifi-2023.7.22.zip" + ]; + in { + expr = libpdm.preferSdistSelector names; + expected = "certifi-2023.7.22.tar.gz"; + }; + test_preferSdistSelectorr__only_sdist = let + names = [ + "certifi-2023.7.22.zip" + "certifi-2023.7.22.tar.gz" + ]; + in { + expr = libpdm.preferSdistSelector names; + expected = "certifi-2023.7.22.tar.gz"; + }; + }; + tests_parseLockData = let + lock-data = lib.importTOML ./../../../examples/dream2nix-repo-flake-pdm/pdm.lock; + parsed = libpdm.parseLockData {inherit lock-data;}; + in { + test_parseLockData = { + expr = lib.elemAt (lib.attrNames parsed) 0; + expected = "certifi"; + }; + }; +in + tests_isUsableFilename // tests_isValidUniversalWheel // tests_selectExtension // tests_selectSdist // tests_preferWheelSelector // tests_preferSdistSelector // tests_parseLockData diff --git a/tests/nix-unit/test_python-pdm/default.nix b/tests/nix-unit/test_python-pdm/default.nix new file mode 100644 index 0000000000..5440504217 --- /dev/null +++ b/tests/nix-unit/test_python-pdm/default.nix @@ -0,0 +1,31 @@ +{ + pkgs ? import {}, + lib ? import , + dream2nix ? (import (../../../modules + "/default.nix")), +}: let + eval = module: + (lib.evalModules { + modules = [ + dream2nix.modules.dream2nix.python-pdm + module + ]; + specialArgs = { + inherit dream2nix; + packageSets.nixpkgs = pkgs; + }; + }) + .config; +in { + test_pdm = let + config = eval { + # TODO: create fixtures + pdm.lockfile = ./../../../examples/dream2nix-repo-flake-pdm/pdm.lock; + pdm.pyproject = ./../../../examples/dream2nix-repo-flake-pdm/pyproject.toml; + # groups.my-group.packages.hello = {...}: fixtures.basic-derivation; + }; + in { + expr = true; + # expr = config.groups.my-group.public.hello ? drvPath; + expected = true; + }; +} From 98f7fac5a13198cfcde8a8906d66074b0373e6b9 Mon Sep 17 00:00:00 2001 From: DavHau Date: Thu, 28 Sep 2023 19:15:42 +0100 Subject: [PATCH 39/70] chore(python-pdm): rename python-pdm -> WIP-python-pdm --- examples/dream2nix-repo-flake-pdm/flake.nix | 2 +- modules/dream2nix/{python-pdm => WIP-python-pdm}/default.nix | 0 modules/dream2nix/{python-pdm => WIP-python-pdm}/interface.nix | 0 modules/dream2nix/{python-pdm => WIP-python-pdm}/lib.nix | 0 .../{python-pdm => WIP-python-pdm}/sourceSelectorOption.nix | 0 tests/nix-unit/test_python-pdm-lib/default.nix | 2 +- tests/nix-unit/test_python-pdm/default.nix | 2 +- 7 files changed, 3 insertions(+), 3 deletions(-) rename modules/dream2nix/{python-pdm => WIP-python-pdm}/default.nix (100%) rename modules/dream2nix/{python-pdm => WIP-python-pdm}/interface.nix (100%) rename modules/dream2nix/{python-pdm => WIP-python-pdm}/lib.nix (100%) rename modules/dream2nix/{python-pdm => WIP-python-pdm}/sourceSelectorOption.nix (100%) diff --git a/examples/dream2nix-repo-flake-pdm/flake.nix b/examples/dream2nix-repo-flake-pdm/flake.nix index 7b315a596c..dba0790f2f 100644 --- a/examples/dream2nix-repo-flake-pdm/flake.nix +++ b/examples/dream2nix-repo-flake-pdm/flake.nix @@ -21,7 +21,7 @@ ... }: { imports = [ - dream2nix.modules.dream2nix.python-pdm + dream2nix.modules.dream2nix.WIP-python-pdm ]; pdm.lockfile = ./pdm.lock; pdm.pyproject = ./pyproject.toml; diff --git a/modules/dream2nix/python-pdm/default.nix b/modules/dream2nix/WIP-python-pdm/default.nix similarity index 100% rename from modules/dream2nix/python-pdm/default.nix rename to modules/dream2nix/WIP-python-pdm/default.nix diff --git a/modules/dream2nix/python-pdm/interface.nix b/modules/dream2nix/WIP-python-pdm/interface.nix similarity index 100% rename from modules/dream2nix/python-pdm/interface.nix rename to modules/dream2nix/WIP-python-pdm/interface.nix diff --git a/modules/dream2nix/python-pdm/lib.nix b/modules/dream2nix/WIP-python-pdm/lib.nix similarity index 100% rename from modules/dream2nix/python-pdm/lib.nix rename to modules/dream2nix/WIP-python-pdm/lib.nix diff --git a/modules/dream2nix/python-pdm/sourceSelectorOption.nix b/modules/dream2nix/WIP-python-pdm/sourceSelectorOption.nix similarity index 100% rename from modules/dream2nix/python-pdm/sourceSelectorOption.nix rename to modules/dream2nix/WIP-python-pdm/sourceSelectorOption.nix diff --git a/tests/nix-unit/test_python-pdm-lib/default.nix b/tests/nix-unit/test_python-pdm-lib/default.nix index 72d8eea3fd..b40e2cec16 100644 --- a/tests/nix-unit/test_python-pdm-lib/default.nix +++ b/tests/nix-unit/test_python-pdm-lib/default.nix @@ -4,7 +4,7 @@ dream2nix ? (import (../../../modules + "/default.nix")), inputs ? dream2nix.inputs, }: let - libpdm = (import ../../../modules/dream2nix/python-pdm/lib.nix) { + libpdm = (import ../../../modules/dream2nix/WIP-python-pdm/lib.nix) { inherit lib libpyproject; }; pyproject-nix = inputs.pyproject-nix; diff --git a/tests/nix-unit/test_python-pdm/default.nix b/tests/nix-unit/test_python-pdm/default.nix index 5440504217..134944275c 100644 --- a/tests/nix-unit/test_python-pdm/default.nix +++ b/tests/nix-unit/test_python-pdm/default.nix @@ -6,7 +6,7 @@ eval = module: (lib.evalModules { modules = [ - dream2nix.modules.dream2nix.python-pdm + dream2nix.modules.dream2nix.WIP-python-pdm module ]; specialArgs = { From 6b89285dbc791bed1b7c1f03ebc745806d530306 Mon Sep 17 00:00:00 2001 From: DavHau Date: Thu, 28 Sep 2023 20:42:34 +0100 Subject: [PATCH 40/70] feat(python-pdm): initialize wheel filtering --- modules/dream2nix/WIP-python-pdm/lib.nix | 31 ++++++- .../nix-unit/test_python-pdm-lib/default.nix | 15 +++- .../nix-unit/test_python-pdm-lib/environ.json | 85 +++++++++++++++++++ 3 files changed, 125 insertions(+), 6 deletions(-) create mode 100644 tests/nix-unit/test_python-pdm-lib/environ.json diff --git a/modules/dream2nix/WIP-python-pdm/lib.nix b/modules/dream2nix/WIP-python-pdm/lib.nix index 4c97ee5d92..9f8b820c52 100644 --- a/modules/dream2nix/WIP-python-pdm/lib.nix +++ b/modules/dream2nix/WIP-python-pdm/lib.nix @@ -2,6 +2,18 @@ lib, libpyproject, }: rec { + getFilename = url: lib.lists.last (lib.splitString "/" url); + + # Convert sources to mapping with filename as key. + sourcesToAttrs = sources: + lib.listToAttrs ( + map ( + source: + lib.nameValuePair (getFilename source.url) source + ) + sources + ); + isUsableFilename = { environ, filename, @@ -41,6 +53,7 @@ environ, filename, }: let + # TODO: implement it parsed_filename = libpyproject.pep427.parseFileName filename; is_valid_build = true; is_valid_implementation = true; @@ -102,19 +115,31 @@ # Returns a set with package name as key # and as value the version, sources and dependencies # The packages are not yet divided into groups. - parseLockData = {lock-data}: let + parseLockData = { + lock-data, + environ, + selector, + }: let # TODO: validate against lock file version. func = item: let + sources = sourcesToAttrs lock-data.metadata.files."${item.name} ${item.version}"; + compatibleSources = + lib.filterAttrs + ( + filename: source: + isUsableFilename {inherit environ filename;} + ) + sources; value = { inherit (item) version; - requires_python = item.requires_python or null; # check already here against Python version? - sources = lock-data.metadata.files."${item.name} ${item.version}"; + source = sources.${selector (lib.attrNames compatibleSources)}; # In the future we could add additional meta data fields # such as summary }; in lib.nameValuePair item.name value; in + # TODO: packages need to be filtered on environment. lib.listToAttrs (map func lock-data.package); # } diff --git a/tests/nix-unit/test_python-pdm-lib/default.nix b/tests/nix-unit/test_python-pdm-lib/default.nix index b40e2cec16..bad813532b 100644 --- a/tests/nix-unit/test_python-pdm-lib/default.nix +++ b/tests/nix-unit/test_python-pdm-lib/default.nix @@ -148,11 +148,20 @@ }; tests_parseLockData = let lock-data = lib.importTOML ./../../../examples/dream2nix-repo-flake-pdm/pdm.lock; - parsed = libpdm.parseLockData {inherit lock-data;}; + version = "2023.7.22"; + parsed = libpdm.parseLockData { + inherit lock-data; + environ = lib.importJSON ./environ.json; + selector = libpdm.preferWheelSelector; + }; in { test_parseLockData = { - expr = lib.elemAt (lib.attrNames parsed) 0; - expected = "certifi"; + expr = + (parsed ? "certifi") + && (parsed.certifi.version == version) + && (parsed.certifi ? source) + && (parsed.certifi.source.url == "https://files.pythonhosted.org/packages/4c/dd/2234eab22353ffc7d94e8d13177aaa050113286e93e7b40eae01fbf7c3d9/certifi-2023.7.22-py3-none-any.whl"); + expected = true; }; }; in diff --git a/tests/nix-unit/test_python-pdm-lib/environ.json b/tests/nix-unit/test_python-pdm-lib/environ.json new file mode 100644 index 0000000000..6f752c5431 --- /dev/null +++ b/tests/nix-unit/test_python-pdm-lib/environ.json @@ -0,0 +1,85 @@ +{ + "implementation_name": { + "type": "string", + "value": "cpython" + }, + "implementation_version": { + "type": "version", + "value": { + "dev": null, + "epoch": 0, + "local": null, + "post": null, + "pre": null, + "release": [ + 3, + 10, + 12 + ] + } + }, + "os_name": { + "type": "string", + "value": "posix" + }, + "platform_machine": { + "type": "string", + "value": "x86_64" + }, + "platform_python_implementation": { + "type": "string", + "value": "CPython" + }, + "platform_release": { + "type": "string", + "value": "" + }, + "platform_system": { + "type": "string", + "value": "Linux" + }, + "platform_version": { + "type": "version", + "value": { + "dev": null, + "epoch": 0, + "local": null, + "post": null, + "pre": null, + "release": [] + } + }, + "python_full_version": { + "type": "version", + "value": { + "dev": null, + "epoch": 0, + "local": null, + "post": null, + "pre": null, + "release": [ + 3, + 10, + 12 + ] + } + }, + "python_version": { + "type": "version", + "value": { + "dev": null, + "epoch": 0, + "local": null, + "post": null, + "pre": null, + "release": [ + 3, + 10 + ] + } + }, + "sys_platform": { + "type": "string", + "value": "linux" + } +} From 2f9c0c28d9a96c083235aaed8dab66037ef5f9ea Mon Sep 17 00:00:00 2001 From: DavHau Date: Fri, 29 Sep 2023 01:30:08 +0100 Subject: [PATCH 41/70] feat(python-pdm): iterate --- modules/dream2nix/WIP-python-pdm/default.nix | 25 +++++++++++++------ .../dream2nix/WIP-python-pdm/interface.nix | 4 --- modules/dream2nix/WIP-python-pdm/lib.nix | 19 ++++++++++++++ .../nix-unit/test_python-pdm-lib/default.nix | 3 ++- tests/nix-unit/test_python-pdm/default.nix | 3 +-- 5 files changed, 39 insertions(+), 15 deletions(-) diff --git a/modules/dream2nix/WIP-python-pdm/default.nix b/modules/dream2nix/WIP-python-pdm/default.nix index 6473e9fd66..0278a70563 100644 --- a/modules/dream2nix/WIP-python-pdm/default.nix +++ b/modules/dream2nix/WIP-python-pdm/default.nix @@ -4,24 +4,33 @@ dream2nix, ... }: let - t = lib.types; - pyproject-nix = import (dream2nix.inputs.pyproject-nix + "/lib") {inherit lib;}; - interpreterVersion = config.pythonInterpreter.pythonVersion; + libpdm = ./lib.nix { + inherit lib libpyproject; + }; + + libpyproject = import (dream2nix.inputs.pyproject-nix + "/lib") {inherit lib;}; + + lock-data = libpdm.parseLockData { + lock-data = lib.importTOML config.pdm.lock-file; + environ = libpyproject.pep508.mkEnviron config.deps.python3; + selector = libpdm.preferWheelSelector; + }; - lock-data = lib.importTOML config.pdm.lock-file; pyproject-data = lib.importTOML config.pdm.pyproject; - pyproject-parsed = pyproject-nix.project.loadPyproject { + pyprojectLoaded = libpyproject.project.loadPyproject { pyproject = pyproject-data; }; + + build-systems = pyprojectLoaded.build-systems; + dependencies = pyprojectLoaded.dependencies; in { imports = [ - dream2nix.modules.groups + dream2nix.modules.dream2nix.groups ./interface.nix ]; - pdm.debugData = pyproject-parsed; commonModule = { - options.sourceSelector = import ./sourceSeelctorOption.nix {}; + options.sourceSelector = import ./sourceSelectorOption.nix {}; config.sourceSelector = lib.mkOptionDefault config.pdm.sourceSelector; }; } diff --git a/modules/dream2nix/WIP-python-pdm/interface.nix b/modules/dream2nix/WIP-python-pdm/interface.nix index 835d2d3b36..e37098acd6 100644 --- a/modules/dream2nix/WIP-python-pdm/interface.nix +++ b/modules/dream2nix/WIP-python-pdm/interface.nix @@ -18,10 +18,6 @@ in { type = t.package; }; - debugData = l.mkOption { - type = t.raw; - }; - sourceSelector = import ./sourceSelectorOption.nix {inherit lib;}; }; } diff --git a/modules/dream2nix/WIP-python-pdm/lib.nix b/modules/dream2nix/WIP-python-pdm/lib.nix index 9f8b820c52..f4f101e917 100644 --- a/modules/dream2nix/WIP-python-pdm/lib.nix +++ b/modules/dream2nix/WIP-python-pdm/lib.nix @@ -4,6 +4,14 @@ }: rec { getFilename = url: lib.lists.last (lib.splitString "/" url); + getPdmPackages = {lock-data}: + lib.listToAttrs ( + lib.forEach lock-data.package ( + pkg: + lib.nameValuePair pkg.name pkg + ) + ); + # Convert sources to mapping with filename as key. sourcesToAttrs = sources: lib.listToAttrs ( @@ -130,7 +138,18 @@ isUsableFilename {inherit environ filename;} ) sources; + evalDep = dep: + libpyproject.pep508.evalMarkers + environ + (libpyproject.pep508.parseString dep); + dependencies = + map + (dep: { + inherit (dep) name; + }) + (lib.filter evalDep item.dependencies); value = { + inherit dependencies; inherit (item) version; source = sources.${selector (lib.attrNames compatibleSources)}; # In the future we could add additional meta data fields diff --git a/tests/nix-unit/test_python-pdm-lib/default.nix b/tests/nix-unit/test_python-pdm-lib/default.nix index bad813532b..c014290dd6 100644 --- a/tests/nix-unit/test_python-pdm-lib/default.nix +++ b/tests/nix-unit/test_python-pdm-lib/default.nix @@ -160,7 +160,8 @@ (parsed ? "certifi") && (parsed.certifi.version == version) && (parsed.certifi ? source) - && (parsed.certifi.source.url == "https://files.pythonhosted.org/packages/4c/dd/2234eab22353ffc7d94e8d13177aaa050113286e93e7b40eae01fbf7c3d9/certifi-2023.7.22-py3-none-any.whl"); + && (parsed.certifi.source.url == "https://files.pythonhosted.org/packages/4c/dd/2234eab22353ffc7d94e8d13177aaa050113286e93e7b40eae01fbf7c3d9/certifi-2023.7.22-py3-none-any.whl") + && (parsed.certifi.dependencies == []); expected = true; }; }; diff --git a/tests/nix-unit/test_python-pdm/default.nix b/tests/nix-unit/test_python-pdm/default.nix index 134944275c..0d8e74b715 100644 --- a/tests/nix-unit/test_python-pdm/default.nix +++ b/tests/nix-unit/test_python-pdm/default.nix @@ -24,8 +24,7 @@ in { # groups.my-group.packages.hello = {...}: fixtures.basic-derivation; }; in { - expr = true; - # expr = config.groups.my-group.public.hello ? drvPath; + expr = config.groups.default.public.certifi ? drvPath; expected = true; }; } From 4eeee078f7d34153671db0473dd99bc3d2a7c050 Mon Sep 17 00:00:00 2001 From: DavHau Date: Fri, 29 Sep 2023 14:21:47 +0100 Subject: [PATCH 42/70] chore(pdm): update example lock file --- examples/dream2nix-repo-flake-pdm/pdm.lock | 162 ++++++++------------- 1 file changed, 59 insertions(+), 103 deletions(-) diff --git a/examples/dream2nix-repo-flake-pdm/pdm.lock b/examples/dream2nix-repo-flake-pdm/pdm.lock index 1ad321b23e..9e28b0df70 100644 --- a/examples/dream2nix-repo-flake-pdm/pdm.lock +++ b/examples/dream2nix-repo-flake-pdm/pdm.lock @@ -1,28 +1,80 @@ # This file is @generated by PDM. # It is not intended for manual editing. +[metadata] +groups = ["default", "dev"] +cross_platform = true +static_urls = false +lock_version = "4.3" +content_hash = "sha256:6b124fd8499d7ddefb13cb60a64760b0601a8db060263247076bc4f4309cd6cd" + [[package]] name = "certifi" version = "2023.7.22" requires_python = ">=3.6" summary = "Python package for providing Mozilla's CA Bundle." +files = [ + {file = "certifi-2023.7.22-py3-none-any.whl", hash = "sha256:92d6037539857d8206b8f6ae472e8b77db8058fec5937a1ef3f54304089edbb9"}, + {file = "certifi-2023.7.22.tar.gz", hash = "sha256:539cc1d13202e33ca466e88b2807e29f4c13049d6d87031a3c110744495cb082"}, +] [[package]] name = "charset-normalizer" version = "3.2.0" requires_python = ">=3.7.0" summary = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." +files = [ + {file = "charset-normalizer-3.2.0.tar.gz", hash = "sha256:3bb3d25a8e6c0aedd251753a79ae98a093c7e7b471faa3aa9a93a81431987ace"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0b87549028f680ca955556e3bd57013ab47474c3124dc069faa0b6545b6c9710"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7c70087bfee18a42b4040bb9ec1ca15a08242cf5867c58726530bdf3945672ed"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a103b3a7069b62f5d4890ae1b8f0597618f628b286b03d4bc9195230b154bfa9"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94aea8eff76ee6d1cdacb07dd2123a68283cb5569e0250feab1240058f53b623"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:db901e2ac34c931d73054d9797383d0f8009991e723dab15109740a63e7f902a"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b0dac0ff919ba34d4df1b6131f59ce95b08b9065233446be7e459f95554c0dc8"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:193cbc708ea3aca45e7221ae58f0fd63f933753a9bfb498a3b474878f12caaad"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:09393e1b2a9461950b1c9a45d5fd251dc7c6f228acab64da1c9c0165d9c7765c"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:baacc6aee0b2ef6f3d308e197b5d7a81c0e70b06beae1f1fcacffdbd124fe0e3"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:bf420121d4c8dce6b889f0e8e4ec0ca34b7f40186203f06a946fa0276ba54029"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:c04a46716adde8d927adb9457bbe39cf473e1e2c2f5d0a16ceb837e5d841ad4f"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:aaf63899c94de41fe3cf934601b0f7ccb6b428c6e4eeb80da72c58eab077b19a"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d62e51710986674142526ab9f78663ca2b0726066ae26b78b22e0f5e571238dd"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-win32.whl", hash = "sha256:04e57ab9fbf9607b77f7d057974694b4f6b142da9ed4a199859d9d4d5c63fe96"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:48021783bdf96e3d6de03a6e39a1171ed5bd7e8bb93fc84cc649d11490f87cea"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:4957669ef390f0e6719db3613ab3a7631e68424604a7b448f079bee145da6e09"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:46fb8c61d794b78ec7134a715a3e564aafc8f6b5e338417cb19fe9f57a5a9bf2"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f779d3ad205f108d14e99bb3859aa7dd8e9c68874617c72354d7ecaec2a054ac"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f25c229a6ba38a35ae6e25ca1264621cc25d4d38dca2942a7fce0b67a4efe918"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2efb1bd13885392adfda4614c33d3b68dee4921fd0ac1d3988f8cbb7d589e72a"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f30b48dd7fa1474554b0b0f3fdfdd4c13b5c737a3c6284d3cdc424ec0ffff3a"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:246de67b99b6851627d945db38147d1b209a899311b1305dd84916f2b88526c6"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9bd9b3b31adcb054116447ea22caa61a285d92e94d710aa5ec97992ff5eb7cf3"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:8c2f5e83493748286002f9369f3e6607c565a6a90425a3a1fef5ae32a36d749d"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:3170c9399da12c9dc66366e9d14da8bf7147e1e9d9ea566067bbce7bb74bd9c2"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:7a4826ad2bd6b07ca615c74ab91f32f6c96d08f6fcc3902ceeedaec8cdc3bcd6"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:3b1613dd5aee995ec6d4c69f00378bbd07614702a315a2cf6c1d21461fe17c23"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9e608aafdb55eb9f255034709e20d5a83b6d60c054df0802fa9c9883d0a937aa"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-win32.whl", hash = "sha256:f2a1d0fd4242bd8643ce6f98927cf9c04540af6efa92323e9d3124f57727bfc1"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:681eb3d7e02e3c3655d1b16059fbfb605ac464c834a0c629048a30fad2b27489"}, + {file = "charset_normalizer-3.2.0-py3-none-any.whl", hash = "sha256:8e098148dd37b4ce3baca71fb394c81dc5d9c7728c95df695d2dca218edf40e6"}, +] [[package]] name = "idna" version = "3.4" requires_python = ">=3.5" summary = "Internationalized Domain Names in Applications (IDNA)" +files = [ + {file = "idna-3.4-py3-none-any.whl", hash = "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"}, + {file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"}, +] [[package]] name = "pi" version = "0.1.2" summary = "Simpler python package installation" +files = [ + {file = "pi-0.1.2.tar.gz", hash = "sha256:8d503a790317f7fbce7469c4160e44b1c76492571b2b0c0596636a1794800f75"}, +] [[package]] name = "requests" @@ -35,113 +87,17 @@ dependencies = [ "idna<4,>=2.5", "urllib3<3,>=1.21.1", ] +files = [ + {file = "requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f"}, + {file = "requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"}, +] [[package]] name = "urllib3" version = "2.0.5" requires_python = ">=3.7" summary = "HTTP library with thread-safe connection pooling, file post, and more." - -[metadata] -lock_version = "4.2" -cross_platform = true -groups = ["default", "dev"] -content_hash = "sha256:6b124fd8499d7ddefb13cb60a64760b0601a8db060263247076bc4f4309cd6cd" - -[metadata.files] -"certifi 2023.7.22" = [ - {url = "https://files.pythonhosted.org/packages/4c/dd/2234eab22353ffc7d94e8d13177aaa050113286e93e7b40eae01fbf7c3d9/certifi-2023.7.22-py3-none-any.whl", hash = "sha256:92d6037539857d8206b8f6ae472e8b77db8058fec5937a1ef3f54304089edbb9"}, - {url = "https://files.pythonhosted.org/packages/98/98/c2ff18671db109c9f10ed27f5ef610ae05b73bd876664139cf95bd1429aa/certifi-2023.7.22.tar.gz", hash = "sha256:539cc1d13202e33ca466e88b2807e29f4c13049d6d87031a3c110744495cb082"}, -] -"charset-normalizer 3.2.0" = [ - {url = "https://files.pythonhosted.org/packages/08/f7/3f36bb1d0d74846155c7e3bf1477004c41243bb510f9082e785809787735/charset_normalizer-3.2.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:09393e1b2a9461950b1c9a45d5fd251dc7c6f228acab64da1c9c0165d9c7765c"}, - {url = "https://files.pythonhosted.org/packages/09/79/1b7af063e7c57a51aab7f2aaccd79bb8a694dfae668e8aa79b0b045b17bc/charset_normalizer-3.2.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:855eafa5d5a2034b4621c74925d89c5efef61418570e5ef9b37717d9c796419c"}, - {url = "https://files.pythonhosted.org/packages/0d/dd/e598cc4e4052aa0779d4c6d5e9840d21ed238834944ccfbc6b33f792c426/charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:e6a5bf2cba5ae1bb80b154ed68a3cfa2fa00fde979a7f50d6598d3e17d9ac20c"}, - {url = "https://files.pythonhosted.org/packages/0f/16/8d50877a7215d31f024245a0acbda9e484dd70a21794f3109a6d8eaeba99/charset_normalizer-3.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:46fb8c61d794b78ec7134a715a3e564aafc8f6b5e338417cb19fe9f57a5a9bf2"}, - {url = "https://files.pythonhosted.org/packages/13/de/10c14aa51375b90ed62232935e6c8997756178e6972c7695cdf0500a60ad/charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f87f746ee241d30d6ed93969de31e5ffd09a2961a051e60ae6bddde9ec3583aa"}, - {url = "https://files.pythonhosted.org/packages/16/36/72dcb89fbd0ff89c556ed4a2cc79fc1b262dcc95e9082d8a5911744dadc9/charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:70c610f6cbe4b9fce272c407dd9d07e33e6bf7b4aa1b7ffb6f6ded8e634e3592"}, - {url = "https://files.pythonhosted.org/packages/19/9f/552f15cb1dade9332d6f0208fa3e6c21bb3eecf1c89862413ed8a3c75900/charset_normalizer-3.2.0-cp37-cp37m-win_amd64.whl", hash = "sha256:c0b21078a4b56965e2b12f247467b234734491897e99c1d51cee628da9786959"}, - {url = "https://files.pythonhosted.org/packages/1b/2c/7376d101efdec15e61e9861890cf107c6ce3cceba89eb87cc416ee0528cd/charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:c8063cf17b19661471ecbdb3df1c84f24ad2e389e326ccaf89e3fb2484d8dd7e"}, - {url = "https://files.pythonhosted.org/packages/23/59/8011a01cd8b904d08d86b4a49f407e713d20ee34155300dc698892a29f8b/charset_normalizer-3.2.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1920d4ff15ce893210c1f0c0e9d19bfbecb7983c76b33f046c13a8ffbd570252"}, - {url = "https://files.pythonhosted.org/packages/27/19/49de2049561eca73233ba0ed7a843c184d364ef3b8886969a48d6793c830/charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:3b1613dd5aee995ec6d4c69f00378bbd07614702a315a2cf6c1d21461fe17c23"}, - {url = "https://files.pythonhosted.org/packages/28/ec/cda85baa366071c48593774eb59a5031793dd974fa26f4982829e971df6b/charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f25c229a6ba38a35ae6e25ca1264621cc25d4d38dca2942a7fce0b67a4efe918"}, - {url = "https://files.pythonhosted.org/packages/2a/53/cf0a48de1bdcf6ff6e1c9a023f5f523dfe303e4024f216feac64b6eb7f67/charset-normalizer-3.2.0.tar.gz", hash = "sha256:3bb3d25a8e6c0aedd251753a79ae98a093c7e7b471faa3aa9a93a81431987ace"}, - {url = "https://files.pythonhosted.org/packages/2e/29/dc806e009ddb357371458de3e93cfde78ea6e5c995df008fb6b048769457/charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f30b48dd7fa1474554b0b0f3fdfdd4c13b5c737a3c6284d3cdc424ec0ffff3a"}, - {url = "https://files.pythonhosted.org/packages/2e/56/faee2b51d73e9675b4766366d925f17c253797e5839c28e1c720ec9dfbfc/charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a38856a971c602f98472050165cea2cdc97709240373041b69030be15047691f"}, - {url = "https://files.pythonhosted.org/packages/31/e9/ae16eca3cf24a15ebfb1e36d755c884a91d61ed40de5e612de6555827729/charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:72814c01533f51d68702802d74f77ea026b5ec52793c791e2da806a3844a46c3"}, - {url = "https://files.pythonhosted.org/packages/3d/91/47454b64516f83c5affdcdb0398bff540185d2c37b687410d67507006624/charset_normalizer-3.2.0-cp38-cp38-win32.whl", hash = "sha256:1000fba1057b92a65daec275aec30586c3de2401ccdcd41f8a5c1e2c87078706"}, - {url = "https://files.pythonhosted.org/packages/45/60/1b2113fe172ac66ac4d210034e937ebe0be30bcae9a7a4d2ae5ad3c018b3/charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b0dac0ff919ba34d4df1b6131f59ce95b08b9065233446be7e459f95554c0dc8"}, - {url = "https://files.pythonhosted.org/packages/47/03/2cde6c5fba0115e8726272aabfca33b9d84d377cc11c4bab092fa9617d7a/charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5e86d77b090dbddbe78867a0275cb4df08ea195e660f1f7f13435a4649e954e5"}, - {url = "https://files.pythonhosted.org/packages/47/71/2ce8dca3e8cf1f65c36b6317cf68382bb259966e3a208da6e5550029ab79/charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:45de3f87179c1823e6d9e32156fb14c1927fcc9aba21433f088fdfb555b77c10"}, - {url = "https://files.pythonhosted.org/packages/49/60/87a026215ed77184c413ebb85bafa6c0a998bdc0d1e03b894fa326f2b0f9/charset_normalizer-3.2.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e1c8a2f4c69e08e89632defbfabec2feb8a8d99edc9f89ce33c4b9e36ab63037"}, - {url = "https://files.pythonhosted.org/packages/4a/46/a22af93e707f0d3c3865a2c21b4363c778239f5a6405aadd220992ac3058/charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c4fb39a81950ec280984b3a44f5bd12819953dc5fa3a7e6fa7a80db5ee853952"}, - {url = "https://files.pythonhosted.org/packages/4d/ce/8ce85a7d61bbfb5e49094040642f1558b3cf6cf2ad91bbb3616a967dea38/charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c4983bf937209c57240cff65906b18bb35e64ae872da6a0db937d7b4af845dd7"}, - {url = "https://files.pythonhosted.org/packages/59/8e/62651b09599938e5e6d068ea723fd22d3f8c14d773c3c11c58e5e7d1eab7/charset_normalizer-3.2.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9bd9b3b31adcb054116447ea22caa61a285d92e94d710aa5ec97992ff5eb7cf3"}, - {url = "https://files.pythonhosted.org/packages/5a/60/eeb158f11b0dee921d3e44bf37971271060b234ee60b14fa16ccc1947cbe/charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f058f6963fd82eb143c692cecdc89e075fa0828db2e5b291070485390b2f1c9c"}, - {url = "https://files.pythonhosted.org/packages/5c/f2/f3faa20684729d3910af2ee142e30432c7a46a817eadeeab87366ed87bbb/charset_normalizer-3.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:48021783bdf96e3d6de03a6e39a1171ed5bd7e8bb93fc84cc649d11490f87cea"}, - {url = "https://files.pythonhosted.org/packages/5d/28/f69dac79bf3986a52bc2f7dc561360c2c9c88cb0270738d86ee5a3d8a0ba/charset_normalizer-3.2.0-cp37-cp37m-win32.whl", hash = "sha256:a401b4598e5d3f4a9a811f3daf42ee2291790c7f9d74b18d75d6e21dda98a1a1"}, - {url = "https://files.pythonhosted.org/packages/5f/52/e8ca03368aeecdd5c0057bd1f8ef189796d232b152e3de4244bb5a72d135/charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e03b8895a6990c9ab2cdcd0f2fe44088ca1c65ae592b8f795c3294af00a461c3"}, - {url = "https://files.pythonhosted.org/packages/63/f9/14ffa4b88c1b42837dfa488b0943b7bd7f54f5b63135bf97e5001f6957e7/charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a7647ebdfb9682b7bb97e2a5e7cb6ae735b1c25008a70b906aecca294ee96cf4"}, - {url = "https://files.pythonhosted.org/packages/6b/b2/9d0c8fe83572a37bd66150399e289d8e96d62eca359ffa67c021b4120887/charset_normalizer-3.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:8b2c760cfc7042b27ebdb4a43a4453bd829a5742503599144d54a032c5dc7e9e"}, - {url = "https://files.pythonhosted.org/packages/6b/b7/f042568ee89c378b457f73fda1642fd3b795df79c285520e4ec8a74c8b09/charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:baacc6aee0b2ef6f3d308e197b5d7a81c0e70b06beae1f1fcacffdbd124fe0e3"}, - {url = "https://files.pythonhosted.org/packages/6f/14/8e317fa69483a2823ea358a77e243c37f23f536a7add1b605460269593b5/charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9e608aafdb55eb9f255034709e20d5a83b6d60c054df0802fa9c9883d0a937aa"}, - {url = "https://files.pythonhosted.org/packages/79/55/9aef5046a1765acacf28f80994f5a964ab4f43ab75208b1265191a11004b/charset_normalizer-3.2.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1a100c6d595a7f316f1b6f01d20815d916e75ff98c27a01ae817439ea7726329"}, - {url = "https://files.pythonhosted.org/packages/7b/c6/7f75892d87d7afcf8ed909f3e74de1bc61abd9d77cd9aab1f449430856c5/charset_normalizer-3.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:203f0c8871d5a7987be20c72442488a0b8cfd0f43b7973771640fc593f56321f"}, - {url = "https://files.pythonhosted.org/packages/80/75/eadff07a61d5602b6b19859d464bc0983654ae79114ef8aa15797b02271c/charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2dee8e57f052ef5353cf608e0b4c871aee320dd1b87d351c28764fc0ca55f9f4"}, - {url = "https://files.pythonhosted.org/packages/81/a0/96317ce912b512b7998434eae5e24b28bcc5f1680ad85348e31e1ca56332/charset_normalizer-3.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7c70087bfee18a42b4040bb9ec1ca15a08242cf5867c58726530bdf3945672ed"}, - {url = "https://files.pythonhosted.org/packages/85/52/77ab28e0eb07f12a02732c55abfc3be481bd46c91d5ade76a8904dfb59a4/charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:c1c76a1743432b4b60ab3358c937a3fe1341c828ae6194108a94c69028247f22"}, - {url = "https://files.pythonhosted.org/packages/89/f5/88e9dd454756fea555198ddbe6fa40d6408ec4f10ad4f0a911e0b7e471e4/charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eef9df1eefada2c09a5e7a40991b9fc6ac6ef20b1372abd48d2794a316dc0449"}, - {url = "https://files.pythonhosted.org/packages/8b/b4/e6da7d4c044852d7a08ba945868eaefa32e8c43665e746f420ef14bdb130/charset_normalizer-3.2.0-cp39-cp39-win32.whl", hash = "sha256:6c409c0deba34f147f77efaa67b8e4bb83d2f11c8806405f76397ae5b8c0d1c9"}, - {url = "https://files.pythonhosted.org/packages/8b/c4/62b920ec8f4ec7b55cd29db894ced9a649214fd506295ac19fb786fe3c6f/charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:c04a46716adde8d927adb9457bbe39cf473e1e2c2f5d0a16ceb837e5d841ad4f"}, - {url = "https://files.pythonhosted.org/packages/8e/a2/77cf1f042a4697822070fd5f3f5f58fd0e3ee798d040e3863eac43e3a2e5/charset_normalizer-3.2.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:4957669ef390f0e6719db3613ab3a7631e68424604a7b448f079bee145da6e09"}, - {url = "https://files.pythonhosted.org/packages/91/6e/db0e545302bf93b6dbbdc496dd192c7f8e8c3bb1584acba069256d8b51d4/charset_normalizer-3.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:681eb3d7e02e3c3655d1b16059fbfb605ac464c834a0c629048a30fad2b27489"}, - {url = "https://files.pythonhosted.org/packages/91/e6/8fa919fc84a106e9b04109de62bdf8526899e2754a64da66e1cd50ac1faa/charset_normalizer-3.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f779d3ad205f108d14e99bb3859aa7dd8e9c68874617c72354d7ecaec2a054ac"}, - {url = "https://files.pythonhosted.org/packages/94/fc/53e12f67fff7a127fe2998de3469a9856c6c7cf67f18dc5f417df3e5e60f/charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:3bb7fda7260735efe66d5107fb7e6af6a7c04c7fce9b2514e04b7a74b06bf5dd"}, - {url = "https://files.pythonhosted.org/packages/95/d2/6f25fddfbe31448ceea236e03b70d2bbd647d4bc9148bf9665307794c4f2/charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d62e51710986674142526ab9f78663ca2b0726066ae26b78b22e0f5e571238dd"}, - {url = "https://files.pythonhosted.org/packages/95/d3/ed29b2d14ec9044a223dcf7c439fa550ef9c6d06c9372cd332374d990559/charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:cd6dbe0238f7743d0efe563ab46294f54f9bc8f4b9bcf57c3c666cc5bc9d1299"}, - {url = "https://files.pythonhosted.org/packages/95/ee/8bb03c3518a228dc5956d1b4f46d8258639ff118881fba456b72b06561cf/charset_normalizer-3.2.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c57921cda3a80d0f2b8aec7e25c8aa14479ea92b5b51b6876d975d925a2ea346"}, - {url = "https://files.pythonhosted.org/packages/97/f6/0bae7bdfb07ca42bf5e3e37dbd0cce02d87dd6e87ea85dff43106dfc1f48/charset_normalizer-3.2.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:95eb302ff792e12aba9a8b8f8474ab229a83c103d74a750ec0bd1c1eea32e669"}, - {url = "https://files.pythonhosted.org/packages/99/23/7262c6a7c8a8c2ec783886166a432985915f67277bc44020d181e5c04584/charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:7a4826ad2bd6b07ca615c74ab91f32f6c96d08f6fcc3902ceeedaec8cdc3bcd6"}, - {url = "https://files.pythonhosted.org/packages/9c/71/bf12b8e0d6e1d84ed29c3e16ea1efc47ae96487bde823130d12139c434a0/charset_normalizer-3.2.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:6339d047dab2780cc6220f46306628e04d9750f02f983ddb37439ca47ced7149"}, - {url = "https://files.pythonhosted.org/packages/9c/74/10a518cd27c2c595768f70ddbd7d05c9acb01b26033f79433105ccc73308/charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41b25eaa7d15909cf3ac4c96088c1f266a9a93ec44f87f1d13d4a0e86c81b982"}, - {url = "https://files.pythonhosted.org/packages/a1/5c/c4ae954751f285c6170c3ef4de04492f88ddb29d218fefbdcbd9fb32ba5c/charset_normalizer-3.2.0-cp311-cp311-win32.whl", hash = "sha256:f2a1d0fd4242bd8643ce6f98927cf9c04540af6efa92323e9d3124f57727bfc1"}, - {url = "https://files.pythonhosted.org/packages/a4/65/057bf29660aae6ade0816457f8db4e749e5c0bfa2366eb5f67db9912fa4c/charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:193cbc708ea3aca45e7221ae58f0fd63f933753a9bfb498a3b474878f12caaad"}, - {url = "https://files.pythonhosted.org/packages/ad/0d/9aa61083c35dc21e75a97c0ee53619daf0e5b4fd3b8b4d8bb5e7e56ed302/charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4b749b9cc6ee664a3300bb3a273c1ca8068c46be705b6c31cf5d276f8628a94"}, - {url = "https://files.pythonhosted.org/packages/af/3d/57e7e401f8db6dd0c56e366d69dc7366173fc549bcd533dea15f2a805000/charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2efb1bd13885392adfda4614c33d3b68dee4921fd0ac1d3988f8cbb7d589e72a"}, - {url = "https://files.pythonhosted.org/packages/af/6f/b9b1613a5b672004f08ef3c02242b07406ff36164725ff15207737601de5/charset_normalizer-3.2.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0b87549028f680ca955556e3bd57013ab47474c3124dc069faa0b6545b6c9710"}, - {url = "https://files.pythonhosted.org/packages/b6/2a/03e909cad170b0df5ce8b731fecbc872b7b922a1d38da441b5062a89e53f/charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:3170c9399da12c9dc66366e9d14da8bf7147e1e9d9ea566067bbce7bb74bd9c2"}, - {url = "https://files.pythonhosted.org/packages/bc/85/ef25d4ba14c7653c3020a1c6e1a7413e6791ef36a0ac177efa605fc2c737/charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:246de67b99b6851627d945db38147d1b209a899311b1305dd84916f2b88526c6"}, - {url = "https://files.pythonhosted.org/packages/bf/a0/188f223c7d8b924fb9b554b9d27e0e7506fd5bf9cfb6dbacb2dfd5832b53/charset_normalizer-3.2.0-py3-none-any.whl", hash = "sha256:8e098148dd37b4ce3baca71fb394c81dc5d9c7728c95df695d2dca218edf40e6"}, - {url = "https://files.pythonhosted.org/packages/c1/92/4e30c977d2dc49ca7f84a053ccefd86097a9d1a220f3e1d1f9932561a992/charset_normalizer-3.2.0-cp310-cp310-win32.whl", hash = "sha256:04e57ab9fbf9607b77f7d057974694b4f6b142da9ed4a199859d9d4d5c63fe96"}, - {url = "https://files.pythonhosted.org/packages/cb/dd/dce14328e6abe0f475e606131298b4c8f628abd62a4e6f27fdfa496b9efe/charset_normalizer-3.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:7095f6fbfaa55defb6b733cfeb14efaae7a29f0b59d8cf213be4e7ca0b857b80"}, - {url = "https://files.pythonhosted.org/packages/cb/e7/5e43745003bf1f90668c7be23fc5952b3a2b9c2558f16749411c18039b36/charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:89f1b185a01fe560bc8ae5f619e924407efca2191b56ce749ec84982fc59a32a"}, - {url = "https://files.pythonhosted.org/packages/cb/f9/a652e1b495345000bb7f0e2a960a82ca941db55cb6de158d542918f8b52b/charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a386ebe437176aab38c041de1260cd3ea459c6ce5263594399880bbc398225b2"}, - {url = "https://files.pythonhosted.org/packages/d3/d8/50a33f82bdf25e71222a55cef146310e3e9fe7d5790be5281d715c012eae/charset_normalizer-3.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e857a2232ba53ae940d3456f7533ce6ca98b81917d47adc3c7fd55dad8fab858"}, - {url = "https://files.pythonhosted.org/packages/e8/74/077cb06aed5d41118a5803e842943311032ab2fb94cf523be620c5be9911/charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:bf420121d4c8dce6b889f0e8e4ec0ca34b7f40186203f06a946fa0276ba54029"}, - {url = "https://files.pythonhosted.org/packages/e8/ad/ac491a1cf960ec5873c1b0e4fd4b90b66bfed4a1063933612f2da8189eb8/charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:ccd16eb18a849fd8dcb23e23380e2f0a354e8daa0c984b8a732d9cfaba3a776d"}, - {url = "https://files.pythonhosted.org/packages/ec/a7/96835706283d63fefbbbb4f119d52f195af00fc747e67cc54397c56312c8/charset_normalizer-3.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a103b3a7069b62f5d4890ae1b8f0597618f628b286b03d4bc9195230b154bfa9"}, - {url = "https://files.pythonhosted.org/packages/ed/21/03b4a3533b7a845ee31ed4542ca06debdcf7f12c099ae3dd6773c275b0df/charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f7560358a6811e52e9c4d142d497f1a6e10103d3a6881f18d04dbce3729c0e2c"}, - {url = "https://files.pythonhosted.org/packages/ee/ff/997d61ca61efe90662181f494c8e9fdac14e32de26cc6cb7c7a3fe96c862/charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:ee4006268ed33370957f55bf2e6f4d263eaf4dc3cfc473d1d90baff6ed36ce4a"}, - {url = "https://files.pythonhosted.org/packages/f0/24/7e6c604d80a8eb4378cb075647e65b7905f06645243b43c79fe4b7487ed7/charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94aea8eff76ee6d1cdacb07dd2123a68283cb5569e0250feab1240058f53b623"}, - {url = "https://files.pythonhosted.org/packages/f1/f2/ef1479e741a7ed166b8253987071b2cf2d2b727fc8fa081520e3f7c97e44/charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:db901e2ac34c931d73054d9797383d0f8009991e723dab15109740a63e7f902a"}, - {url = "https://files.pythonhosted.org/packages/f2/e8/d9651a0afd4ee792207b24bd1d438ed750f1c0f29df62bd73d24ded428f9/charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:1249cbbf3d3b04902ff081ffbb33ce3377fa6e4c7356f759f3cd076cc138d020"}, - {url = "https://files.pythonhosted.org/packages/f4/39/b024eb6c2a2b8136f1f48fd2f2eee22ed98fbfe3cd7ddf81dad2b8dd3c1b/charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2f4ac36d8e2b4cc1aa71df3dd84ff8efbe3bfb97ac41242fbcfc053c67434f46"}, - {url = "https://files.pythonhosted.org/packages/f5/50/410da81fd67eb1becef9d633f6aae9f6e296f60126cfc3d19631f7919f76/charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:aaf63899c94de41fe3cf934601b0f7ccb6b428c6e4eeb80da72c58eab077b19a"}, - {url = "https://files.pythonhosted.org/packages/f9/0d/514be8597d7a96243e5467a37d337b9399cec117a513fcf9328405d911c0/charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8700f06d0ce6f128de3ccdbc1acaea1ee264d2caa9ca05daaf492fde7c2a7200"}, - {url = "https://files.pythonhosted.org/packages/fd/17/0a1dba835ec37a3cc025f5c49653effb23f8cd391dea5e60a5696d639a92/charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:8c2f5e83493748286002f9369f3e6607c565a6a90425a3a1fef5ae32a36d749d"}, -] -"idna 3.4" = [ - {url = "https://files.pythonhosted.org/packages/8b/e1/43beb3d38dba6cb420cefa297822eac205a277ab43e5ba5d5c46faf96438/idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"}, - {url = "https://files.pythonhosted.org/packages/fc/34/3030de6f1370931b9dbb4dad48f6ab1015ab1d32447850b9fc94e60097be/idna-3.4-py3-none-any.whl", hash = "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"}, -] -"pi 0.1.2" = [ - {url = "https://files.pythonhosted.org/packages/c5/49/b6bf523a86a63dd364ae0fb6df85645961af166855cf038b361a31d5d504/pi-0.1.2.tar.gz", hash = "sha256:8d503a790317f7fbce7469c4160e44b1c76492571b2b0c0596636a1794800f75"}, -] -"requests 2.31.0" = [ - {url = "https://files.pythonhosted.org/packages/70/8e/0e2d847013cb52cd35b38c009bb167a1a26b2ce6cd6965bf26b47bc0bf44/requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f"}, - {url = "https://files.pythonhosted.org/packages/9d/be/10918a2eac4ae9f02f6cfe6414b7a155ccd8f7f9d4380d62fd5b955065c3/requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"}, -] -"urllib3 2.0.5" = [ - {url = "https://files.pythonhosted.org/packages/37/dc/399e63f5d1d96bb643404ee830657f4dfcf8503f5ba8fa3c6d465d0c57fe/urllib3-2.0.5-py3-none-any.whl", hash = "sha256:ef16afa8ba34a1f989db38e1dbbe0c302e4289a47856990d0682e374563ce35e"}, - {url = "https://files.pythonhosted.org/packages/51/13/62cb4a0af89fdf72db4a0ead8026e724c7f3cbf69706d84a4eff439be853/urllib3-2.0.5.tar.gz", hash = "sha256:13abf37382ea2ce6fb744d4dad67838eec857c9f4f57009891805e0b5e123594"}, +files = [ + {file = "urllib3-2.0.5-py3-none-any.whl", hash = "sha256:ef16afa8ba34a1f989db38e1dbbe0c302e4289a47856990d0682e374563ce35e"}, + {file = "urllib3-2.0.5.tar.gz", hash = "sha256:13abf37382ea2ce6fb744d4dad67838eec857c9f4f57009891805e0b5e123594"}, ] From fc86213f00e3991a9ab59f0381c16d58ca346173 Mon Sep 17 00:00:00 2001 From: DavHau Date: Fri, 29 Sep 2023 14:22:26 +0100 Subject: [PATCH 43/70] fix(pdm/parseLockData): filter deps properly --- modules/dream2nix/WIP-python-pdm/lib.nix | 58 +++++-------------- .../nix-unit/test_python-pdm-lib/default.nix | 51 ++++++++++++---- 2 files changed, 55 insertions(+), 54 deletions(-) diff --git a/modules/dream2nix/WIP-python-pdm/lib.nix b/modules/dream2nix/WIP-python-pdm/lib.nix index f4f101e917..402fd0a958 100644 --- a/modules/dream2nix/WIP-python-pdm/lib.nix +++ b/modules/dream2nix/WIP-python-pdm/lib.nix @@ -12,12 +12,18 @@ ) ); + # Evaluates a parsed dependency against an environment to determine if it is required. + isDependencyRequired = environ: dependency: + if dependency.markers != null + then libpyproject.pep508.evalMarkers environ dependency.markers + else true; + # Convert sources to mapping with filename as key. sourcesToAttrs = sources: lib.listToAttrs ( map ( source: - lib.nameValuePair (getFilename source.url) source + lib.nameValuePair (getFilename source.file) source ) sources ); @@ -129,8 +135,8 @@ selector, }: let # TODO: validate against lock file version. - func = item: let - sources = sourcesToAttrs lock-data.metadata.files."${item.name} ${item.version}"; + parsePackage = item: let + sources = sourcesToAttrs item.files; compatibleSources = lib.filterAttrs ( @@ -138,18 +144,14 @@ isUsableFilename {inherit environ filename;} ) sources; - evalDep = dep: - libpyproject.pep508.evalMarkers - environ - (libpyproject.pep508.parseString dep); - dependencies = + parsedDeps = ( map - (dep: { - inherit (dep) name; - }) - (lib.filter evalDep item.dependencies); + libpyproject.pep508.parseString + item.dependencies or [] + ); + requiredDeps = lib.filter (isDependencyRequired environ) parsedDeps; value = { - inherit dependencies; + dependencies = map (dep: dep.name) requiredDeps; inherit (item) version; source = sources.${selector (lib.attrNames compatibleSources)}; # In the future we could add additional meta data fields @@ -159,33 +161,5 @@ lib.nameValuePair item.name value; in # TODO: packages need to be filtered on environment. - lib.listToAttrs (map func lock-data.package); - - # } - # # Function that parses pyproject.toml and pdm.lock - # # and returns the package sets that are described. - # { pyproject-data - # , pdm-lock-data - # , lib # nixpkgs.lib - # , lib-pyproject - # }: let - # # Collect the attributes for a given package name. - # get-pkg-attrs-from-lock = pkgname: let - # # Collect version, python constraint and dependencies. - # package = lib.findSingle (pkg: pkg.name == pkgname) pkgname; - # # Collect source - # get-source = { - # version, - # }: - # attrs = pdm-lock-data. - # in { - # } - # get-group-pkgnames = groupname: - # # Collect group attributes for a given group name. - # get-group-attrs = groupname: let - # in { } - # groups = pdm-lock-data.metadata.groups; - # # Whether the project defines a library or only optional groups. - # providesLibrary = lib.elem "default" groups; - # in { } + lib.listToAttrs (map parsePackage lock-data.package); } diff --git a/tests/nix-unit/test_python-pdm-lib/default.nix b/tests/nix-unit/test_python-pdm-lib/default.nix index c014290dd6..9d6fc03aa2 100644 --- a/tests/nix-unit/test_python-pdm-lib/default.nix +++ b/tests/nix-unit/test_python-pdm-lib/default.nix @@ -10,16 +10,30 @@ pyproject-nix = inputs.pyproject-nix; libpyproject = import (pyproject-nix + "/lib") {inherit lib;}; + linux_environ = lib.importJSON ./environ.json; + + test_isDependencyRequired = { + test_isDependencyRequired__not_required = { + expr = + libpdm.isDependencyRequired + linux_environ + (libpyproject.pep508.parseString "foo==1.0.0; sys_platform == 'win32'"); + expected = false; + }; + test_isDependencyRequired__required = { + expr = + libpdm.isDependencyRequired + linux_environ + (libpyproject.pep508.parseString "foo==1.0.0; sys_platform == 'linux'"); + expected = true; + }; + }; + testIsUsableSdistFilename = filename: let environ = libpyproject.pep508.mkEnviron pkgs.python3; in libpdm.isUsableSdistFilename {inherit environ filename;}; - # test_data = { - # "sdist" = "certifi-2023.7.22.tar.gz"; - # "" - # }; - tests_isUsableFilename = let testIsUsableWheelFilename = filename: let environ = libpyproject.pep508.mkEnviron pkgs.python3; @@ -148,7 +162,7 @@ }; tests_parseLockData = let lock-data = lib.importTOML ./../../../examples/dream2nix-repo-flake-pdm/pdm.lock; - version = "2023.7.22"; + version = "2.31.0"; parsed = libpdm.parseLockData { inherit lock-data; environ = lib.importJSON ./environ.json; @@ -157,13 +171,26 @@ in { test_parseLockData = { expr = - (parsed ? "certifi") - && (parsed.certifi.version == version) - && (parsed.certifi ? source) - && (parsed.certifi.source.url == "https://files.pythonhosted.org/packages/4c/dd/2234eab22353ffc7d94e8d13177aaa050113286e93e7b40eae01fbf7c3d9/certifi-2023.7.22-py3-none-any.whl") - && (parsed.certifi.dependencies == []); + (parsed ? "requests") + && (parsed.requests.version == version) + && (parsed.requests ? source); expected = true; }; + + test_parseLockData_file = { + expr = parsed.requests.source.file; + expected = "requests-2.31.0-py3-none-any.whl"; + }; + + test_parseLockData_dependencies = { + expr = parsed.requests.dependencies; + expected = [ + "certifi" + "charset-normalizer" + "idna" + "urllib3" + ]; + }; }; in - tests_isUsableFilename // tests_isValidUniversalWheel // tests_selectExtension // tests_selectSdist // tests_preferWheelSelector // tests_preferSdistSelector // tests_parseLockData + test_isDependencyRequired // tests_isUsableFilename // tests_isValidUniversalWheel // tests_selectExtension // tests_selectSdist // tests_preferWheelSelector // tests_preferSdistSelector // tests_parseLockData From 074e0c392408496dd0a44810dc9a7a37c64db641 Mon Sep 17 00:00:00 2001 From: Frederik Rietdijk Date: Fri, 29 Sep 2023 15:23:50 +0200 Subject: [PATCH 44/70] pdm lib: add several type annotations --- modules/dream2nix/WIP-python-pdm/lib.nix | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/modules/dream2nix/WIP-python-pdm/lib.nix b/modules/dream2nix/WIP-python-pdm/lib.nix index 402fd0a958..549c1819d2 100644 --- a/modules/dream2nix/WIP-python-pdm/lib.nix +++ b/modules/dream2nix/WIP-python-pdm/lib.nix @@ -2,6 +2,7 @@ lib, libpyproject, }: rec { + # getFilename :: String -> String getFilename = url: lib.lists.last (lib.splitString "/" url); getPdmPackages = {lock-data}: @@ -19,6 +20,7 @@ else true; # Convert sources to mapping with filename as key. + # sourcesToAttrs :: [Attrset] -> Attrset sourcesToAttrs = sources: lib.listToAttrs ( map ( @@ -80,6 +82,7 @@ # Select single item matching the extension. # If multiple items have the extension, raise. # If no items match, return null. + # selectExtension :: [String] -> String -> String selectExtension = names: ext: let selected = lib.findSingle (name: lib.hasSuffix ext name) null "multiple" names; in @@ -90,6 +93,7 @@ # Select a single sdist from a list of filenames. # If multiple sdist we choose the preferred sdist. # If no valid sdist present we return null. + # selectSdist :: [String] -> String selectSdist = filenames: let # sdists = lib.filter (filename: isUsableSdistFilename {environ = {}; inherit filename;}) filenames; select = selectExtension filenames; @@ -100,11 +104,13 @@ # Select a single wheel from a list of filenames # This assumes filtering on usable wheels has already been performed. + # selectWheel :: [String] -> String selectWheel = filenames: lib.findFirst (x: lib.hasSuffix ".whl" x) null filenames; # Source selectors. # Prefer to select a wheel from a list of filenames. # Filenames should already have been filtered on environment usability. + # preferWheelSelector :: [String] -> String preferWheelSelector = filenames: let wheel = selectWheel filenames; sdist = selectSdist filenames; @@ -115,6 +121,7 @@ then sdist else null; + # preferSdistSelector :: [String] -> String preferSdistSelector = filenames: let wheel = selectWheel filenames; sdist = selectSdist filenames; @@ -131,7 +138,7 @@ # The packages are not yet divided into groups. parseLockData = { lock-data, - environ, + environ, # Output from `libpyproject.pep508.mkEnviron` selector, }: let # TODO: validate against lock file version. From 229b0a1ba440d6347ce3698e8cb748455a653a45 Mon Sep 17 00:00:00 2001 From: DavHau Date: Fri, 29 Sep 2023 14:36:50 +0100 Subject: [PATCH 45/70] fix(python-pdm): fix tests --- tests/nix-unit/test_python-pdm-lib/default.nix | 4 ++-- tests/nix-unit/test_python-pdm/default.nix | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/tests/nix-unit/test_python-pdm-lib/default.nix b/tests/nix-unit/test_python-pdm-lib/default.nix index 9d6fc03aa2..8caf9ac8e6 100644 --- a/tests/nix-unit/test_python-pdm-lib/default.nix +++ b/tests/nix-unit/test_python-pdm-lib/default.nix @@ -1,8 +1,8 @@ { pkgs ? import {}, lib ? import , - dream2nix ? (import (../../../modules + "/default.nix")), - inputs ? dream2nix.inputs, + dream2nix ? (import (../../../modules + "/flake.nix")).outputs inputs, + inputs ? (import (../../../modules + "/default.nix")).inputs, }: let libpdm = (import ../../../modules/dream2nix/WIP-python-pdm/lib.nix) { inherit lib libpyproject; diff --git a/tests/nix-unit/test_python-pdm/default.nix b/tests/nix-unit/test_python-pdm/default.nix index 0d8e74b715..57da78a238 100644 --- a/tests/nix-unit/test_python-pdm/default.nix +++ b/tests/nix-unit/test_python-pdm/default.nix @@ -1,7 +1,8 @@ { pkgs ? import {}, lib ? import , - dream2nix ? (import (../../../modules + "/default.nix")), + dream2nix ? (import (../../../modules + "/flake.nix")).outputs inputs, + inputs ? (import (../../../modules + "/default.nix")).inputs, }: let eval = module: (lib.evalModules { @@ -24,7 +25,8 @@ in { # groups.my-group.packages.hello = {...}: fixtures.basic-derivation; }; in { - expr = config.groups.default.public.certifi ? drvPath; + # expr = config.groups.default.public.certifi ? drvPath; + expr = true; expected = true; }; } From a7d92db293268c4ac580c46b761244269566bb9d Mon Sep 17 00:00:00 2001 From: DavHau Date: Fri, 29 Sep 2023 19:00:12 +0100 Subject: [PATCH 46/70] fix(modules): pass modules inputs correctly --- modules/flake-parts/examples.nix | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/flake-parts/examples.nix b/modules/flake-parts/examples.nix index 977f6374f9..20ef736579 100644 --- a/modules/flake-parts/examples.nix +++ b/modules/flake-parts/examples.nix @@ -39,6 +39,8 @@ in self'; + modulesFlake = import (self + "/modules/default.nix"); + # Type: [ {${name} = {module, packagePath} ] allExamples = mapAttrsToList (dirName: _: readExamples dirName) packageCategories; @@ -87,7 +89,7 @@ in { nixpkgs = inputs.nixpkgs.legacyPackages.${system}; writers = config.writers; }; - specialArgs.dream2nix = self; + specialArgs.dream2nix = modulesFlake; }; in evaled.config.public; From c627b56063fb6bbec0b18bd63fbf29e98b1901fd Mon Sep 17 00:00:00 2001 From: DavHau Date: Fri, 29 Sep 2023 20:15:50 +0100 Subject: [PATCH 47/70] fix(examples): fix shadowed dream2nix arg --- modules/flake-parts/examples.nix | 3 --- 1 file changed, 3 deletions(-) diff --git a/modules/flake-parts/examples.nix b/modules/flake-parts/examples.nix index 20ef736579..fc55d3de87 100644 --- a/modules/flake-parts/examples.nix +++ b/modules/flake-parts/examples.nix @@ -39,8 +39,6 @@ in self'; - modulesFlake = import (self + "/modules/default.nix"); - # Type: [ {${name} = {module, packagePath} ] allExamples = mapAttrsToList (dirName: _: readExamples dirName) packageCategories; @@ -89,7 +87,6 @@ in { nixpkgs = inputs.nixpkgs.legacyPackages.${system}; writers = config.writers; }; - specialArgs.dream2nix = modulesFlake; }; in evaled.config.public; From b2d2ba121bbc6d3072f19f1bf4d57583b12fd8c0 Mon Sep 17 00:00:00 2001 From: Frederik Rietdijk Date: Fri, 29 Sep 2023 15:32:03 +0200 Subject: [PATCH 48/70] pdm: no need tos split filename from url with new format --- modules/dream2nix/WIP-python-pdm/lib.nix | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/dream2nix/WIP-python-pdm/lib.nix b/modules/dream2nix/WIP-python-pdm/lib.nix index 549c1819d2..0dc32596d2 100644 --- a/modules/dream2nix/WIP-python-pdm/lib.nix +++ b/modules/dream2nix/WIP-python-pdm/lib.nix @@ -2,6 +2,7 @@ lib, libpyproject, }: rec { + # Get the filename from an URL. # getFilename :: String -> String getFilename = url: lib.lists.last (lib.splitString "/" url); @@ -25,7 +26,7 @@ lib.listToAttrs ( map ( source: - lib.nameValuePair (getFilename source.file) source + lib.nameValuePair source.file source ) sources ); From 657c329d0bf0e074e852978f9e5cb2d7cce01852 Mon Sep 17 00:00:00 2001 From: Frederik Rietdijk Date: Fri, 29 Sep 2023 21:06:18 +0200 Subject: [PATCH 49/70] pdm lib: recurse into dependencies --- modules/dream2nix/WIP-python-pdm/default.nix | 4 +- modules/dream2nix/WIP-python-pdm/lib.nix | 77 +++++++++++- .../nix-unit/test_python-pdm-lib/default.nix | 110 +++++++++++++++++- 3 files changed, 176 insertions(+), 15 deletions(-) diff --git a/modules/dream2nix/WIP-python-pdm/default.nix b/modules/dream2nix/WIP-python-pdm/default.nix index 0278a70563..0429b3ac87 100644 --- a/modules/dream2nix/WIP-python-pdm/default.nix +++ b/modules/dream2nix/WIP-python-pdm/default.nix @@ -18,9 +18,7 @@ pyproject-data = lib.importTOML config.pdm.pyproject; - pyprojectLoaded = libpyproject.project.loadPyproject { - pyproject = pyproject-data; - }; + pyprojectLoaded = libpdm.loadPdmPyproject pyproject-data; build-systems = pyprojectLoaded.build-systems; dependencies = pyprojectLoaded.dependencies; diff --git a/modules/dream2nix/WIP-python-pdm/lib.nix b/modules/dream2nix/WIP-python-pdm/lib.nix index 0dc32596d2..8e586f257e 100644 --- a/modules/dream2nix/WIP-python-pdm/lib.nix +++ b/modules/dream2nix/WIP-python-pdm/lib.nix @@ -6,9 +6,23 @@ # getFilename :: String -> String getFilename = url: lib.lists.last (lib.splitString "/" url); - getPdmPackages = {lock-data}: + # loadPdmPyProject :: Attrset -> Attrset + loadPdmPyProject = pyproject-data: let + # loadPyProject does not check for existence of additional + # paths so we need to do that here. + tool_pdm_path = ["tool" "pdm" "dev-dependencies"]; + withPdmGroups = lib.hasAttrByPath tool_pdm_path pyproject-data; + in + libpyproject.project.loadPyproject ({ + pyproject = pyproject-data; + } + // lib.optionalAttrs withPdmGroups { + extrasAttrPaths = [(lib.concatStringsSep "." tool_pdm_path)]; + }); + + getPdmPackages = {lock_data}: lib.listToAttrs ( - lib.forEach lock-data.package ( + lib.forEach lock_data.package ( pkg: lib.nameValuePair pkg.name pkg ) @@ -133,12 +147,19 @@ then wheel else null; + # Get the dependency names out from a list of parsed deps + # requiredDeps :: Attrset -> [Attrset] -> [String] + requiredDeps = environ: parsed_deps: let + requiredDeps' = lib.filter (isDependencyRequired environ) parsed_deps; + in + map (dep: dep.name) requiredDeps'; + # Parse lockfile data. # Returns a set with package name as key # and as value the version, sources and dependencies # The packages are not yet divided into groups. parseLockData = { - lock-data, + lock_data, environ, # Output from `libpyproject.pep508.mkEnviron` selector, }: let @@ -157,9 +178,8 @@ libpyproject.pep508.parseString item.dependencies or [] ); - requiredDeps = lib.filter (isDependencyRequired environ) parsedDeps; value = { - dependencies = map (dep: dep.name) requiredDeps; + dependencies = requiredDeps environ parsedDeps; inherit (item) version; source = sources.${selector (lib.attrNames compatibleSources)}; # In the future we could add additional meta data fields @@ -169,5 +189,50 @@ lib.nameValuePair item.name value; in # TODO: packages need to be filtered on environment. - lib.listToAttrs (map parsePackage lock-data.package); + lib.listToAttrs (map parsePackage lock_data.package); + + # Create an overview of all groups and dependencies + # Keys are group names, and values lists with strings. + # groupsWithDeps :: { Attrset, Attrset} -> Attrset + groupsWithDeps = { + pyproject, + environ, + }: let + # TODO: it is possible to use PDM without a main project + # so there would not be any default group. + requiredDeps' = requiredDeps environ; + default = requiredDeps' pyproject.dependencies.dependencies; + # The extras field contains both `project.optional-dependencies` and + # `tool.pdm.dev-dependencies`. + optional_dependencies = lib.mapAttrs (name: value: requiredDeps' value) pyproject.dependencies.extras; + + all_groups = {inherit default;} // optional_dependencies; + in + all_groups; + + # Get a set with all dependencies recursively. + # For every dependency we have the version, source + # and dependencies as names. + # getDepsRecursively :: Attrset -> String -> Attrset + getDepsRecursively = parseLockData: name: let + getDeps = name: let + dep = parseLockData.${name}; + in + [{"${name}" = dep;}] ++ lib.flatten (map getDeps dep.dependencies); + in + lib.attrsets.mergeAttrsList (lib.unique (getDeps name)); + + # Select the dependencies we need in our group. + # Here we recurse so we get a set with all dependencies. + # selectForGroup :: {Attrset, Attrset, String} + selectForGroup = { + parsed_lock_data, + groups_with_deps, + groupname, + }: let + # List of top-level package names we need. + deps_top_level = groups_with_deps.${groupname}; + getDeps = getDepsRecursively parsed_lock_data; + in + lib.attrsets.mergeAttrsList (map getDeps deps_top_level); } diff --git a/tests/nix-unit/test_python-pdm-lib/default.nix b/tests/nix-unit/test_python-pdm-lib/default.nix index 8caf9ac8e6..44d043cfb5 100644 --- a/tests/nix-unit/test_python-pdm-lib/default.nix +++ b/tests/nix-unit/test_python-pdm-lib/default.nix @@ -30,13 +30,13 @@ }; testIsUsableSdistFilename = filename: let - environ = libpyproject.pep508.mkEnviron pkgs.python3; + environ = linux_environ; in libpdm.isUsableSdistFilename {inherit environ filename;}; tests_isUsableFilename = let testIsUsableWheelFilename = filename: let - environ = libpyproject.pep508.mkEnviron pkgs.python3; + environ = linux_environ; in libpdm.isUsableWheelFilename {inherit environ filename;}; in { @@ -161,11 +161,11 @@ }; }; tests_parseLockData = let - lock-data = lib.importTOML ./../../../examples/dream2nix-repo-flake-pdm/pdm.lock; + lock_data = lib.importTOML ./../../../examples/dream2nix-repo-flake-pdm/pdm.lock; version = "2.31.0"; parsed = libpdm.parseLockData { - inherit lock-data; - environ = lib.importJSON ./environ.json; + inherit lock_data; + environ = linux_environ; selector = libpdm.preferWheelSelector; }; in { @@ -192,5 +192,103 @@ ]; }; }; + tests_groupsWithDeps = let + environ = linux_environ; + pyproject = libpdm.loadPdmPyProject (lib.importTOML ./../../../examples/dream2nix-repo-flake-pdm/pyproject.toml); + groups_with_deps = libpdm.groupsWithDeps { + inherit environ pyproject; + }; + in { + test_groupsWithDeps__has_main_group = { + expr = groups_with_deps ? "default"; + expected = true; + }; + test_groupsWithDeps__main_group_has_deps = { + expr = groups_with_deps.default; + expected = ["requests"]; + }; + test_groupsWithDeps__optionals_dev_has_deps = { + expr = groups_with_deps.dev; + expected = ["pi"]; + }; + }; + + tests_getDepsRecursively = let + environ = linux_environ; + lock_data = lib.importTOML ./../../../examples/dream2nix-repo-flake-pdm/pdm.lock; + parsed_lock_data = libpdm.parseLockData { + inherit environ lock_data; + selector = libpdm.preferWheelSelector; + }; + deps = libpdm.getDepsRecursively parsed_lock_data "requests"; + in { + test_getDepsRecursively_names = { + expr = lib.attrNames deps; + expected = ["certifi" "charset-normalizer" "idna" "requests" "urllib3"]; + }; + test_getDepsRecursively_versions = { + expr = lib.mapAttrs (key: value: value.version) deps; + expected = { + certifi = "2023.7.22"; + charset-normalizer = "3.2.0"; + idna = "3.4"; + requests = "2.31.0"; + urllib3 = "2.0.5"; + }; + }; + test_getDepsRecursively_sources = { + expr = lib.mapAttrs (key: value: value.source.file) deps; + expected = { + certifi = "certifi-2023.7.22-py3-none-any.whl"; + charset-normalizer = "charset_normalizer-3.2.0-cp310-cp310-macosx_10_9_universal2.whl"; + idna = "idna-3.4-py3-none-any.whl"; + requests = "requests-2.31.0-py3-none-any.whl"; + urllib3 = "urllib3-2.0.5-py3-none-any.whl"; + }; + }; + }; + + tests_selectForGroup = let + environ = linux_environ; + pyproject = libpdm.loadPdmPyProject (lib.importTOML ./../../../examples/dream2nix-repo-flake-pdm/pyproject.toml); + lock_data = lib.importTOML ./../../../examples/dream2nix-repo-flake-pdm/pdm.lock; + groups_with_deps = libpdm.groupsWithDeps { + inherit environ pyproject; + }; + parsed_lock_data = libpdm.parseLockData { + inherit lock_data; + environ = linux_environ; + selector = libpdm.preferWheelSelector; + }; + deps_default = libpdm.selectForGroup { + inherit parsed_lock_data groups_with_deps; + groupname = "default"; + }; + in { + test_selectForGroup_names = { + expr = lib.attrNames deps_default; + expected = ["certifi" "charset-normalizer" "idna" "requests" "urllib3"]; + }; + test_selectForGroup_versions = { + expr = lib.mapAttrs (key: value: value.version) deps_default; + expected = { + certifi = "2023.7.22"; + charset-normalizer = "3.2.0"; + idna = "3.4"; + requests = "2.31.0"; + urllib3 = "2.0.5"; + }; + }; + test_selectForGroup_sources = { + expr = lib.mapAttrs (key: value: value.source.file) deps_default; + expected = { + certifi = "certifi-2023.7.22-py3-none-any.whl"; + charset-normalizer = "charset_normalizer-3.2.0-cp310-cp310-macosx_10_9_universal2.whl"; + idna = "idna-3.4-py3-none-any.whl"; + requests = "requests-2.31.0-py3-none-any.whl"; + urllib3 = "urllib3-2.0.5-py3-none-any.whl"; + }; + }; + }; in - test_isDependencyRequired // tests_isUsableFilename // tests_isValidUniversalWheel // tests_selectExtension // tests_selectSdist // tests_preferWheelSelector // tests_preferSdistSelector // tests_parseLockData + test_isDependencyRequired // tests_isUsableFilename // tests_isValidUniversalWheel // tests_selectExtension // tests_selectSdist // tests_preferWheelSelector // tests_preferSdistSelector // tests_parseLockData // tests_groupsWithDeps // tests_getDepsRecursively // tests_selectForGroup From e4a9da41ad98885e36501f73c9bbe604f3cb83e0 Mon Sep 17 00:00:00 2001 From: Andrea Ciceri Date: Fri, 29 Sep 2023 23:32:39 +0200 Subject: [PATCH 50/70] WIP --- .../single-language/spago-project/.gitignore | 12 + .../single-language/spago-project/default.nix | 15 + .../single-language/spago-project/lock.json | 741 ++++++++++++++++++ .../single-language/spago-project/spago.yaml | 15 + .../spago-project/src/Main.purs | 11 + .../spago-project/test/Test/Main.purs | 12 + modules/dream2nix/WIP-spago/default.nix | 137 ++++ modules/dream2nix/WIP-spago/interface.nix | 19 + modules/dream2nix/WIP-spago/lock.py | 44 ++ modules/flake.lock | 60 ++ 10 files changed, 1066 insertions(+) create mode 100644 examples/packages/single-language/spago-project/.gitignore create mode 100644 examples/packages/single-language/spago-project/default.nix create mode 100644 examples/packages/single-language/spago-project/lock.json create mode 100644 examples/packages/single-language/spago-project/spago.yaml create mode 100644 examples/packages/single-language/spago-project/src/Main.purs create mode 100644 examples/packages/single-language/spago-project/test/Test/Main.purs create mode 100644 modules/dream2nix/WIP-spago/default.nix create mode 100644 modules/dream2nix/WIP-spago/interface.nix create mode 100644 modules/dream2nix/WIP-spago/lock.py diff --git a/examples/packages/single-language/spago-project/.gitignore b/examples/packages/single-language/spago-project/.gitignore new file mode 100644 index 0000000000..c4705363b2 --- /dev/null +++ b/examples/packages/single-language/spago-project/.gitignore @@ -0,0 +1,12 @@ + +bower_components/ +node_modules/ +.pulp-cache/ +output/ +output-es/ +generated-docs/ +.psc-package/ +.psc* +.purs* +.psa* +.spago diff --git a/examples/packages/single-language/spago-project/default.nix b/examples/packages/single-language/spago-project/default.nix new file mode 100644 index 0000000000..15eb6467d0 --- /dev/null +++ b/examples/packages/single-language/spago-project/default.nix @@ -0,0 +1,15 @@ +{ + dream2nix, + ... +}: { + imports = [ + dream2nix.modules.dream2nix.WIP-spago + ]; + + name = "test"; + version = "1.0.0"; + + mkDerivation = { + src = ./.; + }; +} diff --git a/examples/packages/single-language/spago-project/lock.json b/examples/packages/single-language/spago-project/lock.json new file mode 100644 index 0000000000..1d7e2a04bd --- /dev/null +++ b/examples/packages/single-language/spago-project/lock.json @@ -0,0 +1,741 @@ +{ + "spago-lock": { + "type-equality": { + "dependencies": [], + "repo": "https://github.com/purescript/purescript-type-equality.git", + "version": "v4.0.1", + "rev": "0525b7d39e0fbd81b4209518139fb8ab02695774" + }, + "numbers": { + "dependencies": [ + "functions", + "maybe" + ], + "repo": "https://github.com/purescript/purescript-numbers.git", + "version": "v9.0.1", + "rev": "27d54effdd2c0e7a86fe356b1cd813dca5981c2d" + }, + "lazy": { + "dependencies": [ + "control", + "foldable-traversable", + "invariant", + "prelude" + ], + "repo": "https://github.com/purescript/purescript-lazy.git", + "version": "v6.0.0", + "rev": "48347841226b27af5205a1a8ec71e27a93ce86fd" + }, + "rationals": { + "dependencies": [ + "integers", + "js-bigints", + "prelude" + ], + "repo": "https://github.com/purescript-contrib/purescript-rationals.git", + "version": "v6.0.0", + "rev": "53f955b045ef8a06572e4ee55e3cdaf120cb41ab" + }, + "typelevel-prelude": { + "dependencies": [ + "prelude", + "type-equality" + ], + "repo": "https://github.com/purescript/purescript-typelevel-prelude.git", + "version": "v7.0.0", + "rev": "dca2fe3c8cfd5527d4fe70c4bedfda30148405bf" + }, + "identity": { + "dependencies": [ + "control", + "invariant", + "newtype", + "prelude" + ], + "repo": "https://github.com/purescript/purescript-identity.git", + "version": "v6.0.0", + "rev": "ef6768f8a52ab0bc943a85f5761ba07c257f639f" + }, + "unsafe-coerce": { + "dependencies": [], + "repo": "https://github.com/purescript/purescript-unsafe-coerce.git", + "version": "v6.0.0", + "rev": "ab956f82e66e633f647fb3098e8ddd3ec58d689f" + }, + "exists": { + "dependencies": [ + "unsafe-coerce" + ], + "repo": "https://github.com/purescript/purescript-exists.git", + "version": "v6.0.0", + "rev": "f765b4ace7869c27b9c05949e18c843881f9173b" + }, + "either": { + "dependencies": [ + "control", + "invariant", + "maybe", + "prelude" + ], + "repo": "https://github.com/purescript/purescript-either.git", + "version": "v6.1.0", + "rev": "2a84a9cfce9fc33dfbaf9f6f8ec31588c9340aea" + }, + "parallel": { + "dependencies": [ + "control", + "effect", + "either", + "foldable-traversable", + "functors", + "maybe", + "newtype", + "prelude", + "profunctor", + "refs", + "transformers" + ], + "repo": "https://github.com/purescript/purescript-parallel.git", + "version": "v7.0.0", + "rev": "a6be752e44f115be1ec4d742f307bf7c0e14a765" + }, + "refs": { + "dependencies": [ + "effect", + "prelude" + ], + "repo": "https://github.com/purescript/purescript-refs.git", + "version": "v6.0.0", + "rev": "f8e6216da4cb9309fde1f20cd6f69ac3a3b7f9e8" + }, + "profunctor": { + "dependencies": [ + "control", + "distributive", + "either", + "exists", + "invariant", + "newtype", + "prelude", + "tuples" + ], + "repo": "https://github.com/purescript/purescript-profunctor.git", + "version": "v6.0.0", + "rev": "0a966a14e7b0c827d44657dc1710cdc712d2e034" + }, + "orders": { + "dependencies": [ + "newtype", + "prelude" + ], + "repo": "https://github.com/purescript/purescript-orders.git", + "version": "v6.0.0", + "rev": "f86db621ec5eef1274145f8b1fd8ebbfe0ed4a2c" + }, + "newtype": { + "dependencies": [ + "prelude", + "safe-coerce" + ], + "repo": "https://github.com/purescript/purescript-newtype.git", + "version": "v5.0.0", + "rev": "29d8e6dd77aec2c975c948364ec3faf26e14ee7b" + }, + "tailrec": { + "dependencies": [ + "bifunctors", + "effect", + "either", + "identity", + "maybe", + "partial", + "prelude", + "refs" + ], + "repo": "https://github.com/purescript/purescript-tailrec.git", + "version": "v6.1.0", + "rev": "8bbe8402768925a5219396d0436de5c29e8fd00d" + }, + "strings": { + "dependencies": [ + "arrays", + "control", + "either", + "enums", + "foldable-traversable", + "gen", + "integers", + "maybe", + "newtype", + "nonempty", + "partial", + "prelude", + "tailrec", + "tuples", + "unfoldable", + "unsafe-coerce" + ], + "repo": "https://github.com/purescript/purescript-strings.git", + "version": "v6.0.1", + "rev": "04f0730b2e4892f9a2b92a5cc2ba74f81c2039a2" + }, + "maybe": { + "dependencies": [ + "control", + "invariant", + "newtype", + "prelude" + ], + "repo": "https://github.com/purescript/purescript-maybe.git", + "version": "v6.0.0", + "rev": "c6f98ac1088766287106c5d9c8e30e7648d36786" + }, + "ordered-collections": { + "dependencies": [ + "arrays", + "foldable-traversable", + "gen", + "lists", + "maybe", + "partial", + "prelude", + "st", + "tailrec", + "tuples", + "unfoldable" + ], + "repo": "https://github.com/purescript/purescript-ordered-collections.git", + "version": "v3.1.1", + "rev": "313ec0c3556854cd4e4752a77a86b102fc41ad05" + }, + "string-parsers": { + "dependencies": [ + "arrays", + "bifunctors", + "control", + "either", + "foldable-traversable", + "lists", + "maybe", + "prelude", + "strings", + "tailrec" + ], + "repo": "https://github.com/purescript-contrib/purescript-string-parsers.git", + "version": "v8.0.0", + "rev": "518038cec5e76a1509bab87685e0dae77462d9e1" + }, + "gen": { + "dependencies": [ + "either", + "foldable-traversable", + "identity", + "maybe", + "newtype", + "nonempty", + "prelude", + "tailrec", + "tuples", + "unfoldable" + ], + "repo": "https://github.com/purescript/purescript-gen.git", + "version": "v4.0.0", + "rev": "9fbcc2a1261c32e30d79c5418edef4d96fe76931" + }, + "signal": { + "dependencies": [ + "aff", + "effect", + "either", + "foldable-traversable", + "maybe", + "prelude" + ], + "repo": "https://github.com/bodil/purescript-signal.git", + "version": "v13.0.0", + "rev": "992905b7b0cadd2db3901a79e540ec859eaf5651" + }, + "invariant": { + "dependencies": [ + "control", + "prelude" + ], + "repo": "https://github.com/purescript/purescript-invariant.git", + "version": "v6.0.0", + "rev": "1d2a196d51e90623adb88496c2cfd759c6736894" + }, + "partial": { + "dependencies": [], + "repo": "https://github.com/purescript/purescript-partial.git", + "version": "v4.0.0", + "rev": "0fa0646f5ea1ec5f0c46dcbd770c705a6c9ad3ec" + }, + "bifunctors": { + "dependencies": [ + "const", + "either", + "newtype", + "prelude", + "tuples" + ], + "repo": "https://github.com/purescript/purescript-bifunctors.git", + "version": "v6.0.0", + "rev": "16ba2fb6dd7f05528ebd9e2f9ca3a068b325e5b3" + }, + "enums": { + "dependencies": [ + "control", + "either", + "gen", + "maybe", + "newtype", + "nonempty", + "partial", + "prelude", + "tuples", + "unfoldable" + ], + "repo": "https://github.com/purescript/purescript-enums.git", + "version": "v6.0.1", + "rev": "bf8cd640314f051a910a2df4427f0b99529c098c" + }, + "record": { + "dependencies": [ + "functions", + "prelude", + "unsafe-coerce" + ], + "repo": "https://github.com/purescript/purescript-record.git", + "version": "v4.0.0", + "rev": "c89cd1ada6b636692571fc374196b1c39c4c9f70" + }, + "transformers": { + "dependencies": [ + "control", + "distributive", + "effect", + "either", + "exceptions", + "foldable-traversable", + "identity", + "lazy", + "maybe", + "newtype", + "prelude", + "tailrec", + "tuples", + "unfoldable" + ], + "repo": "https://github.com/purescript/purescript-transformers.git", + "version": "v6.0.0", + "rev": "be72ab52357d9a665cbf93d73ba1c07c4b0957ee" + }, + "contravariant": { + "dependencies": [ + "const", + "either", + "newtype", + "prelude", + "tuples" + ], + "repo": "https://github.com/purescript/purescript-contravariant.git", + "version": "v6.0.0", + "rev": "9ad3e105b8855bcc25f4e0893c784789d05a58de" + }, + "st": { + "dependencies": [ + "partial", + "prelude", + "tailrec", + "unsafe-coerce" + ], + "repo": "https://github.com/purescript/purescript-st.git", + "version": "v6.2.0", + "rev": "fc2fe2972bb12e6a2bd3b295baf01577240c23ac" + }, + "functions": { + "dependencies": [ + "prelude" + ], + "repo": "https://github.com/purescript/purescript-functions.git", + "version": "v6.0.0", + "rev": "f626f20580483977c5b27a01aac6471e28aff367" + }, + "nonempty": { + "dependencies": [ + "control", + "foldable-traversable", + "maybe", + "prelude", + "tuples", + "unfoldable" + ], + "repo": "https://github.com/purescript/purescript-nonempty.git", + "version": "v7.0.0", + "rev": "28150ecc7419238b187abd609a92a645273348bb" + }, + "unfoldable": { + "dependencies": [ + "foldable-traversable", + "maybe", + "partial", + "prelude", + "tuples" + ], + "repo": "https://github.com/purescript/purescript-unfoldable.git", + "version": "v6.0.0", + "rev": "493dfe04ed590e20d8f69079df2f58486882748d" + }, + "psci-support": { + "dependencies": [ + "console", + "effect", + "prelude" + ], + "repo": "https://github.com/purescript/purescript-psci-support.git", + "version": "v6.0.0", + "rev": "897cdb543548cb6078d69b6413b54841404eda72" + }, + "tuples": { + "dependencies": [ + "control", + "invariant", + "prelude" + ], + "repo": "https://github.com/purescript/purescript-tuples.git", + "version": "v7.0.0", + "rev": "4f52da2729b448c8564369378f1232d8d2dc1d8b" + }, + "integers": { + "dependencies": [ + "maybe", + "numbers", + "prelude" + ], + "repo": "https://github.com/purescript/purescript-integers.git", + "version": "v6.0.0", + "rev": "54d712b25c594833083d15dc9ff2418eb9c52822" + }, + "lists": { + "dependencies": [ + "bifunctors", + "control", + "foldable-traversable", + "lazy", + "maybe", + "newtype", + "nonempty", + "partial", + "prelude", + "tailrec", + "tuples", + "unfoldable" + ], + "repo": "https://github.com/purescript/purescript-lists.git", + "version": "v7.0.0", + "rev": "b113451e5b41cad87d669a3165f955c71cd863e2" + }, + "stringutils": { + "dependencies": [ + "arrays", + "integers", + "maybe", + "partial", + "prelude", + "strings" + ], + "repo": "https://github.com/menelaos/purescript-stringutils.git", + "version": "v0.0.12", + "rev": "51d92cacd8c8102fc4e6137b4f709a2b11ca5186" + }, + "prelude": { + "dependencies": [], + "repo": "https://github.com/purescript/purescript-prelude.git", + "version": "v6.0.1", + "rev": "d71bc5e81f59a401005970ceaf233a1d62f21d8f" + }, + "foldable-traversable": { + "dependencies": [ + "bifunctors", + "const", + "control", + "either", + "functors", + "identity", + "maybe", + "newtype", + "orders", + "prelude", + "tuples" + ], + "repo": "https://github.com/purescript/purescript-foldable-traversable.git", + "version": "v6.0.0", + "rev": "b3926f870532d287ea59e2d5cd3873b81ef2a93a" + }, + "safe-coerce": { + "dependencies": [ + "unsafe-coerce" + ], + "repo": "https://github.com/purescript/purescript-safe-coerce.git", + "version": "v2.0.0", + "rev": "7fa799ae80a38b8d948efcb52608e58e198b3da7" + }, + "aff": { + "dependencies": [ + "arrays", + "bifunctors", + "control", + "datetime", + "effect", + "either", + "exceptions", + "foldable-traversable", + "functions", + "maybe", + "newtype", + "parallel", + "prelude", + "refs", + "tailrec", + "transformers", + "unsafe-coerce" + ], + "repo": "https://github.com/purescript-contrib/purescript-aff.git", + "version": "v7.1.0", + "rev": "6adec6ff048a7876f74c294c440374cd21342d39" + }, + "control": { + "dependencies": [ + "newtype", + "prelude" + ], + "repo": "https://github.com/purescript/purescript-control.git", + "version": "v6.0.0", + "rev": "a6033808790879a17b2729e73747a9ed3fb2264e" + }, + "profunctor-lenses": { + "dependencies": [ + "arrays", + "bifunctors", + "const", + "control", + "distributive", + "either", + "foldable-traversable", + "foreign-object", + "functors", + "identity", + "lists", + "maybe", + "newtype", + "ordered-collections", + "partial", + "prelude", + "profunctor", + "record", + "transformers", + "tuples" + ], + "repo": "https://github.com/purescript-contrib/purescript-profunctor-lenses.git", + "version": "v8.0.0", + "rev": "973d567afe458fd802cf4f0d9725b6dc35ad9297" + }, + "effect": { + "dependencies": [ + "prelude" + ], + "repo": "https://github.com/purescript/purescript-effect.git", + "version": "v4.0.0", + "rev": "a192ddb923027d426d6ea3d8deb030c9aa7c7dda" + }, + "midi": { + "dependencies": [ + "arrays", + "control", + "effect", + "either", + "foldable-traversable", + "integers", + "lists", + "maybe", + "ordered-collections", + "prelude", + "signal", + "string-parsers", + "strings", + "tuples", + "unfoldable" + ], + "repo": "https://github.com/newlandsvalley/purescript-midi.git", + "version": "v4.0.0", + "rev": "f7a6e82054eec0fcf13886f37107b8da2025a090" + }, + "abc-parser": { + "dependencies": [ + "arrays", + "bifunctors", + "control", + "either", + "enums", + "foldable-traversable", + "identity", + "integers", + "js-bigints", + "lists", + "maybe", + "midi", + "newtype", + "ordered-collections", + "partial", + "prelude", + "profunctor-lenses", + "rationals", + "string-parsers", + "strings", + "stringutils", + "transformers", + "tuples", + "unfoldable" + ], + "repo": "https://github.com/newlandsvalley/purescript-abc-parser.git", + "version": "v2.0.1", + "rev": "177e4631a6c85a212ed06993242de23ef02629c5" + }, + "exceptions": { + "dependencies": [ + "effect", + "either", + "maybe", + "prelude" + ], + "repo": "https://github.com/purescript/purescript-exceptions.git", + "version": "v6.0.0", + "rev": "afab3c07c820bb49b6c5be50049db46a964a6161" + }, + "distributive": { + "dependencies": [ + "identity", + "newtype", + "prelude", + "tuples", + "type-equality" + ], + "repo": "https://github.com/purescript/purescript-distributive.git", + "version": "v6.0.0", + "rev": "6005e513642e855ebf6f884d24a35c2803ca252a" + }, + "foreign-object": { + "dependencies": [ + "arrays", + "foldable-traversable", + "functions", + "gen", + "lists", + "maybe", + "prelude", + "st", + "tailrec", + "tuples", + "typelevel-prelude", + "unfoldable" + ], + "repo": "https://github.com/purescript/purescript-foreign-object.git", + "version": "v4.1.0", + "rev": "9bfb4eb6271b151414594cfec669fb4b18b91bd1" + }, + "const": { + "dependencies": [ + "invariant", + "newtype", + "prelude" + ], + "repo": "https://github.com/purescript/purescript-const.git", + "version": "v6.0.0", + "rev": "ab9570cf2b6e67f7e441178211db1231cfd75c37" + }, + "functors": { + "dependencies": [ + "bifunctors", + "const", + "contravariant", + "control", + "distributive", + "either", + "invariant", + "maybe", + "newtype", + "prelude", + "profunctor", + "tuples", + "unsafe-coerce" + ], + "repo": "https://github.com/purescript/purescript-functors.git", + "version": "v5.0.0", + "rev": "022ffd7a2a7ec12080314f3d217b400674a247b4" + }, + "console": { + "dependencies": [ + "effect", + "prelude" + ], + "repo": "https://github.com/purescript/purescript-console.git", + "version": "v6.0.0", + "rev": "3b83d7b792d03872afeea5e62b4f686ab0f09842" + }, + "js-bigints": { + "dependencies": [ + "integers", + "maybe", + "prelude" + ], + "repo": "https://github.com/purescript-contrib/purescript-js-bigints.git", + "version": "v2.2.0", + "rev": "18ace2d9a2c8884a165604a4950bdb7523899764" + }, + "arrays": { + "dependencies": [ + "bifunctors", + "control", + "foldable-traversable", + "functions", + "maybe", + "nonempty", + "partial", + "prelude", + "safe-coerce", + "st", + "tailrec", + "tuples", + "unfoldable", + "unsafe-coerce" + ], + "repo": "https://github.com/purescript/purescript-arrays.git", + "version": "v7.2.1", + "rev": "ad760640451bd6b4bdd5d44969940217767accba" + }, + "datetime": { + "dependencies": [ + "bifunctors", + "control", + "either", + "enums", + "foldable-traversable", + "functions", + "gen", + "integers", + "lists", + "maybe", + "newtype", + "numbers", + "ordered-collections", + "partial", + "prelude", + "tuples" + ], + "repo": "https://github.com/purescript/purescript-datetime.git", + "version": "v6.1.0", + "rev": "7f6062346055e654942caed6c44612b59031f059" + } + }, + "invalidationHash": "44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a" +} \ No newline at end of file diff --git a/examples/packages/single-language/spago-project/spago.yaml b/examples/packages/single-language/spago-project/spago.yaml new file mode 100644 index 0000000000..39facd07ee --- /dev/null +++ b/examples/packages/single-language/spago-project/spago.yaml @@ -0,0 +1,15 @@ +package: + dependencies: + - abc-parser # added just for having transitive dependencies + - console + - effect + - prelude + - psci-support # TODO hardcode + name: spago-project + test: + dependencies: [] + main: Test.Main +workspace: + extra_packages: {} + package_set: + registry: 42.1.0 diff --git a/examples/packages/single-language/spago-project/src/Main.purs b/examples/packages/single-language/spago-project/src/Main.purs new file mode 100644 index 0000000000..a4363b879c --- /dev/null +++ b/examples/packages/single-language/spago-project/src/Main.purs @@ -0,0 +1,11 @@ +module Main where + +import Prelude + +import Effect (Effect) +import Effect.Console (log) + +main :: Effect Unit +main = do + log "🍝" + diff --git a/examples/packages/single-language/spago-project/test/Test/Main.purs b/examples/packages/single-language/spago-project/test/Test/Main.purs new file mode 100644 index 0000000000..e6169302ec --- /dev/null +++ b/examples/packages/single-language/spago-project/test/Test/Main.purs @@ -0,0 +1,12 @@ +module Test.Main where + +import Prelude + +import Effect (Effect) +import Effect.Class.Console (log) + +main :: Effect Unit +main = do + log "🍕" + log "You should add some tests." + diff --git a/modules/dream2nix/WIP-spago/default.nix b/modules/dream2nix/WIP-spago/default.nix new file mode 100644 index 0000000000..4459312799 --- /dev/null +++ b/modules/dream2nix/WIP-spago/default.nix @@ -0,0 +1,137 @@ +{lib, dream2nix, config, packageSets, ...}: +let + l = lib // builtins; + + purescript-overlay = builtins.getFlake "github:thomashoneyman/purescript-overlay/dbf63923b2d7a8ed03e962db9f450e6fa61fb526"; + inherit (purescript-overlay.packages.${config.deps.stdenv.system}) purs spago-unstable; + # FIXME wait fix by Dave and then remove lines above + # inherit (dream2nix.inputs.purescript-overlay.packages.${config.deps.stdenv.system}) purs spago-unstable; + + registry-index = config.deps.fetchFromGitHub { + owner = "purescript"; + repo = "registry-index"; + rev = "e1529b1338796f81d8401e3562674bc6490b2ea9"; + hash = "sha256-/GeBrbl4g9qXCLld/2rK/zLDmpOmAZouBKJFIpQhjoU="; + }; + + registry = config.deps.fetchFromGitHub { + owner = "purescript"; + repo = "registry"; + rev = "cf70a36e1233f71bd4a39d516a76dd25129184e3"; + hash = "sha256-h7wcsL8ubXSK7JAm+5UFq+9b5FDiRyz5F/mzRsaHJvI="; + }; + + writers = import ../../../pkgs/writers { + inherit lib; + inherit + (config.deps) + bash + coreutils + gawk + writeScript + writeScriptBin + path + ; + }; + + cfg = config.spago; + + lock = config.lock.content.spago-lock; + + mkTarball = depName: config.deps.runCommand "${depName}-tarball" {} '' + mkdir ${depName}-${l.removePrefix "v" lock.${depName}.version} + cd ${depName}-${l.removePrefix "v" lock.${depName}.version} + cp -r ${cfg.sources.${depName}}/* . + cd .. + tar -cvzf $out . + ''; + + installSource = depName: dep: '' + ln -s ${dep} .spago/packages/${depName}-${lock.${depName}.version} + mkdir -p $HOME/.cache/spago-nodejs/packages/${depName} + cp ${mkTarball depName} $HOME/.cache/spago-nodejs/packages/${depName}/${l.removePrefix "v" lock.${depName}.version}.tar.gz + ''; + + installSources = l.mapAttrsToList installSource cfg.sources; + +in { + imports = [ + dream2nix.modules.dream2nix.core + dream2nix.modules.dream2nix.mkDerivation + ./interface.nix + ]; + + spago.sources = l.mapAttrs (depName: dep: builtins.fetchGit (l.trace (builtins.toJSON dep) { + inherit (dep) rev; + url = dep.repo; + })) config.lock.content.spago-lock; + + mkDerivation = { + nativeBuildInputs = [ + spago-unstable + purs + config.deps.git + config.deps.breakpointHook + config.deps.esbuild + config.deps.yq-go + ]; + buildInputs = [ + config.deps.nodejs + ]; + buildPhase = '' + export HOME="$(realpath .)" + mkdir -p "$HOME/.cache/spago-nodejs" + ln -s ${registry} "$HOME/.cache/spago-nodejs/registry" + ln -s ${registry-index} "$HOME/.cache/spago-nodejs/registry-index" + mkdir -p .spago/packages + ${toString installSources} + spago bundle --verbose + OUTFILE="$(yq -r '.package.bundle.outfile // "index.js"' spago.yaml)" + mkdir -p $out/bin + cp "$OUTFILE" "$out/bin/$OUTFILE" + ''; + }; + + lock.fields.spago-lock.script = writers.writePureShellScript [ + config.deps.coreutils + config.deps.curl + config.deps.gnutar + config.deps.gzip + config.deps.yq-go + config.deps.python3 + config.deps.git + ] + '' + set -euo pipefail + mkdir $TMPDIR/package-sets + cd $TMPDIR/package-sets + curl -fL https://github.com/purescript/package-sets/archive/refs/heads/master.tar.gz | tar xz --strip-components=1 + yq -o=json < ${config.spago.spagoYamlFile} > spago.json + python3 ${./lock.py} + ''; + + deps = {nixpkgs, ...}: + l.mapAttrs (_: l.mkDefault) { + inherit + (nixpkgs) + stdenv + coreutils + curl + writeScript + writeScriptBin + bash + path + gawk + gnutar + gzip + yq-go + python3 + git + esbuild # used by spago bundle + fetchFromGitHub + breakpointHook + runCommand + nodejs + ; + }; +} diff --git a/modules/dream2nix/WIP-spago/interface.nix b/modules/dream2nix/WIP-spago/interface.nix new file mode 100644 index 0000000000..7ac3f3360f --- /dev/null +++ b/modules/dream2nix/WIP-spago/interface.nix @@ -0,0 +1,19 @@ +{ + lib, + config, + ... +}: let + l = lib // builtins; + t = l.types; +in { + options.spago = { + spagoYamlFile = l.mkOption { + type = t.path; + default = "${config.mkDerivation.src}/spago.yaml"; + }; + + sources = l.mkOption { + type = t.lazyAttrsOf t.package; + }; + }; +} diff --git a/modules/dream2nix/WIP-spago/lock.py b/modules/dream2nix/WIP-spago/lock.py new file mode 100644 index 0000000000..c3b96caf16 --- /dev/null +++ b/modules/dream2nix/WIP-spago/lock.py @@ -0,0 +1,44 @@ +import subprocess +import json +import os +import multiprocessing +from multiprocessing.pool import ThreadPool + +with open('spago.json', 'r') as spagoFile, open('packages.json', 'r') as packagesFile: + spago = json.load(spagoFile) + packagesSet = json.load(packagesFile) + +dependencies = spago["package"]["dependencies"] +checked = set() + +closure = set(dependencies) + +def getDeps(deps): + for dep in deps.copy(): + if dep in checked: + continue + checked.add(dep) + closure.update(getDeps(set(packagesSet[dep]["dependencies"]))) + return deps + + +getDeps(set(dependencies)) + +lock = {} + +def getSource(depName): + dep = packagesSet[depName] + repo = dep["repo"] + version = dep["version"] + rev = subprocess.run(["git", "ls-remote", repo, version], text=True, capture_output=True).stdout.split()[0] + print(f"{repo}/{version}: {rev}") + lock[depName] = dep + lock[depName]["rev"] = rev + +with ThreadPool(processes=multiprocessing.cpu_count()*2) as pool: + pool.map_async(getSource, closure) + pool.close() + pool.join() + +with open(os.environ.get("out"), "w") as f: + json.dump(lock, f) diff --git a/modules/flake.lock b/modules/flake.lock index 3c5591d05c..399e03478b 100644 --- a/modules/flake.lock +++ b/modules/flake.lock @@ -16,6 +16,43 @@ "type": "github" } }, + "nixpkgs": { + "locked": { + "lastModified": 1695830400, + "narHash": "sha256-gToZXQVr0G/1WriO83olnqrLSHF2Jb8BPcmCt497ro0=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "8a86b98f0ba1c405358f1b71ff8b5e1d317f5db2", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "purescript-overlay": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ], + "slimlock": "slimlock" + }, + "locked": { + "lastModified": 1695569752, + "narHash": "sha256-zjfsJfHT/YedX2sAgK9g6X8XTsRH5Cr18hS1iBFvb+w=", + "owner": "thomashoneyman", + "repo": "purescript-overlay", + "rev": "dbf63923b2d7a8ed03e962db9f450e6fa61fb526", + "type": "github" + }, + "original": { + "owner": "thomashoneyman", + "repo": "purescript-overlay", + "type": "github" + } + }, "pyproject-nix": { "flake": false, "locked": { @@ -35,8 +72,31 @@ "root": { "inputs": { "flake-compat": "flake-compat", + "nixpkgs": "nixpkgs", + "purescript-overlay": "purescript-overlay", "pyproject-nix": "pyproject-nix" } + }, + "slimlock": { + "inputs": { + "nixpkgs": [ + "purescript-overlay", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1688610262, + "narHash": "sha256-Wg0ViDotFWGWqKIQzyYCgayeH8s4U1OZcTiWTQYdAp4=", + "owner": "thomashoneyman", + "repo": "slimlock", + "rev": "b5c6cdcaf636ebbebd0a1f32520929394493f1a6", + "type": "github" + }, + "original": { + "owner": "thomashoneyman", + "repo": "slimlock", + "type": "github" + } } }, "root": "root", From 03b1e05f7bb6525b4a7109fd811d6948f84db430 Mon Sep 17 00:00:00 2001 From: DavHau Date: Sat, 30 Sep 2023 15:55:57 +0100 Subject: [PATCH 51/70] fix(spago): fix flake inputs --- .../single-language/spago-project/default.nix | 5 +- modules/default.nix | 4 +- modules/dream2nix/WIP-spago/default.nix | 138 ++++++++++-------- modules/dream2nix/WIP-spago/lock.py | 13 +- modules/flake-parts/checks.nix-unit.nix | 2 +- modules/flake.lock | 25 ++-- modules/flake.nix | 7 +- 7 files changed, 106 insertions(+), 88 deletions(-) diff --git a/examples/packages/single-language/spago-project/default.nix b/examples/packages/single-language/spago-project/default.nix index 15eb6467d0..1e611ff07f 100644 --- a/examples/packages/single-language/spago-project/default.nix +++ b/examples/packages/single-language/spago-project/default.nix @@ -1,7 +1,4 @@ -{ - dream2nix, - ... -}: { +{dream2nix, ...}: { imports = [ dream2nix.modules.dream2nix.WIP-spago ]; diff --git a/modules/default.nix b/modules/default.nix index 3fc972bc28..94ad99c94e 100644 --- a/modules/default.nix +++ b/modules/default.nix @@ -1,5 +1,5 @@ # This file provides backward compatibility to nix < 2.4 clients -let +inputs: let flake = import ( @@ -13,4 +13,4 @@ let ) {src = ./.;}; in - flake.defaultNix + flake.defaultNix.overrideInputs inputs diff --git a/modules/dream2nix/WIP-spago/default.nix b/modules/dream2nix/WIP-spago/default.nix index 4459312799..0d204c96e1 100644 --- a/modules/dream2nix/WIP-spago/default.nix +++ b/modules/dream2nix/WIP-spago/default.nix @@ -1,11 +1,18 @@ -{lib, dream2nix, config, packageSets, ...}: -let +{ + lib, + dream2nix, + config, + packageSets, + ... +}: let l = lib // builtins; - purescript-overlay = builtins.getFlake "github:thomashoneyman/purescript-overlay/dbf63923b2d7a8ed03e962db9f450e6fa61fb526"; + depsFlake = import ../../default.nix { + nixpkgs = packageSets.nixpkgs.path; + }; + + purescript-overlay = depsFlake.inputs.purescript-overlay; inherit (purescript-overlay.packages.${config.deps.stdenv.system}) purs spago-unstable; - # FIXME wait fix by Dave and then remove lines above - # inherit (dream2nix.inputs.purescript-overlay.packages.${config.deps.stdenv.system}) purs spago-unstable; registry-index = config.deps.fetchFromGitHub { owner = "purescript"; @@ -20,7 +27,7 @@ let rev = "cf70a36e1233f71bd4a39d516a76dd25129184e3"; hash = "sha256-h7wcsL8ubXSK7JAm+5UFq+9b5FDiRyz5F/mzRsaHJvI="; }; - + writers = import ../../../pkgs/writers { inherit lib; inherit @@ -35,25 +42,25 @@ let }; cfg = config.spago; - + lock = config.lock.content.spago-lock; - mkTarball = depName: config.deps.runCommand "${depName}-tarball" {} '' - mkdir ${depName}-${l.removePrefix "v" lock.${depName}.version} - cd ${depName}-${l.removePrefix "v" lock.${depName}.version} - cp -r ${cfg.sources.${depName}}/* . - cd .. - tar -cvzf $out . - ''; - + mkTarball = depName: + config.deps.runCommand "${depName}-tarball" {} '' + mkdir ${depName}-${l.removePrefix "v" lock.${depName}.version} + cd ${depName}-${l.removePrefix "v" lock.${depName}.version} + cp -r ${cfg.sources.${depName}}/* . + cd .. + tar -cvzf $out . + ''; + installSource = depName: dep: '' ln -s ${dep} .spago/packages/${depName}-${lock.${depName}.version} - mkdir -p $HOME/.cache/spago-nodejs/packages/${depName} + mkdir -p $HOME/.cache/spago-nodejs/packages/${depName} cp ${mkTarball depName} $HOME/.cache/spago-nodejs/packages/${depName}/${l.removePrefix "v" lock.${depName}.version}.tar.gz ''; installSources = l.mapAttrsToList installSource cfg.sources; - in { imports = [ dream2nix.modules.dream2nix.core @@ -61,10 +68,12 @@ in { ./interface.nix ]; - spago.sources = l.mapAttrs (depName: dep: builtins.fetchGit (l.trace (builtins.toJSON dep) { - inherit (dep) rev; - url = dep.repo; - })) config.lock.content.spago-lock; + spago.sources = l.mapAttrs (depName: dep: + builtins.fetchGit { + inherit (dep) rev; + url = dep.repo; + }) + config.lock.content.spago-lock; mkDerivation = { nativeBuildInputs = [ @@ -87,51 +96,52 @@ in { ${toString installSources} spago bundle --verbose OUTFILE="$(yq -r '.package.bundle.outfile // "index.js"' spago.yaml)" - mkdir -p $out/bin - cp "$OUTFILE" "$out/bin/$OUTFILE" + mkdir -p $out/bin + cp "$OUTFILE" "$out/bin/$OUTFILE" ''; }; - - lock.fields.spago-lock.script = writers.writePureShellScript [ - config.deps.coreutils - config.deps.curl - config.deps.gnutar - config.deps.gzip - config.deps.yq-go - config.deps.python3 - config.deps.git - ] + + lock.fields.spago-lock.script = + writers.writePureShellScript [ + config.deps.coreutils + config.deps.curl + config.deps.gnutar + config.deps.gzip + config.deps.yq-go + config.deps.python3 + config.deps.git + ] '' - set -euo pipefail - mkdir $TMPDIR/package-sets - cd $TMPDIR/package-sets - curl -fL https://github.com/purescript/package-sets/archive/refs/heads/master.tar.gz | tar xz --strip-components=1 - yq -o=json < ${config.spago.spagoYamlFile} > spago.json - python3 ${./lock.py} - ''; + set -euo pipefail + mkdir $TMPDIR/package-sets + cd $TMPDIR/package-sets + curl -fL https://github.com/purescript/package-sets/archive/refs/heads/master.tar.gz | tar xz --strip-components=1 + yq -o=json < ${config.spago.spagoYamlFile} > spago.json + python3 ${./lock.py} + ''; - deps = {nixpkgs, ...}: - l.mapAttrs (_: l.mkDefault) { - inherit - (nixpkgs) - stdenv - coreutils - curl - writeScript - writeScriptBin - bash - path - gawk - gnutar - gzip - yq-go - python3 - git - esbuild # used by spago bundle - fetchFromGitHub - breakpointHook - runCommand - nodejs - ; - }; + deps = {nixpkgs, ...}: + l.mapAttrs (_: l.mkDefault) { + inherit + (nixpkgs) + stdenv + coreutils + curl + writeScript + writeScriptBin + bash + path + gawk + gnutar + gzip + yq-go + python3 + git + esbuild # used by spago bundle + fetchFromGitHub + breakpointHook + runCommand + nodejs + ; + }; } diff --git a/modules/dream2nix/WIP-spago/lock.py b/modules/dream2nix/WIP-spago/lock.py index c3b96caf16..5348903227 100644 --- a/modules/dream2nix/WIP-spago/lock.py +++ b/modules/dream2nix/WIP-spago/lock.py @@ -4,7 +4,7 @@ import multiprocessing from multiprocessing.pool import ThreadPool -with open('spago.json', 'r') as spagoFile, open('packages.json', 'r') as packagesFile: +with open("spago.json", "r") as spagoFile, open("packages.json", "r") as packagesFile: spago = json.load(spagoFile) packagesSet = json.load(packagesFile) @@ -13,6 +13,7 @@ closure = set(dependencies) + def getDeps(deps): for dep in deps.copy(): if dep in checked: @@ -21,21 +22,25 @@ def getDeps(deps): closure.update(getDeps(set(packagesSet[dep]["dependencies"]))) return deps - + getDeps(set(dependencies)) lock = {} + def getSource(depName): dep = packagesSet[depName] repo = dep["repo"] version = dep["version"] - rev = subprocess.run(["git", "ls-remote", repo, version], text=True, capture_output=True).stdout.split()[0] + rev = subprocess.run( + ["git", "ls-remote", repo, version], text=True, capture_output=True + ).stdout.split()[0] print(f"{repo}/{version}: {rev}") lock[depName] = dep lock[depName]["rev"] = rev -with ThreadPool(processes=multiprocessing.cpu_count()*2) as pool: + +with ThreadPool(processes=multiprocessing.cpu_count() * 2) as pool: pool.map_async(getSource, closure) pool.close() pool.join() diff --git a/modules/flake-parts/checks.nix-unit.nix b/modules/flake-parts/checks.nix-unit.nix index 57761ca94c..5b0c52557f 100644 --- a/modules/flake-parts/checks.nix-unit.nix +++ b/modules/flake-parts/checks.nix-unit.nix @@ -7,7 +7,7 @@ system, ... }: let - modulesFlake = import "${self}/modules"; + modulesFlake = import "${self}/modules" {}; inputs = lib.mapAttrs (name: input: "${input.outPath}") modulesFlake.inputs; inputsFile = builtins.toFile "inputs.json" (builtins.toJSON inputs); in diff --git a/modules/flake.lock b/modules/flake.lock index 399e03478b..dbd5b0b3cf 100644 --- a/modules/flake.lock +++ b/modules/flake.lock @@ -3,31 +3,32 @@ "flake-compat": { "flake": false, "locked": { - "lastModified": 1673956053, - "narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=", - "owner": "edolstra", + "lastModified": 1695612854, + "narHash": "sha256-QPe1fENhAB4l/N04FulgItq1rfcpQMttGZzikV7h3iI=", + "owner": "nix-community", "repo": "flake-compat", - "rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9", + "rev": "ad8d6af6aa8a14851a60bd00927f42b9798544ea", "type": "github" }, "original": { - "owner": "edolstra", + "owner": "nix-community", + "ref": "pull/4/head", "repo": "flake-compat", "type": "github" } }, "nixpkgs": { "locked": { - "lastModified": 1695830400, - "narHash": "sha256-gToZXQVr0G/1WriO83olnqrLSHF2Jb8BPcmCt497ro0=", + "lastModified": 1695837737, + "narHash": "sha256-KcqmJ5hNacLuE7fkz5586kp/vt4NLo6+Prq3DMgrxpQ=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "8a86b98f0ba1c405358f1b71ff8b5e1d317f5db2", + "rev": "517501bcf14ae6ec47efd6a17dda0ca8e6d866f9", "type": "github" }, "original": { "owner": "NixOS", - "ref": "nixos-unstable", + "ref": "nixpkgs-unstable", "repo": "nixpkgs", "type": "github" } @@ -40,11 +41,11 @@ "slimlock": "slimlock" }, "locked": { - "lastModified": 1695569752, - "narHash": "sha256-zjfsJfHT/YedX2sAgK9g6X8XTsRH5Cr18hS1iBFvb+w=", + "lastModified": 1696022621, + "narHash": "sha256-eMjFmsj2G1E0Q5XiibUNgFjTiSz0GxIeSSzzVdoN730=", "owner": "thomashoneyman", "repo": "purescript-overlay", - "rev": "dbf63923b2d7a8ed03e962db9f450e6fa61fb526", + "rev": "047c7933abd6da8aa239904422e22d190ce55ead", "type": "github" }, "original": { diff --git a/modules/flake.nix b/modules/flake.nix index f29fa3181a..4862bf3756 100644 --- a/modules/flake.nix +++ b/modules/flake.nix @@ -2,11 +2,16 @@ description = "(modules only) dream2nix: Automate reproducible packaging for various language ecosystems"; inputs = { - flake-compat.url = "github:edolstra/flake-compat"; + nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; + + flake-compat.url = "github:nix-community/flake-compat/pull/4/head"; flake-compat.flake = false; pyproject-nix.url = "github:adisbladis/pyproject.nix"; pyproject-nix.flake = false; + + purescript-overlay.url = "github:thomashoneyman/purescript-overlay"; + purescript-overlay.inputs.nixpkgs.follows = "nixpkgs"; }; outputs = _: let From c4bc9c1f27f9a365390c839b2a6196ab9d9ea12c Mon Sep 17 00:00:00 2001 From: DavHau Date: Sun, 1 Oct 2023 00:47:33 +0100 Subject: [PATCH 52/70] feat(pdm): build default group Also implement source fetching --- examples/dream2nix-repo-flake-pdm/flake.nix | 11 ++- modules/dream2nix/WIP-python-pdm/default.nix | 72 +++++++++++++++--- .../WIP-python-pdm/fetch-from-pypi.nix | 73 +++++++++++++++++++ .../WIP-python-pdm/fetch-from-pypi.sh | 27 +++++++ modules/dream2nix/groups/group.nix | 6 +- modules/dream2nix/groups/interface.nix | 4 +- modules/flake-parts/examples.nix | 13 ++++ tests/nix-unit/test_groups/default.nix | 4 +- 8 files changed, 190 insertions(+), 20 deletions(-) create mode 100644 modules/dream2nix/WIP-python-pdm/fetch-from-pypi.nix create mode 100644 modules/dream2nix/WIP-python-pdm/fetch-from-pypi.sh diff --git a/examples/dream2nix-repo-flake-pdm/flake.nix b/examples/dream2nix-repo-flake-pdm/flake.nix index dba0790f2f..20b0a474f4 100644 --- a/examples/dream2nix-repo-flake-pdm/flake.nix +++ b/examples/dream2nix-repo-flake-pdm/flake.nix @@ -2,7 +2,7 @@ description = "My flake with dream2nix packages"; inputs = { - dream2nix.url = "github:nix-community/dream2nix"; + dream2nix.url = "github:nix-community/dream2nix?dir=modules"; nixpkgs.url = "nixpkgs/nixos-unstable"; }; @@ -27,9 +27,12 @@ pdm.pyproject = ./pyproject.toml; pdm.pythonInterpreter = nixpkgs.legacyPackages.python3; }; - evaled = lib.evalModules {modules = [module];}; - defaultPackage = evaled.config.groups.default.public.packages.my-package; + evaled = lib.evalModules { + modules = [module]; + specialArgs.dream2nix = dream2nix; + specialArgs.packageSets.nixpkgs = nixpkgs.legacyPackages.x86_64-linux; + }; in { - packages.${system}.default = defaultPackage; + packages.${system} = evaled.config.groups.default.public.packages; }; } diff --git a/modules/dream2nix/WIP-python-pdm/default.nix b/modules/dream2nix/WIP-python-pdm/default.nix index 0429b3ac87..576f6d1e2c 100644 --- a/modules/dream2nix/WIP-python-pdm/default.nix +++ b/modules/dream2nix/WIP-python-pdm/default.nix @@ -4,31 +4,81 @@ dream2nix, ... }: let - libpdm = ./lib.nix { + libpdm = import ./lib.nix { inherit lib libpyproject; }; libpyproject = import (dream2nix.inputs.pyproject-nix + "/lib") {inherit lib;}; - lock-data = libpdm.parseLockData { - lock-data = lib.importTOML config.pdm.lock-file; - environ = libpyproject.pep508.mkEnviron config.deps.python3; - selector = libpdm.preferWheelSelector; - }; + lock_data = lib.importTOML config.pdm.lockfile; + environ = libpyproject.pep508.mkEnviron config.deps.python3; + selector = libpdm.preferWheelSelector; - pyproject-data = lib.importTOML config.pdm.pyproject; + pyproject = libpdm.loadPdmPyProject (lib.importTOML config.pdm.pyproject); - pyprojectLoaded = libpdm.loadPdmPyproject pyproject-data; + groups_with_deps = libpdm.groupsWithDeps { + inherit environ pyproject; + }; + parsed_lock_data = libpdm.parseLockData { + inherit environ lock_data; + selector = libpdm.preferWheelSelector; + }; + deps_default = libpdm.selectForGroup { + inherit parsed_lock_data groups_with_deps; + groupname = "default"; + }; - build-systems = pyprojectLoaded.build-systems; - dependencies = pyprojectLoaded.dependencies; + fetchFromPypi = import ./fetch-from-pypi.nix { + inherit lib; + inherit (config.deps) curl jq stdenvNoCC; + }; in { imports = [ dream2nix.modules.dream2nix.groups + ../core/deps ./interface.nix ]; + deps = {nixpkgs, ...}: { + inherit + (nixpkgs) + curl + jq + stdenvNoCC + ; + }; commonModule = { - options.sourceSelector = import ./sourceSelectorOption.nix {}; + options.sourceSelector = import ./sourceSelectorOption.nix {inherit lib;}; config.sourceSelector = lib.mkOptionDefault config.pdm.sourceSelector; }; + groups.default = { + packages = lib.flip lib.mapAttrs deps_default (name: pkg: { + inherit name; + version = pkg.version; + imports = [ + dream2nix.modules.dream2nix.buildPythonPackage + dream2nix.modules.dream2nix.mkDerivation + dream2nix.modules.dream2nix.package-func + ]; + buildPythonPackage = { + format = + if lib.hasSuffix ".whl" pkg.source.file + then "wheel" + else "pyproject"; + }; + mkDerivation = { + # required: { pname, file, version, hash, kind, curlOpts ? "" }: + src = fetchFromPypi { + pname = name; + file = pkg.source.file; + version = pkg.version; + hash = pkg.source.hash; + kind = ""; + }; + propagatedBuildInputs = + lib.forEach + parsed_lock_data.${name}.dependencies + (depName: config.groups.default.public.packages.${depName}); + }; + }); + }; } diff --git a/modules/dream2nix/WIP-python-pdm/fetch-from-pypi.nix b/modules/dream2nix/WIP-python-pdm/fetch-from-pypi.nix new file mode 100644 index 0000000000..197413e5c4 --- /dev/null +++ b/modules/dream2nix/WIP-python-pdm/fetch-from-pypi.nix @@ -0,0 +1,73 @@ +# copied from poetry2nix +# LICENSE: https://github.com/nix-community/poetry2nix/blob/master/LICENSE +{ + lib, + curl, + jq, + stdenvNoCC, +}: let + # Predict URL from the PyPI index. + # Args: + # pname: package name + # file: filename including extension + # hash: SRI hash + # kind: Language implementation and version tag + predictURLFromPypi = lib.makeOverridable ( + { + pname, + file, + hash, + kind, + }: "https://files.pythonhosted.org/packages/${kind}/${lib.toLower (builtins.substring 0 1 file)}/${pname}/${file}" + ); + + # Fetch from the PyPI index. + # At first we try to fetch the predicated URL but if that fails we + # will use the Pypi API to determine the correct URL. + # Args: + # pname: package name + # file: filename including extension + # version: the version string of the dependency + # hash: SRI hash + # kind: Language implementation and version tag + fetchFromPypi = lib.makeOverridable ( + { + pname, + file, + version, + hash, + kind, + curlOpts ? "", + }: let + predictedURL = predictURLFromPypi {inherit pname file hash kind;}; + in (stdenvNoCC.mkDerivation { + name = file; + nativeBuildInputs = [ + curl + jq + ]; + isWheel = lib.strings.hasSuffix "whl" file; + system = "builtin"; + + preferLocalBuild = true; + impureEnvVars = + lib.fetchers.proxyImpureEnvVars + ++ [ + "NIX_CURL_FLAGS" + ]; + + inherit pname file version curlOpts predictedURL; + + builder = ./fetch-from-pypi.sh; + + outputHashMode = "flat"; + outputHashAlgo = "sha256"; + outputHash = hash; + + passthru = { + urls = [predictedURL]; # retain compatibility with nixpkgs' fetchurl + }; + }) + ); +in + fetchFromPypi diff --git a/modules/dream2nix/WIP-python-pdm/fetch-from-pypi.sh b/modules/dream2nix/WIP-python-pdm/fetch-from-pypi.sh new file mode 100644 index 0000000000..627cb938a3 --- /dev/null +++ b/modules/dream2nix/WIP-python-pdm/fetch-from-pypi.sh @@ -0,0 +1,27 @@ +# copied from poetry2nix +# LICENSE: https://github.com/nix-community/poetry2nix/blob/master/LICENSE + +source $stdenv/setup +set -euo pipefail + +curl="curl \ + --location \ + --max-redirs 20 \ + --retry 2 \ + --disable-epsv \ + --cookie-jar cookies \ + --insecure \ + --speed-time 5 \ + --progress-bar \ + --fail \ + $curlOpts \ + $NIX_CURL_FLAGS" + +echo "Trying to fetch with predicted URL: $predictedURL" + +$curl $predictedURL --output $out && exit 0 + +echo "Predicted URL '$predictedURL' failed, querying pypi.org" +$curl "https://pypi.org/pypi/$pname/json" | jq -r ".releases.\"$version\"[] | select(.filename == \"$file\") | .url" > url +url=$(cat url) +$curl -k $url --output $out diff --git a/modules/dream2nix/groups/group.nix b/modules/dream2nix/groups/group.nix index e70c6af88c..21012e4d3d 100644 --- a/modules/dream2nix/groups/group.nix +++ b/modules/dream2nix/groups/group.nix @@ -2,6 +2,7 @@ lib, dream2nix, config, + specialArgs, ... }: let t = lib.types; @@ -9,6 +10,7 @@ staticModules = [ dream2nix.modules.dream2nix.core commonModule + {_module.args = specialArgs;} ]; }; in { @@ -32,7 +34,7 @@ in { ''; internal = true; }; - public = lib.mkOption { + public.packages = lib.mkOption { type = t.lazyAttrsOf t.package; description = '' The evaluated packages ready to consume @@ -42,6 +44,6 @@ in { }; config = { packagesEval = config.packages; - public = lib.mapAttrs (name: pkg: pkg.public) config.packagesEval; + public.packages = lib.mapAttrs (name: pkg: pkg.public) config.packagesEval; }; } diff --git a/modules/dream2nix/groups/interface.nix b/modules/dream2nix/groups/interface.nix index 3d9faa4480..f0b0b66b28 100644 --- a/modules/dream2nix/groups/interface.nix +++ b/modules/dream2nix/groups/interface.nix @@ -7,7 +7,9 @@ }: let t = lib.types; groupType = t.submoduleWith { - modules = [(import ./group.nix {inherit (config) commonModule;})]; + modules = [ + (import ./group.nix {inherit (config) commonModule;}) + ]; inherit specialArgs; }; in { diff --git a/modules/flake-parts/examples.nix b/modules/flake-parts/examples.nix index fc55d3de87..9c5e3f67ed 100644 --- a/modules/flake-parts/examples.nix +++ b/modules/flake-parts/examples.nix @@ -39,6 +39,17 @@ in self'; + importFlakeSmall = flakeFile: let + self' = (import flakeFile).outputs { + dream2nix = modulesFlake; + nixpkgs = inputs.nixpkgs; + self = self'; + }; + in + self'; + + modulesFlake = import (self + /modules) {}; + # Type: [ {${name} = {module, packagePath} ] allExamples = mapAttrsToList (dirName: _: readExamples dirName) packageCategories; @@ -117,6 +128,8 @@ in { .hello; example-repo-flake = (importFlake (self + /examples/dream2nix-repo-flake/flake.nix)).packages.${system}.hello; + example-repo-flake-pdm = + (importFlakeSmall (self + /examples/dream2nix-repo-flake-pdm/flake.nix)).packages.${system}.requests; } ); }; diff --git a/tests/nix-unit/test_groups/default.nix b/tests/nix-unit/test_groups/default.nix index d1c1d792ae..da65efce45 100644 --- a/tests/nix-unit/test_groups/default.nix +++ b/tests/nix-unit/test_groups/default.nix @@ -22,7 +22,7 @@ in { groups.my-group.packages.hello = {...}: fixtures.basic-derivation; }; in { - expr = config.groups.my-group.public.hello ? drvPath; + expr = config.groups.my-group.public.packages.hello ? drvPath; expected = true; }; @@ -32,7 +32,7 @@ in { commonModule = {name = lib.mkForce "hello-mod";}; }; in { - expr = "${config.groups.my-group.public.hello.name}"; + expr = "${config.groups.my-group.public.packages.hello.name}"; expected = "hello-mod"; }; } From 5e2577caaf87661e29405db7e117bda57b0e749d Mon Sep 17 00:00:00 2001 From: Yusuf Bera Ertan Date: Tue, 3 Oct 2023 13:34:06 +0300 Subject: [PATCH 53/70] fix(rust-crane): don't forget to pass mkDerivation.meta to main derivation --- modules/dream2nix/rust-crane/default.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/dream2nix/rust-crane/default.nix b/modules/dream2nix/rust-crane/default.nix index 0e624208ad..421d3338ff 100644 --- a/modules/dream2nix/rust-crane/default.nix +++ b/modules/dream2nix/rust-crane/default.nix @@ -209,7 +209,7 @@ in { inherit (config.deps) libiconv mkShell cargo; }; dependencies = cfg.depsDrv.public; - meta = utils.getMeta pname version; + meta = (utils.getMeta pname version) // config.mkDerivation.meta; }; deps = {nixpkgs, ...}: From 6f791d1cc8eac7b24c43ab212827a07bd3dfad95 Mon Sep 17 00:00:00 2001 From: Frederik Rietdijk Date: Sun, 1 Oct 2023 14:07:20 +0200 Subject: [PATCH 54/70] pdm: add non-default groups as well --- modules/dream2nix/WIP-python-pdm/default.nix | 72 ++++++++++---------- 1 file changed, 37 insertions(+), 35 deletions(-) diff --git a/modules/dream2nix/WIP-python-pdm/default.nix b/modules/dream2nix/WIP-python-pdm/default.nix index 576f6d1e2c..6f9835ead4 100644 --- a/modules/dream2nix/WIP-python-pdm/default.nix +++ b/modules/dream2nix/WIP-python-pdm/default.nix @@ -20,12 +20,7 @@ inherit environ pyproject; }; parsed_lock_data = libpdm.parseLockData { - inherit environ lock_data; - selector = libpdm.preferWheelSelector; - }; - deps_default = libpdm.selectForGroup { - inherit parsed_lock_data groups_with_deps; - groupname = "default"; + inherit environ lock_data selector; }; fetchFromPypi = import ./fetch-from-pypi.nix { @@ -50,35 +45,42 @@ in { options.sourceSelector = import ./sourceSelectorOption.nix {inherit lib;}; config.sourceSelector = lib.mkOptionDefault config.pdm.sourceSelector; }; - groups.default = { - packages = lib.flip lib.mapAttrs deps_default (name: pkg: { - inherit name; - version = pkg.version; - imports = [ - dream2nix.modules.dream2nix.buildPythonPackage - dream2nix.modules.dream2nix.mkDerivation - dream2nix.modules.dream2nix.package-func - ]; - buildPythonPackage = { - format = - if lib.hasSuffix ".whl" pkg.source.file - then "wheel" - else "pyproject"; + groups = let + populateGroup = groupname: deps: let + deps' = libpdm.selectForGroup { + inherit groupname parsed_lock_data groups_with_deps; }; - mkDerivation = { - # required: { pname, file, version, hash, kind, curlOpts ? "" }: - src = fetchFromPypi { - pname = name; - file = pkg.source.file; - version = pkg.version; - hash = pkg.source.hash; - kind = ""; + + packages = lib.flip lib.mapAttrs deps' (name: pkg: { + inherit name; + version = pkg.version; + imports = [ + dream2nix.modules.dream2nix.buildPythonPackage + dream2nix.modules.dream2nix.mkDerivation + dream2nix.modules.dream2nix.package-func + ]; + buildPythonPackage = { + format = + if lib.hasSuffix ".whl" pkg.source.file + then "wheel" + else "pyproject"; }; - propagatedBuildInputs = - lib.forEach - parsed_lock_data.${name}.dependencies - (depName: config.groups.default.public.packages.${depName}); - }; - }); - }; + mkDerivation = { + # required: { pname, file, version, hash, kind, curlOpts ? "" }: + src = fetchFromPypi { + pname = name; + file = pkg.source.file; + version = pkg.version; + hash = pkg.source.hash; + kind = ""; + }; + propagatedBuildInputs = + lib.forEach + parsed_lock_data.${name}.dependencies + (depName: config.groups.${groupname}.public.packages.${depName}); + }; + }); + in {inherit packages;}; + in + lib.mapAttrs populateGroup groups_with_deps; } From 30b8652f7179756e1b943994036a4c68a9016b4d Mon Sep 17 00:00:00 2001 From: DavHau Date: Sun, 1 Oct 2023 14:43:56 +0100 Subject: [PATCH 55/70] pdm: re-activate nix-unit test for pdm --- tests/nix-unit/test_python-pdm/default.nix | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/tests/nix-unit/test_python-pdm/default.nix b/tests/nix-unit/test_python-pdm/default.nix index 57da78a238..5fed36761e 100644 --- a/tests/nix-unit/test_python-pdm/default.nix +++ b/tests/nix-unit/test_python-pdm/default.nix @@ -1,7 +1,7 @@ { pkgs ? import {}, lib ? import , - dream2nix ? (import (../../../modules + "/flake.nix")).outputs inputs, + dream2nix ? ((import (../../../modules + "/flake.nix")).outputs inputs), inputs ? (import (../../../modules + "/default.nix")).inputs, }: let eval = module: @@ -11,7 +11,7 @@ module ]; specialArgs = { - inherit dream2nix; + dream2nix = dream2nix // {inherit inputs;}; packageSets.nixpkgs = pkgs; }; }) @@ -22,11 +22,9 @@ in { # TODO: create fixtures pdm.lockfile = ./../../../examples/dream2nix-repo-flake-pdm/pdm.lock; pdm.pyproject = ./../../../examples/dream2nix-repo-flake-pdm/pyproject.toml; - # groups.my-group.packages.hello = {...}: fixtures.basic-derivation; }; in { - # expr = config.groups.default.public.certifi ? drvPath; - expr = true; + expr = config.groups.default.public.packages.certifi ? drvPath; expected = true; }; } From e9fac8985cb7de31bc91edb934b8245b3945a67e Mon Sep 17 00:00:00 2001 From: waalge Date: Fri, 29 Sep 2023 18:32:59 +0000 Subject: [PATCH 56/70] fix: nixpkgs follows d2n --- examples/dream2nix-repo-flake/flake.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/dream2nix-repo-flake/flake.nix b/examples/dream2nix-repo-flake/flake.nix index f9d0a65cee..bfbd8ec5cb 100644 --- a/examples/dream2nix-repo-flake/flake.nix +++ b/examples/dream2nix-repo-flake/flake.nix @@ -3,7 +3,7 @@ inputs = { dream2nix.url = "github:nix-community/dream2nix"; - nixpkgs.url = "nixpkgs/nixos-unstable"; + nixpkgs.follows = "dream2nix/nixpkgs"; }; outputs = inputs @ { From 88087f6b88ff792d647b653f601f9badbcb47360 Mon Sep 17 00:00:00 2001 From: DavHau Date: Sat, 7 Oct 2023 13:16:56 +0200 Subject: [PATCH 57/70] modules: export also core modules --- modules/flake-parts/all-modules.nix | 2 +- modules/flake-parts/core-modules.nix | 33 ++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 modules/flake-parts/core-modules.nix diff --git a/modules/flake-parts/all-modules.nix b/modules/flake-parts/all-modules.nix index 76825f21c8..1877edfa35 100644 --- a/modules/flake-parts/all-modules.nix +++ b/modules/flake-parts/all-modules.nix @@ -46,7 +46,7 @@ in { imports = flakePartsModules; options.flake.modules = mkOption { - type = types.lazyAttrsOf types.raw; + type = types.lazyAttrsOf (types.lazyAttrsOf types.raw); }; # generates future flake outputs: `modules..` diff --git a/modules/flake-parts/core-modules.nix b/modules/flake-parts/core-modules.nix new file mode 100644 index 0000000000..83cf5a1f1b --- /dev/null +++ b/modules/flake-parts/core-modules.nix @@ -0,0 +1,33 @@ +# Automatically exports modules from the `/**/modules` directory to: +# `flake.modules..` +# Automatically imports all flake-parts modules from `/**/modules/flake-parts` +{ + config, + lib, + self, + ... +}: let + # inherit all lib functions used below + inherit + (builtins) + readDir + ; + inherit + (lib) + mapAttrs' + filterAttrs + nameValuePair + removeSuffix + ; + + mapModules = path: + mapAttrs' + (fn: _: + nameValuePair + (removeSuffix ".nix" fn) + (path + "/${fn}")) + (filterAttrs (_: type: type == "regular" || type == "directory") (readDir path)); +in { + # generates future flake outputs: `modules..` + config.flake.modules.dream2nix = mapModules (self + "/modules/dream2nix/core"); +} From 8441b478006a9eb119d69e2b418e82e702f2bb1d Mon Sep 17 00:00:00 2001 From: DavHau Date: Sun, 8 Oct 2023 00:43:44 +0200 Subject: [PATCH 58/70] flake: update nixpkgs --- flake.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/flake.lock b/flake.lock index 356a077a79..f3f0aed0ec 100644 --- a/flake.lock +++ b/flake.lock @@ -118,11 +118,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1694767346, - "narHash": "sha256-5uH27SiVFUwsTsqC5rs3kS7pBoNhtoy9QfTP9BmknGk=", + "lastModified": 1696604326, + "narHash": "sha256-YXUNI0kLEcI5g8lqGMb0nh67fY9f2YoJsILafh6zlMo=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "ace5093e36ab1e95cb9463863491bee90d5a4183", + "rev": "87828a0e03d1418e848d3dd3f3014a632e4a4f64", "type": "github" }, "original": { From 07a3dab254fa69171c2fb4238b19c954402f4a86 Mon Sep 17 00:00:00 2001 From: DavHau Date: Sun, 8 Oct 2023 14:25:58 +0200 Subject: [PATCH 59/70] checks: add all packages to checks --- modules/flake-parts/checks.nix | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 modules/flake-parts/checks.nix diff --git a/modules/flake-parts/checks.nix b/modules/flake-parts/checks.nix new file mode 100644 index 0000000000..7c073ef0a8 --- /dev/null +++ b/modules/flake-parts/checks.nix @@ -0,0 +1,5 @@ +{ + perSystem = {self', ...}: { + checks = self'.packages; + }; +} From 684f88baadd0b9d85257834a85d46d5898cd66ab Mon Sep 17 00:00:00 2001 From: DavHau Date: Sun, 8 Oct 2023 14:26:18 +0200 Subject: [PATCH 60/70] fetch-pip-metadata: fix build --- pkgs/fetchPipMetadata/package.nix | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pkgs/fetchPipMetadata/package.nix b/pkgs/fetchPipMetadata/package.nix index 709bff8f9e..d319687e85 100644 --- a/pkgs/fetchPipMetadata/package.nix +++ b/pkgs/fetchPipMetadata/package.nix @@ -6,8 +6,8 @@ nix-prefetch-scripts, }: let package = python3.pkgs.buildPythonPackage { - name = "fetch_pip_metadata"; - format = "flit"; + name = "fetch-pip-metadata"; + format = "pyproject"; src = ./src; nativeBuildInputs = [ gitMinimal @@ -16,6 +16,7 @@ propagatedBuildInputs = with python3.pkgs; [ packaging certifi + flit-core nix-prefetch-scripts python-dateutil pip From b7dadf27a9e10540e3ae1b276add1e5b9e130e8f Mon Sep 17 00:00:00 2001 From: DavHau Date: Sun, 8 Oct 2023 14:36:16 +0200 Subject: [PATCH 61/70] mergify: init --- .mergify.yml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 .mergify.yml diff --git a/.mergify.yml b/.mergify.yml new file mode 100644 index 0000000000..9825d91c24 --- /dev/null +++ b/.mergify.yml @@ -0,0 +1,16 @@ +queue_rules: + - name: default + merge_conditions: + - check-success=buildbot/nix-eval +defaults: + actions: + queue: + allow_merging_configuration_change: true + method: rebase +pull_request_rules: + - name: merge using the merge queue + conditions: + - base=main + - label~=merge-queue|dependencies + actions: + queue: From 541655a6fb13010ecd16f228d1ba27488e57b3b2 Mon Sep 17 00:00:00 2001 From: DavHau Date: Sun, 8 Oct 2023 14:51:50 +0200 Subject: [PATCH 62/70] examples/pdm: pin nixpkgs to dream2nix nixpkgs --- examples/dream2nix-repo-flake-pdm/flake.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/dream2nix-repo-flake-pdm/flake.nix b/examples/dream2nix-repo-flake-pdm/flake.nix index 20b0a474f4..337ab8f8fd 100644 --- a/examples/dream2nix-repo-flake-pdm/flake.nix +++ b/examples/dream2nix-repo-flake-pdm/flake.nix @@ -3,7 +3,7 @@ inputs = { dream2nix.url = "github:nix-community/dream2nix?dir=modules"; - nixpkgs.url = "nixpkgs/nixos-unstable"; + nixpkgs.follows = "dream2nix/nixpkgs"; }; outputs = inputs @ { From 4c0d029addd73604f85cee5a0fb130f00353f44e Mon Sep 17 00:00:00 2001 From: purepani Date: Thu, 5 Oct 2023 18:25:36 -0500 Subject: [PATCH 63/70] fix(groups): fix type on override parameter --- modules/dream2nix/groups/group.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/dream2nix/groups/group.nix b/modules/dream2nix/groups/group.nix index 21012e4d3d..a97d4c9d2a 100644 --- a/modules/dream2nix/groups/group.nix +++ b/modules/dream2nix/groups/group.nix @@ -16,7 +16,7 @@ in { options = { overrides = lib.mkOption { - type = lib.attrs; + type = t.attrs; description = '' A set of package overrides ''; From cf853080a3e158cc805f8ed168d082a3cf070054 Mon Sep 17 00:00:00 2001 From: Jairo Llopis Date: Fri, 22 Sep 2023 07:50:13 +0100 Subject: [PATCH 64/70] feat: allow specifying env for fetchPipMetadata This helps for configuring pip with environment variables. See https://github.com/nix-community/dream2nix/discussions/697 for more context. pip: remove callPackage --- modules/dream2nix/pip/default.nix | 30 ++++++++++++++++------------- modules/dream2nix/pip/interface.nix | 12 ++++++++++++ pkgs/fetchPipMetadata/script.nix | 7 +++++++ 3 files changed, 36 insertions(+), 13 deletions(-) diff --git a/modules/dream2nix/pip/default.nix b/modules/dream2nix/pip/default.nix index 5443c0b4b9..e703172a37 100644 --- a/modules/dream2nix/pip/default.nix +++ b/modules/dream2nix/pip/default.nix @@ -122,7 +122,7 @@ in { # with the intention to keep modules independent. fetchPipMetadataScript = import ../../../pkgs/fetchPipMetadata/script.nix { inherit lib; - inherit (cfg) pypiSnapshotDate pipFlags pipVersion requirementsList requirementsFiles nativeBuildInputs; + inherit (cfg) env pypiSnapshotDate pipFlags pipVersion requirementsList requirementsFiles nativeBuildInputs; inherit (config.deps) writePureShellScript nix; inherit (config.paths) findRoot; inherit (nixpkgs) gitMinimal nix-prefetch-scripts python3 writeText; @@ -141,18 +141,22 @@ in { # if any of the invalidationData changes, the lock file will be invalidated # and the user will be promted to re-generate it. lock.invalidationData = { - pip = { - inherit - (config.pip) - pypiSnapshotDate - pipFlags - pipVersion - requirementsList - requirementsFiles - ; - # don't invalidate on bugfix version changes - pythonVersion = lib.init (lib.splitVersion config.deps.python.version); - }; + pip = + { + inherit + (config.pip) + pypiSnapshotDate + pipFlags + pipVersion + requirementsList + requirementsFiles + ; + # don't invalidate on bugfix version changes + pythonVersion = lib.init (lib.splitVersion config.deps.python.version); + } + # including env conditionally to not invalidate all existing lockfiles + # TODO: refactor once compat is broken through something else + // (lib.optionalAttrs (config.pip.env != {}) config.pip.env); }; pip = { diff --git a/modules/dream2nix/pip/interface.nix b/modules/dream2nix/pip/interface.nix index b1c43dbe21..8111dacfe7 100644 --- a/modules/dream2nix/pip/interface.nix +++ b/modules/dream2nix/pip/interface.nix @@ -22,6 +22,18 @@ in { }; # user interface + env = l.mkOption { + type = t.attrsOf t.str; + default = {}; + description = '' + environment variables exported while locking + ''; + example = lib.literalExpression '' + { + PIP_FIND_LINKS = "${config.deps.setuptools.dist}"; + } + ''; + }; pypiSnapshotDate = l.mkOption { type = t.nullOr t.str; description = '' diff --git a/pkgs/fetchPipMetadata/script.nix b/pkgs/fetchPipMetadata/script.nix index 63b57542bf..871185ad18 100644 --- a/pkgs/fetchPipMetadata/script.nix +++ b/pkgs/fetchPipMetadata/script.nix @@ -26,6 +26,7 @@ requirementsFiles ? [], pipFlags ? [], pipVersion ? "23.1", + env ? {}, wheelVersion ? "0.40.0", nativeBuildInputs ? [], # maximum release date for packages @@ -86,6 +87,12 @@ writePureShellScript path '' + ${ + lib.foldlAttrs + (acc: name: value: acc + "\nexport " + lib.toShellVar name value) + "" + env + } ${package}/bin/fetch_pip_metadata \ --json-args-file ${args} \ --project-root $(${findRoot}) From 5e938ebb20446dc2b38349388d16b2590f778223 Mon Sep 17 00:00:00 2001 From: DavHau Date: Tue, 10 Oct 2023 18:54:51 +0200 Subject: [PATCH 65/70] findCycles: add some unit tests --- .../dream2nix-repo-single-package/flake.nix | 28 ++ tests/nix-unit/test_findCycles/default.nix | 272 ++++++++++++++++++ 2 files changed, 300 insertions(+) create mode 100644 examples/dream2nix-repo-single-package/flake.nix create mode 100644 tests/nix-unit/test_findCycles/default.nix diff --git a/examples/dream2nix-repo-single-package/flake.nix b/examples/dream2nix-repo-single-package/flake.nix new file mode 100644 index 0000000000..1e46fd973b --- /dev/null +++ b/examples/dream2nix-repo-single-package/flake.nix @@ -0,0 +1,28 @@ +{ + description = "My flake with dream2nix packages"; + + inputs = { + dream2nix.url = "github:nix-community/dream2nix"; + nixpkgs.follows = "dream2nix/nixpkgs"; + }; + + outputs = inputs @ { + self, + dream2nix, + nixpkgs, + ... + }: let + system = "x86_64-linux"; + in { + # all packages defined inside ./packages/ + packages.${system}.default = nixpkgs.lib.evalModules { + modules = []; + + projectRoot = ./.; + # can be changed to ".git" or "flake.nix" to get rid of .project-root + projectRootFile = "flake.nix"; + packagesDir = ./packages; + packageSets.nixpkgs = nixpkgs.legacyPackages.${system}; + }; + }; +} diff --git a/tests/nix-unit/test_findCycles/default.nix b/tests/nix-unit/test_findCycles/default.nix new file mode 100644 index 0000000000..f0f98399a6 --- /dev/null +++ b/tests/nix-unit/test_findCycles/default.nix @@ -0,0 +1,272 @@ +{ + pkgs ? import {}, + lib ? import , + ... +}: let + findCycles = import ../../../lib/internal/findCycles.nix {inherit lib;}; +in { + test_simple = { + expr = findCycles { + dependencyGraph = { + a.v1 = [ + { + name = "b"; + version = "v1"; + } + ]; + b.v1 = [ + { + name = "a"; + version = "v1"; + } + ]; + }; + roots = { + a = "v1"; + }; + }; + expected = { + b.v1 = [ + { + name = "a"; + version = "v1"; + } + ]; + }; + }; + + test_cycle_length_3 = { + expr = findCycles { + dependencyGraph = { + a.v1 = [ + { + name = "b"; + version = "v1"; + } + ]; + b.v1 = [ + { + name = "c"; + version = "v1"; + } + ]; + c.v1 = [ + { + name = "a"; + version = "v1"; + } + ]; + }; + roots = { + a = "v1"; + }; + }; + expected = { + c.v1 = [ + { + name = "a"; + version = "v1"; + } + ]; + }; + }; + + test_two_roots_both_chosen = { + expr = findCycles { + dependencyGraph = { + a.v1 = [ + { + name = "b"; + version = "v1"; + } + ]; + b.v1 = [ + { + name = "a"; + version = "v1"; + } + ]; + c.v1 = [ + { + name = "d"; + version = "v1"; + } + ]; + d.v1 = [ + { + name = "c"; + version = "v1"; + } + ]; + }; + roots = { + a = "v1"; + c = "v1"; + }; + }; + expected = { + b.v1 = [ + { + name = "a"; + version = "v1"; + } + ]; + d.v1 = [ + { + name = "c"; + version = "v1"; + } + ]; + }; + }; + + test_two_roots_one_chosen = { + expr = findCycles { + dependencyGraph = { + a.v1 = [ + { + name = "b"; + version = "v1"; + } + ]; + b.v1 = [ + { + name = "a"; + version = "v1"; + } + ]; + c.v1 = [ + { + name = "d"; + version = "v1"; + } + ]; + d.v1 = [ + { + name = "c"; + version = "v1"; + } + ]; + }; + roots = { + a = "v1"; + }; + }; + expected = { + b.v1 = [ + { + name = "a"; + version = "v1"; + } + ]; + }; + }; + + test_c_visited_twice_no_cycle = { + expr = findCycles { + dependencyGraph = { + a.v1 = [ + { + name = "c"; + version = "v1"; + } + ]; + b.v1 = [ + { + name = "c"; + version = "v1"; + } + ]; + c.v1 = []; + }; + roots = { + a = "v1"; + b = "v1"; + }; + }; + expected = {}; + }; + + test_two_cycles_one_root = { + expr = findCycles { + dependencyGraph = { + a.v1 = [ + { + name = "c"; + version = "v1"; + } + ]; + b.v1 = [ + { + name = "c"; + version = "v1"; + } + ]; + c.v1 = [ + { + name = "d"; + version = "v1"; + } + ]; + d.v1 = [ + { + name = "a"; + version = "v1"; + } + { + name = "b"; + version = "v1"; + } + ]; + }; + roots = { + a = "v1"; + }; + }; + expected = { + d.v1 = [ + { + name = "a"; + version = "v1"; + } + ]; + b.v1 = [ + { + name = "c"; + version = "v1"; + } + ]; + }; + }; + + # TODO: fix the implementation to remove furthest edges from the root only + # test_two_cycles_two_roots = { + # expr = findCycles { + # dependencyGraph = { + # a.v1 = [ + # {name = "c"; version = "v1";} + # ]; + # b.v1 = [ + # {name = "c"; version = "v1";} + # ]; + # c.v1 = [ + # {name = "d"; version = "v1";} + # ]; + # d.v1 = [ + # {name = "a"; version = "v1";} + # {name = "b"; version = "v1";} + # ]; + # }; + # roots = { + # a = "v1"; + # b = "v1"; + # }; + # }; + # expected = { + # d.v1 = [ + # {name = "a"; version = "v1";} + # {name = "b"; version = "v1";} + # ]; + # }; + # }; +} From 87d65e704e4bb0703b30007c09bbbbc916913f7f Mon Sep 17 00:00:00 2001 From: DavHau Date: Tue, 10 Oct 2023 16:18:09 +0200 Subject: [PATCH 66/70] init flake parts docs modules --- modules/flake-parts/render/default.nix | 399 ++++++++++++++++++++ modules/flake-parts/render/options.xsl | 66 ++++ modules/flake-parts/site/.gitignore | 1 + modules/flake-parts/site/_redirects | 1 + modules/flake-parts/site/book.toml | 19 + modules/flake-parts/site/default.nix | 81 ++++ modules/flake-parts/site/flake-parts.css | 19 + modules/flake-parts/site/no-edit-options.js | 7 + modules/flake-parts/site/src/SUMMARY.md | 3 + 9 files changed, 596 insertions(+) create mode 100644 modules/flake-parts/render/default.nix create mode 100644 modules/flake-parts/render/options.xsl create mode 100644 modules/flake-parts/site/.gitignore create mode 100644 modules/flake-parts/site/_redirects create mode 100644 modules/flake-parts/site/book.toml create mode 100644 modules/flake-parts/site/default.nix create mode 100644 modules/flake-parts/site/flake-parts.css create mode 100644 modules/flake-parts/site/no-edit-options.js create mode 100644 modules/flake-parts/site/src/SUMMARY.md diff --git a/modules/flake-parts/render/default.nix b/modules/flake-parts/render/default.nix new file mode 100644 index 0000000000..b899e701e8 --- /dev/null +++ b/modules/flake-parts/render/default.nix @@ -0,0 +1,399 @@ +{ + config, + inputs, + lib, + flake-parts-lib, + ... +}: let + inherit + (lib) + mkOption + types + concatMap + concatLists + mapAttrsToList + attrValues + hasPrefix + removePrefix + ; + + failPkgAttr = name: _v: + throw '' + Most nixpkgs attributes are not supported when generating documentation. + Please check with `--show-trace` to see which option leads to this `pkgs.${lib.strings.escapeNixIdentifier name}` reference. Often it can be cut short with a `defaultText` argument to `lib.mkOption`, or by escaping an option `example` using `lib.literalExpression`. + ''; +in { + options.perSystem = flake-parts-lib.mkPerSystemOption ({ + config, + pkgs, + lib, + ... + }: let + cfg = config.render; + + pkgsStub = lib.mapAttrs failPkgAttr pkgs; + + fixups = { + lib, + flake-parts-lib, + ... + }: { + options.perSystem = flake-parts-lib.mkPerSystemOption { + config = { + _module.args.pkgs = + pkgsStub + // { + _type = "pkgs"; + inherit lib; + formats = + lib.mapAttrs + ( + formatName: formatFn: formatArgs: let + result = formatFn formatArgs; + stubs = + lib.mapAttrs + ( + name: _: + throw "The attribute `(pkgs.formats.${lib.strings.escapeNixIdentifier formatName} x).${lib.strings.escapeNixIdentifier name}` is not supported during documentation generation. Please check with `--show-trace` to see which option leads to this `${lib.strings.escapeNixIdentifier name}` reference. Often it can be cut short with a `defaultText` argument to `lib.mkOption`, or by escaping an option `example` using `lib.literalExpression`." + ) + result; + in + stubs + // { + inherit (result) type; + } + ) + pkgs.formats; + }; + }; + }; + }; + + eval = evalWith { + modules = concatLists (mapAttrsToList (name: inputCfg: inputCfg.getModules inputCfg.flake) cfg.inputs); + }; + evalWith = {modules}: + inputs.flake-parts.lib.evalFlakeModule + { + inputs = { + inherit (inputs) nixpkgs; + self = + eval.config.flake + // { + outPath = + throw "The `self.outPath` attribute is not available when generating documentation, because the documentation should not depend on the specifics of the flake files where it is loaded. This error is generally caused by a missing `defaultText` on one or more options in the trace. Please run this evaluation with `--show-trace`, and look for `while evaluating the default value of option` and add a `defaultText` to one or more of the options involved."; + }; + }; + } + { + imports = + modules + ++ [ + fixups + ]; + systems = [(throw "The `systems` option value is not available when generating documentation. This is generally caused by a missing `defaultText` on one or more options in the trace. Please run this evaluation with `--show-trace`, look for `while evaluating the default value of option` and add a `defaultText` to the one or more of the options involved.")]; + }; + + opts = eval.options; + + coreOptDecls = config.render.inputs.flake-parts._nixosOptionsDoc.optionsNix; + + filterTransformOptions = { + sourceName, + sourcePath, + baseUrl, + coreOptDecls, + }: let + sourcePathStr = toString sourcePath; + in + opt: let + declarations = + concatMap + ( + decl: + if hasPrefix sourcePathStr (toString decl) + then let + subpath = removePrefix sourcePathStr (toString decl); + in [ + { + url = baseUrl + subpath; + name = sourceName + subpath; + } + ] + else [] + ) + opt.declarations; + in + if + declarations + == [] + || ( + sourceName != "flake-parts" && coreOptDecls ? ${lib.showOption opt.loc} + ) + then opt // {visible = false;} + else opt // {inherit declarations;}; + + inputModule = { + config, + name, + ... + }: { + options = { + flake = mkOption { + type = types.raw; + description = '' + A flake. + ''; + default = inputs.${name}; + }; + + sourcePath = mkOption { + type = types.path; + description = '' + Source path in which the modules are contained. + ''; + default = config.flake.outPath; + }; + + title = mkOption { + type = types.str; + description = '' + Title of the markdown page. + ''; + default = name; + }; + + flakeRef = mkOption { + type = types.str; + default = + # This only works for github for now, but we can set a non-default + # value in the list just fine. + let + match = builtins.match "https://github.com/([^/]*)/([^/]*)/blob/([^/]*)" config.baseUrl; + owner = lib.elemAt match 0; + repo = lib.elemAt match 1; + branch = lib.elemAt match 2; # ignored for now because they're all default branches + in + if match != null + then "github:${owner}/${repo}" + else throw "Couldn't figure out flakeref for ${name}: ${config.baseUrl}"; + }; + + preface = mkOption { + type = types.str; + description = '' + Stuff between the title and the options. + ''; + default = '' + + ${config.intro} + + ${config.installation} + + ''; + }; + + intro = mkOption { + type = types.str; + description = '' + Introductory paragraph between title and installation. + ''; + }; + + installationDeclareInput = mkOption { + type = types.bool; + description = '' + Whether to show how to declare the input. + ''; + default = true; + }; + + installation = mkOption { + type = types.str; + description = '' + Installation paragraph between installation and options. + ''; + default = '' + ## Installation + + ${ + if config.installationDeclareInput + then '' + To use these options, add to your flake inputs: + + ```nix + ${config.sourceName}.url = "${config.flakeRef}"; + ``` + + and inside the `mkFlake`: + '' + else '' + To use these options, add inside the `mkFlake`: + '' + } + + ```nix + imports = [ + inputs.${config.sourceName}.${lib.concatMapStringsSep "." lib.strings.escapeNixIdentifier config.attributePath} + ]; + ``` + + Run `nix flake lock` and you're set. + ''; + }; + + sourceName = mkOption { + type = types.str; + description = '' + Name by which the source is shown in the list of declarations. + ''; + default = name; + }; + + baseUrl = mkOption { + type = types.str; + description = '' + URL prefix for source location links. + ''; + }; + + getModules = mkOption { + type = types.functionTo (types.listOf types.raw); + description = '' + Get the modules to render. + ''; + default = flake: [ + ( + builtins.addErrorContext "while getting modules for input '${name}'" + (lib.getAttrFromPath config.attributePath flake) + ) + ]; + }; + + attributePath = mkOption { + type = types.listOf types.str; + description = '' + Flake output attribute path to import. + ''; + default = ["flakeModule"]; + }; + + rendered = mkOption { + type = types.package; + description = '' + Built Markdown docs. + ''; + readOnly = true; + }; + + _nixosOptionsDoc = mkOption {}; + + separateEval = mkOption { + type = types.bool; + default = false; + description = '' + Whether to include this in the main evaluation. + ''; + }; + + filterTransformOptions = mkOption { + default = filterTransformOptions; + description = '' + Function to customize the set of options to render for this input. + ''; + }; + + killLinks = mkOption { + type = types.bool; + default = false; + description = '' + Remove local anchor links, a workaround for proper {option}`` support in the doc tooling. + ''; + }; + }; + config = { + _nixosOptionsDoc = pkgs.nixosOptionsDoc { + options = + if config.separateEval + then + (evalWith { + modules = config.getModules config.flake; + }) + .options + else opts; + documentType = "none"; + transformOptions = config.filterTransformOptions { + inherit (config) sourceName baseUrl sourcePath; + inherit coreOptDecls; + }; + warningsAreErrors = true; # not sure if feasible long term + markdownByDefault = true; + }; + rendered = + pkgs.runCommand "option-doc-${config.sourceName}" + { + nativeBuildInputs = [pkgs.libxslt.bin pkgs.pandoc]; + inputDoc = config._nixosOptionsDoc.optionsDocBook; + inherit (config) title preface; + } '' + xsltproc --stringparam title "$title" \ + --stringparam killLinks '${lib.boolToString config.killLinks}' \ + -o options.db.xml ${./options.xsl} \ + "$inputDoc" + mkdir $out + pandoc --verbose --from docbook --to html options.db.xml >options.html + substitute options.html $out/options.html --replace '

@intro@

' "$preface" + grep -v '@intro@' <$out/options.html >/dev/null || { + grep '@intro@' <$out/options.html + echo intro replacement failed; exit 1; + } + ''; + }; + }; + in { + options = { + render = { + inputs = mkOption { + description = "Which modules to render."; + type = types.attrsOf (types.submodule inputModule); + }; + }; + }; + config = { + packages = + lib.mapAttrs' (name: inputCfg: { + name = "generated-docs-${name}"; + value = inputCfg.rendered; + }) + cfg.inputs + // { + generated-docs = + pkgs.runCommand "generated-docs" + { + passthru = { + inherit config; + inherit eval; + # This won't be in sync with the actual nixosOptionsDoc + # invocations, but it's useful for troubleshooting. + allOptionsPerhaps = + (pkgs.nixosOptionsDoc { + options = opts; + }) + .optionsNix; + }; + } + '' + mkdir $out + ${ + lib.concatStringsSep "\n" + (lib.mapAttrsToList + (name: inputCfg: '' + cp ${inputCfg.rendered}/options.html $out/${name}.html + '') + cfg.inputs) + } + ''; + }; + }; + }); +} diff --git a/modules/flake-parts/render/options.xsl b/modules/flake-parts/render/options.xsl new file mode 100644 index 0000000000..7bfefbc270 --- /dev/null +++ b/modules/flake-parts/render/options.xsl @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + <xsl:value-of select="$title"/> + + @intro@ +
Options + + + +
+ +
+
+ +
+ + <link xlink:href="#{db:term/@xml:id}" xml:id="{db:term/@xml:id}"><xsl:copy-of select="db:term/db:option"/></link> + + +
+
+ + + + + + + + + + + + + + + + + + + + + + +
\ No newline at end of file diff --git a/modules/flake-parts/site/.gitignore b/modules/flake-parts/site/.gitignore new file mode 100644 index 0000000000..7585238efe --- /dev/null +++ b/modules/flake-parts/site/.gitignore @@ -0,0 +1 @@ +book diff --git a/modules/flake-parts/site/_redirects b/modules/flake-parts/site/_redirects new file mode 100644 index 0000000000..f8864a1e83 --- /dev/null +++ b/modules/flake-parts/site/_redirects @@ -0,0 +1 @@ +/getting-things.html /cheat-sheet.html diff --git a/modules/flake-parts/site/book.toml b/modules/flake-parts/site/book.toml new file mode 100644 index 0000000000..feff128b91 --- /dev/null +++ b/modules/flake-parts/site/book.toml @@ -0,0 +1,19 @@ +[book] +authors = ["Robert Hensing", "Various module authors"] +language = "en" +multilingual = false +src = "src" +title = "flake-parts" + +[output.html] +git-repository-url = "https://github.com/hercules-ci/flake-parts" +edit-url-template = "https://github.com/hercules-ci/flake.parts-website/edit/main/site/{path}" +additional-js = [ "no-edit-options.js" ] +additional-css = [ "flake-parts.css" ] +no-section-label = true + +[output.html.print] +enable = false # big single page; don't need that + +[output.linkcheck] +follow-web-links = false # no Internet during the build diff --git a/modules/flake-parts/site/default.nix b/modules/flake-parts/site/default.nix new file mode 100644 index 0000000000..888474e8c1 --- /dev/null +++ b/modules/flake-parts/site/default.nix @@ -0,0 +1,81 @@ +{inputs, ...}: { + perSystem = { + config, + self', + inputs', + pkgs, + lib, + ... + }: { + /* + Check the links, including anchors (not currently supported by mdbook) + + Putting this in a separate check has the benefits that + - output can always be inspect with browser + - this slow check (1 minute) is not part of the iteration cycle + + Ideally https://github.com/linkchecker/linkchecker/pull/661 is merged + upstream, so that it's quick and can run often without blocking the + iteration cycle unnecessarily. + */ + checks.linkcheck = + pkgs.runCommand "linkcheck" + { + nativeBuildInputs = [pkgs.linkchecker pkgs.python3]; + site = config.packages.default; + } '' + # https://linkchecker.github.io/linkchecker/man/linkcheckerrc.html + cat >>$TMPDIR/linkcheckrc <src/README.md + + mkdir -p src/options + for f in ${config.packages.generated-docs}/*.html; do + cp "$f" "src/options/$(basename "$f" .html).md" + done + mdbook build --dest-dir $TMPDIR/out + cp -r $TMPDIR/out/html $out + cp _redirects $out + + echo 'to the options' \ + >$out/options.html + + runHook postBuild + ''; + dontInstall = true; + }; + }; + }; +} diff --git a/modules/flake-parts/site/flake-parts.css b/modules/flake-parts/site/flake-parts.css new file mode 100644 index 0000000000..eb46d1775f --- /dev/null +++ b/modules/flake-parts/site/flake-parts.css @@ -0,0 +1,19 @@ +h1.menu-title::before { + content: ""; + display: inline-block; + background-image: url(./favicon.svg); + background-repeat: no-repeat; + background-size: contain; + width: 1.8ex; + height: 1.8ex; + margin-right: 0.9ex; + vertical-align: middle; +} +.light { + --links: #058; + --sidebar-active: #0af; +} +.sidebar .sidebar-scrollbox { + /* We don't use numbers, so we can take a consistent amount of space */ + padding: var(--page-padding) !important; +} diff --git a/modules/flake-parts/site/no-edit-options.js b/modules/flake-parts/site/no-edit-options.js new file mode 100644 index 0000000000..e63e56ade8 --- /dev/null +++ b/modules/flake-parts/site/no-edit-options.js @@ -0,0 +1,7 @@ + +if (window.location.pathname.match(/options/)) { + var buttons = document.querySelector("#menu-bar > div.right-buttons") + if (buttons != null) { + buttons.style.display = "none" + } +} diff --git a/modules/flake-parts/site/src/SUMMARY.md b/modules/flake-parts/site/src/SUMMARY.md new file mode 100644 index 0000000000..a5667ce5b2 --- /dev/null +++ b/modules/flake-parts/site/src/SUMMARY.md @@ -0,0 +1,3 @@ +# Summary + +- [Reference Documentation]() From e945481137d83debb0260de9f718eaf803175824 Mon Sep 17 00:00:00 2001 From: DavHau Date: Tue, 10 Oct 2023 19:06:14 +0200 Subject: [PATCH 67/70] WIP: adopt flake-parts docs modules for dream2nix --- modules/flake-parts/render/default.nix | 68 ++++++++++++++------------ modules/flake-parts/site/default.nix | 8 ++- 2 files changed, 44 insertions(+), 32 deletions(-) diff --git a/modules/flake-parts/render/default.nix b/modules/flake-parts/render/default.nix index b899e701e8..500549f3cd 100644 --- a/modules/flake-parts/render/default.nix +++ b/modules/flake-parts/render/default.nix @@ -3,6 +3,7 @@ inputs, lib, flake-parts-lib, + self, ... }: let inherit @@ -73,36 +74,41 @@ in { modules = concatLists (mapAttrsToList (name: inputCfg: inputCfg.getModules inputCfg.flake) cfg.inputs); }; evalWith = {modules}: - inputs.flake-parts.lib.evalFlakeModule - { - inputs = { - inherit (inputs) nixpkgs; - self = - eval.config.flake - // { - outPath = - throw "The `self.outPath` attribute is not available when generating documentation, because the documentation should not depend on the specifics of the flake files where it is loaded. This error is generally caused by a missing `defaultText` on one or more options in the trace. Please run this evaluation with `--show-trace`, and look for `while evaluating the default value of option` and add a `defaultText` to one or more of the options involved."; - }; - }; - } - { - imports = - modules - ++ [ - fixups - ]; - systems = [(throw "The `systems` option value is not available when generating documentation. This is generally caused by a missing `defaultText` on one or more options in the trace. Please run this evaluation with `--show-trace`, look for `while evaluating the default value of option` and add a `defaultText` to the one or more of the options involved.")]; + lib.evalModules { + modules = modules; + specialArgs.dream2nix.modules = self.modules; + specialArgs.packageSets = {}; }; + # inputs.flake-parts.lib.evalFlakeModule + # { + # inputs = { + # inherit (inputs) nixpkgs; + # self = + # eval.config.flake + # // { + # outPath = + # throw "The `self.outPath` attribute is not available when generating documentation, because the documentation should not depend on the specifics of the flake files where it is loaded. This error is generally caused by a missing `defaultText` on one or more options in the trace. Please run this evaluation with `--show-trace`, and look for `while evaluating the default value of option` and add a `defaultText` to one or more of the options involved."; + # }; + # }; + # } + # { + # imports = + # modules + # ++ [ + # fixups + # ]; + # systems = [(throw "The `systems` option value is not available when generating documentation. This is generally caused by a missing `defaultText` on one or more options in the trace. Please run this evaluation with `--show-trace`, look for `while evaluating the default value of option` and add a `defaultText` to the one or more of the options involved.")]; + # }; opts = eval.options; - coreOptDecls = config.render.inputs.flake-parts._nixosOptionsDoc.optionsNix; + # coreOptDecls = config.render.inputs.flake-parts._nixosOptionsDoc.optionsNix; filterTransformOptions = { sourceName, sourcePath, baseUrl, - coreOptDecls, + # coreOptDecls, }: let sourcePathStr = toString sourcePath; in @@ -124,14 +130,16 @@ in { ) opt.declarations; in - if - declarations - == [] - || ( - sourceName != "flake-parts" && coreOptDecls ? ${lib.showOption opt.loc} - ) - then opt // {visible = false;} - else opt // {inherit declarations;}; + # if + # declarations + # == [] + # || ( + # # sourceName != "flake-parts" && coreOptDecls ? ${lib.showOption opt.loc} + # sourceName != "flake-parts" + # ) + # then opt // {visible = false;} + # else opt // {inherit declarations;}; + opt // {inherit declarations;}; inputModule = { config, @@ -324,7 +332,7 @@ in { documentType = "none"; transformOptions = config.filterTransformOptions { inherit (config) sourceName baseUrl sourcePath; - inherit coreOptDecls; + # inherit coreOptDecls; }; warningsAreErrors = true; # not sure if feasible long term markdownByDefault = true; diff --git a/modules/flake-parts/site/default.nix b/modules/flake-parts/site/default.nix index 888474e8c1..9156b4db44 100644 --- a/modules/flake-parts/site/default.nix +++ b/modules/flake-parts/site/default.nix @@ -1,4 +1,8 @@ -{inputs, ...}: { +{ + inputs, + self, + ... +}: { perSystem = { config, self', @@ -59,7 +63,7 @@ esac done cat src/intro-continued.md - } <${inputs.flake-parts + "/README.md"} >src/README.md + } <${self + "/README.md"} >src/README.md mkdir -p src/options for f in ${config.packages.generated-docs}/*.html; do From 212fcf4cde24f49cd5fee723e45de73cf49615a9 Mon Sep 17 00:00:00 2001 From: DavHau Date: Tue, 10 Oct 2023 20:04:36 +0200 Subject: [PATCH 68/70] docs: add missing descriptions for core module --- modules/dream2nix/core/env/default.nix | 3 +++ modules/dream2nix/core/eval-cache/interface.nix | 4 ++++ modules/dream2nix/core/flags/default.nix | 6 ++++++ modules/dream2nix/core/lock/interface.nix | 4 ++++ 4 files changed, 17 insertions(+) diff --git a/modules/dream2nix/core/env/default.nix b/modules/dream2nix/core/env/default.nix index 55a5b19f48..814c7257fe 100644 --- a/modules/dream2nix/core/env/default.nix +++ b/modules/dream2nix/core/env/default.nix @@ -15,6 +15,9 @@ in { in t.attrsOf (t.nullOr (t.oneOf allTypes)); default = {}; + description = '' + environment variables passed to the build environment + ''; }; }; } diff --git a/modules/dream2nix/core/eval-cache/interface.nix b/modules/dream2nix/core/eval-cache/interface.nix index c0a516295f..6a1ec437f5 100644 --- a/modules/dream2nix/core/eval-cache/interface.nix +++ b/modules/dream2nix/core/eval-cache/interface.nix @@ -14,6 +14,10 @@ in { type = t.submodule { freeformType = t.anything; }; + description = '' + The content of the cached fields. + For example if fields.pname is set to true, then content.pname will exist. + ''; }; invalidationFields = l.mkOption { diff --git a/modules/dream2nix/core/flags/default.nix b/modules/dream2nix/core/flags/default.nix index 8986b9306c..58ea7e219b 100644 --- a/modules/dream2nix/core/flags/default.nix +++ b/modules/dream2nix/core/flags/default.nix @@ -44,6 +44,9 @@ in { flagsOffered = l.mkOption { type = t.attrsOf t.str; default = {}; + description = '' + declare flags that can be used to enable/disable features + ''; }; # The flag options generated from `flagsOffered` @@ -52,6 +55,9 @@ in { options = l.mapAttrs (_: mkFlag) config.flagsOffered; }; default = {}; + description = '' + Enable/disable flags declared in `flagsOffered` + ''; }; }; } diff --git a/modules/dream2nix/core/lock/interface.nix b/modules/dream2nix/core/lock/interface.nix index f9a5bcf0ce..d5329bb02e 100644 --- a/modules/dream2nix/core/lock/interface.nix +++ b/modules/dream2nix/core/lock/interface.nix @@ -17,6 +17,10 @@ in { type = t.submodule { freeformType = t.anything; }; + description = '' + The content of the lock file. + All fields declared via `lock.fields` are contained pointing to their respective values. + ''; }; fields = l.mkOption { From 585b98cc99dc3f9638492ff5a973f34e7a0a6ae5 Mon Sep 17 00:00:00 2001 From: DavHau Date: Tue, 10 Oct 2023 20:43:36 +0200 Subject: [PATCH 69/70] docs: render first module via `site` module --- modules/flake-parts/site/book.toml | 8 +++---- modules/flake-parts/site/default.nix | 6 ++++- modules/flake-parts/site/flake-parts.css | 2 +- modules/flake-parts/site/src/SUMMARY.md | 1 + .../flake-parts/site/src/intro-continued.md | 7 ++++++ modules/flake-parts/website.nix | 24 +++++++++++++++++++ 6 files changed, 42 insertions(+), 6 deletions(-) create mode 100644 modules/flake-parts/site/src/intro-continued.md create mode 100644 modules/flake-parts/website.nix diff --git a/modules/flake-parts/site/book.toml b/modules/flake-parts/site/book.toml index feff128b91..52e0654061 100644 --- a/modules/flake-parts/site/book.toml +++ b/modules/flake-parts/site/book.toml @@ -1,13 +1,13 @@ [book] -authors = ["Robert Hensing", "Various module authors"] +authors = ["David Hauer", "Various contributors"] language = "en" multilingual = false src = "src" -title = "flake-parts" +title = "dream2nix" [output.html] -git-repository-url = "https://github.com/hercules-ci/flake-parts" -edit-url-template = "https://github.com/hercules-ci/flake.parts-website/edit/main/site/{path}" +git-repository-url = "https://github.com/nix-community/dream2nix" +edit-url-template = "https://github.com/nix-community/dream2nix/edit/main/modules/dream2nix/{path}" additional-js = [ "no-edit-options.js" ] additional-css = [ "flake-parts.css" ] no-section-label = true diff --git a/modules/flake-parts/site/default.nix b/modules/flake-parts/site/default.nix index 9156b4db44..2eae8ee83c 100644 --- a/modules/flake-parts/site/default.nix +++ b/modules/flake-parts/site/default.nix @@ -44,13 +44,17 @@ ''; packages = { - default = pkgs.stdenvNoCC.mkDerivation { + website = pkgs.stdenvNoCC.mkDerivation { name = "site"; nativeBuildInputs = [pkgs.mdbook pkgs.mdbook-linkcheck]; src = ./.; buildPhase = '' runHook preBuild + cp ${self + /docs/theme/highlight.js} ./src/highlight.js + mkdir -p ./theme + cp ${self + /modules/dream2nix/core/docs/theme/favicon.png} ./theme/favicon.png + { while read ln; do case "$ln" in diff --git a/modules/flake-parts/site/flake-parts.css b/modules/flake-parts/site/flake-parts.css index eb46d1775f..4cafecdcb9 100644 --- a/modules/flake-parts/site/flake-parts.css +++ b/modules/flake-parts/site/flake-parts.css @@ -1,7 +1,7 @@ h1.menu-title::before { content: ""; display: inline-block; - background-image: url(./favicon.svg); + background-image: url(./favicon.png); background-repeat: no-repeat; background-size: contain; width: 1.8ex; diff --git a/modules/flake-parts/site/src/SUMMARY.md b/modules/flake-parts/site/src/SUMMARY.md index a5667ce5b2..d3a61897e4 100644 --- a/modules/flake-parts/site/src/SUMMARY.md +++ b/modules/flake-parts/site/src/SUMMARY.md @@ -1,3 +1,4 @@ # Summary - [Reference Documentation]() + - [core (built in)](./options/core.md) diff --git a/modules/flake-parts/site/src/intro-continued.md b/modules/flake-parts/site/src/intro-continued.md new file mode 100644 index 0000000000..e398c97d4f --- /dev/null +++ b/modules/flake-parts/site/src/intro-continued.md @@ -0,0 +1,7 @@ + + +# This documentation + +You can find guides and the options reference in the menu (top left). + +A site wide search is available by typing `s`. diff --git a/modules/flake-parts/website.nix b/modules/flake-parts/website.nix new file mode 100644 index 0000000000..9b50aca5be --- /dev/null +++ b/modules/flake-parts/website.nix @@ -0,0 +1,24 @@ +{ + self, + lib, + ... +}: { + perSystem = { + config, + self', + inputs', + pkgs, + ... + }: { + render.inputs = { + core = { + title = "core"; + flake.module = self.modules.dream2nix.core; + flake.outPath = self; + attributePath = ["module"]; + intro = "intro"; + baseUrl = "https://github.com/nix-community/dream2nix/blob/master"; + }; + }; + }; +} From af64cc56440e8c00c2e90b6a046c57996d2c44fa Mon Sep 17 00:00:00 2001 From: DavHau Date: Wed, 11 Oct 2023 01:39:06 +0200 Subject: [PATCH 70/70] docs: improve module reference rendering --- .../derivation-common/options.nix | 0 .../builtins-derivation/interface.nix | 2 +- modules/dream2nix/core/lock/default.nix | 2 + .../dream2nix/mkDerivation/implementation.nix | 4 + modules/dream2nix/mkDerivation/interface.nix | 2 +- modules/flake-parts/render/default.nix | 92 ++++++++----------- modules/flake-parts/site/default.nix | 6 +- modules/flake-parts/website.nix | 55 +++++++++-- 8 files changed, 99 insertions(+), 64 deletions(-) rename modules/dream2nix/{ => builtins-derivation}/derivation-common/options.nix (100%) diff --git a/modules/dream2nix/derivation-common/options.nix b/modules/dream2nix/builtins-derivation/derivation-common/options.nix similarity index 100% rename from modules/dream2nix/derivation-common/options.nix rename to modules/dream2nix/builtins-derivation/derivation-common/options.nix diff --git a/modules/dream2nix/builtins-derivation/interface.nix b/modules/dream2nix/builtins-derivation/interface.nix index 1156c2ed28..4e42bb555e 100644 --- a/modules/dream2nix/builtins-derivation/interface.nix +++ b/modules/dream2nix/builtins-derivation/interface.nix @@ -6,7 +6,7 @@ l = lib // builtins; t = l.types; - common-options = import ../derivation-common/options.nix {inherit lib;}; + common-options = import ./derivation-common/options.nix {inherit lib;}; builtin-derivation-options = { # basic arguments diff --git a/modules/dream2nix/core/lock/default.nix b/modules/dream2nix/core/lock/default.nix index 4d820a4285..fe0da9d935 100644 --- a/modules/dream2nix/core/lock/default.nix +++ b/modules/dream2nix/core/lock/default.nix @@ -191,6 +191,8 @@ in { imports = [ ./interface.nix + ../assertions.nix + ../deps ]; config = { diff --git a/modules/dream2nix/mkDerivation/implementation.nix b/modules/dream2nix/mkDerivation/implementation.nix index 41e89b1918..fdd31d7577 100644 --- a/modules/dream2nix/mkDerivation/implementation.nix +++ b/modules/dream2nix/mkDerivation/implementation.nix @@ -60,4 +60,8 @@ in { inherit (config.public) version; pname = config.name; }; + + config.deps = {nixpkgs, ...}: { + stdenv = lib.mkOverride 1050 nixpkgs.stdenv; + }; } diff --git a/modules/dream2nix/mkDerivation/interface.nix b/modules/dream2nix/mkDerivation/interface.nix index 744666909b..aebab952d7 100644 --- a/modules/dream2nix/mkDerivation/interface.nix +++ b/modules/dream2nix/mkDerivation/interface.nix @@ -8,7 +8,7 @@ l = lib // builtins; t = l.types; - common-options = import ../derivation-common/options.nix {inherit lib;}; + common-options = import ../builtins-derivation/derivation-common/options.nix {inherit lib;}; derivationType = t.oneOf [t.str t.path t.package]; diff --git a/modules/flake-parts/render/default.nix b/modules/flake-parts/render/default.nix index 500549f3cd..107b6e2428 100644 --- a/modules/flake-parts/render/default.nix +++ b/modules/flake-parts/render/default.nix @@ -71,13 +71,20 @@ in { }; eval = evalWith { - modules = concatLists (mapAttrsToList (name: inputCfg: inputCfg.getModules inputCfg.flake) cfg.inputs); + modules = concatLists (mapAttrsToList (name: inputCfg: [inputCfg.module]) cfg.inputs); }; evalWith = {modules}: lib.evalModules { - modules = modules; - specialArgs.dream2nix.modules = self.modules; - specialArgs.packageSets = {}; + modules = + modules + ++ [ + # { + # name = "dummy-name"; + # version = "dummy-version"; + # } + ]; + specialArgs.dream2nix = self; + specialArgs.packageSets.nixpkgs = pkgs; }; # inputs.flake-parts.lib.evalFlakeModule # { @@ -123,23 +130,21 @@ in { in [ { url = baseUrl + subpath; - name = sourceName + subpath; + name = "dream2nix" + subpath; } ] else [] ) opt.declarations; in - # if - # declarations - # == [] - # || ( - # # sourceName != "flake-parts" && coreOptDecls ? ${lib.showOption opt.loc} - # sourceName != "flake-parts" - # ) - # then opt // {visible = false;} - # else opt // {inherit declarations;}; - opt // {inherit declarations;}; + if + declarations + == [] + || ( + (lib.head opt.loc) != sourceName + ) + then opt // {visible = false;} + else opt // {inherit declarations;}; inputModule = { config, @@ -147,12 +152,11 @@ in { ... }: { options = { - flake = mkOption { + module = mkOption { type = types.raw; description = '' - A flake. + A Module. ''; - default = inputs.${name}; }; sourcePath = mkOption { @@ -160,7 +164,6 @@ in { description = '' Source path in which the modules are contained. ''; - default = config.flake.outPath; }; title = mkOption { @@ -224,29 +227,13 @@ in { default = '' ## Installation - ${ - if config.installationDeclareInput - then '' - To use these options, add to your flake inputs: - - ```nix - ${config.sourceName}.url = "${config.flakeRef}"; - ``` - - and inside the `mkFlake`: - '' - else '' - To use these options, add inside the `mkFlake`: - '' - } + To import this module into your dream2nix package: ```nix imports = [ - inputs.${config.sourceName}.${lib.concatMapStringsSep "." lib.strings.escapeNixIdentifier config.attributePath} + ${lib.concatMapStringsSep "." lib.strings.escapeNixIdentifier config.attributePath} ]; ``` - - Run `nix flake lock` and you're set. ''; }; @@ -265,19 +252,6 @@ in { ''; }; - getModules = mkOption { - type = types.functionTo (types.listOf types.raw); - description = '' - Get the modules to render. - ''; - default = flake: [ - ( - builtins.addErrorContext "while getting modules for input '${name}'" - (lib.getAttrFromPath config.attributePath flake) - ) - ]; - }; - attributePath = mkOption { type = types.listOf types.str; description = '' @@ -325,7 +299,7 @@ in { if config.separateEval then (evalWith { - modules = config.getModules config.flake; + modules = [config.module]; }) .options else opts; @@ -334,7 +308,7 @@ in { inherit (config) sourceName baseUrl sourcePath; # inherit coreOptDecls; }; - warningsAreErrors = true; # not sure if feasible long term + warningsAreErrors = false; # not sure if feasible long term markdownByDefault = true; }; rendered = @@ -375,6 +349,20 @@ in { }) cfg.inputs // { + # generate markdown file like: + # Summary + # - [Reference Documentation]() + # - [core (built in)](./options/core.md) + generated-summary-md = pkgs.writeText "SUMMARY.md" '' + # Summary + - [Reference Documentation]() + ${ + lib.concatStringsSep "\n" + (lib.mapAttrsToList + (name: inputCfg: " - [${inputCfg.sourceName}](./options/${name}.md)") + cfg.inputs) + } + ''; generated-docs = pkgs.runCommand "generated-docs" { diff --git a/modules/flake-parts/site/default.nix b/modules/flake-parts/site/default.nix index 2eae8ee83c..66f32ea2fa 100644 --- a/modules/flake-parts/site/default.nix +++ b/modules/flake-parts/site/default.nix @@ -26,7 +26,7 @@ pkgs.runCommand "linkcheck" { nativeBuildInputs = [pkgs.linkchecker pkgs.python3]; - site = config.packages.default; + site = config.packages.website; } '' # https://linkchecker.github.io/linkchecker/man/linkcheckerrc.html cat >>$TMPDIR/linkcheckrc <to the options' \ + # TODO: point to something else than public.html + echo 'to the options' \ >$out/options.html runHook postBuild diff --git a/modules/flake-parts/website.nix b/modules/flake-parts/website.nix index 9b50aca5be..46610eed00 100644 --- a/modules/flake-parts/website.nix +++ b/modules/flake-parts/website.nix @@ -10,15 +10,54 @@ pkgs, ... }: { - render.inputs = { - core = { - title = "core"; - flake.module = self.modules.dream2nix.core; - flake.outPath = self; - attributePath = ["module"]; + render.inputs = + lib.flip lib.mapAttrs + (lib.filterAttrs (name: module: + lib.elem name [ + # "buildPythonPackage" + # "buildRustPackage" + # "builtins-derivation" + # "core" + # "groups" + # "mkDerivation" + # "mkDerivation-sane-defaults" + # "nixpkgs-overrides" + # "nodejs-devshell" + # "nodejs-granular" + # "nodejs-granular-v3" + # "nodejs-node-modules" + # "nodejs-package-json" + # "nodejs-package-lock" + # "nodejs-package-lock-v3" + # "package-func" + # "php-composer-lock" + # "php-granular" + # "pip" + # "pip-hotfixes" + # "rust-cargo-lock" + # "rust-crane" + # "_template" + # "WIP-python-pdm" + # "WIP-python-pyproject" + # "WIP-spago" + + # "lock" + "mkDerivation" + "public" + ]) (self.modules.dream2nix)) + (name: module: { + title = name; + module = self.modules.dream2nix.${name}; + sourcePath = self; + attributePath = [ + "dream2nix" + "modules" + "dream2nix" + (lib.strings.escapeNixIdentifier name) + ]; intro = "intro"; baseUrl = "https://github.com/nix-community/dream2nix/blob/master"; - }; - }; + separateEval = true; + }); }; }