Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add options to Python language module #993

Merged
merged 9 commits into from
Mar 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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

10 changes: 10 additions & 0 deletions examples/python-directory/.test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/usr/bin/env bash
set -exu
POETRY_VENV="$PWD/directory/.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 requests'
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;
};
};
}
5 changes: 5 additions & 0 deletions examples/python-directory/devenv.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
inputs:
nixpkgs:
url: github:NixOS/nixpkgs/nixpkgs-unstable
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 <bobvanderlinden@gmail.com>",
"Matthias Thym <git@thym.at>"
]
readme = "README.md"

[tool.poetry.dependencies]
python = "^3.11"
requests = "^2.30"
21 changes: 19 additions & 2 deletions examples/python-poetry/devenv.nix
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{ pkgs, lib, config, ... }:
{ pkgs, config, ... }:

{
packages = [
Expand All @@ -15,6 +15,23 @@

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;
};
};
}
5 changes: 5 additions & 0 deletions examples/python-poetry/devenv.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
inputs:
nixpkgs:
url: github:NixOS/nixpkgs/nixpkgs-unstable
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 <bobvanderlinden@gmail.com>"]
authors = [
"Bob van der Linden <bobvanderlinden@gmail.com>",
"Matthias Thym <git@thym.at>"
]
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
Loading