|
1 |
| -{ pkgs, config, lib, ... }: |
| 1 | +{ pkgs |
| 2 | +, config |
| 3 | +, lib |
| 4 | +, ... |
| 5 | +}: |
2 | 6 |
|
3 | 7 | let
|
4 | 8 | cfg = config.languages.python;
|
|
13 | 17 | package = pkgs.callPackage ../../python-wrapper.nix {
|
14 | 18 | python = cfg.package;
|
15 | 19 | requiredPythonModules = cfg.package.pkgs.requiredPythonModules;
|
16 |
| - makeWrapperArgs = [ |
17 |
| - "--prefix" |
18 |
| - "LD_LIBRARY_PATH" |
19 |
| - ":" |
20 |
| - libraries |
21 |
| - ] ++ lib.optionals pkgs.stdenv.isDarwin [ |
22 |
| - "--prefix" |
23 |
| - "DYLD_LIBRARY_PATH" |
24 |
| - ":" |
25 |
| - libraries |
26 |
| - ]; |
| 20 | + makeWrapperArgs = |
| 21 | + [ |
| 22 | + "--prefix" |
| 23 | + "LD_LIBRARY_PATH" |
| 24 | + ":" |
| 25 | + libraries |
| 26 | + ] |
| 27 | + ++ lib.optionals pkgs.stdenv.isDarwin [ |
| 28 | + "--prefix" |
| 29 | + "DYLD_LIBRARY_PATH" |
| 30 | + ":" |
| 31 | + libraries |
| 32 | + ]; |
27 | 33 | };
|
28 | 34 |
|
29 |
| - requirements = pkgs.writeText "requirements.txt" (toString ( |
30 |
| - if lib.isPath cfg.venv.requirements |
31 |
| - then builtins.readFile cfg.venv.requirements |
32 |
| - else cfg.venv.requirements |
33 |
| - )); |
| 35 | + requirements = pkgs.writeText "requirements.txt" ( |
| 36 | + toString ( |
| 37 | + if lib.isPath cfg.venv.requirements then |
| 38 | + builtins.readFile cfg.venv.requirements |
| 39 | + else |
| 40 | + cfg.venv.requirements |
| 41 | + ) |
| 42 | + ); |
34 | 43 |
|
35 | 44 | nixpkgs-python = config.lib.getInput {
|
36 | 45 | name = "nixpkgs-python";
|
|
39 | 48 | follows = [ "nixpkgs" ];
|
40 | 49 | };
|
41 | 50 |
|
42 |
| - initVenvScript = |
43 |
| - '' |
44 |
| - pushd "${cfg.directory}" |
| 51 | + initVenvScript = '' |
| 52 | + pushd "${cfg.directory}" |
45 | 53 |
|
46 |
| - # Make sure any tools are not attempting to use the Python interpreter from any |
47 |
| - # existing virtual environment. For instance if devenv was started within an venv. |
48 |
| - unset VIRTUAL_ENV |
| 54 | + # Make sure any tools are not attempting to use the Python interpreter from any |
| 55 | + # existing virtual environment. For instance if devenv was started within an venv. |
| 56 | + unset VIRTUAL_ENV |
49 | 57 |
|
50 |
| - VENV_PATH="${config.env.DEVENV_STATE}/venv" |
| 58 | + VENV_PATH="${config.env.DEVENV_STATE}/venv" |
51 | 59 |
|
52 |
| - profile_python="$(${readlink} ${package.interpreter})" |
53 |
| - devenv_interpreter_path="$(${pkgs.coreutils}/bin/cat "$VENV_PATH/.devenv_interpreter" 2> /dev/null || echo false )" |
54 |
| - venv_python="$(${readlink} "$devenv_interpreter_path")" |
| 60 | + profile_python="$(${readlink} ${package.interpreter})" |
| 61 | + devenv_interpreter_path="$(${pkgs.coreutils}/bin/cat "$VENV_PATH/.devenv_interpreter" 2> /dev/null || echo false )" |
| 62 | + venv_python="$(${readlink} "$devenv_interpreter_path")" |
55 | 63 |
|
56 |
| - requirements="${lib.optionalString (cfg.venv.requirements != null) ''${requirements}''}" |
| 64 | + requirements="${lib.optionalString (cfg.venv.requirements != null) ''${requirements}''}" |
57 | 65 |
|
58 |
| - # recreate venv if necessary |
59 |
| - if [ -z $venv_python ] || [ $profile_python != $venv_python ] |
60 |
| - then |
61 |
| - echo "Python interpreter changed, rebuilding Python venv..." |
62 |
| - ${pkgs.coreutils}/bin/rm -rf "$VENV_PATH" |
63 |
| - ${lib.optionalString cfg.poetry.enable '' |
64 |
| - [ -f "${config.env.DEVENV_STATE}/poetry.lock.checksum" ] && rm ${config.env.DEVENV_STATE}/poetry.lock.checksum |
65 |
| - ''} |
66 |
| - ${if cfg.uv.enable then '' |
67 |
| - echo uv venv -p ${package.interpreter} "$VENV_PATH" |
68 |
| - uv venv -p ${package.interpreter} "$VENV_PATH" |
69 |
| - '' |
70 |
| - else '' |
71 |
| - echo ${package.interpreter} -m venv ${if builtins.isNull cfg.version || lib.versionAtLeast cfg.version "3.9" then "--upgrade-deps" else ""} "$VENV_PATH" |
72 |
| - ${package.interpreter} -m venv ${if builtins.isNull cfg.version || lib.versionAtLeast cfg.version "3.9" then "--upgrade-deps" else ""} "$VENV_PATH" |
| 66 | + # recreate venv if necessary |
| 67 | + if [ -z $venv_python ] || [ $profile_python != $venv_python ] |
| 68 | + then |
| 69 | + echo "Python interpreter changed, rebuilding Python venv..." |
| 70 | + ${pkgs.coreutils}/bin/rm -rf "$VENV_PATH" |
| 71 | + ${lib.optionalString cfg.poetry.enable '' |
| 72 | + [ -f "${config.env.DEVENV_STATE}/poetry.lock.checksum" ] && rm ${config.env.DEVENV_STATE}/poetry.lock.checksum |
| 73 | + ''} |
| 74 | + ${ |
| 75 | + if cfg.uv.enable then |
73 | 76 | ''
|
74 |
| - } |
75 |
| - echo "${package.interpreter}" > "$VENV_PATH/.devenv_interpreter" |
76 |
| - fi |
| 77 | + echo uv venv -p ${package.interpreter} "$VENV_PATH" |
| 78 | + uv venv -p ${package.interpreter} "$VENV_PATH" |
| 79 | + '' |
| 80 | + else |
| 81 | + '' |
| 82 | + echo ${package.interpreter} -m venv ${ |
| 83 | + if builtins.isNull cfg.version || lib.versionAtLeast cfg.version "3.9" then "--upgrade-deps" else "" |
| 84 | + } "$VENV_PATH" |
| 85 | + ${package.interpreter} -m venv ${ |
| 86 | + if builtins.isNull cfg.version || lib.versionAtLeast cfg.version "3.9" then "--upgrade-deps" else "" |
| 87 | + } "$VENV_PATH" |
| 88 | + '' |
| 89 | + } |
| 90 | + echo "${package.interpreter}" > "$VENV_PATH/.devenv_interpreter" |
| 91 | + fi |
77 | 92 |
|
78 |
| - source "$VENV_PATH"/bin/activate |
| 93 | + source "$VENV_PATH"/bin/activate |
79 | 94 |
|
80 |
| - # reinstall requirements if necessary |
81 |
| - if [ -n "$requirements" ] |
82 |
| - then |
83 |
| - devenv_requirements_path="$(${pkgs.coreutils}/bin/cat "$VENV_PATH/.devenv_requirements" 2> /dev/null|| echo false )" |
84 |
| - devenv_requirements="$(${readlink} "$devenv_requirements_path")" |
85 |
| - if [ -z $devenv_requirements ] || [ $devenv_requirements != $requirements ] |
86 |
| - then |
87 |
| - echo "${requirements}" > "$VENV_PATH/.devenv_requirements" |
88 |
| - ${if cfg.uv.enable then '' |
89 |
| - echo "Requirements changed, running uv pip install -r ${requirements}..." |
90 |
| - ${cfg.uv.package}/bin/uv pip install --python "$VENV_PATH/bin/python" -r ${requirements} |
91 |
| - '' |
92 |
| - else '' |
| 95 | + # reinstall requirements if necessary |
| 96 | + if [ -n "$requirements" ] |
| 97 | + then |
| 98 | + devenv_requirements_path="$(${pkgs.coreutils}/bin/cat "$VENV_PATH/.devenv_requirements" 2> /dev/null|| echo false )" |
| 99 | + devenv_requirements="$(${readlink} "$devenv_requirements_path")" |
| 100 | + if [ -z $devenv_requirements ] || [ $devenv_requirements != $requirements ] |
| 101 | + then |
| 102 | + echo "${requirements}" > "$VENV_PATH/.devenv_requirements" |
| 103 | + ${ |
| 104 | + if cfg.uv.enable then |
| 105 | + '' |
| 106 | + echo "Requirements changed, running uv pip install -r ${requirements}..." |
| 107 | + ${cfg.uv.package}/bin/uv pip install --python "$VENV_PATH/bin/python" -r ${requirements} |
| 108 | + '' |
| 109 | + else |
| 110 | + '' |
93 | 111 | echo "Requirements changed, running pip install -r ${requirements}..."
|
94 | 112 | "$VENV_PATH"/bin/pip install -r ${requirements}
|
95 | 113 | ''
|
96 |
| - } |
97 |
| - fi |
98 |
| - fi |
| 114 | + } |
| 115 | + fi |
| 116 | + fi |
99 | 117 |
|
100 |
| - popd |
101 |
| - ''; |
| 118 | + popd |
| 119 | + ''; |
102 | 120 |
|
103 | 121 | initUvScript = ''
|
104 | 122 | pushd "${cfg.directory}"
|
|
329 | 347 | enable = lib.mkEnableOption "uv sync during devenv initialisation";
|
330 | 348 | arguments = lib.mkOption {
|
331 | 349 | type = lib.types.listOf lib.types.str;
|
332 |
| - default = [ "--frozen" "--no-install-workspace" ]; |
| 350 | + default = [ |
| 351 | + "--frozen" |
| 352 | + "--no-install-workspace" |
| 353 | + ]; |
333 | 354 | description = "Command line arguments pass to `uv sync` during devenv initialisation.";
|
334 | 355 | internal = true;
|
335 | 356 | };
|
|
417 | 438 | description = "Whether to install all extras. See `--all-extras`.";
|
418 | 439 | };
|
419 | 440 | verbosity = lib.mkOption {
|
420 |
| - type = lib.types.enum [ "no" "little" "more" "debug" ]; |
| 441 | + type = lib.types.enum [ |
| 442 | + "no" |
| 443 | + "little" |
| 444 | + "more" |
| 445 | + "debug" |
| 446 | + ]; |
421 | 447 | default = "no";
|
422 | 448 | description = "What level of verbosity the output of `poetry install` should have.";
|
423 | 449 | };
|
|
439 | 465 | config = lib.mkIf cfg.enable {
|
440 | 466 | languages.python.poetry.install.enable = lib.mkIf cfg.poetry.enable (lib.mkDefault true);
|
441 | 467 | languages.python.poetry.install.arguments =
|
442 |
| - lib.optional cfg.poetry.install.onlyInstallRootPackage "--only-root" ++ |
443 |
| - lib.optional (!cfg.poetry.install.installRootPackage && !cfg.poetry.install.onlyInstallRootPackage) "--no-root" ++ |
444 |
| - lib.optional cfg.poetry.install.compile "--compile" ++ |
445 |
| - lib.optional cfg.poetry.install.quiet "--quiet" ++ |
446 |
| - lib.optionals (cfg.poetry.install.groups != [ ]) [ "--with" ''"${lib.concatStringsSep "," cfg.poetry.install.groups}"'' ] ++ |
447 |
| - lib.optionals (cfg.poetry.install.ignoredGroups != [ ]) [ "--without" ''"${lib.concatStringsSep "," cfg.poetry.install.ignoredGroups}"'' ] ++ |
448 |
| - lib.optionals (cfg.poetry.install.onlyGroups != [ ]) [ "--only" ''"${lib.concatStringsSep " " cfg.poetry.install.onlyGroups}"'' ] ++ |
449 |
| - lib.optional cfg.poetry.install.allGroups "--all-groups" ++ |
450 |
| - lib.optionals (cfg.poetry.install.extras != [ ]) [ "--extras" ''"${lib.concatStringsSep " " cfg.poetry.install.extras}"'' ] ++ |
451 |
| - lib.optional cfg.poetry.install.allExtras "--all-extras" ++ |
452 |
| - lib.optional (cfg.poetry.install.verbosity == "little") "-v" ++ |
453 |
| - lib.optional (cfg.poetry.install.verbosity == "more") "-vv" ++ |
454 |
| - lib.optional (cfg.poetry.install.verbosity == "debug") "-vvv"; |
| 468 | + lib.optional cfg.poetry.install.onlyInstallRootPackage "--only-root" |
| 469 | + ++ lib.optional |
| 470 | + ( |
| 471 | + !cfg.poetry.install.installRootPackage && !cfg.poetry.install.onlyInstallRootPackage |
| 472 | + ) "--no-root" |
| 473 | + ++ lib.optional cfg.poetry.install.compile "--compile" |
| 474 | + ++ lib.optional cfg.poetry.install.quiet "--quiet" |
| 475 | + ++ lib.optionals (cfg.poetry.install.groups != [ ]) [ |
| 476 | + "--with" |
| 477 | + ''"${lib.concatStringsSep "," cfg.poetry.install.groups}"'' |
| 478 | + ] |
| 479 | + ++ lib.optionals (cfg.poetry.install.ignoredGroups != [ ]) [ |
| 480 | + "--without" |
| 481 | + ''"${lib.concatStringsSep "," cfg.poetry.install.ignoredGroups}"'' |
| 482 | + ] |
| 483 | + ++ lib.optionals (cfg.poetry.install.onlyGroups != [ ]) [ |
| 484 | + "--only" |
| 485 | + ''"${lib.concatStringsSep " " cfg.poetry.install.onlyGroups}"'' |
| 486 | + ] |
| 487 | + ++ lib.optional cfg.poetry.install.allGroups "--all-groups" |
| 488 | + ++ lib.optionals (cfg.poetry.install.extras != [ ]) [ |
| 489 | + "--extras" |
| 490 | + ''"${lib.concatStringsSep " " cfg.poetry.install.extras}"'' |
| 491 | + ] |
| 492 | + ++ lib.optional cfg.poetry.install.allExtras "--all-extras" |
| 493 | + ++ lib.optional (cfg.poetry.install.verbosity == "little") "-v" |
| 494 | + ++ lib.optional (cfg.poetry.install.verbosity == "more") "-vv" |
| 495 | + ++ lib.optional (cfg.poetry.install.verbosity == "debug") "-vvv"; |
455 | 496 |
|
456 | 497 | languages.python.poetry.activate.enable = lib.mkIf cfg.poetry.enable (lib.mkDefault true);
|
457 | 498 |
|
458 | 499 | languages.python.package = lib.mkMerge [
|
459 |
| - (lib.mkIf (cfg.version != null) |
460 |
| - (nixpkgs-python.packages.${pkgs.stdenv.system}.${cfg.version} or (throw "Unsupported Python version, see https://github.com/cachix/nixpkgs-python#supported-python-versions"))) |
| 500 | + (lib.mkIf (cfg.version != null) ( |
| 501 | + nixpkgs-python.packages.${pkgs.stdenv.system}.${cfg.version} |
| 502 | + or (throw "Unsupported Python version, see https://github.com/cachix/nixpkgs-python#supported-python-versions") |
| 503 | + )) |
461 | 504 | ];
|
462 | 505 |
|
463 | 506 | cachix.pull = lib.mkIf (cfg.version != null) [ "nixpkgs-python" ];
|
464 | 507 |
|
465 |
| - packages = [ package ] |
| 508 | + packages = |
| 509 | + [ package ] |
466 | 510 | ++ (lib.optional cfg.poetry.enable cfg.poetry.package)
|
467 | 511 | ++ (lib.optional cfg.uv.enable cfg.uv.package);
|
468 | 512 |
|
469 |
| - env = (lib.optionalAttrs cfg.uv.enable { |
470 |
| - # ummmmm how does this work? Can I even know the path to the devenv/state at this point? |
471 |
| - UV_PROJECT_ENVIRONMENT = "${config.env.DEVENV_STATE}/venv"; |
472 |
| - # Force uv not to download a Python binary when the version in pyproject.toml does not match the one installed by devenv |
473 |
| - UV_PYTHON_DOWNLOADS = "never"; |
474 |
| - # Force uv to always use the correct python interpreter. |
475 |
| - UV_PYTHON = "${package.interpreter}"; |
476 |
| - }) // (lib.optionalAttrs cfg.poetry.enable { |
477 |
| - # Make poetry use DEVENV_ROOT/.venv |
478 |
| - POETRY_VIRTUALENVS_IN_PROJECT = "true"; |
479 |
| - # Make poetry create the local virtualenv when it does not exist. |
480 |
| - POETRY_VIRTUALENVS_CREATE = "true"; |
481 |
| - # Make poetry stop accessing any other virtualenvs in $HOME. |
482 |
| - POETRY_VIRTUALENVS_PATH = "/var/empty"; |
483 |
| - }); |
| 513 | + env = |
| 514 | + (lib.optionalAttrs cfg.uv.enable { |
| 515 | + # ummmmm how does this work? Can I even know the path to the devenv/state at this point? |
| 516 | + UV_PROJECT_ENVIRONMENT = "${config.env.DEVENV_STATE}/venv"; |
| 517 | + # Force uv not to download a Python binary when the version in pyproject.toml does not match the one installed by devenv |
| 518 | + UV_PYTHON_DOWNLOADS = "never"; |
| 519 | + }) |
| 520 | + // (lib.optionalAttrs cfg.poetry.enable { |
| 521 | + # Make poetry use DEVENV_ROOT/.venv |
| 522 | + POETRY_VIRTUALENVS_IN_PROJECT = "true"; |
| 523 | + # Make poetry create the local virtualenv when it does not exist. |
| 524 | + POETRY_VIRTUALENVS_CREATE = "true"; |
| 525 | + # Make poetry stop accessing any other virtualenvs in $HOME. |
| 526 | + POETRY_VIRTUALENVS_PATH = "/var/empty"; |
| 527 | + }); |
484 | 528 |
|
485 | 529 | assertions = [
|
486 | 530 | {
|
|
493 | 537 | "devenv:python:virtualenv" = lib.mkIf (cfg.venv.enable && !cfg.uv.sync.enable) {
|
494 | 538 | description = "Initialize Python virtual environment";
|
495 | 539 | exec = initVenvScript;
|
496 |
| - exports = [ "PATH" "VIRTUAL_ENV" ]; |
| 540 | + exports = [ |
| 541 | + "PATH" |
| 542 | + "VIRTUAL_ENV" |
| 543 | + ]; |
497 | 544 | before = [ "devenv:enterShell" ];
|
498 | 545 | };
|
499 | 546 |
|
500 | 547 | "devenv:python:poetry" = lib.mkIf cfg.poetry.install.enable {
|
501 | 548 | description = "Initialize Poetry";
|
502 | 549 | exec = initPoetryScript;
|
503 | 550 | exports = [ "PATH" ] ++ lib.optional cfg.poetry.activate.enable "VIRTUAL_ENV";
|
504 |
| - before = [ "devenv:enterShell" ] |
505 |
| - ++ lib.optional cfg.venv.enable "devenv:python:virtualenv"; |
| 551 | + before = [ "devenv:enterShell" ] ++ lib.optional cfg.venv.enable "devenv:python:virtualenv"; |
506 | 552 | };
|
507 | 553 |
|
508 | 554 | "devenv:python:uv" = lib.mkIf cfg.uv.sync.enable {
|
509 | 555 | description = "Initialize uv sync";
|
510 | 556 | exec = initUvScript;
|
511 |
| - exports = [ "PATH" "VIRTUAL_ENV" ]; |
| 557 | + exports = [ |
| 558 | + "PATH" |
| 559 | + "VIRTUAL_ENV" |
| 560 | + ]; |
512 | 561 | before = [ "devenv:enterShell" ];
|
513 | 562 | };
|
514 | 563 | };
|
|
0 commit comments