Skip to content

Commit

Permalink
Merge branch 'pyproject-location'
Browse files Browse the repository at this point in the history
  • Loading branch information
domenkozar committed Mar 22, 2024
2 parents 4e446c6 + 37cb967 commit 5c3eec6
Show file tree
Hide file tree
Showing 11 changed files with 142 additions and 32 deletions.
2 changes: 1 addition & 1 deletion devenv.nix
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@
cat > docs/languages-all.md <<EOF
\`\`\`nix
${lib.concatStringsSep "\n " (map (lang: "languages.${lang}.enable = true;") (builtins.attrNames config.languages))}
\`\`\`
\`\`\`
EOF
'';

Expand Down
5 changes: 5 additions & 0 deletions examples/python-directory/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@

# Devenv
.devenv*
devenv.local.nix

11 changes: 11 additions & 0 deletions examples/python-directory/.test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/usr/bin/env bash
set -exu
POETRY_VENV="$PWD/directory/.venv"
[ -d "$POETRY_VENV" ]
[ "$(command -v python)" = "$POETRY_VENV/bin/python" ]
python --version
poetry --version
python -c 'import requests'
cd directory
[ "$(poetry env info --path)" = "$POETRY_VENV" ]
poetry run python -c 'import requests'
13 changes: 13 additions & 0 deletions examples/python-directory/devenv.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{ pkgs, config, ... }:

{
languages.python = {
enable = true;
directory = "./directory";
poetry = {
enable = true;
install.enable = true;
activate.enable = true;
};
};
}
3 changes: 3 additions & 0 deletions examples/python-directory/devenv.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
inputs:
nixpkgs-python:
url: github:cachix/nixpkgs-python
17 changes: 17 additions & 0 deletions examples/python-directory/directory/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"

[tool.poetry]
name = "python-directory"
version = "0.1.0"
description = ""
authors = [
"Bob van der Linden <[email protected]>",
"Matthias Thym <[email protected]>"
]
readme = "README.md"

[tool.poetry.dependencies]
python = "^3.11"
requests = "^2.30"
2 changes: 1 addition & 1 deletion examples/python-poetry/.test.sh
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
#!/usr/bin/env bash
set -exu

POETRY_VENV="$PWD/.venv"
[ -d "$POETRY_VENV" ]
[ "$(poetry env info --path)" = "$POETRY_VENV" ]
[ "$(command -v python)" = "$POETRY_VENV/bin/python" ]
python --version
poetry --version
poetry run python -c "import os; print(os.environ['LD_LIBRARY_PATH'])"
ls .devenv/profile/lib
poetry run python -c 'import numpy'
python -c 'import numpy'
python -c 'import pjsua2'
26 changes: 18 additions & 8 deletions examples/python-poetry/devenv.nix
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,25 @@
config.languages.python.package.pkgs.pjsua2
];

# this envvar can be removed and the lib can be moved into
# languages.python.libraries when we start working against env-venv
env.LD_LIBRARY_PATH = lib.makeLibraryPath [
# A native dependency of numpy
pkgs.zlib
];

languages.python = {
enable = true;
poetry.enable = true;
poetry = {
enable = true;
install = {
enable = true;
installRootPackage = false;
onlyInstallRootPackage = false;
compile = false;
quiet = false;
groups = [ ];
ignoredGroups = [ ];
onlyGroups = [ ];
extras = [ ];
allExtras = false;
verbosity = "no";
};
activate.enable = true;
package = pkgs.poetry;
};
};
}
3 changes: 3 additions & 0 deletions examples/python-poetry/devenv.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
inputs:
nixpkgs-python:
url: github:cachix/nixpkgs-python
16 changes: 9 additions & 7 deletions examples/python-poetry/pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"

[tool.poetry]
name = "python-poetry"
version = "0.1.0"
version = "0.2.0"
description = ""
authors = ["Bob van der Linden <[email protected]>"]
authors = [
"Bob van der Linden <[email protected]>",
"Matthias Thym <[email protected]>"
]
readme = "README.md"

[tool.poetry.dependencies]
python = "^3.10"
numpy = "^1.24.1"


[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
76 changes: 61 additions & 15 deletions src/modules/languages/python.nix
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,11 @@ let
};

initVenvScript = pkgs.writeShellScript "init-venv.sh" ''
# Make sure any tools are not attempting to use the python interpreter from any
# Make sure any tools are not attempting to use the Python interpreter from any
# existing virtual environment. For instance if devenv was started within an venv.
unset VIRTUAL_ENV
VENV_PATH="${config.env.DEVENV_STATE}/venv"
VENV_PATH="${config.env.DEVENV_STATE}/${lib.optionalString (cfg.directory != config.devenv.root) ''"${cfg.directory}/"''}venv"
profile_python="$(${readlink} ${package.interpreter})"
devenv_interpreter_path="$(${pkgs.coreutils}/bin/cat "$VENV_PATH/.devenv_interpreter" 2> /dev/null || echo false )"
Expand Down Expand Up @@ -82,22 +82,22 @@ let
initPoetryScript = pkgs.writeShellScript "init-poetry.sh" ''
function _devenv_init_poetry_venv
{
# Make sure any tools are not attempting to use the python interpreter from any
# Make sure any tools are not attempting to use the Python interpreter from any
# existing virtual environment. For instance if devenv was started within an venv.
unset VIRTUAL_ENV
# Make sure poetry's venv uses the configured python executable.
# Make sure poetry's venv uses the configured Python executable.
${cfg.poetry.package}/bin/poetry env use --no-interaction --quiet ${package.interpreter}
}
function _devenv_poetry_install
{
local POETRY_INSTALL_COMMAND=(${cfg.poetry.package}/bin/poetry install --no-interaction ${lib.concatStringsSep " " cfg.poetry.install.arguments})
local POETRY_INSTALL_COMMAND=(${cfg.poetry.package}/bin/poetry install --no-interaction ${lib.concatStringsSep " " cfg.poetry.install.arguments} ${lib.optionalString (cfg.directory != config.devenv.root) ''--directory=${cfg.directory}''})
# Avoid running "poetry install" for every shell.
# Only run it when the "poetry.lock" file or python interpreter has changed.
# Only run it when the "poetry.lock" file or Python interpreter has changed.
# We do this by storing the interpreter path and a hash of "poetry.lock" in venv.
local ACTUAL_POETRY_CHECKSUM="${package.interpreter}:$(${pkgs.nix}/bin/nix-hash --type sha256 pyproject.toml):$(${pkgs.nix}/bin/nix-hash --type sha256 poetry.lock):''${POETRY_INSTALL_COMMAND[@]}"
local POETRY_CHECKSUM_FILE="$DEVENV_ROOT"/.venv/poetry.lock.checksum
local ACTUAL_POETRY_CHECKSUM="${package.interpreter}:$(${pkgs.nix}/bin/nix-hash --type sha256 "$DEVENV_ROOT"/${lib.optionalString (cfg.directory != config.devenv.root) ''${cfg.directory}/''}pyproject.toml):$(${pkgs.nix}/bin/nix-hash --type sha256 "$DEVENV_ROOT"/${lib.optionalString (cfg.directory != config.devenv.root) ''${cfg.directory}/''}poetry.lock):''${POETRY_INSTALL_COMMAND[@]}"
local POETRY_CHECKSUM_FILE="$DEVENV_ROOT"/${lib.optionalString (cfg.directory != config.devenv.root) ''${cfg.directory}/''}.venv/poetry.lock.checksum
if [ -f "$POETRY_CHECKSUM_FILE" ]
then
read -r EXPECTED_POETRY_CHECKSUM < "$POETRY_CHECKSUM_FILE"
Expand All @@ -116,7 +116,7 @@ let
fi
}
if [ ! -f pyproject.toml ]
if [ ! -f "$DEVENV_ROOT"/${lib.optionalString (cfg.directory != config.devenv.root) ''${cfg.directory}/''}pyproject.toml ]
then
echo "No pyproject.toml found. Run 'poetry init' to create one." >&2
else
Expand All @@ -125,7 +125,7 @@ let
_devenv_poetry_install
''}
${lib.optionalString cfg.poetry.activate.enable ''
source "$DEVENV_ROOT"/.venv/bin/activate
source "$DEVENV_ROOT"/${lib.optionalString (cfg.directory != config.devenv.root) ''${cfg.directory}/''}.venv/bin/activate
''}
fi
'';
Expand Down Expand Up @@ -173,6 +173,17 @@ in
example = "3.11 or 3.11.2";
};

directory = lib.mkOption {
type = lib.types.str;
default = config.devenv.root;
defaultText = lib.literalExpression "config.devenv.root";
description = ''
The Python project's root directory. Defaults to the root of the devenv project.
Can be an absolute path or one relative to the root of the devenv project.
'';
example = "./directory";
};

venv.enable = lib.mkEnableOption "Python virtual environment";

venv.requirements = lib.mkOption {
Expand Down Expand Up @@ -205,6 +216,16 @@ in
default = false;
description = "Whether the root package (your project) should be installed. See `--no-root`";
};
onlyInstallRootPackage = lib.mkOption {
type = lib.types.bool;
default = false;
description = "Whether to only install the root package (your project) should be installed, but no dependencies. See `--only-root`";
};
compile = lib.mkOption {
type = lib.types.bool;
default = false;
description = "Whether `poetry install` should compile Python source files to bytecode.";
};
quiet = lib.mkOption {
type = lib.types.bool;
default = false;
Expand All @@ -213,7 +234,17 @@ in
groups = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [ ];
description = "Which dependency-groups to install. See `--with`.";
description = "Which dependency groups to install. See `--with`.";
};
ignoredGroups = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [ ];
description = "Which dependency groups to ignore. See `--without`.";
};
onlyGroups = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [ ];
description = "Which dependency groups to exclusively install. See `--only`.";
};
extras = lib.mkOption {
type = lib.types.listOf lib.types.str;
Expand All @@ -225,9 +256,17 @@ in
default = false;
description = "Whether to install all extras. See `--all-extras`.";
};
verbosity = lib.mkOption {
type = lib.types.enum [ "no" "little" "more" "debug" ];
default = "no";
description = "What level of verbosity the output of `poetry install` should have.";
};
};
activate.enable = lib.mkOption {
type = lib.types.bool;
default = false;
description = "Whether to activate the poetry virtual environment automatically.";
};
activate.enable = lib.mkEnableOption "activate the poetry virtual environment automatically";

package = lib.mkOption {
type = lib.types.package;
default = pkgs.poetry;
Expand All @@ -240,11 +279,18 @@ in
config = lib.mkIf cfg.enable {
languages.python.poetry.install.enable = lib.mkIf cfg.poetry.enable (lib.mkDefault true);
languages.python.poetry.install.arguments =
lib.optional (!cfg.poetry.install.installRootPackage) "--no-root" ++
lib.optional cfg.poetry.install.onlyInstallRootPackage "--only-root" ++
lib.optional (!cfg.poetry.install.installRootPackage && !cfg.poetry.install.onlyInstallRootPackage) "--no-root" ++
lib.optional cfg.poetry.install.compile "--compile" ++
lib.optional cfg.poetry.install.quiet "--quiet" ++
lib.optionals (cfg.poetry.install.groups != [ ]) [ "--with" ''"${lib.concatStringsSep "," cfg.poetry.install.groups}"'' ] ++
lib.optionals (cfg.poetry.install.ignoredGroups != [ ]) [ "--without" ''"${lib.concatStringsSep "," cfg.poetry.install.ignoredGroups}"'' ] ++
lib.optionals (cfg.poetry.install.onlyGroups != [ ]) [ "--only" ''"${lib.concatStringsSep " " cfg.poetry.install.onlyGroups}"'' ] ++
lib.optionals (cfg.poetry.install.extras != [ ]) [ "--extras" ''"${lib.concatStringsSep " " cfg.poetry.install.extras}"'' ] ++
lib.optional cfg.poetry.install.allExtras "--all-extras";
lib.optional cfg.poetry.install.allExtras "--all-extras" ++
lib.optional (cfg.poetry.install.verbosity == "little") "-v" ++
lib.optional (cfg.poetry.install.verbosity == "more") "-vv" ++
lib.optional (cfg.poetry.install.verbosity == "debug") "-vvv";

languages.python.poetry.activate.enable = lib.mkIf cfg.poetry.enable (lib.mkDefault true);

Expand Down

0 comments on commit 5c3eec6

Please sign in to comment.