From 30829df30f7072a2b266f9e5b4aa71fa0427105e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Fri, 21 Jul 2023 16:45:53 +0100 Subject: [PATCH 001/146] generating examples should depend on successful build --- .github/workflows/buildtest.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/buildtest.yml b/.github/workflows/buildtest.yml index 25bba9fde..346a35b75 100644 --- a/.github/workflows/buildtest.yml +++ b/.github/workflows/buildtest.yml @@ -51,7 +51,7 @@ jobs: echo "examples=$json" >> $GITHUB_OUTPUT examples: name: ${{ matrix.example }} (${{ join(matrix.os) }}) - needs: [generate-examples] + needs: [generate-examples, build] strategy: fail-fast: false matrix: From 0d967cd7a72f55137a7cb7f375017497acf3b7cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Fri, 21 Jul 2023 19:12:04 +0100 Subject: [PATCH 002/146] unpin python 3.7 for cloudflare & fix build --- poetry.lock | 10 +++++----- runtime.txt | 1 - 2 files changed, 5 insertions(+), 6 deletions(-) delete mode 100644 runtime.txt diff --git a/poetry.lock b/poetry.lock index 9ab9e70d1..249883eab 100644 --- a/poetry.lock +++ b/poetry.lock @@ -634,9 +634,9 @@ doc = ["mkdocs-bootswatch (>=1,<2)", "mkdocs-minify-plugin (>=0.5.0,<0.6.0)", "p [package.source] type = "git" -url = "https://github.com/cachix/mkdocs-rss-plugin" -reference = "no-git" -resolved_reference = "017bdb52095703c79e0632f219b5adf9f212873c" +url = "https://github.com/Guts/mkdocs-rss-plugin" +reference = "feature/no-git-no-cry" +resolved_reference = "bac5e8935196011b4fb16c5076113d5e3ff13806" [[package]] name = "packaging" @@ -1183,5 +1183,5 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p [metadata] lock-version = "2.0" -python-versions = ">=3.8,<3.12" -content-hash = "c95d6d277e491fdec58f5bf5c45e8395dc06ca2e02b876aac01b6bf9e50d45af" +python-versions = ">=3.9,<3.12" +content-hash = "9747b6c0d68ebabcf88721e81fa39c89b5529282e1d62761c09003663b966ee1" diff --git a/runtime.txt b/runtime.txt deleted file mode 100644 index 2c0733315..000000000 --- a/runtime.txt +++ /dev/null @@ -1 +0,0 @@ -3.11 From 21d606c0926f2251b7fdc4d323819e7f1b40c75f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Sat, 22 Jul 2023 11:14:45 +0100 Subject: [PATCH 003/146] switch to nix ide with lsp support --- devenv.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/devenv.nix b/devenv.nix index a1886af84..d8ae46202 100644 --- a/devenv.nix +++ b/devenv.nix @@ -14,7 +14,7 @@ languages.python.poetry.enable = true; devcontainer.enable = true; - devcontainer.settings.customizations.vscode.extensions = [ "bbenoist.Nix" ]; + devcontainer.settings.customizations.vscode.extensions = [ "jnoortheen.nix-ide" ]; difftastic.enable = true; dotenv.enable = true; From b4e98ae926cff2647a7ac9003cae68aadfe4280f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Sat, 22 Jul 2023 12:39:41 +0100 Subject: [PATCH 004/146] ci: name the reinstallation step --- .github/workflows/buildtest.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/buildtest.yml b/.github/workflows/buildtest.yml index 346a35b75..dcd2c6651 100644 --- a/.github/workflows/buildtest.yml +++ b/.github/workflows/buildtest.yml @@ -25,9 +25,10 @@ jobs: with: name: devenv authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}' - - run: | - nix profile remove '.*' - nix profile install --accept-flake-config . + - name: "Reinstall devenv" + run: | + nix profile remove '.*' + nix profile install --accept-flake-config . - name: Run tests run: | devenv ci From b9c1704f32974657070d209f6e5f332d6e2f60ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Mon, 10 Jul 2023 11:27:33 +0100 Subject: [PATCH 005/146] Rewrite CLI in Python --- .devcontainer.json | 2 +- .envrc | 4 - .github/workflows/buildtest.yml | 4 +- .gitignore | 13 +- devenv.nix | 17 +- flake.lock | 91 ++++++- flake.nix | 8 +- package.nix | 33 +++ poetry.lock | 126 ++++----- pyproject.toml | 28 +- src/devenv-yaml.nix | 47 ---- src/devenv.nix | 302 --------------------- src/devenv/__init__.py | 0 src/devenv/cli.py | 459 ++++++++++++++++++++++++++++++++ src/devenv/log.py | 31 +++ src/devenv/yaml.py | 44 +++ src/flake.nix | 85 ------ src/modules/flake.tmpl.nix | 91 +++++++ 18 files changed, 844 insertions(+), 541 deletions(-) create mode 100644 package.nix delete mode 100644 src/devenv-yaml.nix delete mode 100644 src/devenv.nix create mode 100644 src/devenv/__init__.py create mode 100644 src/devenv/cli.py create mode 100644 src/devenv/log.py create mode 100644 src/devenv/yaml.py delete mode 100644 src/flake.nix create mode 100644 src/modules/flake.tmpl.nix diff --git a/.devcontainer.json b/.devcontainer.json index e76098216..e3c39242c 100644 --- a/.devcontainer.json +++ b/.devcontainer.json @@ -2,7 +2,7 @@ "customizations": { "vscode": { "extensions": [ - "bbenoist.Nix" + "jnoortheen.nix-ide" ] } }, diff --git a/.envrc b/.envrc index d0de725ed..e207b3c3b 100755 --- a/.envrc +++ b/.envrc @@ -3,10 +3,6 @@ # Used by https://direnv.net set -euo pipefail -# Use our own last built devenv/nix in CLI -devenv_bin=$(nix build --print-out-paths --accept-flake-config) -PATH_add "$devenv_bin/bin" - # External users should use `source_url` to load this file source_env ./direnvrc diff --git a/.github/workflows/buildtest.yml b/.github/workflows/buildtest.yml index dcd2c6651..51ac2834c 100644 --- a/.github/workflows/buildtest.yml +++ b/.github/workflows/buildtest.yml @@ -80,6 +80,7 @@ jobs: - run: devenv shell devenv-test-example ${{ matrix.example }} direnv: name: direnv (${{ join(matrix.os) }}) + needs: build strategy: fail-fast: false matrix: @@ -104,7 +105,7 @@ jobs: } ' ./examples/simple/devenv.yaml.orig > ./examples/simple/devenv.yaml nix profile remove '.*' - nix profile install . 'nixpkgs#direnv' + nix profile install . 'nixpkgs#direnv' nix profile install --accept-flake-config mkdir -p ~/.config/direnv/ cat > ~/.config/direnv/direnv.toml << 'EOF' [global] @@ -114,6 +115,7 @@ jobs: direnv exec ./examples/simple true fish-zsh: name: zsh/fish (${{ join(matrix.os) }}) + needs: build strategy: fail-fast: false matrix: diff --git a/.gitignore b/.gitignore index 420e5d62f..8de6048b7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,13 +1,14 @@ +# Nix & devenv result .env .env.* .devenv* /.cache /.pre-commit-config.yaml -/bin -/include -/lib -pyvenv.cfg -/.direnv -/.venv + +# examples examples/rust/app/target + +# Python +/.venv +*.pyc diff --git a/devenv.nix b/devenv.nix index d8ae46202..f0ad2c025 100644 --- a/devenv.nix +++ b/devenv.nix @@ -1,8 +1,11 @@ { inputs, pkgs, lib, config, ... }: { + env = { + DEVENV_NIX = inputs.nix.packages.${pkgs.stdenv.system}.nix; + }; + packages = [ - (import ./src/devenv.nix { inherit pkgs; nix = inputs.nix; }) pkgs.cairo pkgs.xorg.libxcb pkgs.yaml2json @@ -10,8 +13,9 @@ languages.nix.enable = true; languages.python.enable = true; - languages.python.venv.enable = true; languages.python.poetry.enable = true; + languages.python.poetry.install.installRootPackage = true; + languages.python.poetry.install.groups = [ "docs" ]; devcontainer.enable = true; devcontainer.settings.customizations.vscode.extensions = [ "jnoortheen.nix-ide" ]; @@ -20,7 +24,6 @@ dotenv.enable = true; processes.docs.exec = "mkdocs serve"; - processes.build.exec = "${pkgs.watchexec}/bin/watchexec -e nix nix build"; scripts.devenv-bump-version.exec = '' # TODO: ask for the new version @@ -50,7 +53,7 @@ nix flake init --template ''${DEVENV_ROOT}#simple nix flake update \ --override-input devenv ''${DEVENV_ROOT} - nix develop --impure --command echo nix-develop started succesfully |& tee ./console + nix develop --accept-flake-config --impure --command echo nix-develop started succesfully |& tee ./console grep -F 'nix-develop started succesfully' <./console grep -F "$(${lib.getExe pkgs.hello})" <./console @@ -70,15 +73,13 @@ nix flake init --template ''${DEVENV_ROOT}#flake-parts nix flake update \ --override-input devenv ''${DEVENV_ROOT} - nix develop --impure --command echo nix-develop started succesfully |& tee ./console + nix develop --accept-flake-config --impure --command echo nix-develop started succesfully |& tee ./console grep -F 'nix-develop started succesfully' <./console grep -F "$(${lib.getExe pkgs.hello})" <./console # Test that a container can be built - nix build --impure .#container-processes + nix build --impure --accept-flake-config .#container-processes popd rm -rf "$tmp" - - # TODO: test DIRENV_ACTIVE ''; scripts.devenv-test-all-examples.exec = '' for dir in $(ls examples); do diff --git a/flake.lock b/flake.lock index c0bc8dac4..8d1c9b0a2 100644 --- a/flake.lock +++ b/flake.lock @@ -20,6 +20,24 @@ "inputs": { "systems": "systems" }, + "locked": { + "lastModified": 1689068808, + "narHash": "sha256-6ixXo3wt24N/melDWjq70UuHQLxGV8jZvooRanIHXw0=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "919d646de7be200f3bf08cb76ae1f09402b6f9b4", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_2": { + "inputs": { + "systems": "systems_2" + }, "locked": { "lastModified": 1685518550, "narHash": "sha256-o2d0KcvaXzTrPRIo0kOLV0/QXHhDQ5DTi+OxcjO8xqY=", @@ -94,13 +112,34 @@ "type": "github" } }, + "nix-github-actions": { + "inputs": { + "nixpkgs": [ + "poetry2nix", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1688870561, + "narHash": "sha256-4UYkifnPEw1nAzqqPOTL2MvWtm3sNGw1UTYTalkTcGY=", + "owner": "nix-community", + "repo": "nix-github-actions", + "rev": "165b1650b753316aa7f1787f3005a8d2da0f5301", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "nix-github-actions", + "type": "github" + } + }, "nixpkgs": { "locked": { - "lastModified": 1678875422, - "narHash": "sha256-T3o6NcQPwXjxJMn2shz86Chch4ljXgZn746c2caGxd8=", + "lastModified": 1690083312, + "narHash": "sha256-I3egwgNXavad1eIjWu1kYyi0u73di/sMmlnQIuzQASk=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "126f49a01de5b7e35a43fd43f891ecf6d3a51459", + "rev": "af8cd5ded7735ca1df1a1174864daab75feeb64a", "type": "github" }, "original": { @@ -142,12 +181,34 @@ "type": "github" } }, + "poetry2nix": { + "inputs": { + "flake-utils": "flake-utils", + "nix-github-actions": "nix-github-actions", + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1689849924, + "narHash": "sha256-d259Z2S7CS7Na04qQNQ6LYQILuI7cf4Rpe76qc4mz40=", + "owner": "nix-community", + "repo": "poetry2nix", + "rev": "1d7eda9336f336392d24e9602be5cb9be7ae405c", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "poetry2nix", + "type": "github" + } + }, "pre-commit-hooks": { "inputs": { "flake-compat": [ "flake-compat" ], - "flake-utils": "flake-utils", + "flake-utils": "flake-utils_2", "gitignore": "gitignore", "nixpkgs": [ "nixpkgs" @@ -155,11 +216,11 @@ "nixpkgs-stable": "nixpkgs-stable" }, "locked": { - "lastModified": 1704725188, - "narHash": "sha256-qq8NbkhRZF1vVYQFt1s8Mbgo8knj+83+QlL5LBnYGpI=", + "lastModified": 1689668210, + "narHash": "sha256-XAATwDkaUxH958yXLs1lcEOmU6pSEIkatY3qjqk8X0E=", "owner": "cachix", "repo": "pre-commit-hooks.nix", - "rev": "ea96f0c05924341c551a797aaba8126334c505d2", + "rev": "eb433bff05b285258be76513add6f6c57b441775", "type": "github" }, "original": { @@ -173,6 +234,7 @@ "flake-compat": "flake-compat", "nix": "nix", "nixpkgs": "nixpkgs", + "poetry2nix": "poetry2nix", "pre-commit-hooks": "pre-commit-hooks" } }, @@ -190,6 +252,21 @@ "repo": "default", "type": "github" } + }, + "systems_2": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } } }, "root": "root", diff --git a/flake.nix b/flake.nix index e73f2eb20..339fba55e 100644 --- a/flake.nix +++ b/flake.nix @@ -22,14 +22,16 @@ url = "github:domenkozar/nix/relaxed-flakes"; inputs.nixpkgs.follows = "nixpkgs"; }; + inputs.poetry2nix = { + url = "github:nix-community/poetry2nix"; + inputs.nixpkgs.follows = "nixpkgs"; + }; outputs = { self, nixpkgs, pre-commit-hooks, nix, ... }@inputs: let systems = [ "x86_64-linux" "i686-linux" "x86_64-darwin" "aarch64-linux" "aarch64-darwin" ]; forAllSystems = f: builtins.listToAttrs (map (name: { inherit name; value = f name; }) systems); - mkPackage = pkgs: import ./src/devenv.nix { - inherit pkgs nix; - }; + mkPackage = pkgs: import ./package.nix { inherit pkgs inputs; }; mkDevShellPackage = config: pkgs: import ./src/devenv-devShell.nix { inherit config pkgs; }; mkDocOptions = pkgs: let diff --git a/package.nix b/package.nix new file mode 100644 index 000000000..61c4f7d5a --- /dev/null +++ b/package.nix @@ -0,0 +1,33 @@ +{ pkgs, inputs }: + +let + python_slim = pkgs.python311.override { + mimetypesSupport = false; + x11Support = false; + stripConfig = true; + stripIdlelib = true; + stripTests = true; + stripTkinter = true; + enableLTO = false; + rebuildBytecode = false; + stripBytecode = true; + includeSiteCustomize = false; + enableOptimizations = false; + bzip2 = null; + gdbm = null; + xz = null; + ncurses = null; + readline = null; + sqlite = null; + tzdata = null; + self = python_slim; + }; +in +(inputs.poetry2nix.legacyPackages.${pkgs.stdenv.system}.mkPoetryApplication { + projectDir = ./.; + python = python_slim; +}).overrideAttrs (old: { + makeWrapperArgs = [ + "--set DEVENV_NIX ${inputs.nix.packages.${pkgs.stdenv.system}.nix}" + ]; +}) diff --git a/poetry.lock b/poetry.lock index 249883eab..6dd48e078 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.4.2 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.5.1 and should not be changed by hand. [[package]] name = "babel" @@ -31,7 +31,6 @@ files = [ name = "cairocffi" version = "1.6.1" description = "cffi-based cairo bindings for Python" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -51,7 +50,6 @@ xcb = ["xcffib (>=1.4.0)"] name = "cairosvg" version = "2.7.1" description = "A Simple SVG Converter based on Cairo" -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -74,7 +72,6 @@ test = ["flake8", "isort", "pytest"] name = "certifi" version = "2023.7.22" description = "Python package for providing Mozilla's CA Bundle." -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -86,7 +83,6 @@ files = [ name = "cffi" version = "1.15.1" description = "Foreign Function Interface for Python calling C code." -category = "main" optional = false python-versions = "*" files = [ @@ -163,7 +159,6 @@ pycparser = "*" name = "charset-normalizer" version = "3.2.0" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." -category = "main" optional = false python-versions = ">=3.7.0" files = [ @@ -248,7 +243,6 @@ files = [ name = "click" version = "8.1.7" description = "Composable command line interface toolkit" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -263,7 +257,6 @@ colorama = {version = "*", markers = "platform_system == \"Windows\""} name = "colorama" version = "0.4.6" description = "Cross-platform colored terminal text." -category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" files = [ @@ -275,7 +268,6 @@ files = [ name = "cssselect2" version = "0.7.0" description = "CSS selectors for Python ElementTree" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -295,7 +287,6 @@ test = ["flake8", "isort", "pytest"] name = "defusedxml" version = "0.7.1" description = "XML bomb protection for Python stdlib modules" -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" files = [ @@ -303,11 +294,25 @@ files = [ {file = "defusedxml-0.7.1.tar.gz", hash = "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69"}, ] +[[package]] +name = "filelock" +version = "3.12.2" +description = "A platform independent file lock." +optional = false +python-versions = ">=3.7" +files = [ + {file = "filelock-3.12.2-py3-none-any.whl", hash = "sha256:cbb791cdea2a72f23da6ac5b5269ab0a0d161e9ef0100e653b69049a7706d1ec"}, + {file = "filelock-3.12.2.tar.gz", hash = "sha256:002740518d8aa59a26b0c76e10fb8c6e15eae825d34b6fdf670333fd7b938d81"}, +] + +[package.extras] +docs = ["furo (>=2023.5.20)", "sphinx (>=7.0.1)", "sphinx-autodoc-typehints (>=1.23,!=1.23.4)"] +testing = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "diff-cover (>=7.5)", "pytest (>=7.3.1)", "pytest-cov (>=4.1)", "pytest-mock (>=3.10)", "pytest-timeout (>=2.1)"] + [[package]] name = "ghp-import" version = "2.1.0" description = "Copy your docs directly to the gh-pages branch." -category = "main" optional = false python-versions = "*" files = [ @@ -325,7 +330,6 @@ dev = ["flake8", "markdown", "twine", "wheel"] name = "gitdb" version = "4.0.10" description = "Git Object Database" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -340,7 +344,6 @@ smmap = ">=3.0.1,<6" name = "gitpython" version = "3.1.36" description = "GitPython is a Python library used to interact with Git repositories" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -358,7 +361,6 @@ test = ["black", "coverage[toml]", "ddt (>=1.1.1,!=1.4.3)", "mypy", "pre-commit" name = "idna" version = "3.4" description = "Internationalized Domain Names in Applications (IDNA)" -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -370,7 +372,6 @@ files = [ name = "importlib-metadata" version = "6.8.0" description = "Read metadata from Python packages" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -390,7 +391,6 @@ testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs name = "jinja2" version = "3.1.2" description = "A very fast and expressive template engine." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -427,7 +427,6 @@ testing = ["coverage", "pyyaml"] name = "markupsafe" version = "2.1.3" description = "Safely add untrusted strings to HTML/XML markup." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -497,7 +496,6 @@ files = [ name = "mergedeep" version = "1.3.4" description = "A deep merge function for 🐍." -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -509,7 +507,6 @@ files = [ name = "mkdocs" version = "1.5.3" description = "Project documentation with Markdown." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -541,7 +538,6 @@ min-versions = ["babel (==2.9.0)", "click (==7.0)", "colorama (==0.4)", "ghp-imp name = "mkdocs-include-markdown-plugin" version = "6.0.1" description = "Mkdocs Markdown includer plugin." -category = "main" optional = false python-versions = "<3.13,>=3.8" files = [ @@ -559,7 +555,6 @@ cache = ["platformdirs"] name = "mkdocs-markdownextradata-plugin" version = "0.2.5" description = "A MkDocs plugin that injects the mkdocs.yml extra variables into the markdown template" -category = "main" optional = false python-versions = ">=2.7.9,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*" files = [ @@ -574,7 +569,6 @@ pyyaml = "*" name = "mkdocs-material" version = "9.4.0" description = "Documentation that simply works" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -604,7 +598,6 @@ recommended = ["mkdocs-minify-plugin (>=0.7,<1.0)", "mkdocs-redirects (>=1.2,<2. name = "mkdocs-material-extensions" version = "1.2" description = "Extension pack for Python Markdown and MkDocs Material." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -614,35 +607,28 @@ files = [ [[package]] name = "mkdocs-rss-plugin" -version = "1.5.0" +version = "1.8.0" description = "MkDocs plugin which generates a static RSS feed using git log and page.meta." -category = "main" optional = false -python-versions = ">=3.7, <4" -files = [] -develop = false +python-versions = ">=3.8, <4" +files = [ + {file = "mkdocs-rss-plugin-1.8.0.tar.gz", hash = "sha256:475bf4ea05cbe786af38d519b55352b1b2eb87597ad680fcbc309056864ed5c4"}, + {file = "mkdocs_rss_plugin-1.8.0-py2.py3-none-any.whl", hash = "sha256:0fa13c99730c1d3ad9ec05102ff3d148c9849396c40b30be789339d38722fa8f"}, +] [package.dependencies] GitPython = ">=3.1,<3.2" mkdocs = ">=1.1,<2" -pytz = {version = ">=2022.0.0,<2023.0.0", markers = "python_version < \"3.9\""} -tzdata = {version = ">=2022.0.0,<2023.0.0", markers = "python_version >= \"3.9\" and sys_platform == \"win32\""} +tzdata = {version = "==2023.*", markers = "python_version >= \"3.9\" and sys_platform == \"win32\""} [package.extras] -dev = ["black", "feedparser (>=6.0,<6.1)", "flake8 (>=4,<5.1)", "pre-commit (>=2.10,<2.21)", "pytest-cov (>=4.0.0,<4.1.0)", "validator-collection (>=1.5,<1.6)"] -doc = ["mkdocs-bootswatch (>=1,<2)", "mkdocs-minify-plugin (>=0.5.0,<0.6.0)", "pygments (>=2.5,<3)", "pymdown-extensions (>=7,<10)"] - -[package.source] -type = "git" -url = "https://github.com/Guts/mkdocs-rss-plugin" -reference = "feature/no-git-no-cry" -resolved_reference = "bac5e8935196011b4fb16c5076113d5e3ff13806" +dev = ["black", "feedparser (>=6.0,<6.1)", "flake8 (>=4,<7)", "pre-commit (>=3,<4)", "pytest-cov (>=4,<4.2)", "validator-collection (>=1.5,<1.6)"] +doc = ["mkdocs-bootswatch (>=1,<2)", "mkdocs-minify-plugin (==0.6.*)", "pygments (>=2.5,<3)", "pymdown-extensions (>=10,<11)"] [[package]] name = "packaging" version = "23.1" description = "Core utilities for Python packages" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -677,7 +663,6 @@ files = [ name = "pillow" version = "10.0.1" description = "Python Imaging Library (Fork)" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -761,7 +746,6 @@ test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4)", "pytest-co name = "pycparser" version = "2.21" description = "C parser in Python" -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -773,7 +757,6 @@ files = [ name = "pygments" version = "2.16.1" description = "Pygments is a syntax highlighting package written in Python." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -788,7 +771,6 @@ plugins = ["importlib-metadata"] name = "pymdown-extensions" version = "10.3" description = "Extension pack for Python Markdown." -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -807,7 +789,6 @@ extra = ["pygments (>=2.12)"] name = "python-dateutil" version = "2.8.2" description = "Extensions to the standard Python datetime module" -category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ @@ -818,23 +799,10 @@ files = [ [package.dependencies] six = ">=1.5" -[[package]] -name = "pytz" -version = "2022.7.1" -description = "World timezone definitions, modern and historical" -category = "main" -optional = false -python-versions = "*" -files = [ - {file = "pytz-2022.7.1-py2.py3-none-any.whl", hash = "sha256:78f4f37d8198e0627c5f1143240bb0206b8691d8d7ac6d78fee88b78733f8c4a"}, - {file = "pytz-2022.7.1.tar.gz", hash = "sha256:01a0681c4b9684a28304615eba55d1ab31ae00bf68ec157ec3708a8182dbbcd0"}, -] - [[package]] name = "pyyaml" version = "6.0.1" description = "YAML parser and emitter for Python" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -894,7 +862,6 @@ files = [ name = "pyyaml-env-tag" version = "0.1" description = "A custom YAML tag for referencing environment variables in YAML files. " -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -909,7 +876,6 @@ pyyaml = "*" name = "regex" version = "2022.10.31" description = "Alternative regular expression module, to replace re." -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -1007,7 +973,6 @@ files = [ name = "requests" version = "2.31.0" description = "Python HTTP for Humans." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1029,7 +994,6 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] name = "six" version = "1.16.0" description = "Python 2 and 3 compatibility utilities" -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" files = [ @@ -1041,7 +1005,6 @@ files = [ name = "smmap" version = "5.0.1" description = "A pure Python implementation of a sliding window memory map manager" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1049,11 +1012,35 @@ files = [ {file = "smmap-5.0.1.tar.gz", hash = "sha256:dceeb6c0028fdb6734471eb07c0cd2aae706ccaecab45965ee83f11c8d3b1f62"}, ] +[[package]] +name = "strictyaml" +version = "1.7.3" +description = "Strict, typed YAML parser" +optional = false +python-versions = ">=3.7.0" +files = [ + {file = "strictyaml-1.7.3-py3-none-any.whl", hash = "sha256:fb5c8a4edb43bebb765959e420f9b3978d7f1af88c80606c03fb420888f5d1c7"}, + {file = "strictyaml-1.7.3.tar.gz", hash = "sha256:22f854a5fcab42b5ddba8030a0e4be51ca89af0267961c8d6cfa86395586c407"}, +] + +[package.dependencies] +python-dateutil = ">=2.6.0" + +[[package]] +name = "terminaltables" +version = "3.1.10" +description = "Generate simple tables in terminals from a nested list of strings." +optional = false +python-versions = ">=2.6" +files = [ + {file = "terminaltables-3.1.10-py2.py3-none-any.whl", hash = "sha256:e4fdc4179c9e4aab5f674d80f09d76fa436b96fdc698a8505e0a36bf0804a874"}, + {file = "terminaltables-3.1.10.tar.gz", hash = "sha256:ba6eca5cb5ba02bba4c9f4f985af80c54ec3dccf94cfcd190154386255e47543"}, +] + [[package]] name = "tinycss2" version = "1.2.1" description = "A tiny CSS parser" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1070,21 +1057,19 @@ test = ["flake8", "isort", "pytest"] [[package]] name = "tzdata" -version = "2022.7" +version = "2023.3" description = "Provider of IANA time zone data" -category = "main" optional = false python-versions = ">=2" files = [ - {file = "tzdata-2022.7-py2.py3-none-any.whl", hash = "sha256:2b88858b0e3120792a3c0635c23daf36a7d7eeeca657c323da299d2094402a0d"}, - {file = "tzdata-2022.7.tar.gz", hash = "sha256:fe5f866eddd8b96e9fcba978f8e503c909b19ea7efda11e52e39494bad3a7bfa"}, + {file = "tzdata-2023.3-py2.py3-none-any.whl", hash = "sha256:7e65763eef3120314099b6939b5546db7adce1e7d6f2e179e3df563c70511eda"}, + {file = "tzdata-2023.3.tar.gz", hash = "sha256:11ef1e08e54acb0d4f95bdb1be05da659673de4acbd21bf9c69e94cc5e907a3a"}, ] [[package]] name = "urllib3" version = "2.0.5" description = "HTTP library with thread-safe connection pooling, file post, and more." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1102,7 +1087,6 @@ zstd = ["zstandard (>=0.18.0)"] name = "watchdog" version = "3.0.0" description = "Filesystem events monitoring" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1157,7 +1141,6 @@ bracex = ">=2.1.1" name = "webencodings" version = "0.5.1" description = "Character encoding aliases for legacy web content" -category = "main" optional = false python-versions = "*" files = [ @@ -1169,7 +1152,6 @@ files = [ name = "zipp" version = "3.17.0" description = "Backport of pathlib-compatible object wrapper for zip files" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1184,4 +1166,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p [metadata] lock-version = "2.0" python-versions = ">=3.9,<3.12" -content-hash = "9747b6c0d68ebabcf88721e81fa39c89b5529282e1d62761c09003663b966ee1" +content-hash = "0f22aaee71aeb64eeb85f1d625333b93ec21eeab62918b70c8f5777370a64841" diff --git a/pyproject.toml b/pyproject.toml index e52f2c80c..92f95112a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,19 +1,37 @@ [tool.poetry] name = "devenv" -version = "0" -description = "" -authors = ["Domen Kožar "] +version = "1.0" +description = "Fast, Declarative, Reproducible, and Composable Developer Environments using Nix" +authors = ["Domen Kožar "] readme = "README.md" +repository = "https://github.com/cachix/devenv" +packages = [{include = "devenv", from = "src"}] +include = [ + { path = "src", format = ["sdist", "wheel"] }, + { path = "examples/simple", format = ["sdist", "wheel"] } +] [tool.poetry.dependencies] -python = ">=3.8,<3.12" -pillow = "^10.0.1" +python = ">=3.9,<3.12" +click = "^8.1.4" +strictyaml = "^1.7.3" +terminaltables = "^3.1.10" +filelock = "^3.12.0" + +[tool.poetry.group.docs] +optional = true + +[tool.poetry.group.docs.dependencies] +pillow = "^9.5.0" cairosvg = "^2.7.0" mkdocs-markdownextradata-plugin = "^0.2.5" mkdocs-include-markdown-plugin = "^6.0.1" mkdocs-material = "^9.4.0" mkdocs-rss-plugin = {git = "https://github.com/cachix/mkdocs-rss-plugin", rev = "no-git"} +[tool.poetry.scripts] +devenv = "devenv.cli:cli" + [build-system] requires = ["poetry-core"] build-backend = "poetry.core.masonry.api" diff --git a/src/devenv-yaml.nix b/src/devenv-yaml.nix deleted file mode 100644 index 2f920495e..000000000 --- a/src/devenv-yaml.nix +++ /dev/null @@ -1,47 +0,0 @@ -{ pkgs }: - -pkgs.writers.writePython3Bin "devenv-yaml" { libraries = with pkgs.python3Packages; [ strictyaml path ]; } '' - from strictyaml import Map, MapPattern, Str, Seq - from strictyaml import load, Bool, Any, Optional, YAMLError - import json - import sys - import os - from path import Path - - inputsSchema = MapPattern(Str(), Map({ - "url": Str(), - Optional("flake", default=None): Bool(), - Optional("inputs", default=None): Any(), - Optional("overlays", default=None): Seq(Str()) - })) - - schema = Map({ - Optional("inputs", default=None): inputsSchema, - Optional("allowUnfree", default=False): Bool(), - Optional("imports", default=None): Seq(Str()), - Optional("permittedInsecurePackages", default=None): Seq(Str()) - }) - - filename = Path("devenv.yaml").bytes().decode('utf8') - try: - devenv = load(filename, schema, label="devenv.yaml").data - except YAMLError as error: - print("Error in `devenv.yaml`", error) - sys.exit(1) - - inputs = {} - for input, attrs in devenv.get('inputs', {}).items(): - inputs[input] = {k: attrs[k] for k in ('url', 'inputs', 'flake') - if k in attrs} - - devenv_dir = sys.argv[1] - - with open(os.path.join(devenv_dir, "flake.json"), 'w') as f: - f.write(json.dumps(inputs)) - - with open(os.path.join(devenv_dir, "devenv.json"), 'w') as f: - f.write(json.dumps(devenv)) - - with open(os.path.join(devenv_dir, "imports.txt"), 'w') as f: - f.write("\n".join(devenv.get('imports', []))) -'' diff --git a/src/devenv.nix b/src/devenv.nix deleted file mode 100644 index 2e307b836..000000000 --- a/src/devenv.nix +++ /dev/null @@ -1,302 +0,0 @@ -{ pkgs, ... } @ args: -let - examples = ../examples; - lib = pkgs.lib; - version = lib.fileContents ./modules/latest-version; - inherit (pkgs) - bash - coreutils - findutils - gnugrep - jq - docopts - util-linuxMinimal; - devenv-yaml = import ./devenv-yaml.nix { inherit pkgs; }; - nix = args.nix.packages.${pkgs.stdenv.system}.nix; -in -pkgs.writeScriptBin "devenv" '' - #!${bash}/bin/bash - - # we want subshells to fail the program - set -e - - NIX_FLAGS="--show-trace --extra-experimental-features nix-command --extra-experimental-features flakes --option warn-dirty false" - - # current hack to test if we have resolved all Nix annoyances - export FLAKE_FILE=.devenv.flake.nix - export FLAKE_LOCK=devenv.lock - - function assemble { - if [[ ! -f devenv.nix ]]; then - echo "File devenv.nix does not exist. To get started, run:" - echo - echo " $ devenv init" - exit 1 - fi - - export DEVENV_DIR="$(pwd)/.devenv" - export DEVENV_GC="$DEVENV_DIR/gc" - ${coreutils}/bin/mkdir -p "$DEVENV_GC" - if [[ -f devenv.yaml ]]; then - ${devenv-yaml}/bin/devenv-yaml "$DEVENV_DIR" - else - [[ -f "$DEVENV_DIR/devenv.json" ]] && ${coreutils}/bin/rm "$DEVENV_DIR/devenv.json" - [[ -f "$DEVENV_DIR/flake.json" ]] && ${coreutils}/bin/rm "$DEVENV_DIR/flake.json" - [[ -f "$DEVENV_DIR/imports.txt" ]] && ${coreutils}/bin/rm "$DEVENV_DIR/imports.txt" - fi - ${coreutils}/bin/cp -f ${import ./flake.nix { inherit pkgs version; }} "$FLAKE_FILE" - ${coreutils}/bin/chmod +w "$FLAKE_FILE" - } - - if [[ -z "$XDG_DATA_HOME" ]]; then - GC_ROOT="$HOME/.devenv/gc" - else - GC_ROOT="$XDG_DATA_HOME/devenv/gc" - fi - - ${coreutils}/bin/mkdir -p "$GC_ROOT" - GC_DIR="$GC_ROOT/$(${coreutils}/bin/date +%s%3N)" - - function add_gc { - name=$1 - storePath=$2 - - ${nix}/bin/nix-store --add-root "$DEVENV_GC/$name" -r $storePath >/dev/null - ${coreutils}/bin/ln -sf $storePath "$GC_DIR-$name" - } - - function shell { - assemble - echo "Building shell ..." 1>&2 - env=$(${nix}/bin/nix $NIX_FLAGS print-dev-env --impure --profile "$DEVENV_GC/shell") - ${nix}/bin/nix-env -p "$DEVENV_GC/shell" --delete-generations old 2>/dev/null - ${coreutils}/bin/ln -sf $(${coreutils}/bin/readlink -f "$DEVENV_GC/shell") "$GC_DIR-shell" - } - - command=$1 - if [[ ! -z $command ]]; then - shift - fi - - case $command in - up) - shell - eval "$env" - procfilescript=$(${nix}/bin/nix $NIX_FLAGS build --no-link --print-out-paths --impure '.#procfileScript') - if [ "$(${coreutils}/bin/cat $procfilescript|tail -n +2)" = "" ]; then - echo "No 'processes' option defined: https://devenv.sh/processes/" - exit 1 - else - add_gc procfilescript $procfilescript - $procfilescript - fi - ;; - assemble) - assemble - ;; - print-dev-env) - shell - echo "$env" - ;; - shell) - shell - if [ $# -eq 0 ]; then - echo "Entering shell ..." 1>&2 - echo "" 1>&2 - ${nix}/bin/nix $NIX_FLAGS develop "$DEVENV_GC/shell" - else - set -e - ${nix}/bin/nix $NIX_FLAGS develop "$DEVENV_GC/shell" -c "$@" - fi - ;; - container) - assemble - help=$(${coreutils}/bin/cat << 'EOF' - Usage: container [options] CONTAINER-NAME - - Options: - --registry= Registry to copy the container to. - --copy Copy the container to the registry. - --copy-args= Arguments passed to `skopeo copy`. - --docker-run Execute `docker run`. - EOF - ) - - eval "$(${docopts}/bin/docopts -A subcommand -h "$help" : "$@")" - - export DEVENV_CONTAINER=1 - container="''${subcommand[CONTAINER-NAME]}" - - # build container - spec=$(${nix}/bin/nix $NIX_FLAGS build --impure --print-out-paths --no-link ".#devenv.containers.\"$container\".derivation") - echo $spec - - # copy container - if [[ ''${subcommand[--copy]} != false || ''${subcommand[--docker-run]} != false ]]; then - copyScript=$(${nix}/bin/nix $NIX_FLAGS build --print-out-paths --no-link --impure ".#devenv.containers.\"$container\".copyScript") - - if [[ ''${subcommand[--docker-run]} == true ]]; then - registry=docker-daemon: - else - registry="''${subcommand[--registry]}" - fi - $copyScript $spec $registry ''${subcommand[--copy-args]} - fi - - # docker run - if [[ ''${subcommand[--docker-run]} != false ]]; then - $(${nix}/bin/nix $NIX_FLAGS build --print-out-paths --no-link --impure ".#devenv.containers.\"$container\".dockerRun") - fi - ;; - search) - name=$1 - shift - assemble - options=$(${nix}/bin/nix $NIX_FLAGS build --no-link --print-out-paths '.#optionsJSON' --impure) - results=$(${nix}/bin/nix $NIX_FLAGS search --json nixpkgs $name) - results_options=$(${coreutils}/bin/cat $options/share/doc/nixos/options.json | ${jq}/bin/jq "with_entries(select(.key | contains(\"$name\")))") - if [ "$results" = "{}" ]; then - echo "No packages found for '$name'." - else - ${jq}/bin/jq -r '[to_entries[] | {name: ("pkgs." + (.key | split(".") | del(.[0, 1]) | join("."))) } * (.value | { version, description})] | (.[0] |keys_unsorted | @tsv) , (["----", "-------", "-----------"] | @tsv), (.[] |map(.) |@tsv)' <<< "$results" | ${util-linuxMinimal}/bin/column -ts $'\t' - echo - fi - echo - if [ "$results_options" = "{}" ]; then - echo "No options found for '$name'." - else - ${jq}/bin/jq -r '["option","type","default", "description"], ["------", "----", "-------", "-----------"],(to_entries[] | [.key, .value.type, .value.default, .value.description[0:80]]) | @tsv' <<< "$results_options" | ${util-linuxMinimal}/bin/column -ts $'\t' - fi - echo - echo "Found $(${jq}/bin/jq 'length' <<< "$results") packages and $(${jq}/bin/jq 'length' <<< "$results_options") options for '$name'." - ;; - init) - if [ "$#" -eq "1" ] - then - target="$1" - ${coreutils}/bin/mkdir -p "$target" - cd "$target" - fi - - if [[ -f devenv.nix && -f devenv.yaml && -f .envrc ]]; then - echo "Aborting since devenv.nix, devenv.yaml and .envrc already exist." - exit 1 - fi - - # TODO: allow selecting which example and list them - example=simple - - if [[ ! -f .envrc ]]; then - echo "Creating .envrc" - ${coreutils}/bin/cat ${examples}/$example/.envrc > .envrc - fi - - if [[ ! -f devenv.nix ]]; then - echo "Creating devenv.nix" - ${coreutils}/bin/cat ${examples}/$example/devenv.nix > devenv.nix - fi - - if [[ ! -f devenv.yaml ]]; then - echo "Creating devenv.yaml" - ${coreutils}/bin/cat ${examples}/$example/devenv.yaml > devenv.yaml - fi - - if [[ ! -f .gitignore ]]; then - ${coreutils}/bin/touch .gitignore - fi - - if ! ${gnugrep}/bin/grep -q "devenv" .gitignore; then - echo "Appending defaults to .gitignore" - - echo "" >> .gitignore - echo "# Devenv" >> .gitignore - echo ".devenv*" >> .gitignore - echo "devenv.local.nix" >> .gitignore - echo "" >> .gitignore - echo "# direnv" >> .gitignore - echo ".direnv" >> .gitignore - echo "" >> .gitignore - echo "# pre-commit" >> .gitignore - echo ".pre-commit-config.yaml" >> .gitignore - echo "" >> .gitignore - fi - echo "Done." - - if command -v direnv &> /dev/null; then - echo "direnv is installed. Running direnv allow." - direnv allow - fi - ;; - info) - assemble - ${nix}/bin/nix $NIX_FLAGS flake metadata | ${gnugrep}/bin/grep Inputs -A10000 - echo - ${nix}/bin/nix $NIX_FLAGS eval --raw '.#info' --impure - ;; - update) - assemble - ${nix}/bin/nix $NIX_FLAGS flake update - ;; - version) - echo "devenv: ${version} ${pkgs.stdenv.system}" - ;; - ci) - assemble - ci=$(${nix}/bin/nix $NIX_FLAGS build --no-link --print-out-paths '.#ci' --impure) - add_gc ci $ci - ;; - gc) - SECONDS=0 - - for link in $(${findutils}/bin/find $GC_ROOT -type l); do - if [ ! -f $link ]; then - ${coreutils}/bin/unlink $link - fi - done - - echo "Counting old devenvs ..." - echo - candidates=$(${findutils}/bin/find $GC_ROOT -type l) - - before=$(${nix}/bin/nix $NIX_FLAGS path-info $candidates -r -S --json | ${jq}/bin/jq '[.[].closureSize | tonumber] | add') - - echo "Found $(echo $candidates | ${coreutils}/bin/wc -l) environments of sum size $(( $before / 1024 / 1024 )) MB." - echo - echo "Garbage collecting ..." - echo - echo "Note: If you'd like this command to run much faster, leave a thumbs up at https://github.com/NixOS/nix/issues/7239" - - ${nix}/bin/nix $NIX_FLAGS store delete --recursive $candidates - - # after GC delete links again - for link in $(${findutils}/bin/find $GC_ROOT -type l); do - if [ ! -f $link ]; then - ${coreutils}/bin/unlink $link - fi - done - - echo "Done in $SECONDS seconds." - ;; - *) - echo "https://devenv.sh (version ${version}): Fast, Declarative, Reproducible, and Composable Developer Environments" - echo - echo "Usage: devenv command [options] [arguments]" - echo - echo "Commands:" - echo - echo "init Scaffold devenv.yaml, devenv.nix, and .envrc inside the current directory." - echo "init TARGET Scaffold devenv.yaml, devenv.nix, and .envrc inside TARGET directory." - echo "search NAME Search packages matching NAME in nixpkgs input." - echo "shell Activate the developer environment." - echo "shell CMD [args] Run CMD with ARGS in the developer environment. Useful when scripting." - echo "container [options] NAME Generate a container for NAME. See devenv container --help and http://devenv.sh/containers" - echo "info Print information about the current developer environment." - echo "update Update devenv.lock from devenv.yaml inputs. See http://devenv.sh/inputs/#locking-and-updating-inputs" - echo "up Starts processes in foreground. See http://devenv.sh/processes" - echo "gc Removes old devenv generations. See http://devenv.sh/garbage-collection" - echo "ci Builds your developer environment and make sure all checks pass." - echo "version Display devenv version" - echo - exit 1 - esac -'' diff --git a/src/devenv/__init__.py b/src/devenv/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/src/devenv/cli.py b/src/devenv/cli.py new file mode 100644 index 000000000..bf04ac97a --- /dev/null +++ b/src/devenv/cli.py @@ -0,0 +1,459 @@ +import os +import shutil +import subprocess +import time +import re +from filelock import FileLock +from contextlib import suppress +from pathlib import Path +import pkgutil +import json + +import click +import terminaltables + + +from .yaml import validate_and_parse_yaml +from .log import log, log_task + + +NIX_FLAGS = [ + "--show-trace", + "--extra-experimental-features", + "\"nix-command flakes\"", + "--option", + "warn-dirty", + "false", +] +FILE = pkgutil.get_loader(__package__).load_module(__package__).__file__ +if 'site-packages' in FILE: + SRC_DIR = Path(FILE, '..', '..', 'src') +else: + SRC_DIR = Path(FILE, '..', '..') +MODULES_DIR = (SRC_DIR / 'modules').resolve() +FLAKE_FILE_TEMPL = os.path.join(MODULES_DIR, "flake.tmpl.nix") +FLAKE_FILE = ".devenv.flake.nix" +FLAKE_LOCK = "devenv.lock" + +# define system like x86_64-linux +SYSTEM = os.uname().machine.lower().replace("arm", "aarch") + "-" + os.uname().sysname.lower() + +def run_nix(command: str) -> str: + ctx = click.get_current_context() + nix_flags = ctx.obj['nix_flags'] + flags = " ".join(NIX_FLAGS) + " " + " ".join(nix_flags) + command_flags = " ".join(ctx.obj['command_flags']) + return run_command(f"nix {flags} {command} {command_flags}") + +def run_command(command: str) -> str: + if command.startswith("nix"): + if os.environ.get("DEVENV_NIX"): + nix = os.path.join(os.environ["DEVENV_NIX"], "bin") + command = f"{nix}/{command}" + else: + log("$DEVENV_NIX is not set, but required as devenv doesn't work without a few Nix patches.", level="error") + log("Please follow https://devenv.sh/getting-started/ to install devenv.", level="error") + exit(1) + try: + return subprocess.run( + command, + shell=True, + check=True, + env=os.environ.copy(), + stdout=subprocess.PIPE, + universal_newlines=True).stdout.strip() + except subprocess.CalledProcessError as e: + if e.returncode == 130: + pass # we're exiting the shell + else: + log(f"Following command exited with code {e.returncode}:\n\n {e.cmd}", level="error") + exit(e.returncode) + +CONTEXT_SETTINGS = dict(max_content_width=120) + +@click.group(context_settings=CONTEXT_SETTINGS) +@click.option( + '--nix-flags', '-n', + help='Flags to pass to Nix. See `man nix.conf 5`. Example: --nix-flags "--option bash-prompt >"', + metavar="NIX-FLAGS", + multiple=True) +@click.option( + '--debugger', '-d', + help='Enable Nix debugger.', + is_flag=True) +@click.option( + '--system', '-s', + help='Nix system to use.', + default=SYSTEM) +@click.option( + '--offline', '-o', + help='Disable network access.', + is_flag=True) +@click.option( + '--disable-eval-cache', + help='Disable Nix evaluation cache.', + is_flag=True) +@click.pass_context +def cli(ctx, disable_eval_cache, offline, system, debugger, nix_flags): + """https://devenv.sh: Fast, Declarative, Reproducible, and Composable Developer Environments.""" + ctx.ensure_object(dict) + ctx.obj['system'] = system + ctx.obj['command_flags'] = [] + ctx.obj['nix_flags'] = list(nix_flags) + ctx.obj['nix_flags'] += ['--system', system] + if offline: + ctx.obj['nix_flags'] += ['--offline'] + if debugger: + # ignore-try is needed to avoid catching unrelated errors + ctx.obj['command_flags'] += ['--debugger', '--ignore-try'] + # to avoid confusing errors + disable_eval_cache = True + if disable_eval_cache: + ctx.obj['nix_flags'] += ['--option', 'eval-cache', 'false'] + + if 'XDG_DATA_HOME' not in os.environ: + ctx.obj['gc_root'] = os.path.join(os.environ['HOME'], '.devenv', 'gc') + else: + ctx.obj['gc_root'] = os.path.join(os.environ['XDG_DATA_HOME'], 'devenv', 'gc') + + Path(ctx.obj['gc_root']).mkdir(parents=True, exist_ok=True) + ctx.obj['gc_project'] = os.path.join(ctx.obj['gc_root'], str(int(time.time() * 1000))) + + +def add_gc(name, store_path): + """Register a GC root""" + ctx = click.get_current_context() + run_command(f'nix-store --add-root "{os.environ["DEVENV_GC"]}/{name}" -r {store_path} >/dev/null') + os.symlink(store_path, f'{ctx.obj["gc_project"]}-{name}', True) + + +@cli.command(hidden=True) +@click.pass_context +def assemble(ctx): + if not os.path.exists('devenv.nix'): + log('File devenv.nix does not exist. To get started, run:', level="error") + log(' $ devenv init', level="error") + exit(1) + + DEVENV_DIR = Path(os.getcwd()) / '.devenv' + os.environ['DEVENV_DIR'] = str(DEVENV_DIR) + DEVENV_GC = DEVENV_DIR / 'gc' + os.environ['DEVENV_GC'] = str(DEVENV_GC) + DEVENV_GC.mkdir(parents=True, exist_ok=True) + + if os.path.exists('devenv.yaml'): + validate_and_parse_yaml(DEVENV_DIR) + else: + for file in ['devenv.json', 'flake.json', 'imports.txt']: + file_path = DEVENV_DIR / file + if file_path.exists(): + os.remove(file_path) + + with open(FLAKE_FILE_TEMPL) as f: + flake = f.read() + system = ctx.obj['system'] + + with open(FLAKE_FILE, 'w') as f: + devenv_vars = (f""" + version = "{get_version()}"; + system = "{system}"; + devenv_root = "{os.getcwd()}"; + """) + # replace __DEVENV_VARS__ in flake using regex + flake = re.sub(r'__DEVENV_VARS__', devenv_vars, flake) + f.write(flake) + + +@cli.command( + help="Deletes previous devenv generations. See http://devenv.sh/garbage-collection", + short_help="Deletes previous devenv generations. See http://devenv.sh/garbage-collection", +) +@click.pass_context +def gc(ctx): + GC_ROOTS = ctx.obj['gc_root'] + start = time.time() + + # remove dangling symlinks + with log_task(f'Removing non-existings symlinks in {GC_ROOTS} ...'): + to_gc, removed_symlinks = cleanup_symlinks(GC_ROOTS) + + click.echo(f' Found {len(to_gc)} active symlinks.') + click.echo(f' Deleted {len(removed_symlinks)} dangling symlinks.') + click.echo() + + log(f'Running garbage collection (this process may take some time) ...', level="info") + # TODO: ideally nix would report some statistics about the GC as JSON + run_nix(f'store delete --recursive {" ".join(to_gc)}') + + after_gc, removed_symlinks = cleanup_symlinks(GC_ROOTS) + end = time.time() + + click.echo() + log(f'Done. Successfully removed {len(to_gc) - len(after_gc)} symlinks in {end - start:.0f} seconds.', level="info") + +def cleanup_symlinks(folder): + to_gc = [] + removed_symlinks = [] + for root, dirs, files in os.walk(folder): + for name in files: + full_path = os.path.join(root, name) + if os.path.islink(full_path): + if not os.path.isfile(full_path): + os.unlink(full_path) + removed_symlinks.append(full_path) + else: + to_gc.append(full_path) + return to_gc, removed_symlinks + +def get_dev_environment(ctx, is_shell=False): + ctx.invoke(assemble) + if is_shell: + action = log_task('Building shell') + else: + action = suppress() + with action: + gc_root = os.path.join(os.environ['DEVENV_GC'], 'shell') + env = run_nix(f"print-dev-env --impure --profile '{gc_root}'") + run_command(f"nix-env -p '{gc_root}' --delete-generations old") + symlink_force(Path(f'{ctx.obj["gc_project"]}-shell'), gc_root) + return env, gc_root + + + +@cli.command( + help="Activate the developer environment.", + short_help="Activate the developer environment.", + context_settings=dict( + ignore_unknown_options=True, + ) +) +@click.argument('extra_args', nargs=-1, type=click.UNPROCESSED) +@click.argument('cmd', required=False) +@click.pass_context +def shell(ctx, cmd, extra_args): + env, gc_root = get_dev_environment(ctx, is_shell=True) + if cmd: + run_nix(f"develop '{gc_root}' -c {cmd} {' '.join(extra_args)}") + else: + log('Entering shell', level="info") + run_nix(f"develop '{gc_root}'") + +def symlink_force(src, dst): + # locking is needed until https://github.com/python/cpython/pull/14464 + with FileLock(f"{dst}.lock", timeout=10): + src.unlink(missing_ok=True) + Path(src).symlink_to(dst) + +@cli.command( + help="Starts processes in foreground. See http://devenv.sh/processes", + short_help="Starts processes in foreground. See http://devenv.sh/processes", +) +@click.argument('command', required=False) +@click.pass_context +def up(ctx, command): + with log_task('Building processes'): + ctx.invoke(assemble) + procfilescript = run_nix(f"build --no-link --print-out-paths --impure '.#procfileScript'") + with open(procfilescript, 'r') as file: + contents = file.read().strip() + if contents == '': + log("No 'processes' option defined: https://devenv.sh/processes/", level="error") + exit(1) + else: + log('Starting processes ...', level="info") + add_gc('procfilescript', procfilescript) + # TODO: print output to stdout + #run_command(procfilescript + ' ' + (command or '')) + args = [] if not command else [command] + subprocess.run([procfilescript] + args) + +@cli.command() +@click.argument('name') +@click.pass_context +def search(ctx, name): + """Search packages matching NAME in nixpkgs input.""" + ctx.invoke(assemble) + options = run_nix(f"build --no-link --print-out-paths '.#optionsJSON' --impure") + search = run_nix(f"search --json nixpkgs {name}") + + with open(Path(options) / 'share' / 'doc' / 'nixos' / 'options.json') as f: + options_results = [] + for key, value in json.load(f).items(): + if name in key: + options_results.append(( + key, + value['type'], + value['default'], + value['description'][:80] + )) + results_options_count = len(options_results) + + search_results = [] + for key, value in json.loads(search).items(): + search_results.append( + (".".join(key.split('.')[2:]) + , value['version'] + , value['description'][:80] + ) + ) + search_results_count = len(search_results) + + if search_results: + click.echo( + terminaltables.AsciiTable( + [("Package", "Version", "Description")] + + search_results + ).table + ) + + if options_results: + click.echo( + terminaltables.AsciiTable( + [("Option", "Type", "Default", "Description")] + + options_results + ).table + ) + + log(f"Found {search_results_count} packages and {results_options_count} options for '{name}'.", level="info") + +@cli.command( + help="Build, copy and run a container. See http://devenv.sh/containers", + short_help="Build, copy and run a container. See http://devenv.sh/containers", +) +@click.option('--registry', default=None, help='Registry to copy the container to.', metavar="REGISTRY") +@click.option('--copy', is_flag=True, help='Copy the container to the registry.') +@click.option('--copy-args', default=None, help='Arguments passed to `skopeo copy`.', metavar="ARGS") +@click.option('--docker-run', is_flag=True, help='Execute `docker run`.') +@click.argument('container_name') +@click.pass_context +def container(ctx, registry, copy, copy_args, docker_run, container_name): + os.environ['DEVENV_CONTAINER'] = container_name + + with log_task(f'Building {container_name} container'): + ctx.invoke(assemble) + # NOTE: we need --impure here to read DEVENV_CONTAINER + spec = run_nix(f"build --impure --print-out-paths --no-link .#devenv.containers.\"{container_name}\".derivation") + click.echo(spec) + + # copy container + if copy or docker_run: + with log_task(f'Copying {container_name} container'): + copy_script = run_nix(f"build --print-out-paths --no-link \ + --impure .#devenv.containers.\"{container_name}\".copyScript") + + if docker_run: + registry = "docker-daemon:" + + subprocess.run( + f"{copy_script} {spec} {registry} {copy_args or ''}", + shell=True, + check=True) + + if docker_run: + with log_task(f'Starting {container_name} container'): + docker_script = run_nix(f"build --print-out-paths --no-link --impure \ + .#devenv.containers.\"{container_name}\".dockerRun") + + subprocess.run(docker_script) + +@cli.command( + help="Print information about this developer environment.", + short_help="Print information about this developer environment.", +) +@click.pass_context +def info(ctx): + ctx.invoke(assemble) + # TODO: use --json and reconstruct input metadata + metadata = run_nix("flake metadata") + matches = re.search(r"(Inputs:.+)$", metadata, re.DOTALL) + if matches: + inputs = matches.group(1) + else: + inputs = "" + info_ = run_nix("eval --raw '.#info' --impure") + click.echo(f"{inputs}\n{info_}") + +@cli.command() +@click.pass_context +def version(ctx): + """Display devenv version.""" + version = get_version() + click.echo(f"devenv {version} ({ctx.obj['system']})") + +@cli.command( + help="Scaffold devenv.yaml, devenv.nix, and .envrc.", + short_help="Scaffold devenv.yaml, devenv.nix, and .envrc.", +) +@click.argument('target', default='.') +def init(target): + os.makedirs(target, exist_ok=True) + + required_files = ['devenv.nix', 'devenv.yaml', '.envrc'] + for filename in required_files: + if os.path.exists(Path(target, filename)): + log(f"Aborting since {filename} already exist.", level="error") + exit(1) + return + + example = "simple" + examples_path = Path(MODULES_DIR / ".." / ".." / "examples").resolve() + + for filename in required_files: + full_filename = Path(target, filename) + if not os.path.exists(full_filename): + log(f"Creating {full_filename}", level="info") + shutil.copyfile(os.path.join(examples_path, example, filename), full_filename) + + with open('.gitignore', 'a+') as gitignore_file: + if 'devenv' not in gitignore_file.read(): + log("Appending defaults to .gitignore", level="info") + gitignore_file.write("\n") + gitignore_file.write("# Devenv\n") + gitignore_file.write(".devenv*\n") + gitignore_file.write("devenv.local.nix\n") + gitignore_file.write("\n") + gitignore_file.write("# direnv\n") + gitignore_file.write(".direnv\n") + gitignore_file.write("\n") + gitignore_file.write("# pre-commit\n") + gitignore_file.write(".pre-commit-config.yaml\n") + gitignore_file.write("\n") + + log("Done.", level="info") + + # Check if direnv is installed + if shutil.which('direnv'): + log("direnv is installed. Running $ direnv allow .", level="info") + subprocess.run(['direnv', 'allow']) + +@cli.command( + help="Update devenv.lock from devenv.yaml inputs. See http://devenv.sh/inputs/", + short_help="Update devenv.lock from devenv.yaml inputs. See http://devenv.sh/inputs/", +) +@click.argument('input_name', required=False) +@click.pass_context +def update(ctx, input_name): + ctx.invoke(assemble) + + if input_name: + run_nix(f"flake lock --update-input {input_name}") + else: + run_nix(f"flake update") + +@cli.command() +@click.pass_context +def ci(ctx): + """Builds your developer environment and checks if everything builds.""" + ctx.invoke(assemble) + output_path = run_nix(f"build --no-link --print-out-paths --impure .#ci") + add_gc('ci', output_path) + +@cli.command() +@click.pass_context +def print_dev_env(ctx): + env, _ = get_dev_environment(ctx) + click.echo(env) + +def get_version(): + with open(Path(MODULES_DIR, "latest-version")) as f: + return f.read().strip() diff --git a/src/devenv/log.py b/src/devenv/log.py new file mode 100644 index 000000000..04709e3f4 --- /dev/null +++ b/src/devenv/log.py @@ -0,0 +1,31 @@ +from typing import Literal + +import click + + +class log_task: + """Context manager for logging progress of a task.""" + def __init__(self, message,): + self.message = message + + def __enter__(self): + prefix = click.style("•", fg="blue") + click.echo(f"{prefix} {self.message} ...", nl=False) + + def __exit__(self, exc, *args): + if exc: + prefix = click.style("✖", fg="red") + else: + prefix = click.style("✔", fg="green") + click.echo(f"\r{prefix} {self.message}") + +LogLevel = Literal["info", "warning", "error"] + +def log(message, level: LogLevel): + match level: + case "info": + click.echo(click.style("• ", fg="green") + message) + case "warning": + click.echo(click.style("• ", fg="yellow") + message, err=True) + case "error": + click.echo(click.style("✖ ", fg="red") + message, err=True) diff --git a/src/devenv/yaml.py b/src/devenv/yaml.py new file mode 100644 index 000000000..b43582baa --- /dev/null +++ b/src/devenv/yaml.py @@ -0,0 +1,44 @@ +import json +import sys +import os +from pathlib import Path + +from strictyaml import Map, MapPattern, Str, Seq +from strictyaml import load, Bool, Any, Optional, YAMLError + + +inputsSchema = MapPattern(Str(), Map({ + "url": Str(), + Optional("flake", default=None): Bool(), + Optional("inputs", default=None): Any(), + Optional("overlays", default=None): Seq(Str()) +})) + +schema = Map({ + Optional("inputs", default=None): inputsSchema, + Optional("allowUnfree", default=False): Bool(), + Optional("imports", default=None): Seq(Str()), + Optional("permittedInsecurePackages", default=None): Seq(Str()) +}) + +def validate_and_parse_yaml(dot_devenv_root): + try: + with open(Path("devenv.yaml")) as f: + devenv = load(f.read(), schema, label="devenv.yaml").data + except YAMLError as error: + print("Validation error in `devenv.yaml`", error) + sys.exit(1) + + inputs = {} + for input, attrs in devenv.get('inputs', {}).items(): + inputs[input] = {k: attrs[k] for k in ('url', 'inputs', 'flake') + if k in attrs} + + with open(os.path.join(dot_devenv_root, "flake.json"), 'w') as f: + f.write(json.dumps(inputs)) + + with open(os.path.join(dot_devenv_root, "devenv.json"), 'w') as f: + f.write(json.dumps(devenv)) + + with open(os.path.join(dot_devenv_root, "imports.txt"), 'w') as f: + f.write("\n".join(devenv.get('imports', []))) \ No newline at end of file diff --git a/src/flake.nix b/src/flake.nix deleted file mode 100644 index 970585903..000000000 --- a/src/flake.nix +++ /dev/null @@ -1,85 +0,0 @@ -{ pkgs, version }: pkgs.writeText "devenv-flake" '' - { - inputs = { - pre-commit-hooks.url = "github:cachix/pre-commit-hooks.nix"; - pre-commit-hooks.inputs.nixpkgs.follows = "nixpkgs"; - nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; - devenv.url = "github:cachix/devenv?dir=src/modules"; - } // (if builtins.pathExists ./.devenv/flake.json - then builtins.fromJSON (builtins.readFile ./.devenv/flake.json) - else {}); - - outputs = { nixpkgs, ... }@inputs: - let - devenv = if builtins.pathExists ./.devenv/devenv.json - then builtins.fromJSON (builtins.readFile ./.devenv/devenv.json) - else {}; - getOverlays = inputName: inputAttrs: - map (overlay: let - input = inputs.''${inputName} or (throw "No such input `''${inputName}` while trying to configure overlays."); - in input.overlays.''${overlay} or (throw "Input `''${inputName}` has no overlay called `''${overlay}`. Supported overlays: ''${nixpkgs.lib.concatStringsSep ", " (builtins.attrNames input.overlays)}")) - inputAttrs.overlays or []; - overlays = nixpkgs.lib.flatten (nixpkgs.lib.mapAttrsToList getOverlays (devenv.inputs or {})); - pkgs = import nixpkgs { - system = "${pkgs.stdenv.system}"; - config = { - allowUnfree = devenv.allowUnfree or false; - permittedInsecurePackages = devenv.permittedInsecurePackages or []; - }; - inherit overlays; - }; - lib = pkgs.lib; - importModule = path: - if lib.hasPrefix "./" path - then if lib.hasSuffix ".nix" path - then ./. + (builtins.substring 1 255 path) - else ./. + (builtins.substring 1 255 path) + "/devenv.nix" - else if lib.hasPrefix "../" path - then throw "devenv: ../ is not supported for imports" - else let - paths = lib.splitString "/" path; - name = builtins.head paths; - input = inputs.''${name} or (throw "Unknown input ''${name}"); - subpath = "/''${lib.concatStringsSep "/" (builtins.tail paths)}"; - devenvpath = "''${input}" + subpath + "/devenv.nix"; - in if builtins.pathExists devenvpath - then devenvpath - else throw (devenvpath + " file does not exist for input ''${name}."); - project = pkgs.lib.evalModules { - specialArgs = inputs // { inherit inputs pkgs; }; - modules = [ - (inputs.devenv.modules + /top-level.nix) - { devenv.cliVersion = "${version}"; } - ] ++ (map importModule (devenv.imports or [])) ++ [ - ./devenv.nix - (devenv.devenv or {}) - (if builtins.pathExists ./devenv.local.nix then ./devenv.local.nix else {}) - ]; - }; - config = project.config; - - options = pkgs.nixosOptionsDoc { - options = builtins.removeAttrs project.options [ "_module" ]; - # Unpack Nix types, e.g. literalExpression, mDoc. - transformOptions = - let isDocType = v: builtins.elem v [ "literalDocBook" "literalExpression" "literalMD" "mdDoc" ]; - in lib.attrsets.mapAttrs (_: v: - if v ? _type && isDocType v._type then - v.text - else if v ? _type && v._type == "derivation" then - v.name - else - v - ); - }; - in { - packages."${pkgs.stdenv.system}" = { - optionsJSON = options.optionsJSON; - inherit (config) info procfileScript procfileEnv procfile; - ci = config.ciDerivation; - }; - devenv.containers = config.containers; - devShell."${pkgs.stdenv.system}" = config.shell; - }; - } -'' diff --git a/src/modules/flake.tmpl.nix b/src/modules/flake.tmpl.nix new file mode 100644 index 000000000..cbb8ac88c --- /dev/null +++ b/src/modules/flake.tmpl.nix @@ -0,0 +1,91 @@ +{ + inputs = { + pre-commit-hooks.url = "github:cachix/pre-commit-hooks.nix"; + pre-commit-hooks.inputs.nixpkgs.follows = "nixpkgs"; + nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; + devenv.url = "github:cachix/devenv?dir=src/modules"; + } // (if builtins.pathExists ./.devenv/flake.json + then builtins.fromJSON (builtins.readFile ./.devenv/flake.json) + else { }); + + outputs = { nixpkgs, ... }@inputs: + let + __DEVENV_VARS__ + devenv = + if builtins.pathExists ./.devenv/devenv.json + then builtins.fromJSON (builtins.readFile ./.devenv/devenv.json) + else { }; + getOverlays = inputName: inputAttrs: + map + (overlay: + let + input = inputs.${inputName} or (throw "No such input `${inputName}` while trying to configure overlays."); + in + input.overlays.${overlay} or (throw "Input `${inputName}` has no overlay called `${overlay}`. Supported overlays: ${nixpkgs.lib.concatStringsSep ", " (builtins.attrNames input.overlays)}")) + inputAttrs.overlays or [ ]; + overlays = nixpkgs.lib.flatten (nixpkgs.lib.mapAttrsToList getOverlays (devenv.inputs or { })); + pkgs = import nixpkgs { + inherit system; + config = { + allowUnfree = devenv.allowUnfree or false; + permittedInsecurePackages = devenv.permittedInsecurePackages or [ ]; + }; + inherit overlays; + }; + lib = pkgs.lib; + importModule = path: + if lib.hasPrefix "./" path + then if lib.hasSuffix ".nix" path + then ./. + (builtins.substring 1 255 path) + else ./. + (builtins.substring 1 255 path) + "/devenv.nix" + else if lib.hasPrefix "../" path + then throw "devenv: ../ is not supported for imports" + else + let + paths = lib.splitString "/" path; + name = builtins.head paths; + input = inputs.${name} or (throw "Unknown input ${name}"); + subpath = "/${lib.concatStringsSep "/" (builtins.tail paths)}"; + devenvpath = "${input}" + subpath + "/devenv.nix"; + in + if builtins.pathExists devenvpath + then devenvpath + else throw (devenvpath + " file does not exist for input ${name}."); + project = pkgs.lib.evalModules { + specialArgs = inputs // { inherit inputs pkgs; }; + modules = [ + (inputs.devenv.modules + /top-level.nix) + { devenv.cliVersion = "${version}"; } + ] ++ (map importModule (devenv.imports or [ ])) ++ [ + ./devenv.nix + (devenv.devenv or { }) + (if builtins.pathExists ./devenv.local.nix then ./devenv.local.nix else { }) + ]; + }; + config = project.config; + + options = pkgs.nixosOptionsDoc { + options = builtins.removeAttrs project.options [ "_module" ]; + # Unpack Nix types, e.g. literalExpression, mDoc. + transformOptions = + let isDocType = v: builtins.elem v [ "literalDocBook" "literalExpression" "literalMD" "mdDoc" ]; + in lib.attrsets.mapAttrs (_: v: + if v ? _type && isDocType v._type then + v.text + else if v ? _type && v._type == "derivation" then + v.name + else + v + ); + }; + in + { + packages."${system}" = { + optionsJSON = options.optionsJSON; + inherit (config) info procfileScript procfileEnv procfile; + ci = config.ciDerivation; + }; + devenv.containers = config.containers; + devShell."${system}" = config.shell; + }; +} From c81069c83ab242dd831e74a992c1d38d32b77d14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Thu, 27 Jul 2023 14:06:46 +0100 Subject: [PATCH 006/146] devenv inputs add --- src/devenv/cli.py | 35 +++++++++++++++++++++++++++++++- src/devenv/yaml.py | 15 +++++++++++--- src/modules/containers.nix | 25 ++++++++++++----------- src/modules/devenv-lib.nix | 27 ++++++++++++++++++++++++ src/modules/languages/gleam.nix | 32 ++--------------------------- src/modules/languages/php.nix | 18 ++++++++-------- src/modules/languages/python.nix | 14 ++++++------- src/modules/languages/ruby.nix | 18 ++++++++-------- src/modules/languages/rust.nix | 22 +++++++++----------- src/modules/latest-version | 2 +- 10 files changed, 122 insertions(+), 86 deletions(-) create mode 100644 src/modules/devenv-lib.nix diff --git a/src/devenv/cli.py b/src/devenv/cli.py index bf04ac97a..6031ea449 100644 --- a/src/devenv/cli.py +++ b/src/devenv/cli.py @@ -13,7 +13,7 @@ import terminaltables -from .yaml import validate_and_parse_yaml +from .yaml import validate_and_parse_yaml, read_yaml, write_yaml from .log import log, log_task @@ -66,6 +66,7 @@ def run_command(command: str) -> str: if e.returncode == 130: pass # we're exiting the shell else: + click.echo("\n", err=True) log(f"Following command exited with code {e.returncode}:\n\n {e.cmd}", level="error") exit(e.returncode) @@ -457,3 +458,35 @@ def print_dev_env(ctx): def get_version(): with open(Path(MODULES_DIR, "latest-version")) as f: return f.read().strip() + +@cli.group( + help="Manage inputs in devenv.yaml. See http://devenv.sh/inputs/", + short_help="Manage inputs in devenv.yaml. See http://devenv.sh/inputs/" +) +def inputs(): + pass + +@inputs.command( + help="Add a new input to the developer environment.", + short_help="Add a new input to the developer environment.", +) +@click.argument('name') +@click.argument('url') +@click.option('--follows', '-f', multiple=True, help='Add a dependency to the input.') +@click.pass_context +def add(ctx, name, url, follows): + devenv = read_yaml() + attrs = {'url': url} + + inputs = {} + for follow in follows: + if follow not in devenv['inputs']: + log(f"Input {follow} does not exist so it can't be followed.", level="error") + exit(1) + inputs[follow] = {"follows": follow} + + if inputs: + attrs['inputs'] = inputs + devenv['inputs'][name] = attrs + + write_yaml(devenv) \ No newline at end of file diff --git a/src/devenv/yaml.py b/src/devenv/yaml.py index b43582baa..434f340fc 100644 --- a/src/devenv/yaml.py +++ b/src/devenv/yaml.py @@ -21,14 +21,23 @@ Optional("permittedInsecurePackages", default=None): Seq(Str()) }) -def validate_and_parse_yaml(dot_devenv_root): +YAML_FILE = Path("devenv.yaml") + +def read_yaml(): try: - with open(Path("devenv.yaml")) as f: - devenv = load(f.read(), schema, label="devenv.yaml").data + with open(YAML_FILE) as f: + return load(f.read(), schema, label="devenv.yaml") except YAMLError as error: print("Validation error in `devenv.yaml`", error) sys.exit(1) +def write_yaml(yaml): + with open(YAML_FILE, "w") as f: + f.write(yaml.as_yaml()) + +def validate_and_parse_yaml(dot_devenv_root): + devenv = read_yaml().data + inputs = {} for input, attrs in devenv.get('inputs', {}).items(): inputs[input] = {k: attrs[k] for k in ('url', 'inputs', 'flake') diff --git a/src/modules/containers.nix b/src/modules/containers.nix index 6273993a9..167e0ffdb 100644 --- a/src/modules/containers.nix +++ b/src/modules/containers.nix @@ -5,21 +5,22 @@ let if config.name == null then throw ''You need to set `name = "myproject";` or `containers.${name}.name = "mycontainer"; to be able to generate a container.'' else config.name; - setup = '' - inputs: - nix2container: - url: github:nlewo/nix2container - inputs: - nixpkgs: - follows: nixpkgs - mk-shell-bin: - url: github:rrbutani/nix-mk-shell-bin - ''; types = lib.types; envContainerName = builtins.getEnv "DEVENV_CONTAINER"; - nix2containerInput = inputs.nix2container or (throw "To build the container, you need to add the following to your devenv.yaml:\n\n${setup}"); + devenvlib = import ./devenv-lib.nix { inherit pkgs config inputs lib; }; + + nix2containerInput = devenvlib.getInput { + name = "nix2container"; + url = "github:nlewo/nix2container"; + attribute = "containers"; + follows = [ "nixpkgs" ]; + }; nix2container = nix2containerInput.packages.${pkgs.stdenv.system}; - mk-shell-bin = inputs.mk-shell-bin or (throw "To build the container, you need to add the following to your devenv.yaml:\n\n${setup}"); + mk-shell-bin = devenvlib.getInput { + name = "mk-shell-bin"; + url = "github:rrbutani/nix-mk-shell-bin"; + attribute = "containers"; + }; shell = mk-shell-bin.lib.mkShellBin { drv = config.shell; nixpkgs = pkgs; }; mkEntrypoint = cfg: pkgs.writeScript "entrypoint" '' #!${pkgs.bash}/bin/bash diff --git a/src/modules/devenv-lib.nix b/src/modules/devenv-lib.nix new file mode 100644 index 000000000..0dee070f5 --- /dev/null +++ b/src/modules/devenv-lib.nix @@ -0,0 +1,27 @@ +{ pkgs, lib, config, inputs }: + +{ + getInput = { name, url, attribute, follows ? [ ] }: + let + flags = lib.concatStringsSep " " (map (i: "--follows ${i}") follows); + yaml_follows = lib.concatStringsSep "\n " (map (i: "${i}:\n follows: ${i}") follows); + command = + if lib.versionAtLeast config.devenv.cliVersion "1.0" + then '' + run the following command: + + $ devenv inputs add ${name} ${url} ${flags} + '' + else '' + add the following to your devenv.yaml: + + ✨ devenv 1.0 made this easier: https://devenv.sh/getting-started/#installation ✨ + + inputs: + ${name}: + url: ${url} + ${if follows != [] then "inputs:\n ${yaml_follows}" else ""} + ''; + in + inputs.${name} or (throw "To use '${attribute}', ${command}\n\n"); +} diff --git a/src/modules/languages/gleam.nix b/src/modules/languages/gleam.nix index d96f8446c..ae8f14217 100644 --- a/src/modules/languages/gleam.nix +++ b/src/modules/languages/gleam.nix @@ -1,35 +1,7 @@ -{ pkgs, config, lib, inputs, ... }: +{ pkgs, config, lib, ... }: let cfg = config.languages.gleam; - - setup = '' - To use gleam, you need to add the following to your devenv.yaml: - - inputs: - gleam-nix: - url: github:vic/gleam-nix - overlays: - - default - - - Optionally, if you want a specific gleam branch or version, do - the following: - - inputs: - gleam: - url: github:gleam-lang/gleam/main # or any other branch - flake: false - gleam-nix: - url: github:vic/gleam-nix - overlays: - - default - inputs: - gleam = "gleam" - ''; - - gleamPkg = pkgs.gleam or (throw setup); - in { options.languages.gleam = { @@ -37,7 +9,7 @@ in package = lib.mkOption { type = lib.types.package; - default = gleamPkg; + default = pkgs.gleam; description = "The Gleam package to use."; defaultText = lib.literalExpression "pkgs.gleam"; }; diff --git a/src/modules/languages/php.nix b/src/modules/languages/php.nix index fbac9d530..8098d37a9 100644 --- a/src/modules/languages/php.nix +++ b/src/modules/languages/php.nix @@ -3,20 +3,18 @@ with lib; let - inherit (lib.attrsets) attrValues genAttrs; + inherit (lib.attrsets) attrValues; cfg = config.languages.php; - setup = '' - inputs: - phps: - url: github:fossar/nix-phps - inputs: - nixpkgs: - follows: nixpkgs - ''; + devenvlib = import ../devenv-lib.nix { inherit pkgs config inputs lib; }; - phps = inputs.phps or (throw "To use languages.php.version, you need to add the following to your devenv.yaml:\n\n${setup}"); + phps = devenvlib.getInput { + name = "phps"; + url = "github:fossar/nix-phps"; + attribute = "languages.php.version"; + follows = [ "nixpkgs" ]; + }; filterDefaultExtensions = ext: builtins.length (builtins.filter (inner: inner == ext.extensionName) cfg.disableExtensions) == 0; diff --git a/src/modules/languages/python.nix b/src/modules/languages/python.nix index 10a8e9792..16a0ec5dd 100644 --- a/src/modules/languages/python.nix +++ b/src/modules/languages/python.nix @@ -2,20 +2,20 @@ let cfg = config.languages.python; - + requirements = pkgs.writeText "requirements.txt" ( if lib.isPath cfg.venv.requirements then builtins.readFile cfg.venv.requirements else cfg.venv.requirements ); - nixpkgs-python = inputs.nixpkgs-python or (throw '' - To use languages.python.version, you need to add the following to your devenv.yaml: + devenvlib = import ../devenv-lib.nix { inherit pkgs config inputs lib; }; - inputs: - nixpkgs-python: - url: github:cachix/nixpkgs-python - ''); + nixpkgs-python = devenvlib.getInput { + name = "nixpkgs-python"; + url = "github:cachix/nixpkgs-python"; + attribute = "languages.python.version"; + }; initVenvScript = pkgs.writeShellScript "init-venv.sh" '' # Make sure any tools are not attempting to use the python interpreter from any diff --git a/src/modules/languages/ruby.nix b/src/modules/languages/ruby.nix index 9e745f858..cbf41644a 100644 --- a/src/modules/languages/ruby.nix +++ b/src/modules/languages/ruby.nix @@ -3,16 +3,14 @@ let cfg = config.languages.ruby; - nixpkgs-ruby = inputs.nixpkgs-ruby or (throw '' - To use languages.ruby.version or languages.ruby.versionFile, you need to add the following to your devenv.yaml: - - inputs: - nixpkgs-ruby: - url: github:bobvanderlinden/nixpkgs-ruby - inputs: - nixpkgs: - follows: nixpkgs - ''); + devenvlib = import ../devenv-lib.nix { inherit pkgs config inputs lib; }; + + nixpkgs-ruby = devenvlib.getInput { + name = "nixpkgs-ruby"; + url = "github:bobvanderlinden/nixpkgs-ruby"; + attribute = "languages.ruby.version or languages.ruby.versionFile"; + follows = [ "nixpkgs" ]; + }; in { options.languages.ruby = { diff --git a/src/modules/languages/rust.nix b/src/modules/languages/rust.nix index 4d88f710d..1db14c5f1 100644 --- a/src/modules/languages/rust.nix +++ b/src/modules/languages/rust.nix @@ -2,16 +2,16 @@ let cfg = config.languages.rust; - setup = '' - inputs: - fenix: - url: github:nix-community/fenix - inputs: - nixpkgs: - follows: nixpkgs - ''; - error = dbg: "To use languages.rust.${dbg}, you need to add the following to your devenv.yaml:\n\n${setup}"; + devenvlib = import ../devenv-lib.nix { inherit pkgs config inputs lib; }; + + fenix = devenvlib.getInput { + name = "fenix"; + url = "github:nix-community/fenix"; + attribute = "languages.rust.version"; + follows = [ "nixpkgs" ]; + }; + in { imports = [ @@ -104,9 +104,7 @@ in }) (lib.mkIf (cfg.channel != "nixpkgs") ( let - err = error "channel"; - fenix = inputs.fenix or (throw err); - rustPackages = fenix.packages.${pkgs.stdenv.system} or (throw err); + rustPackages = fenix.packages.${pkgs.stdenv.system}; in { languages.rust.toolchain = diff --git a/src/modules/latest-version b/src/modules/latest-version index 844f6a91a..d3827e75a 100644 --- a/src/modules/latest-version +++ b/src/modules/latest-version @@ -1 +1 @@ -0.6.3 +1.0 From cf9d1229b814ac8d6aa2014a0ed9d6cd8d09e111 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Thu, 27 Jul 2023 14:10:32 +0100 Subject: [PATCH 007/146] cli --- .envrc | 2 +- .github/workflows/buildtest.yml | 8 +- devenv.lock | 12 +- devenv.nix | 51 +--- devenv.yaml | 4 +- docs/binary-caching.md | 34 +++ docs/community/contributing.md | 17 +- docs/tests.md | 55 ++++ examples/clickhouse/.test.sh | 17 +- examples/clickhouse/devenv.nix | 2 +- examples/mailpit/.test.sh | 10 - examples/minio/.test.sh | 13 +- examples/mysql/.test.sh | 13 +- examples/overlays/devenv.nix | 8 +- examples/overlays/devenv.yaml | 4 + examples/overlays/subflake/flake.nix | 7 + examples/postgres/.test.sh | 4 - examples/rubyonrails/.test.sh | 14 +- examples/rubyonrails/Gemfile | 8 - examples/rubyonrails/devenv.nix | 7 +- examples/temporal/.test.sh | 16 +- examples/vault/.test.sh | 18 +- mkdocs.yml | 2 + poetry.lock | 34 +-- pyproject.toml | 1 + src/devenv/cli.py | 424 ++++++++++++++++++++++----- src/devenv/log.py | 26 +- src/devenv/yaml.py | 16 +- src/modules/cachix.nix | 30 ++ src/modules/containers.nix | 7 +- src/modules/devenv-lib.nix | 27 -- src/modules/flake.tmpl.nix | 7 +- src/modules/languages/php.nix | 6 +- src/modules/languages/python.nix | 18 +- src/modules/languages/ruby.nix | 6 +- src/modules/languages/rust.nix | 7 +- src/modules/lib.nix | 53 ++++ src/modules/mkNakedShell.nix | 140 --------- src/modules/tests.nix | 60 ++++ src/modules/top-level.nix | 86 ++++-- tests/cli/.test.sh | 2 + tests/cli/devenv.nix | 3 + 42 files changed, 797 insertions(+), 482 deletions(-) create mode 100644 docs/binary-caching.md create mode 100644 docs/tests.md create mode 100644 examples/overlays/subflake/flake.nix delete mode 100644 examples/rubyonrails/Gemfile create mode 100644 src/modules/cachix.nix delete mode 100644 src/modules/devenv-lib.nix create mode 100644 src/modules/lib.nix delete mode 100644 src/modules/mkNakedShell.nix create mode 100644 src/modules/tests.nix create mode 100755 tests/cli/.test.sh create mode 100644 tests/cli/devenv.nix diff --git a/.envrc b/.envrc index e207b3c3b..53b74fc41 100755 --- a/.envrc +++ b/.envrc @@ -6,4 +6,4 @@ set -euo pipefail # External users should use `source_url` to load this file source_env ./direnvrc -use devenv +use devenv \ No newline at end of file diff --git a/.github/workflows/buildtest.yml b/.github/workflows/buildtest.yml index 51ac2834c..7283c3064 100644 --- a/.github/workflows/buildtest.yml +++ b/.github/workflows/buildtest.yml @@ -72,12 +72,12 @@ jobs: authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}' - run: | nix profile remove '.*' - nix profile install --accept-flake-config . "nixpkgs#gawk" + nix profile install --accept-flake-config . - name: Disable package aliases run: | mkdir -p ~/.config/nixpkgs echo '{ allowAliases = false; }' > ~/.config/nixpkgs/config.nix - - run: devenv shell devenv-test-example ${{ matrix.example }} + - run: devenv test ${{ matrix.example }} direnv: name: direnv (${{ join(matrix.os) }}) needs: build @@ -97,7 +97,7 @@ jobs: authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}' - run: | mv ./examples/simple/devenv.yaml ./examples/simple/devenv.yaml.orig - awk ' + nix run nixpkgs#gawk -- ' { print } /^inputs:$/ { print " devenv:"; @@ -105,7 +105,7 @@ jobs: } ' ./examples/simple/devenv.yaml.orig > ./examples/simple/devenv.yaml nix profile remove '.*' - nix profile install . 'nixpkgs#direnv' nix profile install --accept-flake-config + nix profile install . 'nixpkgs#direnv' mkdir -p ~/.config/direnv/ cat > ~/.config/direnv/direnv.toml << 'EOF' [global] diff --git a/devenv.lock b/devenv.lock index 025c4a7e8..5f7d4f8f5 100644 --- a/devenv.lock +++ b/devenv.lock @@ -107,11 +107,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1701693815, - "narHash": "sha256-7BkrXykVWfkn6+c1EhFA3ko4MLi3gVG0p9G96PNnKTM=", + "lastModified": 1690952720, + "narHash": "sha256-fPsiQHARfhVxXpWgcuSKvkYwSco8K13K7XevBpdIfPg=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "09ec6a0881e1a36c29d67497693a67a16f4da573", + "rev": "96112a3ed5d12bb1758b42c63b924c004b6c0bc9", "type": "github" }, "original": { @@ -164,11 +164,11 @@ "nixpkgs-stable": "nixpkgs-stable" }, "locked": { - "lastModified": 1700922917, - "narHash": "sha256-ej2fch/T584b5K9sk1UhmZF7W6wEfDHuoUYpFN8dtvM=", + "lastModified": 1690743255, + "narHash": "sha256-dsJzQsyJGWCym1+LMyj2rbYmvjYmzeOrk7ypPrSFOPo=", "owner": "cachix", "repo": "pre-commit-hooks.nix", - "rev": "e5ee5c5f3844550c01d2131096c7271cec5e9b78", + "rev": "fcbf4705d98398d084e6cb1c826a0b90a91d22d7", "type": "github" }, "original": { diff --git a/devenv.nix b/devenv.nix index f0ad2c025..b9197e319 100644 --- a/devenv.nix +++ b/devenv.nix @@ -1,14 +1,15 @@ { inputs, pkgs, lib, config, ... }: { - env = { - DEVENV_NIX = inputs.nix.packages.${pkgs.stdenv.system}.nix; - }; + env.DEVENV_NIX = inputs.nix.packages.${pkgs.stdenv.system}.nix; + # TODO: manylinux for python + env.LD_LIBRARY_PATH = config.devenv.dotfile + "/profile/lib"; packages = [ pkgs.cairo pkgs.xorg.libxcb pkgs.yaml2json + pkgs.tesh ]; languages.nix.enable = true; @@ -43,7 +44,11 @@ tmp="$(mktemp -d)" devenv init "$tmp" pushd "$tmp" + echo -e " devenv:\n url: path:${config.devenv.root}/src/modules" >> devenv.yaml + cat devenv.yaml + devenv version devenv ci + devenv test popd rm -rf "$tmp" @@ -81,43 +86,6 @@ popd rm -rf "$tmp" ''; - scripts.devenv-test-all-examples.exec = '' - for dir in $(ls examples); do - devenv-test-example $dir - done - ''; - scripts.devenv-test-example.exec = '' - # execute all trap_ function on exit - trap 'eval $(declare -F | grep -o "trap_[^ ]*" | tr "\n" ";")' EXIT - - set -e - example="$PWD/examples/$1" - pushd $example - mv devenv.yaml devenv.yaml.orig - awk ' - { print } - /^inputs:$/ { - print " devenv:"; - print " url: path:../../src/modules"; - } - ' devenv.yaml.orig > devenv.yaml - trap_restore_yaml() { - mv "$example/devenv.yaml.orig" "$example/devenv.yaml" - } - devenv ci - if [ -f .test.sh ]; then - trap_restore_local() { - rm "$example/devenv.local.nix" - rm -rf "$example/.devenv" - } - # coreutils-full provides timeout on darwin - echo "{ pkgs, ... }: { packages = [ pkgs.coreutils-full ]; }" > devenv.local.nix - devenv shell ./.test.sh - else - devenv shell ls - fi - popd - ''; scripts."devenv-generate-doc-options".exec = '' set -e options=$(nix build --impure --extra-experimental-features 'flakes nix-command' --show-trace --print-out-paths --no-link '.#devenv-docs-options') @@ -161,4 +129,7 @@ MD033 = false; MD034 = false; }; + + tests = config.lib.mkTests ./examples + // config.lib.mkTests ./tests; } diff --git a/devenv.yaml b/devenv.yaml index d759fba2c..9cbe87bf5 100644 --- a/devenv.yaml +++ b/devenv.yaml @@ -5,11 +5,11 @@ inputs: url: github:domenkozar/nix/relaxed-flakes inputs: nixpkgs: - follows: "nixpkgs" + follows: nixpkgs devenv: url: path:./src/modules pre-commit-hooks: url: github:cachix/pre-commit-hooks.nix inputs: nixpkgs: - follows: "nixpkgs" \ No newline at end of file + follows: nixpkgs diff --git a/docs/binary-caching.md b/docs/binary-caching.md new file mode 100644 index 000000000..2189e01db --- /dev/null +++ b/docs/binary-caching.md @@ -0,0 +1,34 @@ +Typically [packages](./packages.md) come prebuilt with binaries provided by [the official binary cache](https://cache.nixos.org). + +If you're modifying a package or using a package that's not built upstream, +Nix will build it from source instead of downloading a binary. + +To prevent packages from being built more than once, there's seamless integration with +binary caches using [Cachix](https://cachix.org). + +## Setup + +If you'd like to push binaries to your own cache, you'll need [to create one](https://app.cachix.org/cache). + +After that you'll need to set `cachix authtoken XXX` with either [a personal auth token](https://app.cachix.org/personal-auth-tokens) or a cache token (that you can create in cache settings). + +## devenv.nix + +To specify `pre-commit-hooks` as a cache to pull from and `mycache` to pull from and push to: + +```nix title="devenv.nix" +{ + cachix.pull = [ "pre-commit-hooks" ]; + cachix.push = "mycache"; +} +``` + +# Pushing only in specific cases + +You'll likely not want every user to push to the cache. + +It's usually convenient to push [explicitly](./files-and-variables/#devenvlocalnix), for example as part of CI run: + +```shell-session +$ echo '{ cachix.push = "mycache"; }' > devenv.local.nix +``` \ No newline at end of file diff --git a/docs/community/contributing.md b/docs/community/contributing.md index 971fc75eb..ffe18bf4a 100644 --- a/docs/community/contributing.md +++ b/docs/community/contributing.md @@ -6,28 +6,23 @@ We have a rule that new features need to come with documentation and tests (`dev ## Preparing the `devenv` development environment -1. Follow the [installation instructions for Nix and Cachix](../../getting-started/#installation). +1. Follow the [installation instructions for Nix and Cachix](../../getting-started/#installation) and [install direnv](../../automatic-shell-activation/). 2. `git clone https://github.com/cachix/devenv.git` 3. `cd devenv` -4. To build the project, run `nix-build`. - -5. `./result/bin/devenv shell` - -6. Once you have made changes, run `./result/bin/devenv shell` again. - -To automate this workflow, [install and use direnv](../../automatic-shell-activation/). +4. To build the project, run `direnv allow .`. ## Repository structure -- The `devenv` CLI is in `src/devenv.nix`. -- The `flake.nix` auto-generation logic lies in `src/flake.nix`. +- The `devenv` CLI is in `src/devenv/cli.py`. +- The `flake.nix` auto-generation logic lies in `src/modules/flake.tmpl.nix`. - All modules related to `devenv.nix` are in `src/modules/`. -- Examples are automatically tested on CI and are the best way to work on developing new modules, see `examples/`. +- Examples are automatically tested on CI and are the best way to work on developing new modules, see `examples/` and `tests/` - Documentation is in `docs/`. - To run a development server, run `devenv up`. +- To run a test, run `devnenv test `. ## Contributing language improvements diff --git a/docs/tests.md b/docs/tests.md new file mode 100644 index 000000000..6c1f53ff7 --- /dev/null +++ b/docs/tests.md @@ -0,0 +1,55 @@ +To ease testing of your environments, +we provide a way to define the tests and to run them. + +## Writing devenv tests + +A simple test would look like: + +```nix title="devenv.nix" +{ pkgs, ... }: { + tests.basic = { + nix = '' + { pkgs, ... }: { + packages = [ pkgs.ncdu ]; + } + ''; + test = '' + ncdu --version | grep "ncdu 2.2" + ''; + }; +} +``` + +```shell-session +$ devenv test +✔ Gathering tests in 0.3s. +• Found 1 test(s), running 1: +• Testing basic ... +• Running $ devenv ci +• Running .test.sh. +✔ Running basic in 16.7s. +``` + +## Defining tests in a folder + +A simple test with a test script: + +```shell-session +$ ls tests/mytest/ +.test.sh devenv.nix devenv.yaml +``` + +Define tests: + +```nix title="devenv.nix" +{ config, ... }: { + tests = config.lib.mkTests ./tests; +} +``` + +Run tests: + +```shell-session +$ devenv test +... +``` \ No newline at end of file diff --git a/examples/clickhouse/.test.sh b/examples/clickhouse/.test.sh index 2591599e4..723bab881 100755 --- a/examples/clickhouse/.test.sh +++ b/examples/clickhouse/.test.sh @@ -1,18 +1,5 @@ -#!/usr/bin/env bash - -set -ex - -devenv up & -DEVENV_PID=$! -export DEVENV_PID - -devenv_stop() { - pkill -P "$DEVENV_PID" -} - -trap devenv_stop EXIT - +set -xe timeout 20 bash -c 'until echo > /dev/tcp/localhost/9000; do sleep 0.5; done' sleep 2 -clickhouse-client --query "SELECT 1" +clickhouse-client --query "SELECT 1" \ No newline at end of file diff --git a/examples/clickhouse/devenv.nix b/examples/clickhouse/devenv.nix index 1ff391f49..e464a3732 100644 --- a/examples/clickhouse/devenv.nix +++ b/examples/clickhouse/devenv.nix @@ -4,7 +4,7 @@ services.clickhouse = { enable = true; config = '' - http_port: 9050 + # http_port: 8123 ''; }; } diff --git a/examples/mailpit/.test.sh b/examples/mailpit/.test.sh index 4ff1ba4ce..812751e5f 100755 --- a/examples/mailpit/.test.sh +++ b/examples/mailpit/.test.sh @@ -1,16 +1,6 @@ #!/usr/bin/env bash set -ex -devenv up & -DEVENV_PID=$! -export DEVENV_PID - -function stop() { - pkill -P "$DEVENV_PID" -} - -trap stop EXIT - timeout 20 bash -c 'until echo > /dev/tcp/localhost/1025; do sleep 0.5; done' sendmail john@example.com < /dev/tcp/localhost/9000; do sleep 0.5; done' - -mc admin info local +mc admin info local \ No newline at end of file diff --git a/examples/mysql/.test.sh b/examples/mysql/.test.sh index 5b42ae290..7bdadcb31 100755 --- a/examples/mysql/.test.sh +++ b/examples/mysql/.test.sh @@ -1,14 +1,3 @@ -#!/usr/bin/env bash set -ex -devenv up & -DEVENV_PID=$! -export DEVENV_PID - -devenv_stop() { - pkill -P "$DEVENV_PID" -} - -trap devenv_stop EXIT - -timeout 60 bash -c 'until MYSQL_PWD="" mysql -u root test_database < /dev/null; do sleep 0.5; done' +timeout 60 bash -c 'until MYSQL_PWD="" mysql -u root test_database < /dev/null; do sleep 0.5; done' \ No newline at end of file diff --git a/examples/overlays/devenv.nix b/examples/overlays/devenv.nix index c27092e92..d7eae18cc 100644 --- a/examples/overlays/devenv.nix +++ b/examples/overlays/devenv.nix @@ -1,7 +1,11 @@ { pkgs, ... }: { - packages = [ pkgs.rust-bin.stable.latest.default ]; + packages = [ + # from the rust-overlay + pkgs.rust-bin.stable.latest.default - services.blackfire.enable = true; + # from subflake + pkgs.hello2 + ]; } diff --git a/examples/overlays/devenv.yaml b/examples/overlays/devenv.yaml index 205510e49..044462b43 100644 --- a/examples/overlays/devenv.yaml +++ b/examples/overlays/devenv.yaml @@ -2,6 +2,10 @@ allowUnfree: true inputs: nixpkgs: url: github:NixOS/nixpkgs/nixpkgs-unstable + subflake: + url: path:./subflake + overlays: + - default rust-overlay: url: github:oxalica/rust-overlay overlays: diff --git a/examples/overlays/subflake/flake.nix b/examples/overlays/subflake/flake.nix new file mode 100644 index 000000000..d3ebe7a83 --- /dev/null +++ b/examples/overlays/subflake/flake.nix @@ -0,0 +1,7 @@ +{ + outputs = { ... }: { + overlays.default = self: super: { + hello2 = self.hello; + }; + }; +} diff --git a/examples/postgres/.test.sh b/examples/postgres/.test.sh index 4f95fa994..56081a2af 100755 --- a/examples/postgres/.test.sh +++ b/examples/postgres/.test.sh @@ -1,6 +1,2 @@ -#!/usr/bin/env bash set -ex - -devenv up & - timeout 20 bash -c 'until psql -h /tmp -c "SELECT 1" mydb 2>/dev/null; do sleep 0.5; done' diff --git a/examples/rubyonrails/.test.sh b/examples/rubyonrails/.test.sh index 4d5c9821a..2e03dd625 100755 --- a/examples/rubyonrails/.test.sh +++ b/examples/rubyonrails/.test.sh @@ -1,7 +1,11 @@ #!/usr/bin/env bash set -ex -rails new blog -d=postgresql -devenv up& -timeout 20 bash -c 'until echo > /dev/tcp/localhost/5100; do sleep 0.5; done' -(cd blog && rails db:create) -curl -s http://localhost:5100/ | grep "version" \ No newline at end of file + +pushd blog + timeout 20 bash -c 'until echo > /dev/tcp/localhost/5100; do sleep 0.5; done' + rails db:create + curl -s http://localhost:5100/ | grep "version" +popd + +# make sure puma was compiled with ssl +ruby -rpuma -e 'exit 1 unless Puma.ssl?' \ No newline at end of file diff --git a/examples/rubyonrails/Gemfile b/examples/rubyonrails/Gemfile deleted file mode 100644 index 3f9616659..000000000 --- a/examples/rubyonrails/Gemfile +++ /dev/null @@ -1,8 +0,0 @@ -# frozen_string_literal: true - -source "https://rubygems.org" - -ruby "3.2.2" - -gem "rails" -gem "puma" diff --git a/examples/rubyonrails/devenv.nix b/examples/rubyonrails/devenv.nix index 497bfa258..aaea47e1a 100644 --- a/examples/rubyonrails/devenv.nix +++ b/examples/rubyonrails/devenv.nix @@ -9,7 +9,12 @@ processes.rails.exec = "rails server"; enterShell = '' + if [ ! -d "blog" ]; then + rails new blog -d=postgresql + fi export PATH="$DEVENV_ROOT/blog/bin:$PATH" - bundle + pushd blog + bundle + popd ''; } diff --git a/examples/temporal/.test.sh b/examples/temporal/.test.sh index 968345280..3c27ee2f7 100755 --- a/examples/temporal/.test.sh +++ b/examples/temporal/.test.sh @@ -1,17 +1,6 @@ #!/usr/bin/env bash set -x -echo "Starting temporal service..." -devenv up & -DEVENV_PID=$! -export DEVENV_PID - -devenv_stop() { - pkill -P "$DEVENV_PID" -} - -trap devenv_stop EXIT - export TEMPORAL_ADDRESS=127.0.0.1:17233 timeout 20 bash -c 'until echo > /dev/tcp/localhost/17233; do sleep 0.5; done' @@ -29,4 +18,7 @@ temporal operator namespace describe mynamespace # Print the captured output when temporal status succeeds echo "Startup complete..." temporal operator cluster system -echo "$TEMPORAL_OUTPUT" \ No newline at end of file +echo "$TEMPORAL_OUTPUT" + +# Exit the script +exit $TEMPORAL_EXIT_STATUS \ No newline at end of file diff --git a/examples/vault/.test.sh b/examples/vault/.test.sh index 23bebe597..e511bd6ce 100755 --- a/examples/vault/.test.sh +++ b/examples/vault/.test.sh @@ -1,20 +1,16 @@ #!/usr/bin/env bash set -ex -echo "Starting vault service..." -devenv up & -DEVENV_PID=$! -export DEVENV_PID - -# shellcheck disable=SC2317 # ShellCheck may incorrectly believe that code is unreachable if it's invoked by variable name or in a trap -devenv_stop() { - pkill -P "$DEVENV_PID" +# vault status and store its exit status +check_vault_status() { + echo "Waiting for service to become available..." + VAULT_OUTPUT=$(vault status 2>&1) + VAULT_EXIT_STATUS=$? } trap devenv_stop EXIT timeout 20 bash -c 'until echo > /dev/tcp/localhost/8200; do sleep 0.5; done' -timeout 5 bash -c 'until vault status; do sleep 0.5; done' - -vault status \ No newline at end of file +# Exit the script +exit $VAULT_EXIT_STATUS \ No newline at end of file diff --git a/mkdocs.yml b/mkdocs.yml index a116dcbbb..c0dc9b34d 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -40,7 +40,9 @@ nav: - Processes: processes.md - Services: services.md - Containers: containers.md + - Binary Caching: binary-caching.md - Pre-Commit Hooks: pre-commit-hooks.md + - Tests: tests.md - Common Patterns: common-patterns.md - Writing devenv.yaml: - Inputs: inputs.md diff --git a/poetry.lock b/poetry.lock index 6dd48e078..65e0ec62a 100644 --- a/poetry.lock +++ b/poetry.lock @@ -505,13 +505,13 @@ files = [ [[package]] name = "mkdocs" -version = "1.5.3" +version = "1.5.1" description = "Project documentation with Markdown." optional = false python-versions = ">=3.7" files = [ - {file = "mkdocs-1.5.3-py3-none-any.whl", hash = "sha256:3b3a78e736b31158d64dbb2f8ba29bd46a379d0c6e324c2246c3bc3d2189cfc1"}, - {file = "mkdocs-1.5.3.tar.gz", hash = "sha256:eb7c99214dcb945313ba30426c2451b735992c73c2e10838f76d09e39ff4d0e2"}, + {file = "mkdocs-1.5.1-py3-none-any.whl", hash = "sha256:67e889f8d8ba1fe5decdfc59f5f8f21d6a8925a129339e93dede303bdea03a98"}, + {file = "mkdocs-1.5.1.tar.gz", hash = "sha256:f2f323c62fffdf1b71b84849e39aef56d6852b3f0a5571552bca32cefc650209"}, ] [package.dependencies] @@ -567,27 +567,25 @@ pyyaml = "*" [[package]] name = "mkdocs-material" -version = "9.4.0" +version = "9.1.21" description = "Documentation that simply works" optional = false python-versions = ">=3.8" files = [ - {file = "mkdocs_material-9.4.0-py3-none-any.whl", hash = "sha256:b9f1bb8bf3377fa1b7edd34276b1923928c39b2d4a56543af0e811f0cfe59085"}, - {file = "mkdocs_material-9.4.0.tar.gz", hash = "sha256:492108aae369c12af21af2b14160f9bd5c0d6d7da28055877a74a554a704a671"}, + {file = "mkdocs_material-9.1.21-py3-none-any.whl", hash = "sha256:58bb2f11ef240632e176d6f0f7d1cff06be1d11c696a5a1b553b808b4280ed47"}, + {file = "mkdocs_material-9.1.21.tar.gz", hash = "sha256:71940cdfca84ab296b6362889c25395b1621273fb16c93deda257adb7ff44ec8"}, ] [package.dependencies] -babel = ">=2.10,<3.0" -colorama = ">=0.4,<1.0" -jinja2 = ">=3.0,<4.0" -markdown = ">=3.2,<4.0" -mkdocs = ">=1.5.3,<2.0" -mkdocs-material-extensions = ">=1.2,<2.0" -paginate = ">=0.5,<1.0" -pygments = ">=2.16,<3.0" -pymdown-extensions = ">=10.2,<11.0" -regex = ">=2022.4,<2023.0" -requests = ">=2.26,<3.0" +colorama = ">=0.4" +jinja2 = ">=3.0" +markdown = ">=3.2" +mkdocs = ">=1.5.0" +mkdocs-material-extensions = ">=1.1" +pygments = ">=2.14" +pymdown-extensions = ">=9.9.1" +regex = ">=2022.4.24" +requests = ">=2.26" [package.extras] git = ["mkdocs-git-committers-plugin-2 (>=1.1,<2.0)", "mkdocs-git-revision-date-localized-plugin (>=1.2,<2.0)"] @@ -1166,4 +1164,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p [metadata] lock-version = "2.0" python-versions = ">=3.9,<3.12" -content-hash = "0f22aaee71aeb64eeb85f1d625333b93ec21eeab62918b70c8f5777370a64841" +content-hash = "ce967b04c0d8c2818599d333bdcf495f9932b7771fcd151f41c6579c22c1e812" diff --git a/pyproject.toml b/pyproject.toml index 92f95112a..3f9931caf 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -17,6 +17,7 @@ click = "^8.1.4" strictyaml = "^1.7.3" terminaltables = "^3.1.10" filelock = "^3.12.0" +requests = "^2.31.0" [tool.poetry.group.docs] optional = true diff --git a/src/devenv/cli.py b/src/devenv/cli.py index 6031ea449..0300bdc7e 100644 --- a/src/devenv/cli.py +++ b/src/devenv/cli.py @@ -1,29 +1,42 @@ +import functools import os +import shlex import shutil +import signal import subprocess +import tempfile import time import re +import sys +import pkgutil +import json from filelock import FileLock from contextlib import suppress from pathlib import Path -import pkgutil -import json import click import terminaltables +import strictyaml +import requests - -from .yaml import validate_and_parse_yaml, read_yaml, write_yaml -from .log import log, log_task +from .yaml import validate_and_parse_yaml, read_yaml, write_yaml, schema +from .log import log, log_task, log_error, log_warning, log_info, log_debug NIX_FLAGS = [ "--show-trace", "--extra-experimental-features", - "\"nix-command flakes\"", + "nix-command", + "--extra-experimental-features", + "flakes", + # remove unnecessary warnings "--option", "warn-dirty", "false", + # flake caching is too aggressive + "--option", + "eval-cache", + "false", ] FILE = pkgutil.get_loader(__package__).load_module(__package__).__file__ if 'site-packages' in FILE: @@ -31,21 +44,38 @@ else: SRC_DIR = Path(FILE, '..', '..') MODULES_DIR = (SRC_DIR / 'modules').resolve() -FLAKE_FILE_TEMPL = os.path.join(MODULES_DIR, "flake.tmpl.nix") -FLAKE_FILE = ".devenv.flake.nix" +FLAKE_FILE_TEMPL = Path(MODULES_DIR) / "flake.tmpl.nix" +FLAKE_FILE = Path(".devenv.flake.nix") FLAKE_LOCK = "devenv.lock" +# home vars +if 'XDG_DATA_HOME' not in os.environ: + DEVENV_HOME = Path(os.environ['HOME']) / '.devenv' +else: + DEVENV_HOME = Path(os.environ['XDG_DATA_HOME']) / '.devenv' +DEVENV_HOME_GC = DEVENV_HOME / 'gc' +DEVENV_HOME_GC.mkdir(parents=True, exist_ok=True) +CACHIX_KNOWN_PUBKEYS = DEVENV_HOME / "cachix_pubkeys.json" + # define system like x86_64-linux SYSTEM = os.uname().machine.lower().replace("arm", "aarch") + "-" + os.uname().sysname.lower() -def run_nix(command: str) -> str: +def run_nix(command: str, replace_shell=False, use_cachix=False, logging=True) -> str: ctx = click.get_current_context() nix_flags = ctx.obj['nix_flags'] flags = " ".join(NIX_FLAGS) + " " + " ".join(nix_flags) command_flags = " ".join(ctx.obj['command_flags']) - return run_command(f"nix {flags} {command} {command_flags}") - -def run_command(command: str) -> str: + return run_command(f"nix {flags} {command} {command_flags}", + replace_shell=replace_shell, + use_cachix=use_cachix, + logging=logging) + +def run_command(command: str, + disable_stderr=False, + replace_shell=False, + use_cachix=False, + logging=True) -> str: + nix = "" if command.startswith("nix"): if os.environ.get("DEVENV_NIX"): nix = os.path.join(os.environ["DEVENV_NIX"], "bin") @@ -54,25 +84,47 @@ def run_command(command: str) -> str: log("$DEVENV_NIX is not set, but required as devenv doesn't work without a few Nix patches.", level="error") log("Please follow https://devenv.sh/getting-started/ to install devenv.", level="error") exit(1) + if use_cachix: + caches, known_keys = get_cachix_caches(logging) + pull_caches = ' '.join(map(lambda cache: f'https://{cache}.cachix.org', caches.get('pull'))) + command = f"{command} --option extra-trusted-public-keys '{' '.join(known_keys.values())}'" + command = f"{command} --option extra-substituters '{pull_caches}'" + push_cache = caches.get("push") + if push_cache and os.environ.get('CACHIX_AUTH_TOKEN'): + if shutil.which("cachix") is None: + if logging: + log_warning("cachix is not installed, skipping pushing. Please follow https://devenv.sh/getting-started/#2-install-cachix to install cachix.", level="error") + else: + command = f"cachix watch-exec {push_cache} {command}" + try: - return subprocess.run( - command, - shell=True, - check=True, - env=os.environ.copy(), - stdout=subprocess.PIPE, - universal_newlines=True).stdout.strip() - except subprocess.CalledProcessError as e: - if e.returncode == 130: - pass # we're exiting the shell + if click.get_current_context().obj['verbose']: + log(f"Running command: {command}", level="debug") + if replace_shell: + splitted_command = shlex.split(command.strip()) + os.execv(splitted_command[0], splitted_command) else: - click.echo("\n", err=True) - log(f"Following command exited with code {e.returncode}:\n\n {e.cmd}", level="error") - exit(e.returncode) + return subprocess.run( + command, + shell=True, + check=True, + env=os.environ.copy(), + stdout=subprocess.PIPE, + stdin=subprocess.PIPE, + stderr=None if not disable_stderr else subprocess.DEVNULL, + universal_newlines=True).stdout.strip() + except subprocess.CalledProcessError as e: + click.echo("\n", err=True) + log(f"Following command exited with code {e.returncode}:\n\n {e.cmd}", level="error") + exit(e.returncode) CONTEXT_SETTINGS = dict(max_content_width=120) @click.group(context_settings=CONTEXT_SETTINGS) +@click.option( + '--verbose', '-v', + help='Enable verbose output.', + is_flag=True) @click.option( '--nix-flags', '-n', help='Flags to pass to Nix. See `man nix.conf 5`. Example: --nix-flags "--option bash-prompt >"', @@ -90,15 +142,12 @@ def run_command(command: str) -> str: '--offline', '-o', help='Disable network access.', is_flag=True) -@click.option( - '--disable-eval-cache', - help='Disable Nix evaluation cache.', - is_flag=True) @click.pass_context -def cli(ctx, disable_eval_cache, offline, system, debugger, nix_flags): +def cli(ctx, offline, system, debugger, nix_flags, verbose): """https://devenv.sh: Fast, Declarative, Reproducible, and Composable Developer Environments.""" ctx.ensure_object(dict) ctx.obj['system'] = system + ctx.obj['verbose'] = verbose ctx.obj['command_flags'] = [] ctx.obj['nix_flags'] = list(nix_flags) ctx.obj['nix_flags'] += ['--system', system] @@ -107,25 +156,29 @@ def cli(ctx, disable_eval_cache, offline, system, debugger, nix_flags): if debugger: # ignore-try is needed to avoid catching unrelated errors ctx.obj['command_flags'] += ['--debugger', '--ignore-try'] - # to avoid confusing errors - disable_eval_cache = True - if disable_eval_cache: - ctx.obj['nix_flags'] += ['--option', 'eval-cache', 'false'] - if 'XDG_DATA_HOME' not in os.environ: - ctx.obj['gc_root'] = os.path.join(os.environ['HOME'], '.devenv', 'gc') - else: - ctx.obj['gc_root'] = os.path.join(os.environ['XDG_DATA_HOME'], 'devenv', 'gc') - - Path(ctx.obj['gc_root']).mkdir(parents=True, exist_ok=True) - ctx.obj['gc_project'] = os.path.join(ctx.obj['gc_root'], str(int(time.time() * 1000))) + ctx.obj['gc_root'] = DEVENV_HOME_GC + ctx.obj['gc_project'] = DEVENV_HOME_GC / str(int(time.time() * 1000)) + +@cli.group() +def processes(): + pass + + +DEVENV_DIR = Path(os.getcwd()) / '.devenv' +os.environ['DEVENV_DIR'] = str(DEVENV_DIR) +DEVENV_GC = DEVENV_DIR / 'gc' +os.environ['DEVENV_GC'] = str(DEVENV_GC) + +PROCESSES_PID = DEVENV_DIR / 'processes.pid' +PROCESSES_LOG = DEVENV_DIR / 'processes.log' def add_gc(name, store_path): """Register a GC root""" ctx = click.get_current_context() run_command(f'nix-store --add-root "{os.environ["DEVENV_GC"]}/{name}" -r {store_path} >/dev/null') - os.symlink(store_path, f'{ctx.obj["gc_project"]}-{name}', True) + symlink_force(store_path, f'{ctx.obj["gc_project"]}-{name}') @cli.command(hidden=True) @@ -136,10 +189,6 @@ def assemble(ctx): log(' $ devenv init', level="error") exit(1) - DEVENV_DIR = Path(os.getcwd()) / '.devenv' - os.environ['DEVENV_DIR'] = str(DEVENV_DIR) - DEVENV_GC = DEVENV_DIR / 'gc' - os.environ['DEVENV_GC'] = str(DEVENV_GC) DEVENV_GC.mkdir(parents=True, exist_ok=True) if os.path.exists('devenv.yaml'): @@ -147,8 +196,7 @@ def assemble(ctx): else: for file in ['devenv.json', 'flake.json', 'imports.txt']: file_path = DEVENV_DIR / file - if file_path.exists(): - os.remove(file_path) + file_path.unlink(missing_ok=True) with open(FLAKE_FILE_TEMPL) as f: flake = f.read() @@ -182,7 +230,7 @@ def gc(ctx): click.echo(f' Deleted {len(removed_symlinks)} dangling symlinks.') click.echo() - log(f'Running garbage collection (this process may take some time) ...', level="info") + log('Running garbage collection (this process may take some time) ...', level="info") # TODO: ideally nix would report some statistics about the GC as JSON run_nix(f'store delete --recursive {" ".join(to_gc)}') @@ -206,16 +254,16 @@ def cleanup_symlinks(folder): to_gc.append(full_path) return to_gc, removed_symlinks -def get_dev_environment(ctx, is_shell=False): +def get_dev_environment(ctx, logging=True): ctx.invoke(assemble) - if is_shell: + if logging: action = log_task('Building shell') else: action = suppress() with action: gc_root = os.path.join(os.environ['DEVENV_GC'], 'shell') - env = run_nix(f"print-dev-env --impure --profile '{gc_root}'") - run_command(f"nix-env -p '{gc_root}' --delete-generations old") + env = run_nix(f"print-dev-env --profile '{gc_root}'", logging=False, use_cachix=True) + run_command(f"nix-env -p '{gc_root}' --delete-generations old", logging=False, disable_stderr=True) symlink_force(Path(f'{ctx.obj["gc_project"]}-shell'), gc_root) return env, gc_root @@ -232,41 +280,86 @@ def get_dev_environment(ctx, is_shell=False): @click.argument('cmd', required=False) @click.pass_context def shell(ctx, cmd, extra_args): - env, gc_root = get_dev_environment(ctx, is_shell=True) + env, gc_root = get_dev_environment(ctx) if cmd: - run_nix(f"develop '{gc_root}' -c {cmd} {' '.join(extra_args)}") + run_nix(f"develop '{gc_root}' -c {cmd} {' '.join(extra_args)}", replace_shell=True) else: log('Entering shell', level="info") - run_nix(f"develop '{gc_root}'") + run_nix(f"develop '{gc_root}'", replace_shell=True) def symlink_force(src, dst): + src = Path(src) + dst = Path(dst) # locking is needed until https://github.com/python/cpython/pull/14464 with FileLock(f"{dst}.lock", timeout=10): - src.unlink(missing_ok=True) - Path(src).symlink_to(dst) + dst.unlink(missing_ok=True) + dst.symlink_to(src) @cli.command( help="Starts processes in foreground. See http://devenv.sh/processes", short_help="Starts processes in foreground. See http://devenv.sh/processes", ) -@click.argument('command', required=False) +@click.argument('process', required=False) +@click.option('--detach', '-d', is_flag=True, help="Starts processes in the background.") @click.pass_context -def up(ctx, command): +def up(ctx, process, detach): with log_task('Building processes'): ctx.invoke(assemble) - procfilescript = run_nix(f"build --no-link --print-out-paths --impure '.#procfileScript'") + procfilescript = run_nix("build --no-link --print-out-paths '.#procfileScript'", use_cachix=True) with open(procfilescript, 'r') as file: contents = file.read().strip() if contents == '': log("No 'processes' option defined: https://devenv.sh/processes/", level="error") exit(1) else: + env, _ = get_dev_environment(ctx) log('Starting processes ...', level="info") add_gc('procfilescript', procfilescript) - # TODO: print output to stdout - #run_command(procfilescript + ' ' + (command or '')) - args = [] if not command else [command] - subprocess.run([procfilescript] + args) + processes_script = os.path.join(DEVENV_DIR, 'processes') + with open(processes_script, 'w') as f: + f.write(f"""#!/usr/bin/env bash +{env} +{procfilescript} {process or ""} + """) + os.chmod(processes_script, 0o755) + + if detach: + process = subprocess.Popen( + [processes_script], + stdout=open(PROCESSES_LOG, 'w'), + stderr=subprocess.STDOUT, + ) + + with open(PROCESSES_PID, 'w') as file: + file.write(str(process.pid)) + log(f" PID is {process.pid}.", level="info") + log(f" See logs: $ tail -f {PROCESSES_LOG}", level="info") + log(" Stop: $ devenv processes stop", level="info") + else: + os.execv(processes_script, [processes_script]) + +processes.add_command(up) + +@processes.command( + help="Stops processes started with 'devenv up'.", + short_help="Stops processes started with 'devenv up'.", +) +def stop(): + with log_task('Stopping processes', newline=False): + if not os.path.exists(PROCESSES_PID): + log("No processes running.", level="error") + exit(1) + + with open(PROCESSES_PID, 'r') as file: + pid = int(file.read()) + + try: + os.kill(pid, signal.SIGTERM) + except ProcessLookupError: + log(f"Process with PID {pid} not found.", level="error") + exit(1) + + os.remove(PROCESSES_PID) @cli.command() @click.argument('name') @@ -274,7 +367,7 @@ def up(ctx, command): def search(ctx, name): """Search packages matching NAME in nixpkgs input.""" ctx.invoke(assemble) - options = run_nix(f"build --no-link --print-out-paths '.#optionsJSON' --impure") + options = run_nix("build --no-link --print-out-paths '.#optionsJSON' ", use_cachix=True) search = run_nix(f"search --json nixpkgs {name}") with open(Path(options) / 'share' / 'doc' / 'nixos' / 'options.json') as f: @@ -292,7 +385,7 @@ def search(ctx, name): search_results = [] for key, value in json.loads(search).items(): search_results.append( - (".".join(key.split('.')[2:]) + ("pkgs." + (".".join(key.split('.')[2:])) , value['version'] , value['description'][:80] ) @@ -333,14 +426,15 @@ def container(ctx, registry, copy, copy_args, docker_run, container_name): with log_task(f'Building {container_name} container'): ctx.invoke(assemble) # NOTE: we need --impure here to read DEVENV_CONTAINER - spec = run_nix(f"build --impure --print-out-paths --no-link .#devenv.containers.\"{container_name}\".derivation") + spec = run_nix(f"build --impure --print-out-paths --no-link .#devenv.containers.\"{container_name}\".derivation", use_cachix=True) click.echo(spec) # copy container if copy or docker_run: with log_task(f'Copying {container_name} container'): + # we need --impure here for DEVENV_CONTAINER copy_script = run_nix(f"build --print-out-paths --no-link \ - --impure .#devenv.containers.\"{container_name}\".copyScript") + --impure .#devenv.containers.\"{container_name}\".copyScript", use_cachix=True) if docker_run: registry = "docker-daemon:" @@ -351,9 +445,10 @@ def container(ctx, registry, copy, copy_args, docker_run, container_name): check=True) if docker_run: - with log_task(f'Starting {container_name} container'): - docker_script = run_nix(f"build --print-out-paths --no-link --impure \ - .#devenv.containers.\"{container_name}\".dockerRun") + log(f'Starting {container_name} container', level="info") + # we need --impure here for DEVENV_CONTAINER + docker_script = run_nix(f"build --print-out-paths --no-link --impure \ + .#devenv.containers.\"{container_name}\".dockerRun", use_cachix=True) subprocess.run(docker_script) @@ -371,7 +466,7 @@ def info(ctx): inputs = matches.group(1) else: inputs = "" - info_ = run_nix("eval --raw '.#info' --impure") + info_ = run_nix("eval --raw '.#info'") click.echo(f"{inputs}\n{info_}") @cli.command() @@ -439,20 +534,22 @@ def update(ctx, input_name): if input_name: run_nix(f"flake lock --update-input {input_name}") else: - run_nix(f"flake update") + run_nix("flake update") @cli.command() @click.pass_context def ci(ctx): """Builds your developer environment and checks if everything builds.""" ctx.invoke(assemble) - output_path = run_nix(f"build --no-link --print-out-paths --impure .#ci") + print("running ci") + print(run_command("cat ${FLAKE_FILE}")) + output_path = run_nix("build --no-link --print-out-paths .#ci", use_cachix=True) add_gc('ci', output_path) -@cli.command() +@cli.command(hidden=True) @click.pass_context def print_dev_env(ctx): - env, _ = get_dev_environment(ctx) + env, _ = get_dev_environment(ctx, logging=False) click.echo(env) def get_version(): @@ -489,4 +586,175 @@ def add(ctx, name, url, follows): attrs['inputs'] = inputs devenv['inputs'][name] = attrs - write_yaml(devenv) \ No newline at end of file + write_yaml(devenv) + +@cli.command( + help="Run tests. See http://devenv.sh/tests/", + short_help="Run tests. See http://devenv.sh/tests/", +) +@click.argument('names', nargs=-1) +@click.option('--debug', is_flag=True, help='Run tests in debug mode.') +@click.pass_context +def test(ctx, debug, names): + ctx.invoke(assemble) + with log_task("Gathering tests", newline=False): + tests = json.loads(run_nix("eval .#devenv.tests --json")) + + if not names: + names = [ "local" ] + + # group tests by tags + tags = {} + for name, test in tests.items(): + for tag in test['tags']: + if tag not in tags: + tags[tag] = [] + tags[tag].append(name) + + selected_tests = [] + for name in names: + if name in tests: + selected_tests.append(name) + tag_tests = tags.get(name, {}) + if tag_tests: + selected_tests.extend(tag_tests) + + log(f"Found {len(tests)} test(s), running {len(selected_tests)}:", level="info") + + pwd = os.getcwd() + + for name in selected_tests: + with log_task(f" Testing {name}"): + with tempfile.TemporaryDirectory(prefix=name + "_") as tmpdir: + os.chdir(tmpdir) + test = tests[name] + + if test.get('src'): + shutil.copytree( + test['src'], '.', + dirs_exist_ok=True, + copy_function=shutil.copy + ) + run_command("find . -type d -exec chmod +wx {} \;") + else: + write_if_defined("devenv.nix", test.get('nix')) + write_if_defined("devenv.yaml", test.get('yaml')) + write_if_defined(".test.sh", test.get('test')) + if os.path.exists(".test.sh"): + os.chmod(".test.sh", 0o755) + + # predefined utilities + write_if_defined("devenv.local.nix", """ +{ pkgs, ... }: { + packages = [ pkgs.coreutils-full ]; +} + """.strip() + "\n") + + # plug in devenv input if needed + if os.path.exists(os.path.join(pwd, 'src/modules/latest-version')): + log(" Detected devenv module. Using src/modules for tests.", level="info") + + modules = os.path.join(pwd, 'src/modules') + if not os.path.exists("devenv.yaml"): + write_yaml(strictyaml.as_document({"inputs": {}}, schema=schema)) + os.chmod("devenv.yaml", 0o644) + yaml = read_yaml() + inputs = yaml.get('inputs', {}) + inputs['devenv'] = {'url': f'path:{modules}'} + yaml['inputs'] = inputs + write_yaml(yaml) + + devenv = sys.argv[0] + has_processes = False + try: + log(" Running $ devenv ci ...", level="info") + run_command(f"{devenv} ci") + + has_processes = os.path.exists(".devenv/gc/ci") and "-devenv-up" in run_command("cat .devenv/gc/ci") + + if has_processes: + log(" Starting processes ...", level="info") + run_command(f"{devenv} up -d") + # stream logs + p = subprocess.Popen("tail -f .devenv/processes.log", + shell=True, + ) + else: + p = None + + try: + if os.path.exists(".test.sh"): + log(" Running .test.sh ...", level="info") + run_command(f"{devenv} shell bash ./.test.sh") + finally: + if has_processes and not debug: + run_command(f"{devenv} processes stop") + if p: + p.kill() + except BaseException as e: + log_error(f"Test {name} failed.") + if debug: + log("Entering shell because of the --debug flag:", level="warning") + log(f" - devenv: {devenv}", level="warning") + log(f" - cwd: {tmpdir}", level="warning") + if has_processes: + log(" - up logs: .devenv/processes.log:", level="warning") + os.execv("/bin/sh", ["/bin/sh"]) + else: + log_warning('Pass --debug flag to enter shell.') + raise e + +def write_if_defined(file, content): + if content: + with open(file, 'w') as f: + f.write(content) + +@functools.cache +def get_cachix_caches(logging=True): + """Get the full list of cachix caches we need and their public keys. + + This is cached because it's expensive to run. + """ + + caches = json.loads(run_nix("eval .#devenv.cachix --json")) + if CACHIX_KNOWN_PUBKEYS.exists(): + known_keys = json.loads(CACHIX_KNOWN_PUBKEYS.read_text()) + else: + known_keys = {} + new_known_keys = {} + for name in caches.get("pull", []): + if name not in known_keys: + resp = requests.get(f"https://cachix.org/api/v1/cache/{name}") + if resp.status_code in [401, 404]: + log_error(f"Cache {name} does not exist or you don't have a CACHIX_AUTH_TOKEN configured.") + # TODO: instruct how to best configure netrc + #log_error("To configure a token, run `cachix authtoken `.") + log_error("To create a cache, go to https://app.cachix.org/.") + exit(1) + else: + resp.raise_for_status() + pubkey = resp.json()["publicSigningKeys"][0] + new_known_keys[name] = pubkey + + if caches.get("pull"): + if logging: + log_info(f"Using Cachix: {', '.join(caches.get('pull', []))} ") + if new_known_keys: + for name, pubkey in new_known_keys.items(): + if logging: + log_info(f" Trusting {name}.cachix.org on first use with the public key {pubkey}") + known_keys.update(new_known_keys) + CACHIX_KNOWN_PUBKEYS.write_text(json.dumps(known_keys)) + return caches, known_keys + +@cli.command() +@click.argument('attrs', nargs=-1, required=True) +@click.pass_context +def build(ctx, attrs): + """Build attributes in your devenv.nix.""" + ctx.invoke(assemble) + attrs = " ".join(map(lambda attr: f'.#devenv.{attr}', attrs)) + output = run_nix(f"build --print-out-paths --print-build-logs --no-link {attrs}", use_cachix=True) + log("Built:", level="info") + for path in output.splitlines(): + log(path, level="info") \ No newline at end of file diff --git a/src/devenv/log.py b/src/devenv/log.py index 04709e3f4..64ac34c07 100644 --- a/src/devenv/log.py +++ b/src/devenv/log.py @@ -1,25 +1,29 @@ from typing import Literal +import time import click class log_task: """Context manager for logging progress of a task.""" - def __init__(self, message,): + def __init__(self, message, newline=True): self.message = message + self.newline = newline def __enter__(self): prefix = click.style("•", fg="blue") - click.echo(f"{prefix} {self.message} ...", nl=False) + self.start = time.time() + click.echo(f"{prefix} {self.message} ...", nl=self.newline) def __exit__(self, exc, *args): + end = time.time() if exc: prefix = click.style("✖", fg="red") else: prefix = click.style("✔", fg="green") - click.echo(f"\r{prefix} {self.message}") + click.echo(f"\r{prefix} {self.message} in {end - self.start:.1f}s.") -LogLevel = Literal["info", "warning", "error"] +LogLevel = Literal["info", "warning", "error", "debug"] def log(message, level: LogLevel): match level: @@ -29,3 +33,17 @@ def log(message, level: LogLevel): click.echo(click.style("• ", fg="yellow") + message, err=True) case "error": click.echo(click.style("✖ ", fg="red") + message, err=True) + case "debug": + click.echo(click.style("• ", fg="magenta") + message, err=True) + +def log_error(message): + log(message, "error") + +def log_warning(message): + log(message, "warning") + +def log_info(message): + log(message, "info") + +def log_debug(message): + log(message, "debug") \ No newline at end of file diff --git a/src/devenv/yaml.py b/src/devenv/yaml.py index 434f340fc..d62074734 100644 --- a/src/devenv/yaml.py +++ b/src/devenv/yaml.py @@ -4,10 +4,10 @@ from pathlib import Path from strictyaml import Map, MapPattern, Str, Seq -from strictyaml import load, Bool, Any, Optional, YAMLError +from strictyaml import load, Bool, Any, Optional, YAMLError, EmptyDict -inputsSchema = MapPattern(Str(), Map({ +inputsSchema = EmptyDict() | MapPattern(Str(), Map({ "url": Str(), Optional("flake", default=None): Bool(), Optional("inputs", default=None): Any(), @@ -24,12 +24,12 @@ YAML_FILE = Path("devenv.yaml") def read_yaml(): - try: - with open(YAML_FILE) as f: - return load(f.read(), schema, label="devenv.yaml") - except YAMLError as error: - print("Validation error in `devenv.yaml`", error) - sys.exit(1) + try: + with open(YAML_FILE) as f: + return load(f.read(), schema, label="devenv.yaml") + except YAMLError as error: + print("Validation error in `devenv.yaml`", error) + sys.exit(1) def write_yaml(yaml): with open(YAML_FILE, "w") as f: diff --git a/src/modules/cachix.nix b/src/modules/cachix.nix new file mode 100644 index 000000000..e5413f450 --- /dev/null +++ b/src/modules/cachix.nix @@ -0,0 +1,30 @@ +{ lib, config, ... }: +let + cfg = config.cachix; +in +{ + options.cachix = { + pull = lib.mkOption { + type = lib.types.listOf lib.types.str; + description = "What caches to pull from."; + }; + + push = lib.mkOption { + type = lib.types.nullOr lib.types.str; + description = "What cache to push to. Automatically also adds it to the list of caches to pull from."; + default = null; + }; + }; + + config = { + cachix.pull = [ "devenv" ] + ++ (lib.optionals (cfg.push != null) [ config.cachix.push ]); + + warnings = lib.optionals (!config.devenv.flakesIntegration && lib.versionOlder config.devenv.cliVersion "1.0") [ + '' + For cachix.push and cachix.pull attributes to have an effect, + upgrade to devenv 1.0 or later. + '' + ]; + }; +} diff --git a/src/modules/containers.nix b/src/modules/containers.nix index 167e0ffdb..5e7efbc79 100644 --- a/src/modules/containers.nix +++ b/src/modules/containers.nix @@ -1,4 +1,4 @@ -{ pkgs, config, lib, inputs, self, ... }: +{ pkgs, config, lib, self, ... }: let projectName = name: @@ -7,16 +7,15 @@ let else config.name; types = lib.types; envContainerName = builtins.getEnv "DEVENV_CONTAINER"; - devenvlib = import ./devenv-lib.nix { inherit pkgs config inputs lib; }; - nix2containerInput = devenvlib.getInput { + nix2containerInput = config.lib.getInput { name = "nix2container"; url = "github:nlewo/nix2container"; attribute = "containers"; follows = [ "nixpkgs" ]; }; nix2container = nix2containerInput.packages.${pkgs.stdenv.system}; - mk-shell-bin = devenvlib.getInput { + mk-shell-bin = config.lib.getInput { name = "mk-shell-bin"; url = "github:rrbutani/nix-mk-shell-bin"; attribute = "containers"; diff --git a/src/modules/devenv-lib.nix b/src/modules/devenv-lib.nix deleted file mode 100644 index 0dee070f5..000000000 --- a/src/modules/devenv-lib.nix +++ /dev/null @@ -1,27 +0,0 @@ -{ pkgs, lib, config, inputs }: - -{ - getInput = { name, url, attribute, follows ? [ ] }: - let - flags = lib.concatStringsSep " " (map (i: "--follows ${i}") follows); - yaml_follows = lib.concatStringsSep "\n " (map (i: "${i}:\n follows: ${i}") follows); - command = - if lib.versionAtLeast config.devenv.cliVersion "1.0" - then '' - run the following command: - - $ devenv inputs add ${name} ${url} ${flags} - '' - else '' - add the following to your devenv.yaml: - - ✨ devenv 1.0 made this easier: https://devenv.sh/getting-started/#installation ✨ - - inputs: - ${name}: - url: ${url} - ${if follows != [] then "inputs:\n ${yaml_follows}" else ""} - ''; - in - inputs.${name} or (throw "To use '${attribute}', ${command}\n\n"); -} diff --git a/src/modules/flake.tmpl.nix b/src/modules/flake.tmpl.nix index cbb8ac88c..92f403721 100644 --- a/src/modules/flake.tmpl.nix +++ b/src/modules/flake.tmpl.nix @@ -55,7 +55,10 @@ specialArgs = inputs // { inherit inputs pkgs; }; modules = [ (inputs.devenv.modules + /top-level.nix) - { devenv.cliVersion = "${version}"; } + { + devenv.cliVersion = "${version}"; + devenv.root = devenv_root; + } ] ++ (map importModule (devenv.imports or [ ])) ++ [ ./devenv.nix (devenv.devenv or { }) @@ -85,7 +88,7 @@ inherit (config) info procfileScript procfileEnv procfile; ci = config.ciDerivation; }; - devenv.containers = config.containers; + devenv = config; devShell."${system}" = config.shell; }; } diff --git a/src/modules/languages/php.nix b/src/modules/languages/php.nix index 8098d37a9..f8303fea3 100644 --- a/src/modules/languages/php.nix +++ b/src/modules/languages/php.nix @@ -1,4 +1,4 @@ -{ pkgs, config, lib, inputs, ... }: +{ pkgs, config, lib, ... }: with lib; @@ -7,9 +7,7 @@ let cfg = config.languages.php; - devenvlib = import ../devenv-lib.nix { inherit pkgs config inputs lib; }; - - phps = devenvlib.getInput { + phps = config.lib.getInput { name = "phps"; url = "github:fossar/nix-phps"; attribute = "languages.php.version"; diff --git a/src/modules/languages/python.nix b/src/modules/languages/python.nix index 16a0ec5dd..d9b6dc3da 100644 --- a/src/modules/languages/python.nix +++ b/src/modules/languages/python.nix @@ -1,17 +1,15 @@ -{ pkgs, config, lib, inputs, ... }: +{ pkgs, config, lib, ... }: let cfg = config.languages.python; - + requirements = pkgs.writeText "requirements.txt" ( if lib.isPath cfg.venv.requirements then builtins.readFile cfg.venv.requirements else cfg.venv.requirements ); - devenvlib = import ../devenv-lib.nix { inherit pkgs config inputs lib; }; - - nixpkgs-python = devenvlib.getInput { + nixpkgs-python = config.lib.getInput { name = "nixpkgs-python"; url = "github:cachix/nixpkgs-python"; attribute = "languages.python.version"; @@ -47,7 +45,7 @@ let ''; initPoetryScript = pkgs.writeShellScript "init-poetry.sh" '' - function _devenv-init-poetry-venv() + function _devenv_init_poetry_venv { # 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. @@ -57,7 +55,7 @@ let ${cfg.poetry.package}/bin/poetry env use --no-interaction --quiet ${cfg.package.interpreter} } - function _devenv-poetry-install() + function _devenv_poetry_install { local POETRY_INSTALL_COMMAND=(${cfg.poetry.package}/bin/poetry install --no-interaction ${lib.concatStringsSep " " cfg.poetry.install.arguments}) # Avoid running "poetry install" for every shell. @@ -87,9 +85,9 @@ let then echo "No pyproject.toml found. Run 'poetry init' to create one." >&2 else - _devenv-init-poetry-venv + _devenv_init_poetry_venv ${lib.optionalString cfg.poetry.install.enable '' - _devenv-poetry-install + _devenv_poetry_install ''} ${lib.optionalString cfg.poetry.activate.enable '' source "$DEVENV_ROOT"/.venv/bin/activate @@ -197,6 +195,8 @@ in (lib.mkIf (cfg.version != null) (nixpkgs-python.packages.${pkgs.stdenv.system}.${cfg.version} or (throw "Unsupported Python version, see https://github.com/cachix/nixpkgs-python#supported-python-versions"))) ]; + cachix.pull = lib.mkIf (cfg.version != null) [ "nixpkgs-python" ]; + packages = [ cfg.package ] ++ (lib.optional cfg.poetry.enable cfg.poetry.package); diff --git a/src/modules/languages/ruby.nix b/src/modules/languages/ruby.nix index cbf41644a..9425e3f99 100644 --- a/src/modules/languages/ruby.nix +++ b/src/modules/languages/ruby.nix @@ -1,11 +1,9 @@ -{ pkgs, config, lib, inputs, ... }: +{ pkgs, config, lib, ... }: let cfg = config.languages.ruby; - devenvlib = import ../devenv-lib.nix { inherit pkgs config inputs lib; }; - - nixpkgs-ruby = devenvlib.getInput { + nixpkgs-ruby = config.lib.getInput { name = "nixpkgs-ruby"; url = "github:bobvanderlinden/nixpkgs-ruby"; attribute = "languages.ruby.version or languages.ruby.versionFile"; diff --git a/src/modules/languages/rust.nix b/src/modules/languages/rust.nix index 1db14c5f1..1f1f15787 100644 --- a/src/modules/languages/rust.nix +++ b/src/modules/languages/rust.nix @@ -1,17 +1,14 @@ -{ pkgs, config, lib, inputs, ... }: +{ pkgs, config, lib, ... }: let cfg = config.languages.rust; - devenvlib = import ../devenv-lib.nix { inherit pkgs config inputs lib; }; - - fenix = devenvlib.getInput { + fenix = config.lib.getInput { name = "fenix"; url = "github:nix-community/fenix"; attribute = "languages.rust.version"; follows = [ "nixpkgs" ]; }; - in { imports = [ diff --git a/src/modules/lib.nix b/src/modules/lib.nix new file mode 100644 index 000000000..f9e2752a3 --- /dev/null +++ b/src/modules/lib.nix @@ -0,0 +1,53 @@ +{ lib, config, inputs, ... }: + +{ + # freestyle + options.lib = lib.mkOption { + type = lib.types.attrsOf lib.types.anything; + internal = true; + }; + + config.lib = { + getInput = { name, url, attribute, follows ? [ ] }: + let + flags = lib.concatStringsSep " " (map (i: "--follows ${i}") follows); + yaml_follows = lib.concatStringsSep "\n " (map (i: "${i}:\n follows: ${i}") follows); + command = + if config.devenv.flakesIntegration + then '' + Add the following to flake.nix: + + inputs.${name}.url = "${url}"; + ${if follows != [] + then "inputs.${name}.inputs = { ${lib.concatStringsSep "; " (map (i: "${i}.follows = \"${i}\";") follows)}; };" + else ""} + '' + else if lib.versionAtLeast config.devenv.cliVersion "1.0" + then '' + run the following command: + + $ devenv inputs add ${name} ${url} ${flags} + '' + else '' + add the following to your devenv.yaml: + + ✨ devenv 1.0 made this easier: https://devenv.sh/getting-started/#installation ✨ + + inputs: + ${name}: + url: ${url} + ${if follows != [] then "inputs:\n ${yaml_follows}" else ""} + ''; + in + inputs.${name} or (throw "To use '${attribute}', ${command}\n\n"); + + mkTests = folder: + let + mk = dir: { + tags = [ "local" ]; + src = "${folder}/${dir}"; + }; + in + lib.genAttrs (builtins.attrNames (builtins.readDir folder)) mk; + }; +} diff --git a/src/modules/mkNakedShell.nix b/src/modules/mkNakedShell.nix deleted file mode 100644 index f7c320f92..000000000 --- a/src/modules/mkNakedShell.nix +++ /dev/null @@ -1,140 +0,0 @@ -# using copied code from https://github.com/numtide/devshell -# -# MIT License - -# Copyright (c) 2021 Numtide and contributors - -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: - -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. - -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -{ bashInteractive -, coreutils -, stdenv -, writeTextFile -, pkgs -, lib -}: -let - bashPath = "${bashInteractive}/bin/bash"; - stdenv = writeTextFile { - name = "naked-stdenv"; - destination = "/setup"; - text = '' - # Fix for `nix develop` - : ''${outputs:=out} - - runHook() { - eval "$shellHook" - unset runHook - } - ''; - }; -in -{ name -, # A path to a buildEnv that will be loaded by the shell. - # We assume that the buildEnv contains an ./env.bash script. - profile -, env ? { } -, shellHook ? "" -, meta ? { } -, passthru ? { } -, debug ? false -}: -let - # simpler version of https://github.com/numtide/devshell/blob/20d50fc6adf77fd8a652fc824c6e282d7737b85d/modules/env.nix#L41 - envToBash = name: value: "export ${name}=${lib.escapeShellArg (toString value)}"; - startupEnv = lib.concatStringsSep "\n" (lib.mapAttrsToList envToBash env); - derivationArg = { - inherit name; - inherit (stdenv) system; - - # `nix develop` actually checks and uses builder. And it must be bash. - builder = bashPath; - - # Bring in the dependencies on `nix-build` - args = [ "-ec" "${coreutils}/bin/ln -s ${profile} $out; exit 0" ]; - - # $stdenv/setup is loaded by nix-shell during startup. - # https://github.com/nixos/nix/blob/377345e26f1ac4bbc87bb21debcc52a1d03230aa/src/nix-build/nix-build.cc#L429-L432 - stdenv = stdenv; - - # The shellHook is loaded directly by `nix develop`. But nix-shell - # requires that other trampoline. - shellHook = '' - ${lib.optionalString debug "set -x"} - # Remove all the unnecessary noise that is set by the build env - unset NIX_BUILD_TOP NIX_BUILD_CORES NIX_STORE - unset TEMP TEMPDIR TMP ${lib.optionalString (!pkgs.stdenv.isDarwin) "TMPDIR"} - # $name variable is preserved to keep it compatible with pure shell https://github.com/sindresorhus/pure/blob/47c0c881f0e7cfdb5eaccd335f52ad17b897c060/pure.zsh#L235 - unset builder out shellHook stdenv system - # Flakes stuff - unset dontAddDisableDepTrack outputs - - # For `nix develop`. We get /noshell on Linux and /sbin/nologin on macOS. - if [[ "$SHELL" == "/noshell" || "$SHELL" == "/sbin/nologin" ]]; then - export SHELL=${bashPath} - fi - - # https://github.com/numtide/devshell/issues/158 - PATH=''${PATH#/path-not-set:} - - export DEVENV_PROFILE=${profile} - - # add installed packages to PATH - export PATH="$DEVENV_PROFILE/bin:$PATH" - - # prepend common compilation lookup paths - export PKG_CONFIG_PATH="$DEVENV_PROFILE/lib/pkgconfig:''${PKG_CONFIG_PATH-}" - export LD_LIBRARY_PATH="$DEVENV_PROFILE/lib:''${LD_LIBRARY_PATH-}" - export LIBRARY_PATH="$DEVENV_PROFILE/lib:''${LIBRARY_PATH-}" - export C_INCLUDE_PATH="$DEVENV_PROFILE/include:''${C_INCLUDE_PATH-}" - - # these provide shell completions / default config options - export XDG_DATA_DIRS="$DEVENV_PROFILE/share:''${XDG_DATA_DIRS-}" - export XDG_CONFIG_DIRS="$DEVENV_PROFILE/etc/xdg:''${XDG_CONFIG_DIRS-}" - - ${startupEnv} - - ${shellHook} - ''; - }; -in -(derivation derivationArg) // { - inherit meta passthru; - - # https://github.com/NixOS/nixpkgs/blob/41f7e338216fd7f5e57817c4f8e148d42fb88b24/pkgs/stdenv/generic/make-derivation.nix#L486-L504 - inputDerivation = derivation (derivationArg // { - # Add a name in case the original drv didn't have one - name = derivationArg.name or "inputDerivation"; - # This always only has one output - outputs = [ "out" ]; - - # Propagate the original builder and arguments, since we override - # them and they might contain references to build inputs - _derivation_original_builder = derivationArg.builder; - _derivation_original_args = derivationArg.args; - - builder = bashPath; - # The bash builtin `export` dumps all current environment variables, - # which is where all build input references end up (e.g. $PATH for - # binaries). By writing this to $out, Nix can find and register - # them as runtime dependencies (since Nix greps for store paths - # through $out to find them) - args = [ "-c" "export > $out" ]; - }); -} // passthru diff --git a/src/modules/tests.nix b/src/modules/tests.nix new file mode 100644 index 000000000..5eba38745 --- /dev/null +++ b/src/modules/tests.nix @@ -0,0 +1,60 @@ +{ config, lib, ... }: + +let + testType = lib.types.submodule ({ config, ... }: { + options = { + tags = lib.mkOption { + type = lib.types.listOf lib.types.str; + default = [ "local" ]; + description = "Tags for this test."; + }; + + nix = lib.mkOption { + type = lib.types.nullOr lib.types.str; + default = null; + example = "{ pkgs, ... }: {}"; + description = "devenv.nix code."; + }; + + yaml = lib.mkOption { + type = lib.types.nullOr lib.types.str; + default = null; + example = '' + inputs: + nixpkgs: + url: github:NixOS/nixpkgs/nixpkgs-unstable + ''; + description = "devenv.yaml code."; + }; + + test = lib.mkOption { + type = lib.types.nullOr lib.types.str; + description = "Bash to be executed."; + default = null; + }; + + src = lib.mkOption { + type = lib.types.nullOr lib.types.path; + default = null; + description = "Source code with all the files."; + }; + }; + }); +in +{ + options.tests = lib.mkOption { + type = lib.types.attrsOf testType; + default = { }; + description = "Tests for this module."; + }; + + config.assertions = + let + mk = name: cfg: + { + assertion = cfg.nix != null || cfg.src != null; + message = "Either tests.${name}.nix or tests.${name}.src needs to be defined."; + }; + in + lib.mapAttrsToList mk config.tests; +} diff --git a/src/modules/top-level.nix b/src/modules/top-level.nix index f884a504b..4f5ecc2f1 100644 --- a/src/modules/top-level.nix +++ b/src/modules/top-level.nix @@ -1,7 +1,6 @@ { config, pkgs, lib, ... }: let types = lib.types; - mkNakedShell = pkgs.callPackage ./mkNakedShell.nix { }; # Returns a list of all the entries in a folder listEntries = path: map (name: path + "/${name}") (builtins.attrNames (builtins.readDir path)); @@ -67,6 +66,42 @@ in default = [ ]; }; + unsetEnvVars = lib.mkOption { + type = types.listOf types.str; + description = "Remove these list of env vars from being exported to keep the shell/direnv more lean."; + # manually determined with knowledge from https://nixos.wiki/wiki/C + default = [ + "HOST_PATH" + "NIX_BUILD_CORES" + "__structuredAttrs" + "buildInputs" + "buildPhase" + "builder" + "depsBuildBuild" + "depsBuildBuildPropagated" + "depsBuildTarget" + "depsBuildTargetPropagated" + "depsHostHost" + "depsHostHostPropagated" + "depsTargetTarget" + "depsTargetTargetPropagated" + "doCheck" + "doInstallCheck" + "nativeBuildInputs" + "out" + "outputs" + "patches" + "phases" + "preferLocalBuild" + "propagatedBuildInputs" + "propagatedNativeBuildInputs" + "shell" + "shellHook" + "stdenv" + "strictDeps" + ]; + }; + shell = lib.mkOption { type = types.package; internal = true; @@ -100,7 +135,7 @@ in default = [ ]; example = [ "you should fix this or that" ]; description = '' - This option allows modules to express warnings about theV + This option allows modules to express warnings about the configuration. For example, `lib.mkRenamedOptionModule` uses this to display a warning message when a renamed option is used. ''; @@ -110,6 +145,7 @@ in root = lib.mkOption { type = types.str; internal = true; + default = builtins.getEnv "PWD"; }; dotfile = lib.mkOption { @@ -137,6 +173,9 @@ in ./update-check.nix ./containers.nix ./debug.nix + ./lib.nix + ./tests.nix + ./cachix.nix ] ++ (listEntries ./languages) ++ (listEntries ./services) @@ -145,20 +184,16 @@ in ; config = { - # TODO: figure out how to get relative path without impure mode - devenv.root = lib.mkDefault ( - let - pwd = builtins.getEnv "PWD"; - in - if pwd == "" then - throw '' + assertions = [ + { + assertion = config.devenv.root != ""; + message = '' devenv was not able to determine the current directory. - Make sure Nix runs with the `--impure` flag. - See https://devenv.sh/guides/using-with-flakes/ - '' - else pwd - ); + See https://devenv.sh/guides/using-with-flakes/ how to use it with flakes. + ''; + } + ]; devenv.dotfile = config.devenv.root + "/.devenv"; devenv.state = config.devenv.dotfile + "/state"; devenv.profile = profile; @@ -168,6 +203,11 @@ in env.DEVENV_DOTFILE = config.devenv.dotfile; env.DEVENV_ROOT = config.devenv.root; + packages = [ + # needed to make sure we can load libs + pkgs.pkg-config + ]; + enterShell = '' export PS1="\[\e[0;34m\](devenv)\[\e[0m\] ''${PS1-}" @@ -192,22 +232,24 @@ in mkdir -p .devenv rm -f .devenv/profile ln -s ${profile} .devenv/profile + unset ${lib.concatStringsSep " " config.unsetEnvVars} ''; shell = performAssertions ( - mkNakedShell { + pkgs.mkShell ({ name = "devenv-shell"; - env = config.env; - profile = profile; - shellHook = config.enterShell; - debug = config.devenv.debug; - } + packages = config.packages; + shellHook = '' + ${lib.optionalString config.devenv.debug "set -x"} + ${config.enterShell} + ''; + } // config.env) ); infoSections."env" = lib.mapAttrsToList (name: value: "${name}: ${toString value}") config.env; infoSections."packages" = builtins.map (package: package.name) (builtins.filter (package: !(builtins.elem package.name (builtins.attrNames config.scripts))) config.packages); - ci = [ config.shell.inputDerivation ]; - ciDerivation = pkgs.runCommand "ci" { } ("ls " + toString config.ci + " && touch $out"); + ci = [ config.shell ]; + ciDerivation = pkgs.runCommand "ci" { } "echo ${toString config.ci} > $out"; }; } diff --git a/tests/cli/.test.sh b/tests/cli/.test.sh new file mode 100755 index 000000000..d9cdf6e3c --- /dev/null +++ b/tests/cli/.test.sh @@ -0,0 +1,2 @@ +set -xe +devenv build languages.python.package \ No newline at end of file diff --git a/tests/cli/devenv.nix b/tests/cli/devenv.nix new file mode 100644 index 000000000..ecce39d5a --- /dev/null +++ b/tests/cli/devenv.nix @@ -0,0 +1,3 @@ +{ ... }: { + languages.python.enable = true; +} From cfc0cb8ea74c96b16297d740c4a6a7586cae6b8e Mon Sep 17 00:00:00 2001 From: figsoda Date: Mon, 14 Aug 2023 11:27:12 -0400 Subject: [PATCH 008/146] devenv print-dev-env --json --- src/devenv/cli.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/devenv/cli.py b/src/devenv/cli.py index 0300bdc7e..1a6ba2c7d 100644 --- a/src/devenv/cli.py +++ b/src/devenv/cli.py @@ -254,7 +254,7 @@ def cleanup_symlinks(folder): to_gc.append(full_path) return to_gc, removed_symlinks -def get_dev_environment(ctx, logging=True): +def get_dev_environment(ctx, json=False, logging=True): ctx.invoke(assemble) if logging: action = log_task('Building shell') @@ -262,7 +262,10 @@ def get_dev_environment(ctx, logging=True): action = suppress() with action: gc_root = os.path.join(os.environ['DEVENV_GC'], 'shell') - env = run_nix(f"print-dev-env --profile '{gc_root}'", logging=False, use_cachix=True) + cmd = f"print-dev-env --profile '{gc_root}'" + if json: + cmd += " --json" + env = run_nix(cmd, logging=False, use_cachix=True) run_command(f"nix-env -p '{gc_root}' --delete-generations old", logging=False, disable_stderr=True) symlink_force(Path(f'{ctx.obj["gc_project"]}-shell'), gc_root) return env, gc_root @@ -547,9 +550,10 @@ def ci(ctx): add_gc('ci', output_path) @cli.command(hidden=True) +@click.option("--json", is_flag=True) @click.pass_context -def print_dev_env(ctx): - env, _ = get_dev_environment(ctx, logging=False) +def print_dev_env(ctx, json): + env, _ = get_dev_environment(ctx, json=json, logging=False) click.echo(env) def get_version(): @@ -757,4 +761,4 @@ def build(ctx, attrs): output = run_nix(f"build --print-out-paths --print-build-logs --no-link {attrs}", use_cachix=True) log("Built:", level="info") for path in output.splitlines(): - log(path, level="info") \ No newline at end of file + log(path, level="info") From d517bf084e6a53fbcd9c2b1e14ceed2cb9746de6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Wed, 16 Aug 2023 17:28:12 +0100 Subject: [PATCH 009/146] Nix 2.17 + patches --- devenv.lock | 39 ++++++++++++++++++++++++++++----------- devenv.yaml | 2 +- flake.lock | 43 ++++++++++++++++++++++++++++++------------- flake.nix | 2 +- 4 files changed, 60 insertions(+), 26 deletions(-) diff --git a/devenv.lock b/devenv.lock index 5f7d4f8f5..78186f724 100644 --- a/devenv.lock +++ b/devenv.lock @@ -27,6 +27,22 @@ "type": "github" } }, + "flake-compat_2": { + "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" + } + }, "flake-utils": { "inputs": { "systems": "systems" @@ -84,6 +100,7 @@ }, "nix": { "inputs": { + "flake-compat": "flake-compat", "lowdown-src": "lowdown-src", "nixpkgs": [ "nixpkgs" @@ -91,27 +108,27 @@ "nixpkgs-regression": "nixpkgs-regression" }, "locked": { - "lastModified": 1676545802, - "narHash": "sha256-EK4rZ+Hd5hsvXnzSzk2ikhStJnD63odF7SzsQ8CuSPU=", + "lastModified": 1692371301, "owner": "domenkozar", "repo": "nix", - "rev": "7c91803598ffbcfe4a55c44ac6d49b2cf07a527f", + "rev": "46fdc0fc02ca40b12c825176e8ae8aa1c9ea78dd", + "treeHash": "2e6d64573b0179ba7698ff499d53d8fdcadb824c", "type": "github" }, "original": { "owner": "domenkozar", - "ref": "relaxed-flakes", + "ref": "devenv-2.17", "repo": "nix", "type": "github" } }, "nixpkgs": { "locked": { - "lastModified": 1690952720, - "narHash": "sha256-fPsiQHARfhVxXpWgcuSKvkYwSco8K13K7XevBpdIfPg=", + "lastModified": 1692311226, "owner": "NixOS", "repo": "nixpkgs", - "rev": "96112a3ed5d12bb1758b42c63b924c004b6c0bc9", + "rev": "ef8288935ba859fc3b30632fa6e04705f81b9c2a", + "treeHash": "f5a95213a097b73df9d76855ed69477a10203da5", "type": "github" }, "original": { @@ -155,7 +172,7 @@ }, "pre-commit-hooks": { "inputs": { - "flake-compat": "flake-compat", + "flake-compat": "flake-compat_2", "flake-utils": "flake-utils", "gitignore": "gitignore", "nixpkgs": [ @@ -164,11 +181,11 @@ "nixpkgs-stable": "nixpkgs-stable" }, "locked": { - "lastModified": 1690743255, - "narHash": "sha256-dsJzQsyJGWCym1+LMyj2rbYmvjYmzeOrk7ypPrSFOPo=", + "lastModified": 1692274144, "owner": "cachix", "repo": "pre-commit-hooks.nix", - "rev": "fcbf4705d98398d084e6cb1c826a0b90a91d22d7", + "rev": "7e3517c03d46159fdbf8c0e5c97f82d5d4b0c8fa", + "treeHash": "afa8541829678435ff40faa2141bbe85bc567a75", "type": "github" }, "original": { diff --git a/devenv.yaml b/devenv.yaml index 9cbe87bf5..9ce3974f9 100644 --- a/devenv.yaml +++ b/devenv.yaml @@ -2,7 +2,7 @@ inputs: nixpkgs: url: github:NixOS/nixpkgs/nixpkgs-unstable nix: - url: github:domenkozar/nix/relaxed-flakes + url: github:domenkozar/nix/devenv-2.17 inputs: nixpkgs: follows: nixpkgs diff --git a/flake.lock b/flake.lock index 8d1c9b0a2..69bb58415 100644 --- a/flake.lock +++ b/flake.lock @@ -16,6 +16,22 @@ "type": "github" } }, + "flake-compat_2": { + "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" + } + }, "flake-utils": { "inputs": { "systems": "systems" @@ -91,6 +107,7 @@ }, "nix": { "inputs": { + "flake-compat": "flake-compat_2", "lowdown-src": "lowdown-src", "nixpkgs": [ "nixpkgs" @@ -98,16 +115,16 @@ "nixpkgs-regression": "nixpkgs-regression" }, "locked": { - "lastModified": 1676545802, - "narHash": "sha256-EK4rZ+Hd5hsvXnzSzk2ikhStJnD63odF7SzsQ8CuSPU=", + "lastModified": 1692371301, + "narHash": "sha256-lQUS9G1qnzOkQlvafgb01/ewHVwLS4MwEipd4k96cnw=", "owner": "domenkozar", "repo": "nix", - "rev": "7c91803598ffbcfe4a55c44ac6d49b2cf07a527f", + "rev": "46fdc0fc02ca40b12c825176e8ae8aa1c9ea78dd", "type": "github" }, "original": { "owner": "domenkozar", - "ref": "relaxed-flakes", + "ref": "devenv-2.17", "repo": "nix", "type": "github" } @@ -135,11 +152,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1690083312, - "narHash": "sha256-I3egwgNXavad1eIjWu1kYyi0u73di/sMmlnQIuzQASk=", + "lastModified": 1692311226, + "narHash": "sha256-mRzNup0PIUD6YxbrYvjzL7f+1oaOGy9nmGCV3AZkQus=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "af8cd5ded7735ca1df1a1174864daab75feeb64a", + "rev": "ef8288935ba859fc3b30632fa6e04705f81b9c2a", "type": "github" }, "original": { @@ -190,11 +207,11 @@ ] }, "locked": { - "lastModified": 1689849924, - "narHash": "sha256-d259Z2S7CS7Na04qQNQ6LYQILuI7cf4Rpe76qc4mz40=", + "lastModified": 1692369730, + "narHash": "sha256-VcCb/XxybOv0Py1Gnhmih9mfwyCUVDds/gID2VcscAo=", "owner": "nix-community", "repo": "poetry2nix", - "rev": "1d7eda9336f336392d24e9602be5cb9be7ae405c", + "rev": "e4cd574cac251dd44bdbc77c1e98d790fe27b781", "type": "github" }, "original": { @@ -216,11 +233,11 @@ "nixpkgs-stable": "nixpkgs-stable" }, "locked": { - "lastModified": 1689668210, - "narHash": "sha256-XAATwDkaUxH958yXLs1lcEOmU6pSEIkatY3qjqk8X0E=", + "lastModified": 1692274144, + "narHash": "sha256-BxTQuRUANQ81u8DJznQyPmRsg63t4Yc+0kcyq6OLz8s=", "owner": "cachix", "repo": "pre-commit-hooks.nix", - "rev": "eb433bff05b285258be76513add6f6c57b441775", + "rev": "7e3517c03d46159fdbf8c0e5c97f82d5d4b0c8fa", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index 339fba55e..e38499094 100644 --- a/flake.nix +++ b/flake.nix @@ -19,7 +19,7 @@ flake = false; }; inputs.nix = { - url = "github:domenkozar/nix/relaxed-flakes"; + url = "github:domenkozar/nix/devenv-2.17"; inputs.nixpkgs.follows = "nixpkgs"; }; inputs.poetry2nix = { From 1d37fdb0d13c36be996d68ee06bed5bde8f39083 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Sat, 19 Aug 2023 09:38:53 +0100 Subject: [PATCH 010/146] shellcheck --- devcontainer/nix-entrypoint.sh | 1 + examples/clickhouse/.test.sh | 1 + examples/dotenv/.test.sh | 1 - examples/fly.io/.test.sh | 1 - examples/imports/.test.sh | 1 - examples/mysql/.test.sh | 1 + examples/postgres/.test.sh | 1 + examples/temporal/.test.sh | 14 ++++++++++++-- examples/vault/.test.sh | 16 +++++++++++++--- tests/cli/.test.sh | 1 + 10 files changed, 30 insertions(+), 8 deletions(-) diff --git a/devcontainer/nix-entrypoint.sh b/devcontainer/nix-entrypoint.sh index 63fd59c4e..7665b9e13 100644 --- a/devcontainer/nix-entrypoint.sh +++ b/devcontainer/nix-entrypoint.sh @@ -4,6 +4,7 @@ set +e if ! pidof nix-daemon > /dev/null 2>&1; then start_ok=false if [ "$(id -u)" = "0" ]; then + # shellcheck disable=SC1091 # shellcheck source=/dev/null ( . /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh; /nix/var/nix/profiles/default/bin/nix-daemon > /tmp/nix-daemon.log 2>&1 ) & # shellcheck disable=SC2181 diff --git a/examples/clickhouse/.test.sh b/examples/clickhouse/.test.sh index 723bab881..4fb1ced15 100755 --- a/examples/clickhouse/.test.sh +++ b/examples/clickhouse/.test.sh @@ -1,3 +1,4 @@ +#!/usr/bin/env bash set -xe timeout 20 bash -c 'until echo > /dev/tcp/localhost/9000; do sleep 0.5; done' sleep 2 diff --git a/examples/dotenv/.test.sh b/examples/dotenv/.test.sh index d4cb543c4..a7e1d576a 100755 --- a/examples/dotenv/.test.sh +++ b/examples/dotenv/.test.sh @@ -1,5 +1,4 @@ #!/usr/bin/env bash - env | grep FOO=1 env | grep BAR=1 env | grep BAZ=5 diff --git a/examples/fly.io/.test.sh b/examples/fly.io/.test.sh index db0f6a31c..b85301004 100755 --- a/examples/fly.io/.test.sh +++ b/examples/fly.io/.test.sh @@ -1,5 +1,4 @@ #!/usr/bin/env bash - if [ "$(uname -s)" == "Linux" ]; then devenv container shell devenv container processes diff --git a/examples/imports/.test.sh b/examples/imports/.test.sh index 6f8d16c29..10cb4a879 100755 --- a/examples/imports/.test.sh +++ b/examples/imports/.test.sh @@ -1,4 +1,3 @@ #!/usr/bin/env bash - env | grep "FILE=1" env | grep "FOLDER=1" \ No newline at end of file diff --git a/examples/mysql/.test.sh b/examples/mysql/.test.sh index 7bdadcb31..e16683de7 100755 --- a/examples/mysql/.test.sh +++ b/examples/mysql/.test.sh @@ -1,3 +1,4 @@ +#!/usr/bin/env bash set -ex timeout 60 bash -c 'until MYSQL_PWD="" mysql -u root test_database < /dev/null; do sleep 0.5; done' \ No newline at end of file diff --git a/examples/postgres/.test.sh b/examples/postgres/.test.sh index 56081a2af..36f49e3d8 100755 --- a/examples/postgres/.test.sh +++ b/examples/postgres/.test.sh @@ -1,2 +1,3 @@ +#!/usr/bin/env bash set -ex timeout 20 bash -c 'until psql -h /tmp -c "SELECT 1" mydb 2>/dev/null; do sleep 0.5; done' diff --git a/examples/temporal/.test.sh b/examples/temporal/.test.sh index 3c27ee2f7..86f7ffeb2 100755 --- a/examples/temporal/.test.sh +++ b/examples/temporal/.test.sh @@ -5,7 +5,17 @@ export TEMPORAL_ADDRESS=127.0.0.1:17233 timeout 20 bash -c 'until echo > /dev/tcp/localhost/17233; do sleep 0.5; done' -sleep 1 +# Continuously check temporal status until it returns successfully (up to a maximum of 20 times) +# shellcheck disable=SC2034 +for i in $(seq 1 20); do + check_temporal_status + if [ $TEMPORAL_EXIT_STATUS -eq 0 ]; then + echo "Service is up..." + break + else + sleep 1 + fi +done if ! temporal operator cluster health; then echo "Temporal not started" @@ -21,4 +31,4 @@ temporal operator cluster system echo "$TEMPORAL_OUTPUT" # Exit the script -exit $TEMPORAL_EXIT_STATUS \ No newline at end of file +exit "$TEMPORAL_EXIT_STATUS" \ No newline at end of file diff --git a/examples/vault/.test.sh b/examples/vault/.test.sh index e511bd6ce..408a4ecf1 100755 --- a/examples/vault/.test.sh +++ b/examples/vault/.test.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -set -ex +set -x # vault status and store its exit status check_vault_status() { @@ -8,9 +8,19 @@ check_vault_status() { VAULT_EXIT_STATUS=$? } -trap devenv_stop EXIT +# Continuously check vault status until it returns successfully (up to a maximum of 100 times) +# shellcheck disable=SC2034 +for i in $(seq 1 20); do + check_vault_status + if [ $VAULT_EXIT_STATUS -eq 0 ]; then + echo "Service is up..." + break + else + sleep 1 + fi +done timeout 20 bash -c 'until echo > /dev/tcp/localhost/8200; do sleep 0.5; done' # Exit the script -exit $VAULT_EXIT_STATUS \ No newline at end of file +exit "$VAULT_EXIT_STATUS" \ No newline at end of file diff --git a/tests/cli/.test.sh b/tests/cli/.test.sh index d9cdf6e3c..40a01a3ed 100755 --- a/tests/cli/.test.sh +++ b/tests/cli/.test.sh @@ -1,2 +1,3 @@ +#!/usr/bin/env bash set -xe devenv build languages.python.package \ No newline at end of file From 0fa6402c19a3ba595aea913a86dd9592a49db7d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Sat, 19 Aug 2023 12:25:56 +0100 Subject: [PATCH 011/146] Debug --- .github/workflows/buildtest.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/buildtest.yml b/.github/workflows/buildtest.yml index 7283c3064..600f16948 100644 --- a/.github/workflows/buildtest.yml +++ b/.github/workflows/buildtest.yml @@ -29,6 +29,8 @@ jobs: run: | nix profile remove '.*' nix profile install --accept-flake-config . + - name: Setup tmate session + uses: mxschmitt/action-tmate@v3 - name: Run tests run: | devenv ci From 1cc2387c2e2203c47d2edcf322888bb1d75b23f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Sat, 19 Aug 2023 19:18:12 +0100 Subject: [PATCH 012/146] Disable macos-latest for now --- .github/workflows/buildtest.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/buildtest.yml b/.github/workflows/buildtest.yml index 600f16948..73b273468 100644 --- a/.github/workflows/buildtest.yml +++ b/.github/workflows/buildtest.yml @@ -13,7 +13,7 @@ jobs: strategy: fail-fast: false matrix: - os: [[ubuntu-latest], [macos-latest], [self-hosted, macOS], [self-hosted, linux, ARM64]] + os: [[ubuntu-latest], [self-hosted, macOS], [nscloud-arm64]] runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v4 @@ -29,8 +29,6 @@ jobs: run: | nix profile remove '.*' nix profile install --accept-flake-config . - - name: Setup tmate session - uses: mxschmitt/action-tmate@v3 - name: Run tests run: | devenv ci From 868f1b96eb9e3eaa4db40aa270fb3f8483188fb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Sun, 20 Aug 2023 09:29:13 +0100 Subject: [PATCH 013/146] fix a few examples --- examples/cockroachdb/devenv.yaml | 1 + examples/modern-c/devenv.nix | 1 + examples/rubyonrails/devenv.nix | 4 ++++ 3 files changed, 6 insertions(+) diff --git a/examples/cockroachdb/devenv.yaml b/examples/cockroachdb/devenv.yaml index 89a8475be..c1430d735 100644 --- a/examples/cockroachdb/devenv.yaml +++ b/examples/cockroachdb/devenv.yaml @@ -2,3 +2,4 @@ allowUnfree: true inputs: nixpkgs: url: github:NixOS/nixpkgs/nixpkgs-unstable +allowUnfree: true \ No newline at end of file diff --git a/examples/modern-c/devenv.nix b/examples/modern-c/devenv.nix index fb8ab98d0..b50201b2c 100644 --- a/examples/modern-c/devenv.nix +++ b/examples/modern-c/devenv.nix @@ -7,6 +7,7 @@ cmake --version ''; + pre-commit.excludes = [ ".devenv" ]; pre-commit.hooks = { clang-tidy.enable = true; }; diff --git a/examples/rubyonrails/devenv.nix b/examples/rubyonrails/devenv.nix index aaea47e1a..e93024ee8 100644 --- a/examples/rubyonrails/devenv.nix +++ b/examples/rubyonrails/devenv.nix @@ -4,6 +4,10 @@ languages.ruby.enable = true; languages.ruby.version = "3.2.2"; + packages = [ + pkgs.openssl + ]; + services.postgres.enable = true; processes.rails.exec = "rails server"; From ce115efe24ba2317147f6b85e430e63bf0e62977 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Mon, 21 Aug 2023 18:02:15 +0100 Subject: [PATCH 014/146] python: wrap to specify LD_LIBRARY_PATH --- devenv.nix | 2 -- src/modules/languages/python.nix | 25 +++++++++++++++++++------ tests/python-native-libs/.test.sh | 7 +++++++ tests/python-native-libs/devenv.nix | 18 ++++++++++++++++++ 4 files changed, 44 insertions(+), 8 deletions(-) create mode 100755 tests/python-native-libs/.test.sh create mode 100644 tests/python-native-libs/devenv.nix diff --git a/devenv.nix b/devenv.nix index b9197e319..79a1ac507 100644 --- a/devenv.nix +++ b/devenv.nix @@ -2,8 +2,6 @@ { env.DEVENV_NIX = inputs.nix.packages.${pkgs.stdenv.system}.nix; - # TODO: manylinux for python - env.LD_LIBRARY_PATH = config.devenv.dotfile + "/profile/lib"; packages = [ pkgs.cairo diff --git a/src/modules/languages/python.nix b/src/modules/languages/python.nix index d9b6dc3da..1e427830b 100644 --- a/src/modules/languages/python.nix +++ b/src/modules/languages/python.nix @@ -2,6 +2,18 @@ let cfg = config.languages.python; + package = cfg.package.override (old: { + self = pkgs.callPackage "${pkgs.path}/pkgs/development/interpreters/python/wrapper.nix" { + python = old.self; + requiredPythonModules = cfg.package.pkgs.requiredPythonModules; + makeWrapperArgs = [ + "--set" + "LD_LIBRARY_PATH" + # Make sure the python interpreter can find the native libraries. + "${config.devenv.dotfile}/profile/lib" + ]; + }; + }); requirements = pkgs.writeText "requirements.txt" ( if lib.isPath cfg.venv.requirements @@ -33,7 +45,7 @@ let ${lib.optionalString cfg.poetry.enable '' [ -f "${config.env.DEVENV_STATE}/poetry.lock.checksum" ] && rm ${config.env.DEVENV_STATE}/poetry.lock.checksum ''} - ${cfg.package.interpreter} -m venv "$VENV_PATH" + ${package.interpreter} -m venv "$VENV_PATH" ${pkgs.coreutils}/bin/ln -sf ${config.devenv.profile} "$VENV_PATH"/devenv-profile fi source "$VENV_PATH"/bin/activate @@ -52,7 +64,7 @@ let unset VIRTUAL_ENV # Make sure poetry's venv uses the configured python executable. - ${cfg.poetry.package}/bin/poetry env use --no-interaction --quiet ${cfg.package.interpreter} + ${cfg.poetry.package}/bin/poetry env use --no-interaction --quiet ${package.interpreter} } function _devenv_poetry_install @@ -61,7 +73,7 @@ let # Avoid running "poetry install" for every shell. # 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="${cfg.package.interpreter}:$(${pkgs.nix}/bin/nix-hash --type sha256 pyproject.toml):$(${pkgs.nix}/bin/nix-hash --type sha256 poetry.lock):''${POETRY_INSTALL_COMMAND[@]}" + 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 if [ -f "$POETRY_CHECKSUM_FILE" ] then @@ -192,13 +204,14 @@ in languages.python.poetry.activate.enable = lib.mkIf cfg.poetry.enable (lib.mkDefault true); languages.python.package = lib.mkMerge [ - (lib.mkIf (cfg.version != null) (nixpkgs-python.packages.${pkgs.stdenv.system}.${cfg.version} or (throw "Unsupported Python version, see https://github.com/cachix/nixpkgs-python#supported-python-versions"))) + (lib.mkIf (cfg.version != null) + (nixpkgs-python.packages.${pkgs.stdenv.system}.${cfg.version} or (throw "Unsupported Python version, see https://github.com/cachix/nixpkgs-python#supported-python-versions"))) ]; cachix.pull = lib.mkIf (cfg.version != null) [ "nixpkgs-python" ]; packages = [ - cfg.package + package ] ++ (lib.optional cfg.poetry.enable cfg.poetry.package); env = lib.optionalAttrs cfg.poetry.enable { @@ -212,7 +225,7 @@ in enterShell = lib.concatStringsSep "\n" ([ '' - export PYTHONPATH="$DEVENV_PROFILE/${cfg.package.sitePackages}''${PYTHONPATH:+:$PYTHONPATH}" + export PYTHONPATH="$DEVENV_PROFILE/${package.sitePackages}''${PYTHONPATH:+:$PYTHONPATH}" '' ] ++ (lib.optional cfg.venv.enable '' diff --git a/tests/python-native-libs/.test.sh b/tests/python-native-libs/.test.sh new file mode 100755 index 000000000..0d13911ad --- /dev/null +++ b/tests/python-native-libs/.test.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash +set -ex + +python -c "from PIL import Image" +python -c "import grpc_tools" +python -c "import transformers" +python -c "import torch" \ No newline at end of file diff --git a/tests/python-native-libs/devenv.nix b/tests/python-native-libs/devenv.nix new file mode 100644 index 000000000..ddccfb6bb --- /dev/null +++ b/tests/python-native-libs/devenv.nix @@ -0,0 +1,18 @@ +{ pkgs, ... }: { + packages = with pkgs; [ + pkgs.stdenv.cc.cc.lib + pkgs.cairo + pkgs.glibc + ]; + + languages.python = { + enable = true; + venv.enable = true; + venv.requirements = '' + pillow + grpcio-tools + transformers + torch + ''; + }; +} From bc7f048a8f29dd701ea16d10004a90cd866e87f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Mon, 21 Aug 2023 18:26:24 +0100 Subject: [PATCH 015/146] bump nix --- devenv.lock | 12 ++++++------ flake.lock | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/devenv.lock b/devenv.lock index 78186f724..b8057944f 100644 --- a/devenv.lock +++ b/devenv.lock @@ -108,11 +108,11 @@ "nixpkgs-regression": "nixpkgs-regression" }, "locked": { - "lastModified": 1692371301, + "lastModified": 1692627130, "owner": "domenkozar", "repo": "nix", - "rev": "46fdc0fc02ca40b12c825176e8ae8aa1c9ea78dd", - "treeHash": "2e6d64573b0179ba7698ff499d53d8fdcadb824c", + "rev": "96e8d6a3f33fa0c770ad421463ab168239dc921b", + "treeHash": "8ce5bd7323dd5d1a7015cb7f5fcf0cefb0047069", "type": "github" }, "original": { @@ -124,11 +124,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1692311226, + "lastModified": 1692494774, "owner": "NixOS", "repo": "nixpkgs", - "rev": "ef8288935ba859fc3b30632fa6e04705f81b9c2a", - "treeHash": "f5a95213a097b73df9d76855ed69477a10203da5", + "rev": "3476a10478587dec90acb14ec6bde0966c545cc0", + "treeHash": "96162525b38e424adc09e55f362302401e9f1762", "type": "github" }, "original": { diff --git a/flake.lock b/flake.lock index 69bb58415..a5d79d4c9 100644 --- a/flake.lock +++ b/flake.lock @@ -115,11 +115,11 @@ "nixpkgs-regression": "nixpkgs-regression" }, "locked": { - "lastModified": 1692371301, - "narHash": "sha256-lQUS9G1qnzOkQlvafgb01/ewHVwLS4MwEipd4k96cnw=", + "lastModified": 1692627130, + "narHash": "sha256-vJ0KINKrqKR38an/K/0UaMwstpHDnA6cvE0ukWHa3yg=", "owner": "domenkozar", "repo": "nix", - "rev": "46fdc0fc02ca40b12c825176e8ae8aa1c9ea78dd", + "rev": "96e8d6a3f33fa0c770ad421463ab168239dc921b", "type": "github" }, "original": { @@ -152,11 +152,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1692311226, - "narHash": "sha256-mRzNup0PIUD6YxbrYvjzL7f+1oaOGy9nmGCV3AZkQus=", + "lastModified": 1692494774, + "narHash": "sha256-noGVoOTyZ2Kr5OFglzKYOX48cx3hggdCPbXrYMG2FDw=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "ef8288935ba859fc3b30632fa6e04705f81b9c2a", + "rev": "3476a10478587dec90acb14ec6bde0966c545cc0", "type": "github" }, "original": { From 78d4f825f5362209ceefaa3d75979731ad01682b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Mon, 21 Aug 2023 20:29:13 +0100 Subject: [PATCH 016/146] python-poetry: debug LD_LIBRARY_PATH --- examples/python-poetry/.test.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/examples/python-poetry/.test.sh b/examples/python-poetry/.test.sh index c40dc901d..3675ebf54 100755 --- a/examples/python-poetry/.test.sh +++ b/examples/python-poetry/.test.sh @@ -6,6 +6,8 @@ POETRY_VENV="$PWD/.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' From a70c6173038dc5c4c38434a50f7294398ca297f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Mon, 21 Aug 2023 21:33:28 +0100 Subject: [PATCH 017/146] python: specify also DYLD_LIBRARY_PATH --- src/modules/languages/python.nix | 9 +++++++-- tests/python-native-libs/.test.sh | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/modules/languages/python.nix b/src/modules/languages/python.nix index 1e427830b..e103752f5 100644 --- a/src/modules/languages/python.nix +++ b/src/modules/languages/python.nix @@ -7,8 +7,13 @@ let python = old.self; requiredPythonModules = cfg.package.pkgs.requiredPythonModules; makeWrapperArgs = [ - "--set" - "LD_LIBRARY_PATH" + "--prefix" + "LIBRARY_PATH" + # Make sure the python interpreter can find the native libraries. + "${config.devenv.dotfile}/profile/lib" + ] ++ lib.optionals pkgs.stdenv.isDarwin [ + "--prefix" + "DYLD_LIBRARY_PATH" # Make sure the python interpreter can find the native libraries. "${config.devenv.dotfile}/profile/lib" ]; diff --git a/tests/python-native-libs/.test.sh b/tests/python-native-libs/.test.sh index 0d13911ad..7b91c3485 100755 --- a/tests/python-native-libs/.test.sh +++ b/tests/python-native-libs/.test.sh @@ -2,6 +2,6 @@ set -ex python -c "from PIL import Image" -python -c "import grpc_tools" +python -c "import grpc_tools.protoc" python -c "import transformers" python -c "import torch" \ No newline at end of file From 434e9155ad63cab441a70778f3d39e4ef82926e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Mon, 21 Aug 2023 21:33:52 +0100 Subject: [PATCH 018/146] Add languages.python.manylinux.enable, pass libraries to the interpreter. --- src/modules/languages/python.nix | 70 +++++++++++++++++++--------- tests/python-native-libs/.test.sh | 4 +- tests/python-native-libs/devenv.nix | 6 +-- tests/python-native-libs/devenv.yaml | 3 ++ 4 files changed, 56 insertions(+), 27 deletions(-) create mode 100644 tests/python-native-libs/devenv.yaml diff --git a/src/modules/languages/python.nix b/src/modules/languages/python.nix index e103752f5..a2d713667 100644 --- a/src/modules/languages/python.nix +++ b/src/modules/languages/python.nix @@ -2,23 +2,29 @@ let cfg = config.languages.python; - package = cfg.package.override (old: { - self = pkgs.callPackage "${pkgs.path}/pkgs/development/interpreters/python/wrapper.nix" { - python = old.self; - requiredPythonModules = cfg.package.pkgs.requiredPythonModules; - makeWrapperArgs = [ - "--prefix" - "LIBRARY_PATH" - # Make sure the python interpreter can find the native libraries. - "${config.devenv.dotfile}/profile/lib" - ] ++ lib.optionals pkgs.stdenv.isDarwin [ - "--prefix" - "DYLD_LIBRARY_PATH" - # Make sure the python interpreter can find the native libraries. - "${config.devenv.dotfile}/profile/lib" - ]; - }; - }); + libraries = lib.makeLibraryPath + ((lib.optional cfg.manylinux.enable pkgs.pythonManylinuxPackages.manylinux2014Package) + # see https://matrix.to/#/!kjdutkOsheZdjqYmqp:nixos.org/$XJ5CO4bKMevYzZq_rrNo64YycknVFJIJTy6hVCJjRlA?via=nixos.org&via=matrix.org&via=nixos.dev + ++ [ pkgs.stdenv.cc.cc.lib ] + ++ cfg.libraries + ); + + readlink = "${pkgs.coreutils}/bin/readlink -f "; + package = pkgs.callPackage "${pkgs.path}/pkgs/development/interpreters/python/wrapper.nix" { + python = cfg.package; + requiredPythonModules = cfg.package.pkgs.requiredPythonModules; + makeWrapperArgs = [ + "--prefix" + "LD_LIBRARY_PATH" + ":" + libraries + ] ++ lib.optionals pkgs.stdenv.isDarwin [ + "--prefix" + "DYLD_LIBRARY_PATH" + ":" + libraries + ]; + }; requirements = pkgs.writeText "requirements.txt" ( if lib.isPath cfg.venv.requirements @@ -39,19 +45,19 @@ let VENV_PATH="${config.env.DEVENV_STATE}/venv" - if [ ! -L "$VENV_PATH"/devenv-profile ] \ - || [ "$(${pkgs.coreutils}/bin/readlink "$VENV_PATH"/devenv-profile)" != "${config.devenv.profile}" ] + if [ "$(${readlink} "$VENV_PATH"/bin/python)" != "$(${readlink} ${package.interpreter}/bin/python)" ] \ + || [ "$(${readlink} "$VENV_PATH"/requirements.txt)" != "$(${readlink} ${if requirements != null then requirements else "$VENV_PATH/requirements.txt"})" ] then if [ -d "$VENV_PATH" ] then - echo "Rebuilding Python venv..." + echo "Python interpreter/requirements changed, rebuilding Python venv..." ${pkgs.coreutils}/bin/rm -rf "$VENV_PATH" fi ${lib.optionalString cfg.poetry.enable '' [ -f "${config.env.DEVENV_STATE}/poetry.lock.checksum" ] && rm ${config.env.DEVENV_STATE}/poetry.lock.checksum ''} + echo ${package.interpreter} -m venv "$VENV_PATH" ${package.interpreter} -m venv "$VENV_PATH" - ${pkgs.coreutils}/bin/ln -sf ${config.devenv.profile} "$VENV_PATH"/devenv-profile fi source "$VENV_PATH"/bin/activate ${lib.optionalString (cfg.venv.requirements != null) '' @@ -123,6 +129,28 @@ in description = "The Python package to use."; }; + manylinux.enable = lib.mkOption { + type = lib.types.bool; + default = pkgs.stdenv.isLinux; + description = '' + Whether to install manylinux2014 libraries. + + Enabled by default on linux; + + This is useful when you want to use Python wheels that depend on manylinux2014 libraries. + ''; + }; + + libraries = lib.mkOption { + type = lib.types.listOf lib.types.path; + default = [ "${config.devenv.dotfile}/profile" ]; + description = '' + Additional libraries to make available to the Python interpreter. + + This is useful when you want to use Python wheels that depend on native libraries. + ''; + }; + version = lib.mkOption { type = lib.types.nullOr lib.types.str; default = null; diff --git a/tests/python-native-libs/.test.sh b/tests/python-native-libs/.test.sh index 7b91c3485..119fd2259 100755 --- a/tests/python-native-libs/.test.sh +++ b/tests/python-native-libs/.test.sh @@ -4,4 +4,6 @@ set -ex python -c "from PIL import Image" python -c "import grpc_tools.protoc" python -c "import transformers" -python -c "import torch" \ No newline at end of file +python -c "import torch" + +# TODO: invoke a subprocess with an old glibc and assert it doesn't crash \ No newline at end of file diff --git a/tests/python-native-libs/devenv.nix b/tests/python-native-libs/devenv.nix index ddccfb6bb..d8c5e5d34 100644 --- a/tests/python-native-libs/devenv.nix +++ b/tests/python-native-libs/devenv.nix @@ -1,9 +1,5 @@ { pkgs, ... }: { - packages = with pkgs; [ - pkgs.stdenv.cc.cc.lib - pkgs.cairo - pkgs.glibc - ]; + packages = [ pkgs.cairo ]; languages.python = { enable = true; diff --git a/tests/python-native-libs/devenv.yaml b/tests/python-native-libs/devenv.yaml new file mode 100644 index 000000000..d417691da --- /dev/null +++ b/tests/python-native-libs/devenv.yaml @@ -0,0 +1,3 @@ +inputs: + devenv: + url: path:./../../src/modules From 6c1194bb0beff22f060fffa4f81a7a3b0afa64cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Thu, 24 Aug 2023 18:19:42 +0100 Subject: [PATCH 019/146] if there's no cachix defined, ignore the error --- src/devenv/cli.py | 26 +++++++++++++++++++++----- tests/python-native-libs/devenv.yaml | 2 ++ 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/src/devenv/cli.py b/src/devenv/cli.py index 1a6ba2c7d..0b6b968e1 100644 --- a/src/devenv/cli.py +++ b/src/devenv/cli.py @@ -60,7 +60,11 @@ # define system like x86_64-linux SYSTEM = os.uname().machine.lower().replace("arm", "aarch") + "-" + os.uname().sysname.lower() -def run_nix(command: str, replace_shell=False, use_cachix=False, logging=True) -> str: +def run_nix(command: str, + replace_shell=False, + use_cachix=False, + logging=True, + dont_exit=False) -> str: ctx = click.get_current_context() nix_flags = ctx.obj['nix_flags'] flags = " ".join(NIX_FLAGS) + " " + " ".join(nix_flags) @@ -68,13 +72,15 @@ def run_nix(command: str, replace_shell=False, use_cachix=False, logging=True) - return run_command(f"nix {flags} {command} {command_flags}", replace_shell=replace_shell, use_cachix=use_cachix, - logging=logging) + logging=logging, + dont_exit=dont_exit) def run_command(command: str, disable_stderr=False, replace_shell=False, use_cachix=False, - logging=True) -> str: + logging=True, + dont_exit=False) -> str: nix = "" if command.startswith("nix"): if os.environ.get("DEVENV_NIX"): @@ -116,7 +122,10 @@ def run_command(command: str, except subprocess.CalledProcessError as e: click.echo("\n", err=True) log(f"Following command exited with code {e.returncode}:\n\n {e.cmd}", level="error") - exit(e.returncode) + if dont_exit: + raise e + else: + exit(e.returncode) CONTEXT_SETTINGS = dict(max_content_width=120) @@ -719,8 +728,15 @@ def get_cachix_caches(logging=True): This is cached because it's expensive to run. """ + try: + caches_raw = run_nix("eval .#devenv.cachix --json", dont_exit=True) + except subprocess.CalledProcessError as e: + log_warning("Failed to evaluate .#devenv.cachix") + log_warning("Maybe you need to upgrade to devenv 1.0: https://devenv.sh/getting-started/") + return {"pull": [], "push": None}, {} + + caches = json.loads(caches_raw) - caches = json.loads(run_nix("eval .#devenv.cachix --json")) if CACHIX_KNOWN_PUBKEYS.exists(): known_keys = json.loads(CACHIX_KNOWN_PUBKEYS.read_text()) else: diff --git a/tests/python-native-libs/devenv.yaml b/tests/python-native-libs/devenv.yaml index d417691da..f8523e963 100644 --- a/tests/python-native-libs/devenv.yaml +++ b/tests/python-native-libs/devenv.yaml @@ -1,3 +1,5 @@ inputs: devenv: url: path:./../../src/modules + nixpkgs: + url: github:NixOS/nixpkgs/08a3497b59051c2839c8ced79d39687b8485ab26 From a4e43db11670c9526f920f3e1f09653ffea7f500 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Thu, 24 Aug 2023 18:22:15 +0100 Subject: [PATCH 020/146] bump nix --- flake.lock | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/flake.lock b/flake.lock index a5d79d4c9..dd642d65d 100644 --- a/flake.lock +++ b/flake.lock @@ -115,11 +115,11 @@ "nixpkgs-regression": "nixpkgs-regression" }, "locked": { - "lastModified": 1692627130, - "narHash": "sha256-vJ0KINKrqKR38an/K/0UaMwstpHDnA6cvE0ukWHa3yg=", + "lastModified": 1692895818, + "narHash": "sha256-lfIz37c24QpkwAHJCDHrDNtQyMBdxq7RWG5sojbtARU=", "owner": "domenkozar", "repo": "nix", - "rev": "96e8d6a3f33fa0c770ad421463ab168239dc921b", + "rev": "ca8a41cfc176dc7adad02ab756f6faef6e90ff1f", "type": "github" }, "original": { @@ -152,11 +152,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1692494774, - "narHash": "sha256-noGVoOTyZ2Kr5OFglzKYOX48cx3hggdCPbXrYMG2FDw=", + "lastModified": 1692808169, + "narHash": "sha256-x9Opq06rIiwdwGeK2Ykj69dNc2IvUH1fY55Wm7atwrE=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "3476a10478587dec90acb14ec6bde0966c545cc0", + "rev": "9201b5ff357e781bf014d0330d18555695df7ba8", "type": "github" }, "original": { @@ -207,11 +207,11 @@ ] }, "locked": { - "lastModified": 1692369730, - "narHash": "sha256-VcCb/XxybOv0Py1Gnhmih9mfwyCUVDds/gID2VcscAo=", + "lastModified": 1692876271, + "narHash": "sha256-IXfZEkI0Mal5y1jr6IRWMqK8GW2/f28xJenZIPQqkY0=", "owner": "nix-community", "repo": "poetry2nix", - "rev": "e4cd574cac251dd44bdbc77c1e98d790fe27b781", + "rev": "d5006be9c2c2417dafb2e2e5034d83fabd207ee3", "type": "github" }, "original": { From 588179263a34642dd1f58cd0370c03c02cc1fdb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Sun, 10 Sep 2023 10:07:37 +0100 Subject: [PATCH 021/146] fix $ devenv shell ls -la --- src/devenv/cli.py | 2 +- tests/cli/.test.sh | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/devenv/cli.py b/src/devenv/cli.py index 0b6b968e1..0a3a8c5b3 100644 --- a/src/devenv/cli.py +++ b/src/devenv/cli.py @@ -288,8 +288,8 @@ def get_dev_environment(ctx, json=False, logging=True): ignore_unknown_options=True, ) ) -@click.argument('extra_args', nargs=-1, type=click.UNPROCESSED) @click.argument('cmd', required=False) +@click.argument('extra_args', nargs=-1, type=click.UNPROCESSED) @click.pass_context def shell(ctx, cmd, extra_args): env, gc_root = get_dev_environment(ctx) diff --git a/tests/cli/.test.sh b/tests/cli/.test.sh index 40a01a3ed..769fea488 100755 --- a/tests/cli/.test.sh +++ b/tests/cli/.test.sh @@ -1,3 +1,4 @@ #!/usr/bin/env bash set -xe -devenv build languages.python.package \ No newline at end of file +devenv build languages.python.package +devenv shell ls -la \ No newline at end of file From 5b6f6f2343b52efda09e5a53909b005c799cde3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Sun, 10 Sep 2023 17:27:19 +0100 Subject: [PATCH 022/146] fix gc symlink --- src/devenv/cli.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/devenv/cli.py b/src/devenv/cli.py index 0a3a8c5b3..2495ba482 100644 --- a/src/devenv/cli.py +++ b/src/devenv/cli.py @@ -270,13 +270,13 @@ def get_dev_environment(ctx, json=False, logging=True): else: action = suppress() with action: - gc_root = os.path.join(os.environ['DEVENV_GC'], 'shell') + gc_root = DEVENV_GC / 'shell' cmd = f"print-dev-env --profile '{gc_root}'" if json: cmd += " --json" env = run_nix(cmd, logging=False, use_cachix=True) run_command(f"nix-env -p '{gc_root}' --delete-generations old", logging=False, disable_stderr=True) - symlink_force(Path(f'{ctx.obj["gc_project"]}-shell'), gc_root) + symlink_force(gc_root, Path(f'{ctx.obj["gc_project"]}-shell')) return env, gc_root From 506e189e183bdd6f37517ee1ac0c415da7e787d5 Mon Sep 17 00:00:00 2001 From: Bob van der Linden Date: Sat, 16 Sep 2023 12:07:45 +0200 Subject: [PATCH 023/146] allow passing through arguments from run_nix to run_command --- src/devenv/cli.py | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/devenv/cli.py b/src/devenv/cli.py index 2495ba482..c5720da02 100644 --- a/src/devenv/cli.py +++ b/src/devenv/cli.py @@ -61,19 +61,13 @@ SYSTEM = os.uname().machine.lower().replace("arm", "aarch") + "-" + os.uname().sysname.lower() def run_nix(command: str, - replace_shell=False, - use_cachix=False, - logging=True, - dont_exit=False) -> str: + **kwargs) -> str: ctx = click.get_current_context() nix_flags = ctx.obj['nix_flags'] flags = " ".join(NIX_FLAGS) + " " + " ".join(nix_flags) command_flags = " ".join(ctx.obj['command_flags']) return run_command(f"nix {flags} {command} {command_flags}", - replace_shell=replace_shell, - use_cachix=use_cachix, - logging=logging, - dont_exit=dont_exit) + **kwargs) def run_command(command: str, disable_stderr=False, From 5ff197ac57373a08ea93496dc52726fc81135e27 Mon Sep 17 00:00:00 2001 From: Bob van der Linden Date: Sat, 16 Sep 2023 12:08:13 +0200 Subject: [PATCH 024/146] only log command errors when logging is enabled --- src/devenv/cli.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/devenv/cli.py b/src/devenv/cli.py index c5720da02..ed3c3d4b5 100644 --- a/src/devenv/cli.py +++ b/src/devenv/cli.py @@ -114,8 +114,9 @@ def run_command(command: str, stderr=None if not disable_stderr else subprocess.DEVNULL, universal_newlines=True).stdout.strip() except subprocess.CalledProcessError as e: - click.echo("\n", err=True) - log(f"Following command exited with code {e.returncode}:\n\n {e.cmd}", level="error") + if logging: + click.echo("\n", err=True) + log(f"Following command exited with code {e.returncode}:\n\n {e.cmd}", level="error") if dont_exit: raise e else: From 64f252fb8fe0feb73766bea56de680ac5098d4eb Mon Sep 17 00:00:00 2001 From: Bob van der Linden Date: Sat, 16 Sep 2023 12:09:00 +0200 Subject: [PATCH 025/146] disable stderr and logging for cachix evaluation --- src/devenv/cli.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/devenv/cli.py b/src/devenv/cli.py index ed3c3d4b5..83777f8c4 100644 --- a/src/devenv/cli.py +++ b/src/devenv/cli.py @@ -724,10 +724,8 @@ def get_cachix_caches(logging=True): This is cached because it's expensive to run. """ try: - caches_raw = run_nix("eval .#devenv.cachix --json", dont_exit=True) + caches_raw = run_nix("eval .#devenv.cachix --json", dont_exit=True, disable_stderr=True, logging=False) except subprocess.CalledProcessError as e: - log_warning("Failed to evaluate .#devenv.cachix") - log_warning("Maybe you need to upgrade to devenv 1.0: https://devenv.sh/getting-started/") return {"pull": [], "push": None}, {} caches = json.loads(caches_raw) From 369233d471312597bc114214059944c828e0015b Mon Sep 17 00:00:00 2001 From: Bob van der Linden Date: Sat, 16 Sep 2023 13:19:47 +0200 Subject: [PATCH 026/146] add black pre-commit --- devenv.nix | 2 ++ 1 file changed, 2 insertions(+) diff --git a/devenv.nix b/devenv.nix index 79a1ac507..220372d33 100644 --- a/devenv.nix +++ b/devenv.nix @@ -8,6 +8,7 @@ pkgs.xorg.libxcb pkgs.yaml2json pkgs.tesh + pkgs.python3Packages.black ]; languages.nix.enable = true; @@ -118,6 +119,7 @@ pre-commit.hooks = { nixpkgs-fmt.enable = true; shellcheck.enable = true; + black.enable = true; #markdownlint.enable = true; }; pre-commit.settings.markdownlint.config = { From 28fcf4a789612cff827bcbd0d0c1447f49a8b2ee Mon Sep 17 00:00:00 2001 From: Bob van der Linden Date: Fri, 6 Oct 2023 15:36:36 +0200 Subject: [PATCH 027/146] format python files using black --- examples/fly.io/hello.py | 1 + src/devenv/cli.py | 516 +++++++++++++++++++++++---------------- src/devenv/log.py | 11 +- src/devenv/yaml.py | 57 +++-- 4 files changed, 353 insertions(+), 232 deletions(-) diff --git a/examples/fly.io/hello.py b/examples/fly.io/hello.py index 05b62393b..924d3eb22 100644 --- a/examples/fly.io/hello.py +++ b/examples/fly.io/hello.py @@ -2,6 +2,7 @@ app = Flask(__name__) + @app.route("/") def hello_world(): return "

Hello, World!

" diff --git a/src/devenv/cli.py b/src/devenv/cli.py index 83777f8c4..7f1e78b3c 100644 --- a/src/devenv/cli.py +++ b/src/devenv/cli.py @@ -39,181 +39,197 @@ "false", ] FILE = pkgutil.get_loader(__package__).load_module(__package__).__file__ -if 'site-packages' in FILE: - SRC_DIR = Path(FILE, '..', '..', 'src') +if "site-packages" in FILE: + SRC_DIR = Path(FILE, "..", "..", "src") else: - SRC_DIR = Path(FILE, '..', '..') -MODULES_DIR = (SRC_DIR / 'modules').resolve() + SRC_DIR = Path(FILE, "..", "..") +MODULES_DIR = (SRC_DIR / "modules").resolve() FLAKE_FILE_TEMPL = Path(MODULES_DIR) / "flake.tmpl.nix" FLAKE_FILE = Path(".devenv.flake.nix") FLAKE_LOCK = "devenv.lock" # home vars -if 'XDG_DATA_HOME' not in os.environ: - DEVENV_HOME = Path(os.environ['HOME']) / '.devenv' +if "XDG_DATA_HOME" not in os.environ: + DEVENV_HOME = Path(os.environ["HOME"]) / ".devenv" else: - DEVENV_HOME = Path(os.environ['XDG_DATA_HOME']) / '.devenv' -DEVENV_HOME_GC = DEVENV_HOME / 'gc' + DEVENV_HOME = Path(os.environ["XDG_DATA_HOME"]) / ".devenv" +DEVENV_HOME_GC = DEVENV_HOME / "gc" DEVENV_HOME_GC.mkdir(parents=True, exist_ok=True) CACHIX_KNOWN_PUBKEYS = DEVENV_HOME / "cachix_pubkeys.json" # define system like x86_64-linux -SYSTEM = os.uname().machine.lower().replace("arm", "aarch") + "-" + os.uname().sysname.lower() +SYSTEM = ( + os.uname().machine.lower().replace("arm", "aarch") + + "-" + + os.uname().sysname.lower() +) + -def run_nix(command: str, - **kwargs) -> str: +def run_nix(command: str, **kwargs) -> str: ctx = click.get_current_context() - nix_flags = ctx.obj['nix_flags'] + nix_flags = ctx.obj["nix_flags"] flags = " ".join(NIX_FLAGS) + " " + " ".join(nix_flags) - command_flags = " ".join(ctx.obj['command_flags']) - return run_command(f"nix {flags} {command} {command_flags}", - **kwargs) - -def run_command(command: str, - disable_stderr=False, - replace_shell=False, - use_cachix=False, - logging=True, - dont_exit=False) -> str: + command_flags = " ".join(ctx.obj["command_flags"]) + return run_command(f"nix {flags} {command} {command_flags}", **kwargs) + + +def run_command( + command: str, + disable_stderr=False, + replace_shell=False, + use_cachix=False, + logging=True, + dont_exit=False, +) -> str: nix = "" if command.startswith("nix"): if os.environ.get("DEVENV_NIX"): nix = os.path.join(os.environ["DEVENV_NIX"], "bin") command = f"{nix}/{command}" else: - log("$DEVENV_NIX is not set, but required as devenv doesn't work without a few Nix patches.", level="error") - log("Please follow https://devenv.sh/getting-started/ to install devenv.", level="error") + log( + "$DEVENV_NIX is not set, but required as devenv doesn't work without a few Nix patches.", + level="error", + ) + log( + "Please follow https://devenv.sh/getting-started/ to install devenv.", + level="error", + ) exit(1) if use_cachix: caches, known_keys = get_cachix_caches(logging) - pull_caches = ' '.join(map(lambda cache: f'https://{cache}.cachix.org', caches.get('pull'))) + pull_caches = " ".join( + map(lambda cache: f"https://{cache}.cachix.org", caches.get("pull")) + ) command = f"{command} --option extra-trusted-public-keys '{' '.join(known_keys.values())}'" command = f"{command} --option extra-substituters '{pull_caches}'" push_cache = caches.get("push") - if push_cache and os.environ.get('CACHIX_AUTH_TOKEN'): + if push_cache and os.environ.get("CACHIX_AUTH_TOKEN"): if shutil.which("cachix") is None: if logging: - log_warning("cachix is not installed, skipping pushing. Please follow https://devenv.sh/getting-started/#2-install-cachix to install cachix.", level="error") + log_warning( + "cachix is not installed, skipping pushing. Please follow https://devenv.sh/getting-started/#2-install-cachix to install cachix.", + level="error", + ) else: command = f"cachix watch-exec {push_cache} {command}" - + try: - if click.get_current_context().obj['verbose']: + if click.get_current_context().obj["verbose"]: log(f"Running command: {command}", level="debug") if replace_shell: splitted_command = shlex.split(command.strip()) os.execv(splitted_command[0], splitted_command) else: return subprocess.run( - command, + command, shell=True, - check=True, + check=True, env=os.environ.copy(), stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=None if not disable_stderr else subprocess.DEVNULL, - universal_newlines=True).stdout.strip() + universal_newlines=True, + ).stdout.strip() except subprocess.CalledProcessError as e: if logging: click.echo("\n", err=True) - log(f"Following command exited with code {e.returncode}:\n\n {e.cmd}", level="error") + log( + f"Following command exited with code {e.returncode}:\n\n {e.cmd}", + level="error", + ) if dont_exit: raise e else: exit(e.returncode) + CONTEXT_SETTINGS = dict(max_content_width=120) + @click.group(context_settings=CONTEXT_SETTINGS) +@click.option("--verbose", "-v", help="Enable verbose output.", is_flag=True) @click.option( - '--verbose', '-v', - help='Enable verbose output.', - is_flag=True) -@click.option( - '--nix-flags', '-n', + "--nix-flags", + "-n", help='Flags to pass to Nix. See `man nix.conf 5`. Example: --nix-flags "--option bash-prompt >"', metavar="NIX-FLAGS", - multiple=True) -@click.option( - '--debugger', '-d', - help='Enable Nix debugger.', - is_flag=True) -@click.option( - '--system', '-s', - help='Nix system to use.', - default=SYSTEM) -@click.option( - '--offline', '-o', - help='Disable network access.', - is_flag=True) + multiple=True, +) +@click.option("--debugger", "-d", help="Enable Nix debugger.", is_flag=True) +@click.option("--system", "-s", help="Nix system to use.", default=SYSTEM) +@click.option("--offline", "-o", help="Disable network access.", is_flag=True) @click.pass_context def cli(ctx, offline, system, debugger, nix_flags, verbose): """https://devenv.sh: Fast, Declarative, Reproducible, and Composable Developer Environments.""" ctx.ensure_object(dict) - ctx.obj['system'] = system - ctx.obj['verbose'] = verbose - ctx.obj['command_flags'] = [] - ctx.obj['nix_flags'] = list(nix_flags) - ctx.obj['nix_flags'] += ['--system', system] + ctx.obj["system"] = system + ctx.obj["verbose"] = verbose + ctx.obj["command_flags"] = [] + ctx.obj["nix_flags"] = list(nix_flags) + ctx.obj["nix_flags"] += ["--system", system] if offline: - ctx.obj['nix_flags'] += ['--offline'] + ctx.obj["nix_flags"] += ["--offline"] if debugger: # ignore-try is needed to avoid catching unrelated errors - ctx.obj['command_flags'] += ['--debugger', '--ignore-try'] + ctx.obj["command_flags"] += ["--debugger", "--ignore-try"] + + ctx.obj["gc_root"] = DEVENV_HOME_GC + ctx.obj["gc_project"] = DEVENV_HOME_GC / str(int(time.time() * 1000)) - ctx.obj['gc_root'] = DEVENV_HOME_GC - ctx.obj['gc_project'] = DEVENV_HOME_GC / str(int(time.time() * 1000)) @cli.group() def processes(): pass -DEVENV_DIR = Path(os.getcwd()) / '.devenv' -os.environ['DEVENV_DIR'] = str(DEVENV_DIR) -DEVENV_GC = DEVENV_DIR / 'gc' -os.environ['DEVENV_GC'] = str(DEVENV_GC) +DEVENV_DIR = Path(os.getcwd()) / ".devenv" +os.environ["DEVENV_DIR"] = str(DEVENV_DIR) +DEVENV_GC = DEVENV_DIR / "gc" +os.environ["DEVENV_GC"] = str(DEVENV_GC) -PROCESSES_PID = DEVENV_DIR / 'processes.pid' -PROCESSES_LOG = DEVENV_DIR / 'processes.log' +PROCESSES_PID = DEVENV_DIR / "processes.pid" +PROCESSES_LOG = DEVENV_DIR / "processes.log" def add_gc(name, store_path): """Register a GC root""" ctx = click.get_current_context() - run_command(f'nix-store --add-root "{os.environ["DEVENV_GC"]}/{name}" -r {store_path} >/dev/null') + run_command( + f'nix-store --add-root "{os.environ["DEVENV_GC"]}/{name}" -r {store_path} >/dev/null' + ) symlink_force(store_path, f'{ctx.obj["gc_project"]}-{name}') @cli.command(hidden=True) @click.pass_context def assemble(ctx): - if not os.path.exists('devenv.nix'): - log('File devenv.nix does not exist. To get started, run:', level="error") - log(' $ devenv init', level="error") + if not os.path.exists("devenv.nix"): + log("File devenv.nix does not exist. To get started, run:", level="error") + log(" $ devenv init", level="error") exit(1) DEVENV_GC.mkdir(parents=True, exist_ok=True) - if os.path.exists('devenv.yaml'): + if os.path.exists("devenv.yaml"): validate_and_parse_yaml(DEVENV_DIR) else: - for file in ['devenv.json', 'flake.json', 'imports.txt']: + for file in ["devenv.json", "flake.json", "imports.txt"]: file_path = DEVENV_DIR / file file_path.unlink(missing_ok=True) with open(FLAKE_FILE_TEMPL) as f: flake = f.read() - system = ctx.obj['system'] + system = ctx.obj["system"] - with open(FLAKE_FILE, 'w') as f: - devenv_vars = (f""" + with open(FLAKE_FILE, "w") as f: + devenv_vars = f""" version = "{get_version()}"; system = "{system}"; devenv_root = "{os.getcwd()}"; - """) + """ # replace __DEVENV_VARS__ in flake using regex - flake = re.sub(r'__DEVENV_VARS__', devenv_vars, flake) + flake = re.sub(r"__DEVENV_VARS__", devenv_vars, flake) f.write(flake) @@ -223,18 +239,20 @@ def assemble(ctx): ) @click.pass_context def gc(ctx): - GC_ROOTS = ctx.obj['gc_root'] + GC_ROOTS = ctx.obj["gc_root"] start = time.time() # remove dangling symlinks - with log_task(f'Removing non-existings symlinks in {GC_ROOTS} ...'): + with log_task(f"Removing non-existings symlinks in {GC_ROOTS} ..."): to_gc, removed_symlinks = cleanup_symlinks(GC_ROOTS) - click.echo(f' Found {len(to_gc)} active symlinks.') - click.echo(f' Deleted {len(removed_symlinks)} dangling symlinks.') + click.echo(f" Found {len(to_gc)} active symlinks.") + click.echo(f" Deleted {len(removed_symlinks)} dangling symlinks.") click.echo() - log('Running garbage collection (this process may take some time) ...', level="info") + log( + "Running garbage collection (this process may take some time) ...", level="info" + ) # TODO: ideally nix would report some statistics about the GC as JSON run_nix(f'store delete --recursive {" ".join(to_gc)}') @@ -242,7 +260,11 @@ def gc(ctx): end = time.time() click.echo() - log(f'Done. Successfully removed {len(to_gc) - len(after_gc)} symlinks in {end - start:.0f} seconds.', level="info") + log( + f"Done. Successfully removed {len(to_gc) - len(after_gc)} symlinks in {end - start:.0f} seconds.", + level="info", + ) + def cleanup_symlinks(folder): to_gc = [] @@ -258,42 +280,49 @@ def cleanup_symlinks(folder): to_gc.append(full_path) return to_gc, removed_symlinks + def get_dev_environment(ctx, json=False, logging=True): ctx.invoke(assemble) if logging: - action = log_task('Building shell') + action = log_task("Building shell") else: action = suppress() with action: - gc_root = DEVENV_GC / 'shell' + gc_root = DEVENV_GC / "shell" cmd = f"print-dev-env --profile '{gc_root}'" if json: cmd += " --json" env = run_nix(cmd, logging=False, use_cachix=True) - run_command(f"nix-env -p '{gc_root}' --delete-generations old", logging=False, disable_stderr=True) + run_command( + f"nix-env -p '{gc_root}' --delete-generations old", + logging=False, + disable_stderr=True, + ) symlink_force(gc_root, Path(f'{ctx.obj["gc_project"]}-shell')) return env, gc_root - @cli.command( help="Activate the developer environment.", short_help="Activate the developer environment.", context_settings=dict( ignore_unknown_options=True, - ) + ), ) -@click.argument('cmd', required=False) -@click.argument('extra_args', nargs=-1, type=click.UNPROCESSED) +@click.argument("cmd", required=False) +@click.argument("extra_args", nargs=-1, type=click.UNPROCESSED) @click.pass_context def shell(ctx, cmd, extra_args): env, gc_root = get_dev_environment(ctx) if cmd: - run_nix(f"develop '{gc_root}' -c {cmd} {' '.join(extra_args)}", replace_shell=True) + run_nix( + f"develop '{gc_root}' -c {cmd} {' '.join(extra_args)}", replace_shell=True + ) else: - log('Entering shell', level="info") + log("Entering shell", level="info") run_nix(f"develop '{gc_root}'", replace_shell=True) - + + def symlink_force(src, dst): src = Path(src) dst = Path(dst) @@ -302,42 +331,51 @@ def symlink_force(src, dst): dst.unlink(missing_ok=True) dst.symlink_to(src) + @cli.command( - help="Starts processes in foreground. See http://devenv.sh/processes", + help="Starts processes in foreground. See http://devenv.sh/processes", short_help="Starts processes in foreground. See http://devenv.sh/processes", ) -@click.argument('process', required=False) -@click.option('--detach', '-d', is_flag=True, help="Starts processes in the background.") +@click.argument("process", required=False) +@click.option( + "--detach", "-d", is_flag=True, help="Starts processes in the background." +) @click.pass_context def up(ctx, process, detach): - with log_task('Building processes'): + with log_task("Building processes"): ctx.invoke(assemble) - procfilescript = run_nix("build --no-link --print-out-paths '.#procfileScript'", use_cachix=True) - with open(procfilescript, 'r') as file: + procfilescript = run_nix( + "build --no-link --print-out-paths '.#procfileScript'", use_cachix=True + ) + with open(procfilescript, "r") as file: contents = file.read().strip() - if contents == '': - log("No 'processes' option defined: https://devenv.sh/processes/", level="error") + if contents == "": + log( + "No 'processes' option defined: https://devenv.sh/processes/", level="error" + ) exit(1) else: env, _ = get_dev_environment(ctx) - log('Starting processes ...', level="info") - add_gc('procfilescript', procfilescript) - processes_script = os.path.join(DEVENV_DIR, 'processes') - with open(processes_script, 'w') as f: - f.write(f"""#!/usr/bin/env bash + log("Starting processes ...", level="info") + add_gc("procfilescript", procfilescript) + processes_script = os.path.join(DEVENV_DIR, "processes") + with open(processes_script, "w") as f: + f.write( + f"""#!/usr/bin/env bash {env} {procfilescript} {process or ""} - """) + """ + ) os.chmod(processes_script, 0o755) - + if detach: process = subprocess.Popen( [processes_script], - stdout=open(PROCESSES_LOG, 'w'), + stdout=open(PROCESSES_LOG, "w"), stderr=subprocess.STDOUT, ) - - with open(PROCESSES_PID, 'w') as file: + + with open(PROCESSES_PID, "w") as file: file.write(str(process.pid)) log(f" PID is {process.pid}.", level="info") log(f" See logs: $ tail -f {PROCESSES_LOG}", level="info") @@ -345,21 +383,23 @@ def up(ctx, process, detach): else: os.execv(processes_script, [processes_script]) + processes.add_command(up) + @processes.command( help="Stops processes started with 'devenv up'.", short_help="Stops processes started with 'devenv up'.", ) def stop(): - with log_task('Stopping processes', newline=False): + with log_task("Stopping processes", newline=False): if not os.path.exists(PROCESSES_PID): log("No processes running.", level="error") exit(1) - with open(PROCESSES_PID, 'r') as file: + with open(PROCESSES_PID, "r") as file: pid = int(file.read()) - + try: os.kill(pid, signal.SIGTERM) except ProcessLookupError: @@ -368,33 +408,34 @@ def stop(): os.remove(PROCESSES_PID) + @cli.command() -@click.argument('name') +@click.argument("name") @click.pass_context def search(ctx, name): """Search packages matching NAME in nixpkgs input.""" ctx.invoke(assemble) - options = run_nix("build --no-link --print-out-paths '.#optionsJSON' ", use_cachix=True) + options = run_nix( + "build --no-link --print-out-paths '.#optionsJSON' ", use_cachix=True + ) search = run_nix(f"search --json nixpkgs {name}") - with open(Path(options) / 'share' / 'doc' / 'nixos' / 'options.json') as f: + with open(Path(options) / "share" / "doc" / "nixos" / "options.json") as f: options_results = [] for key, value in json.load(f).items(): if name in key: - options_results.append(( - key, - value['type'], - value['default'], - value['description'][:80] - )) + options_results.append( + (key, value["type"], value["default"], value["description"][:80]) + ) results_options_count = len(options_results) search_results = [] for key, value in json.loads(search).items(): search_results.append( - ("pkgs." + (".".join(key.split('.')[2:])) - , value['version'] - , value['description'][:80] + ( + "pkgs." + (".".join(key.split(".")[2:])), + value["version"], + value["description"][:80], ) ) search_results_count = len(search_results) @@ -402,63 +443,86 @@ def search(ctx, name): if search_results: click.echo( terminaltables.AsciiTable( - [("Package", "Version", "Description")] - + search_results + [("Package", "Version", "Description")] + search_results ).table ) if options_results: click.echo( terminaltables.AsciiTable( - [("Option", "Type", "Default", "Description")] - + options_results + [("Option", "Type", "Default", "Description")] + options_results ).table ) - - log(f"Found {search_results_count} packages and {results_options_count} options for '{name}'.", level="info") + + log( + f"Found {search_results_count} packages and {results_options_count} options for '{name}'.", + level="info", + ) + @cli.command( help="Build, copy and run a container. See http://devenv.sh/containers", short_help="Build, copy and run a container. See http://devenv.sh/containers", ) -@click.option('--registry', default=None, help='Registry to copy the container to.', metavar="REGISTRY") -@click.option('--copy', is_flag=True, help='Copy the container to the registry.') -@click.option('--copy-args', default=None, help='Arguments passed to `skopeo copy`.', metavar="ARGS") -@click.option('--docker-run', is_flag=True, help='Execute `docker run`.') -@click.argument('container_name') +@click.option( + "--registry", + default=None, + help="Registry to copy the container to.", + metavar="REGISTRY", +) +@click.option("--copy", is_flag=True, help="Copy the container to the registry.") +@click.option( + "--copy-args", + default=None, + help="Arguments passed to `skopeo copy`.", + metavar="ARGS", +) +@click.option("--docker-run", is_flag=True, help="Execute `docker run`.") +@click.argument("container_name") @click.pass_context def container(ctx, registry, copy, copy_args, docker_run, container_name): - os.environ['DEVENV_CONTAINER'] = container_name + os.environ["DEVENV_CONTAINER"] = container_name - with log_task(f'Building {container_name} container'): + with log_task(f"Building {container_name} container"): ctx.invoke(assemble) # NOTE: we need --impure here to read DEVENV_CONTAINER - spec = run_nix(f"build --impure --print-out-paths --no-link .#devenv.containers.\"{container_name}\".derivation", use_cachix=True) + spec = run_nix( + f'build --impure --print-out-paths --no-link .#devenv.containers."{container_name}".derivation', + use_cachix=True, + ) click.echo(spec) - + # copy container if copy or docker_run: - with log_task(f'Copying {container_name} container'): + with log_task(f"Copying {container_name} container"): # we need --impure here for DEVENV_CONTAINER - copy_script = run_nix(f"build --print-out-paths --no-link \ - --impure .#devenv.containers.\"{container_name}\".copyScript", use_cachix=True) - + copy_script = run_nix( + f'build --print-out-paths --no-link \ + --impure .#devenv.containers."{container_name}".copyScript', + use_cachix=True, + ) + if docker_run: registry = "docker-daemon:" - + subprocess.run( f"{copy_script} {spec} {registry} {copy_args or ''}", shell=True, - check=True) + check=True, + ) if docker_run: - log(f'Starting {container_name} container', level="info") + log(f"Starting {container_name} container", level="info") # we need --impure here for DEVENV_CONTAINER - docker_script = run_nix(f"build --print-out-paths --no-link --impure \ - .#devenv.containers.\"{container_name}\".dockerRun", use_cachix=True) - + docker_script = run_nix( + f'build --print-out-paths --no-link --impure \ + .#devenv.containers."{container_name}".dockerRun', + use_cachix=True, + ) + subprocess.run(docker_script) + @cli.command( help="Print information about this developer environment.", short_help="Print information about this developer environment.", @@ -476,6 +540,7 @@ def info(ctx): info_ = run_nix("eval --raw '.#info'") click.echo(f"{inputs}\n{info_}") + @cli.command() @click.pass_context def version(ctx): @@ -483,15 +548,16 @@ def version(ctx): version = get_version() click.echo(f"devenv {version} ({ctx.obj['system']})") + @cli.command( help="Scaffold devenv.yaml, devenv.nix, and .envrc.", short_help="Scaffold devenv.yaml, devenv.nix, and .envrc.", ) -@click.argument('target', default='.') +@click.argument("target", default=".") def init(target): os.makedirs(target, exist_ok=True) - required_files = ['devenv.nix', 'devenv.yaml', '.envrc'] + required_files = ["devenv.nix", "devenv.yaml", ".envrc"] for filename in required_files: if os.path.exists(Path(target, filename)): log(f"Aborting since {filename} already exist.", level="error") @@ -505,10 +571,12 @@ def init(target): full_filename = Path(target, filename) if not os.path.exists(full_filename): log(f"Creating {full_filename}", level="info") - shutil.copyfile(os.path.join(examples_path, example, filename), full_filename) + shutil.copyfile( + os.path.join(examples_path, example, filename), full_filename + ) - with open('.gitignore', 'a+') as gitignore_file: - if 'devenv' not in gitignore_file.read(): + with open(".gitignore", "a+") as gitignore_file: + if "devenv" not in gitignore_file.read(): log("Appending defaults to .gitignore", level="info") gitignore_file.write("\n") gitignore_file.write("# Devenv\n") @@ -525,15 +593,16 @@ def init(target): log("Done.", level="info") # Check if direnv is installed - if shutil.which('direnv'): + if shutil.which("direnv"): log("direnv is installed. Running $ direnv allow .", level="info") - subprocess.run(['direnv', 'allow']) + subprocess.run(["direnv", "allow"]) + @cli.command( help="Update devenv.lock from devenv.yaml inputs. See http://devenv.sh/inputs/", short_help="Update devenv.lock from devenv.yaml inputs. See http://devenv.sh/inputs/", ) -@click.argument('input_name', required=False) +@click.argument("input_name", required=False) @click.pass_context def update(ctx, input_name): ctx.invoke(assemble) @@ -543,6 +612,7 @@ def update(ctx, input_name): else: run_nix("flake update") + @cli.command() @click.pass_context def ci(ctx): @@ -551,7 +621,8 @@ def ci(ctx): print("running ci") print(run_command("cat ${FLAKE_FILE}")) output_path = run_nix("build --no-link --print-out-paths .#ci", use_cachix=True) - add_gc('ci', output_path) + add_gc("ci", output_path) + @cli.command(hidden=True) @click.option("--json", is_flag=True) @@ -560,48 +631,54 @@ def print_dev_env(ctx, json): env, _ = get_dev_environment(ctx, json=json, logging=False) click.echo(env) + def get_version(): with open(Path(MODULES_DIR, "latest-version")) as f: return f.read().strip() + @cli.group( help="Manage inputs in devenv.yaml. See http://devenv.sh/inputs/", - short_help="Manage inputs in devenv.yaml. See http://devenv.sh/inputs/" + short_help="Manage inputs in devenv.yaml. See http://devenv.sh/inputs/", ) def inputs(): pass + @inputs.command( help="Add a new input to the developer environment.", short_help="Add a new input to the developer environment.", ) -@click.argument('name') -@click.argument('url') -@click.option('--follows', '-f', multiple=True, help='Add a dependency to the input.') +@click.argument("name") +@click.argument("url") +@click.option("--follows", "-f", multiple=True, help="Add a dependency to the input.") @click.pass_context def add(ctx, name, url, follows): devenv = read_yaml() - attrs = {'url': url} + attrs = {"url": url} inputs = {} for follow in follows: - if follow not in devenv['inputs']: - log(f"Input {follow} does not exist so it can't be followed.", level="error") + if follow not in devenv["inputs"]: + log( + f"Input {follow} does not exist so it can't be followed.", level="error" + ) exit(1) inputs[follow] = {"follows": follow} if inputs: - attrs['inputs'] = inputs - devenv['inputs'][name] = attrs - + attrs["inputs"] = inputs + devenv["inputs"][name] = attrs + write_yaml(devenv) + @cli.command( help="Run tests. See http://devenv.sh/tests/", short_help="Run tests. See http://devenv.sh/tests/", ) -@click.argument('names', nargs=-1) -@click.option('--debug', is_flag=True, help='Run tests in debug mode.') +@click.argument("names", nargs=-1) +@click.option("--debug", is_flag=True, help="Run tests in debug mode.") @click.pass_context def test(ctx, debug, names): ctx.invoke(assemble) @@ -609,12 +686,12 @@ def test(ctx, debug, names): tests = json.loads(run_nix("eval .#devenv.tests --json")) if not names: - names = [ "local" ] + names = ["local"] # group tests by tags tags = {} for name, test in tests.items(): - for tag in test['tags']: + for tag in test["tags"]: if tag not in tags: tags[tag] = [] tags[tag].append(name) @@ -637,39 +714,46 @@ def test(ctx, debug, names): os.chdir(tmpdir) test = tests[name] - if test.get('src'): + if test.get("src"): shutil.copytree( - test['src'], '.', - dirs_exist_ok=True, - copy_function=shutil.copy + test["src"], ".", dirs_exist_ok=True, copy_function=shutil.copy ) run_command("find . -type d -exec chmod +wx {} \;") else: - write_if_defined("devenv.nix", test.get('nix')) - write_if_defined("devenv.yaml", test.get('yaml')) - write_if_defined(".test.sh", test.get('test')) + write_if_defined("devenv.nix", test.get("nix")) + write_if_defined("devenv.yaml", test.get("yaml")) + write_if_defined(".test.sh", test.get("test")) if os.path.exists(".test.sh"): os.chmod(".test.sh", 0o755) # predefined utilities - write_if_defined("devenv.local.nix", """ + write_if_defined( + "devenv.local.nix", + """ { pkgs, ... }: { packages = [ pkgs.coreutils-full ]; } - """.strip() + "\n") + """.strip() + + "\n", + ) # plug in devenv input if needed - if os.path.exists(os.path.join(pwd, 'src/modules/latest-version')): - log(" Detected devenv module. Using src/modules for tests.", level="info") - - modules = os.path.join(pwd, 'src/modules') + if os.path.exists(os.path.join(pwd, "src/modules/latest-version")): + log( + " Detected devenv module. Using src/modules for tests.", + level="info", + ) + + modules = os.path.join(pwd, "src/modules") if not os.path.exists("devenv.yaml"): - write_yaml(strictyaml.as_document({"inputs": {}}, schema=schema)) + write_yaml( + strictyaml.as_document({"inputs": {}}, schema=schema) + ) os.chmod("devenv.yaml", 0o644) yaml = read_yaml() - inputs = yaml.get('inputs', {}) - inputs['devenv'] = {'url': f'path:{modules}'} - yaml['inputs'] = inputs + inputs = yaml.get("inputs", {}) + inputs["devenv"] = {"url": f"path:{modules}"} + yaml["inputs"] = inputs write_yaml(yaml) devenv = sys.argv[0] @@ -678,13 +762,16 @@ def test(ctx, debug, names): log(" Running $ devenv ci ...", level="info") run_command(f"{devenv} ci") - has_processes = os.path.exists(".devenv/gc/ci") and "-devenv-up" in run_command("cat .devenv/gc/ci") + has_processes = os.path.exists( + ".devenv/gc/ci" + ) and "-devenv-up" in run_command("cat .devenv/gc/ci") if has_processes: log(" Starting processes ...", level="info") run_command(f"{devenv} up -d") # stream logs - p = subprocess.Popen("tail -f .devenv/processes.log", + p = subprocess.Popen( + "tail -f .devenv/processes.log", shell=True, ) else: @@ -702,34 +789,44 @@ def test(ctx, debug, names): except BaseException as e: log_error(f"Test {name} failed.") if debug: - log("Entering shell because of the --debug flag:", level="warning") + log( + "Entering shell because of the --debug flag:", + level="warning", + ) log(f" - devenv: {devenv}", level="warning") log(f" - cwd: {tmpdir}", level="warning") if has_processes: log(" - up logs: .devenv/processes.log:", level="warning") os.execv("/bin/sh", ["/bin/sh"]) else: - log_warning('Pass --debug flag to enter shell.') + log_warning("Pass --debug flag to enter shell.") raise e + def write_if_defined(file, content): if content: - with open(file, 'w') as f: + with open(file, "w") as f: f.write(content) + @functools.cache def get_cachix_caches(logging=True): """Get the full list of cachix caches we need and their public keys. - + This is cached because it's expensive to run. """ try: - caches_raw = run_nix("eval .#devenv.cachix --json", dont_exit=True, disable_stderr=True, logging=False) + caches_raw = run_nix( + "eval .#devenv.cachix --json", + dont_exit=True, + disable_stderr=True, + logging=False, + ) except subprocess.CalledProcessError as e: return {"pull": [], "push": None}, {} caches = json.loads(caches_raw) - + if CACHIX_KNOWN_PUBKEYS.exists(): known_keys = json.loads(CACHIX_KNOWN_PUBKEYS.read_text()) else: @@ -739,35 +836,42 @@ def get_cachix_caches(logging=True): if name not in known_keys: resp = requests.get(f"https://cachix.org/api/v1/cache/{name}") if resp.status_code in [401, 404]: - log_error(f"Cache {name} does not exist or you don't have a CACHIX_AUTH_TOKEN configured.") + log_error( + f"Cache {name} does not exist or you don't have a CACHIX_AUTH_TOKEN configured." + ) # TODO: instruct how to best configure netrc - #log_error("To configure a token, run `cachix authtoken `.") + # log_error("To configure a token, run `cachix authtoken `.") log_error("To create a cache, go to https://app.cachix.org/.") exit(1) else: resp.raise_for_status() pubkey = resp.json()["publicSigningKeys"][0] new_known_keys[name] = pubkey - + if caches.get("pull"): if logging: log_info(f"Using Cachix: {', '.join(caches.get('pull', []))} ") if new_known_keys: for name, pubkey in new_known_keys.items(): if logging: - log_info(f" Trusting {name}.cachix.org on first use with the public key {pubkey}") + log_info( + f" Trusting {name}.cachix.org on first use with the public key {pubkey}" + ) known_keys.update(new_known_keys) CACHIX_KNOWN_PUBKEYS.write_text(json.dumps(known_keys)) return caches, known_keys + @cli.command() -@click.argument('attrs', nargs=-1, required=True) +@click.argument("attrs", nargs=-1, required=True) @click.pass_context def build(ctx, attrs): """Build attributes in your devenv.nix.""" ctx.invoke(assemble) - attrs = " ".join(map(lambda attr: f'.#devenv.{attr}', attrs)) - output = run_nix(f"build --print-out-paths --print-build-logs --no-link {attrs}", use_cachix=True) + attrs = " ".join(map(lambda attr: f".#devenv.{attr}", attrs)) + output = run_nix( + f"build --print-out-paths --print-build-logs --no-link {attrs}", use_cachix=True + ) log("Built:", level="info") for path in output.splitlines(): log(path, level="info") diff --git a/src/devenv/log.py b/src/devenv/log.py index 64ac34c07..0b56f3b69 100644 --- a/src/devenv/log.py +++ b/src/devenv/log.py @@ -1,11 +1,12 @@ from typing import Literal -import time +import time import click class log_task: """Context manager for logging progress of a task.""" + def __init__(self, message, newline=True): self.message = message self.newline = newline @@ -23,8 +24,10 @@ def __exit__(self, exc, *args): prefix = click.style("✔", fg="green") click.echo(f"\r{prefix} {self.message} in {end - self.start:.1f}s.") + LogLevel = Literal["info", "warning", "error", "debug"] + def log(message, level: LogLevel): match level: case "info": @@ -36,14 +39,18 @@ def log(message, level: LogLevel): case "debug": click.echo(click.style("• ", fg="magenta") + message, err=True) + def log_error(message): log(message, "error") + def log_warning(message): log(message, "warning") + def log_info(message): log(message, "info") + def log_debug(message): - log(message, "debug") \ No newline at end of file + log(message, "debug") diff --git a/src/devenv/yaml.py b/src/devenv/yaml.py index d62074734..825dbccf9 100644 --- a/src/devenv/yaml.py +++ b/src/devenv/yaml.py @@ -7,22 +7,30 @@ from strictyaml import load, Bool, Any, Optional, YAMLError, EmptyDict -inputsSchema = EmptyDict() | MapPattern(Str(), Map({ - "url": Str(), - Optional("flake", default=None): Bool(), - Optional("inputs", default=None): Any(), - Optional("overlays", default=None): Seq(Str()) -})) - -schema = Map({ - Optional("inputs", default=None): inputsSchema, - Optional("allowUnfree", default=False): Bool(), - Optional("imports", default=None): Seq(Str()), - Optional("permittedInsecurePackages", default=None): Seq(Str()) -}) +inputsSchema = EmptyDict() | MapPattern( + Str(), + Map( + { + "url": Str(), + Optional("flake", default=None): Bool(), + Optional("inputs", default=None): Any(), + Optional("overlays", default=None): Seq(Str()), + } + ), +) + +schema = Map( + { + Optional("inputs", default=None): inputsSchema, + Optional("allowUnfree", default=False): Bool(), + Optional("imports", default=None): Seq(Str()), + Optional("permittedInsecurePackages", default=None): Seq(Str()), + } +) YAML_FILE = Path("devenv.yaml") + def read_yaml(): try: with open(YAML_FILE) as f: @@ -31,23 +39,24 @@ def read_yaml(): print("Validation error in `devenv.yaml`", error) sys.exit(1) + def write_yaml(yaml): with open(YAML_FILE, "w") as f: f.write(yaml.as_yaml()) + def validate_and_parse_yaml(dot_devenv_root): - devenv = read_yaml().data + devenv = read_yaml().data - inputs = {} - for input, attrs in devenv.get('inputs', {}).items(): - inputs[input] = {k: attrs[k] for k in ('url', 'inputs', 'flake') - if k in attrs} + inputs = {} + for input, attrs in devenv.get("inputs", {}).items(): + inputs[input] = {k: attrs[k] for k in ("url", "inputs", "flake") if k in attrs} - with open(os.path.join(dot_devenv_root, "flake.json"), 'w') as f: - f.write(json.dumps(inputs)) + with open(os.path.join(dot_devenv_root, "flake.json"), "w") as f: + f.write(json.dumps(inputs)) - with open(os.path.join(dot_devenv_root, "devenv.json"), 'w') as f: - f.write(json.dumps(devenv)) + with open(os.path.join(dot_devenv_root, "devenv.json"), "w") as f: + f.write(json.dumps(devenv)) - with open(os.path.join(dot_devenv_root, "imports.txt"), 'w') as f: - f.write("\n".join(devenv.get('imports', []))) \ No newline at end of file + with open(os.path.join(dot_devenv_root, "imports.txt"), "w") as f: + f.write("\n".join(devenv.get("imports", []))) From 5fa92100d075c04703adfa29adbad2083306272a Mon Sep 17 00:00:00 2001 From: Andrew Coleman Date: Mon, 16 Oct 2023 14:03:04 -0400 Subject: [PATCH 028/146] [FEAT] Conditionally link devenv profile When loading a shell, devenv checks .devenv/profile is 1. not a link 2. readlink reports someplace other than ${profile} Then will remove whatever is .devenv/profile and relink to the current active profile. When running a single command at a time, this is usually not a problem, but if you attempt to run two commands at the same time, then the race condition of one process removing a link while another is creating the link will emit warnings to stderr. --- src/modules/top-level.nix | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/modules/top-level.nix b/src/modules/top-level.nix index 4f5ecc2f1..376d1bbe5 100644 --- a/src/modules/top-level.nix +++ b/src/modules/top-level.nix @@ -230,8 +230,10 @@ in fi mkdir -p .devenv - rm -f .devenv/profile - ln -s ${profile} .devenv/profile + if [ ! -L .devenv/profile ] || [ "$(${pkgs.coreutils}/bin/readlink .devenv/profile)" != "${profile}" ] + then + ln -nsf ${profile} .devenv/profile + fi unset ${lib.concatStringsSep " " config.unsetEnvVars} ''; From a44199cd10d5eadbe31a71a13dc7d8d428010d87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Wed, 25 Oct 2023 15:11:29 +0100 Subject: [PATCH 029/146] containers: correctly pass no registry case --- src/devenv/cli.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/devenv/cli.py b/src/devenv/cli.py index 7f1e78b3c..90816991c 100644 --- a/src/devenv/cli.py +++ b/src/devenv/cli.py @@ -506,7 +506,7 @@ def container(ctx, registry, copy, copy_args, docker_run, container_name): registry = "docker-daemon:" subprocess.run( - f"{copy_script} {spec} {registry} {copy_args or ''}", + f"{copy_script} {spec} {registry or 'false'} {copy_args or ''}", shell=True, check=True, ) From 123c00dec045abdcc1e67a4243c832c1a4b8b872 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Tue, 31 Oct 2023 11:38:25 +0000 Subject: [PATCH 030/146] devenv processes stop: print PID --- src/devenv/cli.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/devenv/cli.py b/src/devenv/cli.py index 90816991c..f2e2f7a4a 100644 --- a/src/devenv/cli.py +++ b/src/devenv/cli.py @@ -400,6 +400,8 @@ def stop(): with open(PROCESSES_PID, "r") as file: pid = int(file.read()) + log(f"Stopping process with PID {pid} ...", level="info") + try: os.kill(pid, signal.SIGTERM) except ProcessLookupError: From 6408e959b507d5f37e821a5b017fb0c15d9fafdb Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 18 Dec 2023 23:32:59 -0500 Subject: [PATCH 031/146] normalize paths when root is / --- src/modules/top-level.nix | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/modules/top-level.nix b/src/modules/top-level.nix index 376d1bbe5..aa1ef0caa 100644 --- a/src/modules/top-level.nix +++ b/src/modules/top-level.nix @@ -194,8 +194,9 @@ in ''; } ]; - devenv.dotfile = config.devenv.root + "/.devenv"; - devenv.state = config.devenv.dotfile + "/state"; + # use builtins.toPath to normalize path if root is "/" (container) + devenv.dotfile = builtins.toPath (config.devenv.root + "/.devenv"); + devenv.state = builtins.toPath (config.devenv.dotfile + "/state"); devenv.profile = profile; env.DEVENV_PROFILE = config.devenv.profile; From b25e8a00d333ea5c4d03a3c1ff558d5791c49188 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 23 Dec 2023 23:57:17 -0500 Subject: [PATCH 032/146] Recreate Python venv and run pip install less often --- src/modules/languages/python.nix | 44 ++++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 14 deletions(-) diff --git a/src/modules/languages/python.nix b/src/modules/languages/python.nix index a2d713667..fde65f358 100644 --- a/src/modules/languages/python.nix +++ b/src/modules/languages/python.nix @@ -45,26 +45,42 @@ let VENV_PATH="${config.env.DEVENV_STATE}/venv" - if [ "$(${readlink} "$VENV_PATH"/bin/python)" != "$(${readlink} ${package.interpreter}/bin/python)" ] \ - || [ "$(${readlink} "$VENV_PATH"/requirements.txt)" != "$(${readlink} ${if requirements != null then requirements else "$VENV_PATH/requirements.txt"})" ] + profile_python="$(${readlink} ${package.interpreter})" + devenv_interpreter_path="$(${pkgs.coreutils}/bin/cat "$VENV_PATH/.devenv_interpreter" 2> /dev/null|| false )" + venv_python="$(${readlink} "$devenv_interpreter_path")" + requirements="${lib.optionalString (cfg.venv.requirements != null) ''${requirements}''}" + + # recreate venv if necessary + if [ -z $venv_python ] || [ $profile_python != $venv_python ] then - if [ -d "$VENV_PATH" ] - then - echo "Python interpreter/requirements changed, rebuilding Python venv..." - ${pkgs.coreutils}/bin/rm -rf "$VENV_PATH" - fi + echo "Python interpreter changed, rebuilding Python venv..." + ${pkgs.coreutils}/bin/rm -rf "$VENV_PATH" ${lib.optionalString cfg.poetry.enable '' [ -f "${config.env.DEVENV_STATE}/poetry.lock.checksum" ] && rm ${config.env.DEVENV_STATE}/poetry.lock.checksum ''} - echo ${package.interpreter} -m venv "$VENV_PATH" - ${package.interpreter} -m venv "$VENV_PATH" + echo ${package.interpreter} -m venv --upgrade-deps "$VENV_PATH" + ${package.interpreter} -m venv --upgrade-deps "$VENV_PATH" + echo "${package.interpreter}" > "$VENV_PATH/.devenv_interpreter" + if [ -n "$requirements" ] + then + echo "${requirements}" > "$VENV_PATH/.devenv_requirements" + fi fi + source "$VENV_PATH"/bin/activate - ${lib.optionalString (cfg.venv.requirements != null) '' - "$VENV_PATH"/bin/pip install -r ${requirements} ${lib.optionalString cfg.venv.quiet '' - --quiet - ''} - ''} + + # reinstall requirements if necessary + if [ -n "$requirements" ] + then + devenv_requirements_path="$(${pkgs.coreutils}/bin/cat "$VENV_PATH/.devenv_requirements" 2> /dev/null|| false )" + devenv_requirements="$(${readlink} "$devenv_requirements_path")" + if [ -z $devenv_requirements ] || [ $devenv_requirements != $requirements ] + then + echo "${requirements}" > "$VENV_PATH/.devenv_requirements" + echo "Requirements changed, running pip install -r ${requirements}..." + "$VENV_PATH"/bin/pip install -r ${requirements} + fi + fi ''; initPoetryScript = pkgs.writeShellScript "init-poetry.sh" '' From fba13cfbe53d10dc96879fbb327cc4be169d7ef3 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 23 Dec 2023 23:57:17 -0500 Subject: [PATCH 033/146] Recreate Python venv and run pip install less often --- src/modules/languages/python.nix | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/modules/languages/python.nix b/src/modules/languages/python.nix index fde65f358..2be1604af 100644 --- a/src/modules/languages/python.nix +++ b/src/modules/languages/python.nix @@ -61,10 +61,6 @@ let echo ${package.interpreter} -m venv --upgrade-deps "$VENV_PATH" ${package.interpreter} -m venv --upgrade-deps "$VENV_PATH" echo "${package.interpreter}" > "$VENV_PATH/.devenv_interpreter" - if [ -n "$requirements" ] - then - echo "${requirements}" > "$VENV_PATH/.devenv_requirements" - fi fi source "$VENV_PATH"/bin/activate From 15d3a6fecf96fb2b32f5768fe49ad03b25d2dc30 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 23 Dec 2023 23:28:53 -0500 Subject: [PATCH 034/146] container startup commands did not work due to quoting of args; we now also evaluate any shell variables in the startup command before executing it --- src/modules/containers.nix | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/modules/containers.nix b/src/modules/containers.nix index 5e7efbc79..06d0b5be0 100644 --- a/src/modules/containers.nix +++ b/src/modules/containers.nix @@ -28,7 +28,10 @@ let source ${shell.envScript} - exec "$@" + # expand any envvars before exec + cmd="`echo "$@"|${pkgs.envsubst}/bin/envsubst`" + + exec $cmd ''; mkDerivation = cfg: nix2container.nix2container.buildImage { name = cfg.name; From 5af48b4369502ab9db6f871e86458e7cd0f1d7ad Mon Sep 17 00:00:00 2001 From: Bob van der Linden Date: Wed, 10 Jan 2024 14:56:33 +0100 Subject: [PATCH 035/146] examples/python-poetry: use python libraries instead of packages --- examples/python-poetry/devenv.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/python-poetry/devenv.nix b/examples/python-poetry/devenv.nix index e3dd29617..318322486 100644 --- a/examples/python-poetry/devenv.nix +++ b/examples/python-poetry/devenv.nix @@ -1,7 +1,7 @@ { pkgs, config, ... }: { - packages = [ + languages.python.libraries = [ # A native dependency of numpy pkgs.zlib From 835ad1d067145ea8e0b7b255e470f78cefb91cba Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sun, 14 Jan 2024 23:02:37 -0500 Subject: [PATCH 036/146] to allow 'devenv processes stop' to stop processes we need to exec the procfilescript --- src/devenv/cli.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/devenv/cli.py b/src/devenv/cli.py index f2e2f7a4a..266f6ba1f 100644 --- a/src/devenv/cli.py +++ b/src/devenv/cli.py @@ -363,7 +363,7 @@ def up(ctx, process, detach): f.write( f"""#!/usr/bin/env bash {env} -{procfilescript} {process or ""} +exec {procfilescript} {process or ""} """ ) os.chmod(processes_script, 0o755) From eef3e4861a523a048ce743169a13dae056803b69 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Fri, 19 Jan 2024 10:50:18 -0500 Subject: [PATCH 037/146] add a --keep-going flag and handle ctrl-C during test running more gracefully --- src/devenv/cli.py | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/devenv/cli.py b/src/devenv/cli.py index 266f6ba1f..9968c53c9 100644 --- a/src/devenv/cli.py +++ b/src/devenv/cli.py @@ -20,7 +20,7 @@ import requests from .yaml import validate_and_parse_yaml, read_yaml, write_yaml, schema -from .log import log, log_task, log_error, log_warning, log_info, log_debug +from .log import log, log_task, log_error, log_warning, log_info NIX_FLAGS = [ @@ -681,8 +681,10 @@ def add(ctx, name, url, follows): ) @click.argument("names", nargs=-1) @click.option("--debug", is_flag=True, help="Run tests in debug mode.") +@click.option( + "--keep-going", is_flag=True, help="Continue running tests if one fails.") @click.pass_context -def test(ctx, debug, names): +def test(ctx, debug, keep_going, names): ctx.invoke(assemble) with log_task("Gathering tests", newline=False): tests = json.loads(run_nix("eval .#devenv.tests --json")) @@ -709,6 +711,7 @@ def test(ctx, debug, names): log(f"Found {len(tests)} test(s), running {len(selected_tests)}:", level="info") pwd = os.getcwd() + failed = [] for name in selected_tests: with log_task(f" Testing {name}"): @@ -788,8 +791,13 @@ def test(ctx, debug, names): run_command(f"{devenv} processes stop") if p: p.kill() + except KeyboardInterrupt: + raise except BaseException as e: log_error(f"Test {name} failed.") + if keep_going: + failed.append(name) + continue if debug: log( "Entering shell because of the --debug flag:", @@ -803,6 +811,9 @@ def test(ctx, debug, names): else: log_warning("Pass --debug flag to enter shell.") raise e + if keep_going and failed: + log_error(f"Failed: {', '.join(failed)}") + sys.exit(2) def write_if_defined(file, content): @@ -824,7 +835,7 @@ def get_cachix_caches(logging=True): disable_stderr=True, logging=False, ) - except subprocess.CalledProcessError as e: + except subprocess.CalledProcessError: return {"pull": [], "push": None}, {} caches = json.loads(caches_raw) From a6155c79ec24c748a3f250655802655b4d308178 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Fri, 19 Jan 2024 12:39:12 -0500 Subject: [PATCH 038/146] until we get the env-venv nixpkgs stuff in a place we can use, we need to set LD_LIBRARY_PATH by hand --- examples/python-poetry/devenv.nix | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/examples/python-poetry/devenv.nix b/examples/python-poetry/devenv.nix index 318322486..2a8cf4179 100644 --- a/examples/python-poetry/devenv.nix +++ b/examples/python-poetry/devenv.nix @@ -1,13 +1,16 @@ -{ pkgs, config, ... }: +{ pkgs, lib, config, ... }: { - languages.python.libraries = [ - # A native dependency of numpy - pkgs.zlib - + packages = [ # A python dependency outside of poetry. config.languages.python.package.pkgs.pjsua2 ]; + + env.LD_LIBRARY_PATH = lib.makeLibraryPath [ + # A native dependency of numpy + pkgs.zlib + ]; + languages.python = { enable = true; poetry.enable = true; From 8ca5e67ef256f1a7504a7f9278f34bce6f41b421 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Fri, 19 Jan 2024 12:39:39 -0500 Subject: [PATCH 039/146] some packages are now unfree --- examples/supported-languages/devenv.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/supported-languages/devenv.yaml b/examples/supported-languages/devenv.yaml index 89a8475be..64617fcf3 100644 --- a/examples/supported-languages/devenv.yaml +++ b/examples/supported-languages/devenv.yaml @@ -2,3 +2,4 @@ allowUnfree: true inputs: nixpkgs: url: github:NixOS/nixpkgs/nixpkgs-unstable +allowUnfree: true From 85acc1c8767be7f6be3f73997f7a9242d110685e Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Fri, 19 Jan 2024 12:40:00 -0500 Subject: [PATCH 040/146] some packages are now unfree --- examples/vault/devenv.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/vault/devenv.yaml b/examples/vault/devenv.yaml index 5d2ccd397..41b52a524 100644 --- a/examples/vault/devenv.yaml +++ b/examples/vault/devenv.yaml @@ -1,4 +1,4 @@ inputs: nixpkgs: url: github:NixOS/nixpkgs/nixpkgs-unstable -allowUnfree: true \ No newline at end of file +allowUnfree: true From 90bb9f2f9eaf35d537cabbfa01e251593ff865b5 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Fri, 19 Jan 2024 12:43:51 -0500 Subject: [PATCH 041/146] install rails via gem, add libyaml to make tests pass --- examples/rubyonrails/devenv.nix | 2 ++ 1 file changed, 2 insertions(+) diff --git a/examples/rubyonrails/devenv.nix b/examples/rubyonrails/devenv.nix index e93024ee8..1273110ca 100644 --- a/examples/rubyonrails/devenv.nix +++ b/examples/rubyonrails/devenv.nix @@ -6,6 +6,7 @@ packages = [ pkgs.openssl + pkgs.libyaml ]; services.postgres.enable = true; @@ -14,6 +15,7 @@ enterShell = '' if [ ! -d "blog" ]; then + gem install rails rails new blog -d=postgresql fi export PATH="$DEVENV_ROOT/blog/bin:$PATH" From a0901d2ea030502fd21bbecc34b6f5e2cd988414 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Fri, 19 Jan 2024 12:44:02 -0500 Subject: [PATCH 042/146] add comment about env-venv --- tests/python-native-libs/devenv.nix | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/python-native-libs/devenv.nix b/tests/python-native-libs/devenv.nix index d8c5e5d34..a8d549c97 100644 --- a/tests/python-native-libs/devenv.nix +++ b/tests/python-native-libs/devenv.nix @@ -1,4 +1,5 @@ { pkgs, ... }: { + # this test fails without use of the env-venv version of nixpkgs packages = [ pkgs.cairo ]; languages.python = { From 1f05fd6af21ca420c592a5b70a675987a69828f8 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Fri, 19 Jan 2024 12:47:20 -0500 Subject: [PATCH 043/146] comment --- examples/python-poetry/devenv.nix | 2 ++ 1 file changed, 2 insertions(+) diff --git a/examples/python-poetry/devenv.nix b/examples/python-poetry/devenv.nix index 2a8cf4179..97fb33a07 100644 --- a/examples/python-poetry/devenv.nix +++ b/examples/python-poetry/devenv.nix @@ -6,6 +6,8 @@ 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 From 9c24a04bb85ea6c20a2255fc07954c1099816235 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Fri, 19 Jan 2024 12:56:43 -0500 Subject: [PATCH 044/146] make python-native-libs test pass --- tests/python-native-libs/devenv.nix | 10 ++++++++-- tests/python-native-libs/devenv.yaml | 2 +- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/tests/python-native-libs/devenv.nix b/tests/python-native-libs/devenv.nix index a8d549c97..5d7bd5a29 100644 --- a/tests/python-native-libs/devenv.nix +++ b/tests/python-native-libs/devenv.nix @@ -1,7 +1,13 @@ -{ pkgs, ... }: { - # this test fails without use of the env-venv version of nixpkgs +{ pkgs, lib, ... }: { packages = [ pkgs.cairo ]; + # we must set LD_LIBRARY_PATH by hand without use of the env-venv + # version of nixpkgs, this can be removed when we switch to one + env.LD_LIBRARY_PATH = lib.makeLibraryPath [ + pkgs.pythonManylinuxPackages.manylinux2014Package + pkgs.zlib + ]; + languages.python = { enable = true; venv.enable = true; diff --git a/tests/python-native-libs/devenv.yaml b/tests/python-native-libs/devenv.yaml index f8523e963..25b947129 100644 --- a/tests/python-native-libs/devenv.yaml +++ b/tests/python-native-libs/devenv.yaml @@ -2,4 +2,4 @@ inputs: devenv: url: path:./../../src/modules nixpkgs: - url: github:NixOS/nixpkgs/08a3497b59051c2839c8ced79d39687b8485ab26 + url: github:NixOS/nixpkgs/nixpkgs-unstable From 43443279950b9cf6e4098aa5b7257fde72efac23 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 20 Jan 2024 12:22:51 -0500 Subject: [PATCH 045/146] put user-defined libs first on LD_LIBRARY_PATH --- src/modules/languages/python.nix | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/modules/languages/python.nix b/src/modules/languages/python.nix index 2be1604af..ecf7b19ef 100644 --- a/src/modules/languages/python.nix +++ b/src/modules/languages/python.nix @@ -2,11 +2,11 @@ let cfg = config.languages.python; - libraries = lib.makeLibraryPath - ((lib.optional cfg.manylinux.enable pkgs.pythonManylinuxPackages.manylinux2014Package) - # see https://matrix.to/#/!kjdutkOsheZdjqYmqp:nixos.org/$XJ5CO4bKMevYzZq_rrNo64YycknVFJIJTy6hVCJjRlA?via=nixos.org&via=matrix.org&via=nixos.dev - ++ [ pkgs.stdenv.cc.cc.lib ] - ++ cfg.libraries + libraries = lib.makeLibraryPath ( + cfg.libraries + ++ (lib.optional cfg.manylinux.enable pkgs.pythonManylinuxPackages.manylinux2014Package) + # see https://matrix.to/#/!kjdutkOsheZdjqYmqp:nixos.org/$XJ5CO4bKMevYzZq_rrNo64YycknVFJIJTy6hVCJjRlA?via=nixos.org&via=matrix.org&via=nixos.dev + ++ [ pkgs.stdenv.cc.cc.lib ] ); readlink = "${pkgs.coreutils}/bin/readlink -f "; From 7d14211bcd98a17ba2cab4a5400af297e5e9ddc2 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 22 Jan 2024 20:15:36 -0500 Subject: [PATCH 046/146] add --exclude feature --- src/devenv/cli.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/devenv/cli.py b/src/devenv/cli.py index 9968c53c9..7cdf25b7c 100644 --- a/src/devenv/cli.py +++ b/src/devenv/cli.py @@ -683,8 +683,12 @@ def add(ctx, name, url, follows): @click.option("--debug", is_flag=True, help="Run tests in debug mode.") @click.option( "--keep-going", is_flag=True, help="Continue running tests if one fails.") +@click.option( + "--exclude", multiple=True, + help="A test name to exclude, may be specified multiple times" +) @click.pass_context -def test(ctx, debug, keep_going, names): +def test(ctx, debug, keep_going, exclude, names): ctx.invoke(assemble) with log_task("Gathering tests", newline=False): tests = json.loads(run_nix("eval .#devenv.tests --json")) @@ -705,8 +709,9 @@ def test(ctx, debug, keep_going, names): if name in tests: selected_tests.append(name) tag_tests = tags.get(name, {}) - if tag_tests: - selected_tests.extend(tag_tests) + for test in tag_tests: + if not test in exclude: + selected_tests.append(test) log(f"Found {len(tests)} test(s), running {len(selected_tests)}:", level="info") From e7211866357791f14d57e774584f5a8beee9ce1f Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 22 Jan 2024 20:15:52 -0500 Subject: [PATCH 047/146] make tests pass --- examples/cockroachdb/devenv.yaml | 3 +-- examples/dotenv/.test.sh | 1 + examples/elasticmq/.test.sh | 12 +----------- examples/influxdb/.test.sh | 12 +----------- examples/supported-languages/devenv.yaml | 1 - examples/temporal/.test.sh | 16 ++++++++-------- examples/varnish/.test.sh | 10 ---------- src/modules/languages/rust.nix | 2 +- 8 files changed, 13 insertions(+), 44 deletions(-) diff --git a/examples/cockroachdb/devenv.yaml b/examples/cockroachdb/devenv.yaml index c1430d735..41b52a524 100644 --- a/examples/cockroachdb/devenv.yaml +++ b/examples/cockroachdb/devenv.yaml @@ -1,5 +1,4 @@ -allowUnfree: true inputs: nixpkgs: url: github:NixOS/nixpkgs/nixpkgs-unstable -allowUnfree: true \ No newline at end of file +allowUnfree: true diff --git a/examples/dotenv/.test.sh b/examples/dotenv/.test.sh index a7e1d576a..e3b1bf477 100755 --- a/examples/dotenv/.test.sh +++ b/examples/dotenv/.test.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +set -ex env | grep FOO=1 env | grep BAR=1 env | grep BAZ=5 diff --git a/examples/elasticmq/.test.sh b/examples/elasticmq/.test.sh index b0a849392..8607368d1 100755 --- a/examples/elasticmq/.test.sh +++ b/examples/elasticmq/.test.sh @@ -1,16 +1,6 @@ #!/usr/bin/env bash set -ex -devenv up & -DEVENV_PID=$! -export DEVENV_PID - -function stop() { - pkill -P "$DEVENV_PID" -} - -trap stop EXIT - timeout 60 bash -c 'until echo > /dev/tcp/localhost/9325; do sleep 0.5; done' QUEUE_NAME=$(curl http://localhost:9325/statistics/queues -s | jq .[].name -r) @@ -18,4 +8,4 @@ QUEUE_NAME=$(curl http://localhost:9325/statistics/queues -s | jq .[].name -r) if [[ "$QUEUE_NAME" != "test-queue" ]]; then echo "The queue is not created" exit 1 -fi \ No newline at end of file +fi diff --git a/examples/influxdb/.test.sh b/examples/influxdb/.test.sh index ce2c18335..270ec901e 100755 --- a/examples/influxdb/.test.sh +++ b/examples/influxdb/.test.sh @@ -1,16 +1,6 @@ #!/usr/bin/env bash set -ex -devenv up & -DEVENV_PID=$! -export DEVENV_PID - -function stop() { - pkill -P "$DEVENV_PID" -} - -trap stop EXIT - # We test for the none-default port, configured in the nix file timeout 60 bash -c 'until echo > /dev/tcp/localhost/8087; do sleep 0.5; done' @@ -20,4 +10,4 @@ DATABASES=$(influx --port 8087 --execute "SHOW DATABASES" | grep devenv) if [[ "$DATABASES" != "devenv" ]]; then echo "The influxdb database was not created" exit 1 -fi \ No newline at end of file +fi diff --git a/examples/supported-languages/devenv.yaml b/examples/supported-languages/devenv.yaml index 64617fcf3..41b52a524 100644 --- a/examples/supported-languages/devenv.yaml +++ b/examples/supported-languages/devenv.yaml @@ -1,4 +1,3 @@ -allowUnfree: true inputs: nixpkgs: url: github:NixOS/nixpkgs/nixpkgs-unstable diff --git a/examples/temporal/.test.sh b/examples/temporal/.test.sh index 86f7ffeb2..19395639c 100755 --- a/examples/temporal/.test.sh +++ b/examples/temporal/.test.sh @@ -1,9 +1,14 @@ -#!/usr/bin/env bash +#!/bin/sh set -x export TEMPORAL_ADDRESS=127.0.0.1:17233 -timeout 20 bash -c 'until echo > /dev/tcp/localhost/17233; do sleep 0.5; done' +# temporal status and store its exit status +check_temporal_status() { + echo "Waiting for service to become available..." + TEMPORAL_OUTPUT=$(temporal operator cluster health) + TEMPORAL_EXIT_STATUS=$? +} # Continuously check temporal status until it returns successfully (up to a maximum of 20 times) # shellcheck disable=SC2034 @@ -17,11 +22,6 @@ for i in $(seq 1 20); do fi done -if ! temporal operator cluster health; then - echo "Temporal not started" - exit 1 -fi - echo "Checking namespace..." temporal operator namespace describe mynamespace @@ -31,4 +31,4 @@ temporal operator cluster system echo "$TEMPORAL_OUTPUT" # Exit the script -exit "$TEMPORAL_EXIT_STATUS" \ No newline at end of file +exit "$TEMPORAL_EXIT_STATUS" diff --git a/examples/varnish/.test.sh b/examples/varnish/.test.sh index 129fd523f..3c7e21296 100755 --- a/examples/varnish/.test.sh +++ b/examples/varnish/.test.sh @@ -1,16 +1,6 @@ #!/usr/bin/env bash set -ex -devenv up & -DEVENV_PID=$! -export DEVENV_PID - -devenv_stop() { - pkill -P "$DEVENV_PID" -} - -trap devenv_stop EXIT - timeout 20 bash -c 'until echo > /dev/tcp/localhost/6081; do sleep 0.5; done' caddy=$(curl http://localhost:8001) diff --git a/src/modules/languages/rust.nix b/src/modules/languages/rust.nix index 1f1f15787..4499f5217 100644 --- a/src/modules/languages/rust.nix +++ b/src/modules/languages/rust.nix @@ -76,7 +76,7 @@ in export PATH="$PATH:$CARGO_INSTALL_ROOT/bin" ''; - packages = (builtins.map (c: cfg.toolchain.${c} or (throw (error "toolchain.${c}"))) cfg.components) + packages = (builtins.map (c: cfg.toolchain.${c} or (throw "toolchain.${c}")) cfg.components) ++ lib.optional pkgs.stdenv.isDarwin pkgs.libiconv; # enable compiler tooling by default to expose things like cc From c926f5a829add6e2acffc139308297c7ad947462 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 22 Jan 2024 20:23:55 -0500 Subject: [PATCH 048/146] try to make these tests pass but they do not --- examples/phoenix/.test.sh | 1 + examples/phoenix/devenv.nix | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/phoenix/.test.sh b/examples/phoenix/.test.sh index b7bdb2f10..75f3c0b25 100755 --- a/examples/phoenix/.test.sh +++ b/examples/phoenix/.test.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash set -ex +mkdir hello mix local.hex --force mix local.rebar --force echo Y | mix archive.install hex phx_new diff --git a/examples/phoenix/devenv.nix b/examples/phoenix/devenv.nix index 62259e772..e6d6a4241 100644 --- a/examples/phoenix/devenv.nix +++ b/examples/phoenix/devenv.nix @@ -7,5 +7,5 @@ services.postgres.enable = true; - processes.phoenix.exec = "cd hello && mix ecto.create && mix phx.server"; + processes.phoenix.exec = "mix ecto.create && mix phx.server"; } From 62b52bc5f8cb850d76020ace90417b6839ef4a72 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Tue, 23 Jan 2024 19:40:14 -0500 Subject: [PATCH 049/146] make vault test pass in reality --- examples/vault/.test.sh | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/examples/vault/.test.sh b/examples/vault/.test.sh index 408a4ecf1..586bd6e5b 100755 --- a/examples/vault/.test.sh +++ b/examples/vault/.test.sh @@ -20,7 +20,10 @@ for i in $(seq 1 20); do fi done -timeout 20 bash -c 'until echo > /dev/tcp/localhost/8200; do sleep 0.5; done' +# Print the captured output when vault status succeeds +echo "Startup complete..." +vault version +echo "$VAULT_OUTPUT" # Exit the script -exit "$VAULT_EXIT_STATUS" \ No newline at end of file +exit "$VAULT_EXIT_STATUS" From 77185f33687dd6b8e07d027973d4d02df965c69f Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Tue, 23 Jan 2024 19:40:25 -0500 Subject: [PATCH 050/146] update poetry lock --- poetry.lock | 924 +++++++++++++++++++++++++++------------------------- 1 file changed, 473 insertions(+), 451 deletions(-) diff --git a/poetry.lock b/poetry.lock index 65e0ec62a..e2c5f21ed 100644 --- a/poetry.lock +++ b/poetry.lock @@ -2,24 +2,22 @@ [[package]] name = "babel" -version = "2.12.1" +version = "2.14.0" description = "Internationalization utilities" -category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "Babel-2.12.1-py3-none-any.whl", hash = "sha256:b4246fb7677d3b98f501a39d43396d3cafdc8eadb045f4a31be01863f655c610"}, - {file = "Babel-2.12.1.tar.gz", hash = "sha256:cc2d99999cd01d44420ae725a21c9e3711b3aadc7976d6147f622d8581963455"}, + {file = "Babel-2.14.0-py3-none-any.whl", hash = "sha256:efb1a25b7118e67ce3a259bed20545c29cb68be8ad2c784c83689981b7a57287"}, + {file = "Babel-2.14.0.tar.gz", hash = "sha256:6919867db036398ba21eb5c7a0f6b28ab8cbc3ae7a73a44ebe34ae74a4e7d363"}, ] -[package.dependencies] -pytz = {version = ">=2015.7", markers = "python_version < \"3.9\""} +[package.extras] +dev = ["freezegun (>=1.0,<2.0)", "pytest (>=6.0)", "pytest-cov"] [[package]] name = "bracex" version = "2.4" description = "Bash style brace expander." -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -70,86 +68,74 @@ test = ["flake8", "isort", "pytest"] [[package]] name = "certifi" -version = "2023.7.22" +version = "2023.11.17" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2023.7.22-py3-none-any.whl", hash = "sha256:92d6037539857d8206b8f6ae472e8b77db8058fec5937a1ef3f54304089edbb9"}, - {file = "certifi-2023.7.22.tar.gz", hash = "sha256:539cc1d13202e33ca466e88b2807e29f4c13049d6d87031a3c110744495cb082"}, + {file = "certifi-2023.11.17-py3-none-any.whl", hash = "sha256:e036ab49d5b79556f99cfc2d9320b34cfbe5be05c5871b51de9329f0603b0474"}, + {file = "certifi-2023.11.17.tar.gz", hash = "sha256:9b469f3a900bf28dc19b8cfbf8019bf47f7fdd1a65a1d4ffb98fc14166beb4d1"}, ] [[package]] name = "cffi" -version = "1.15.1" +version = "1.16.0" description = "Foreign Function Interface for Python calling C code." optional = false -python-versions = "*" +python-versions = ">=3.8" files = [ - {file = "cffi-1.15.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:a66d3508133af6e8548451b25058d5812812ec3798c886bf38ed24a98216fab2"}, - {file = "cffi-1.15.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:470c103ae716238bbe698d67ad020e1db9d9dba34fa5a899b5e21577e6d52ed2"}, - {file = "cffi-1.15.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:9ad5db27f9cabae298d151c85cf2bad1d359a1b9c686a275df03385758e2f914"}, - {file = "cffi-1.15.1-cp27-cp27m-win32.whl", hash = "sha256:b3bbeb01c2b273cca1e1e0c5df57f12dce9a4dd331b4fa1635b8bec26350bde3"}, - {file = "cffi-1.15.1-cp27-cp27m-win_amd64.whl", hash = "sha256:e00b098126fd45523dd056d2efba6c5a63b71ffe9f2bbe1a4fe1716e1d0c331e"}, - {file = "cffi-1.15.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:d61f4695e6c866a23a21acab0509af1cdfd2c013cf256bbf5b6b5e2695827162"}, - {file = "cffi-1.15.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:ed9cb427ba5504c1dc15ede7d516b84757c3e3d7868ccc85121d9310d27eed0b"}, - {file = "cffi-1.15.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:39d39875251ca8f612b6f33e6b1195af86d1b3e60086068be9cc053aa4376e21"}, - {file = "cffi-1.15.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:285d29981935eb726a4399badae8f0ffdff4f5050eaa6d0cfc3f64b857b77185"}, - {file = "cffi-1.15.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3eb6971dcff08619f8d91607cfc726518b6fa2a9eba42856be181c6d0d9515fd"}, - {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:21157295583fe8943475029ed5abdcf71eb3911894724e360acff1d61c1d54bc"}, - {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5635bd9cb9731e6d4a1132a498dd34f764034a8ce60cef4f5319c0541159392f"}, - {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2012c72d854c2d03e45d06ae57f40d78e5770d252f195b93f581acf3ba44496e"}, - {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd86c085fae2efd48ac91dd7ccffcfc0571387fe1193d33b6394db7ef31fe2a4"}, - {file = "cffi-1.15.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:fa6693661a4c91757f4412306191b6dc88c1703f780c8234035eac011922bc01"}, - {file = "cffi-1.15.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:59c0b02d0a6c384d453fece7566d1c7e6b7bae4fc5874ef2ef46d56776d61c9e"}, - {file = "cffi-1.15.1-cp310-cp310-win32.whl", hash = "sha256:cba9d6b9a7d64d4bd46167096fc9d2f835e25d7e4c121fb2ddfc6528fb0413b2"}, - {file = "cffi-1.15.1-cp310-cp310-win_amd64.whl", hash = "sha256:ce4bcc037df4fc5e3d184794f27bdaab018943698f4ca31630bc7f84a7b69c6d"}, - {file = "cffi-1.15.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3d08afd128ddaa624a48cf2b859afef385b720bb4b43df214f85616922e6a5ac"}, - {file = "cffi-1.15.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3799aecf2e17cf585d977b780ce79ff0dc9b78d799fc694221ce814c2c19db83"}, - {file = "cffi-1.15.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a591fe9e525846e4d154205572a029f653ada1a78b93697f3b5a8f1f2bc055b9"}, - {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3548db281cd7d2561c9ad9984681c95f7b0e38881201e157833a2342c30d5e8c"}, - {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:91fc98adde3d7881af9b59ed0294046f3806221863722ba7d8d120c575314325"}, - {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:94411f22c3985acaec6f83c6df553f2dbe17b698cc7f8ae751ff2237d96b9e3c"}, - {file = "cffi-1.15.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:03425bdae262c76aad70202debd780501fabeaca237cdfddc008987c0e0f59ef"}, - {file = "cffi-1.15.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:cc4d65aeeaa04136a12677d3dd0b1c0c94dc43abac5860ab33cceb42b801c1e8"}, - {file = "cffi-1.15.1-cp311-cp311-win32.whl", hash = "sha256:a0f100c8912c114ff53e1202d0078b425bee3649ae34d7b070e9697f93c5d52d"}, - {file = "cffi-1.15.1-cp311-cp311-win_amd64.whl", hash = "sha256:04ed324bda3cda42b9b695d51bb7d54b680b9719cfab04227cdd1e04e5de3104"}, - {file = "cffi-1.15.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50a74364d85fd319352182ef59c5c790484a336f6db772c1a9231f1c3ed0cbd7"}, - {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e263d77ee3dd201c3a142934a086a4450861778baaeeb45db4591ef65550b0a6"}, - {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cec7d9412a9102bdc577382c3929b337320c4c4c4849f2c5cdd14d7368c5562d"}, - {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4289fc34b2f5316fbb762d75362931e351941fa95fa18789191b33fc4cf9504a"}, - {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:173379135477dc8cac4bc58f45db08ab45d228b3363adb7af79436135d028405"}, - {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:6975a3fac6bc83c4a65c9f9fcab9e47019a11d3d2cf7f3c0d03431bf145a941e"}, - {file = "cffi-1.15.1-cp36-cp36m-win32.whl", hash = "sha256:2470043b93ff09bf8fb1d46d1cb756ce6132c54826661a32d4e4d132e1977adf"}, - {file = "cffi-1.15.1-cp36-cp36m-win_amd64.whl", hash = "sha256:30d78fbc8ebf9c92c9b7823ee18eb92f2e6ef79b45ac84db507f52fbe3ec4497"}, - {file = "cffi-1.15.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:198caafb44239b60e252492445da556afafc7d1e3ab7a1fb3f0584ef6d742375"}, - {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5ef34d190326c3b1f822a5b7a45f6c4535e2f47ed06fec77d3d799c450b2651e"}, - {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8102eaf27e1e448db915d08afa8b41d6c7ca7a04b7d73af6514df10a3e74bd82"}, - {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5df2768244d19ab7f60546d0c7c63ce1581f7af8b5de3eb3004b9b6fc8a9f84b"}, - {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8c4917bd7ad33e8eb21e9a5bbba979b49d9a97acb3a803092cbc1133e20343c"}, - {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e2642fe3142e4cc4af0799748233ad6da94c62a8bec3a6648bf8ee68b1c7426"}, - {file = "cffi-1.15.1-cp37-cp37m-win32.whl", hash = "sha256:e229a521186c75c8ad9490854fd8bbdd9a0c9aa3a524326b55be83b54d4e0ad9"}, - {file = "cffi-1.15.1-cp37-cp37m-win_amd64.whl", hash = "sha256:a0b71b1b8fbf2b96e41c4d990244165e2c9be83d54962a9a1d118fd8657d2045"}, - {file = "cffi-1.15.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:320dab6e7cb2eacdf0e658569d2575c4dad258c0fcc794f46215e1e39f90f2c3"}, - {file = "cffi-1.15.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e74c6b51a9ed6589199c787bf5f9875612ca4a8a0785fb2d4a84429badaf22a"}, - {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5c84c68147988265e60416b57fc83425a78058853509c1b0629c180094904a5"}, - {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3b926aa83d1edb5aa5b427b4053dc420ec295a08e40911296b9eb1b6170f6cca"}, - {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:87c450779d0914f2861b8526e035c5e6da0a3199d8f1add1a665e1cbc6fc6d02"}, - {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f2c9f67e9821cad2e5f480bc8d83b8742896f1242dba247911072d4fa94c192"}, - {file = "cffi-1.15.1-cp38-cp38-win32.whl", hash = "sha256:8b7ee99e510d7b66cdb6c593f21c043c248537a32e0bedf02e01e9553a172314"}, - {file = "cffi-1.15.1-cp38-cp38-win_amd64.whl", hash = "sha256:00a9ed42e88df81ffae7a8ab6d9356b371399b91dbdf0c3cb1e84c03a13aceb5"}, - {file = "cffi-1.15.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:54a2db7b78338edd780e7ef7f9f6c442500fb0d41a5a4ea24fff1c929d5af585"}, - {file = "cffi-1.15.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:fcd131dd944808b5bdb38e6f5b53013c5aa4f334c5cad0c72742f6eba4b73db0"}, - {file = "cffi-1.15.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7473e861101c9e72452f9bf8acb984947aa1661a7704553a9f6e4baa5ba64415"}, - {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c9a799e985904922a4d207a94eae35c78ebae90e128f0c4e521ce339396be9d"}, - {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3bcde07039e586f91b45c88f8583ea7cf7a0770df3a1649627bf598332cb6984"}, - {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:33ab79603146aace82c2427da5ca6e58f2b3f2fb5da893ceac0c42218a40be35"}, - {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d598b938678ebf3c67377cdd45e09d431369c3b1a5b331058c338e201f12b27"}, - {file = "cffi-1.15.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db0fbb9c62743ce59a9ff687eb5f4afbe77e5e8403d6697f7446e5f609976f76"}, - {file = "cffi-1.15.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:98d85c6a2bef81588d9227dde12db8a7f47f639f4a17c9ae08e773aa9c697bf3"}, - {file = "cffi-1.15.1-cp39-cp39-win32.whl", hash = "sha256:40f4774f5a9d4f5e344f31a32b5096977b5d48560c5592e2f3d2c4374bd543ee"}, - {file = "cffi-1.15.1-cp39-cp39-win_amd64.whl", hash = "sha256:70df4e3b545a17496c9b3f41f5115e69a4f2e77e94e1d2a8e1070bc0c38c8a3c"}, - {file = "cffi-1.15.1.tar.gz", hash = "sha256:d400bfb9a37b1351253cb402671cea7e89bdecc294e8016a707f6d1d8ac934f9"}, + {file = "cffi-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6b3d6606d369fc1da4fd8c357d026317fbb9c9b75d36dc16e90e84c26854b088"}, + {file = "cffi-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ac0f5edd2360eea2f1daa9e26a41db02dd4b0451b48f7c318e217ee092a213e9"}, + {file = "cffi-1.16.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7e61e3e4fa664a8588aa25c883eab612a188c725755afff6289454d6362b9673"}, + {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a72e8961a86d19bdb45851d8f1f08b041ea37d2bd8d4fd19903bc3083d80c896"}, + {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5b50bf3f55561dac5438f8e70bfcdfd74543fd60df5fa5f62d94e5867deca684"}, + {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7651c50c8c5ef7bdb41108b7b8c5a83013bfaa8a935590c5d74627c047a583c7"}, + {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4108df7fe9b707191e55f33efbcb2d81928e10cea45527879a4749cbe472614"}, + {file = "cffi-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:32c68ef735dbe5857c810328cb2481e24722a59a2003018885514d4c09af9743"}, + {file = "cffi-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:673739cb539f8cdaa07d92d02efa93c9ccf87e345b9a0b556e3ecc666718468d"}, + {file = "cffi-1.16.0-cp310-cp310-win32.whl", hash = "sha256:9f90389693731ff1f659e55c7d1640e2ec43ff725cc61b04b2f9c6d8d017df6a"}, + {file = "cffi-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:e6024675e67af929088fda399b2094574609396b1decb609c55fa58b028a32a1"}, + {file = "cffi-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b84834d0cf97e7d27dd5b7f3aca7b6e9263c56308ab9dc8aae9784abb774d404"}, + {file = "cffi-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1b8ebc27c014c59692bb2664c7d13ce7a6e9a629be20e54e7271fa696ff2b417"}, + {file = "cffi-1.16.0-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ee07e47c12890ef248766a6e55bd38ebfb2bb8edd4142d56db91b21ea68b7627"}, + {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8a9d3ebe49f084ad71f9269834ceccbf398253c9fac910c4fd7053ff1386936"}, + {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e70f54f1796669ef691ca07d046cd81a29cb4deb1e5f942003f401c0c4a2695d"}, + {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5bf44d66cdf9e893637896c7faa22298baebcd18d1ddb6d2626a6e39793a1d56"}, + {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7b78010e7b97fef4bee1e896df8a4bbb6712b7f05b7ef630f9d1da00f6444d2e"}, + {file = "cffi-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c6a164aa47843fb1b01e941d385aab7215563bb8816d80ff3a363a9f8448a8dc"}, + {file = "cffi-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e09f3ff613345df5e8c3667da1d918f9149bd623cd9070c983c013792a9a62eb"}, + {file = "cffi-1.16.0-cp311-cp311-win32.whl", hash = "sha256:2c56b361916f390cd758a57f2e16233eb4f64bcbeee88a4881ea90fca14dc6ab"}, + {file = "cffi-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:db8e577c19c0fda0beb7e0d4e09e0ba74b1e4c092e0e40bfa12fe05b6f6d75ba"}, + {file = "cffi-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:fa3a0128b152627161ce47201262d3140edb5a5c3da88d73a1b790a959126956"}, + {file = "cffi-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:68e7c44931cc171c54ccb702482e9fc723192e88d25a0e133edd7aff8fcd1f6e"}, + {file = "cffi-1.16.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:abd808f9c129ba2beda4cfc53bde801e5bcf9d6e0f22f095e45327c038bfe68e"}, + {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88e2b3c14bdb32e440be531ade29d3c50a1a59cd4e51b1dd8b0865c54ea5d2e2"}, + {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fcc8eb6d5902bb1cf6dc4f187ee3ea80a1eba0a89aba40a5cb20a5087d961357"}, + {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b7be2d771cdba2942e13215c4e340bfd76398e9227ad10402a8767ab1865d2e6"}, + {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e715596e683d2ce000574bae5d07bd522c781a822866c20495e52520564f0969"}, + {file = "cffi-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:2d92b25dbf6cae33f65005baf472d2c245c050b1ce709cc4588cdcdd5495b520"}, + {file = "cffi-1.16.0-cp312-cp312-win32.whl", hash = "sha256:b2ca4e77f9f47c55c194982e10f058db063937845bb2b7a86c84a6cfe0aefa8b"}, + {file = "cffi-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:68678abf380b42ce21a5f2abde8efee05c114c2fdb2e9eef2efdb0257fba1235"}, + {file = "cffi-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0c9ef6ff37e974b73c25eecc13952c55bceed9112be2d9d938ded8e856138bcc"}, + {file = "cffi-1.16.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a09582f178759ee8128d9270cd1344154fd473bb77d94ce0aeb2a93ebf0feaf0"}, + {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e760191dd42581e023a68b758769e2da259b5d52e3103c6060ddc02c9edb8d7b"}, + {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:80876338e19c951fdfed6198e70bc88f1c9758b94578d5a7c4c91a87af3cf31c"}, + {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a6a14b17d7e17fa0d207ac08642c8820f84f25ce17a442fd15e27ea18d67c59b"}, + {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6602bc8dc6f3a9e02b6c22c4fc1e47aa50f8f8e6d3f78a5e16ac33ef5fefa324"}, + {file = "cffi-1.16.0-cp38-cp38-win32.whl", hash = "sha256:131fd094d1065b19540c3d72594260f118b231090295d8c34e19a7bbcf2e860a"}, + {file = "cffi-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:31d13b0f99e0836b7ff893d37af07366ebc90b678b6664c955b54561fc36ef36"}, + {file = "cffi-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:582215a0e9adbe0e379761260553ba11c58943e4bbe9c36430c4ca6ac74b15ed"}, + {file = "cffi-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b29ebffcf550f9da55bec9e02ad430c992a87e5f512cd63388abb76f1036d8d2"}, + {file = "cffi-1.16.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dc9b18bf40cc75f66f40a7379f6a9513244fe33c0e8aa72e2d56b0196a7ef872"}, + {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cb4a35b3642fc5c005a6755a5d17c6c8b6bcb6981baf81cea8bfbc8903e8ba8"}, + {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b86851a328eedc692acf81fb05444bdf1891747c25af7529e39ddafaf68a4f3f"}, + {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c0f31130ebc2d37cdd8e44605fb5fa7ad59049298b3f745c74fa74c62fbfcfc4"}, + {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f8e709127c6c77446a8c0a8c8bf3c8ee706a06cd44b1e827c3e6a2ee6b8c098"}, + {file = "cffi-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:748dcd1e3d3d7cd5443ef03ce8685043294ad6bd7c02a38d1bd367cfd968e000"}, + {file = "cffi-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8895613bcc094d4a1b2dbe179d88d7fb4a15cee43c052e8885783fac397d91fe"}, + {file = "cffi-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed86a35631f7bfbb28e108dd96773b9d5a6ce4811cf6ea468bb6a359b256b1e4"}, + {file = "cffi-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:3686dffb02459559c74dd3d81748269ffb0eb027c39a6fc99502de37d501faa8"}, + {file = "cffi-1.16.0.tar.gz", hash = "sha256:bcb3ef43e58665bbda2fb198698fcae6776483e0c4a631aa5647806c25e02cc0"}, ] [package.dependencies] @@ -157,86 +143,101 @@ pycparser = "*" [[package]] name = "charset-normalizer" -version = "3.2.0" +version = "3.3.2" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false python-versions = ">=3.7.0" 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-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c57921cda3a80d0f2b8aec7e25c8aa14479ea92b5b51b6876d975d925a2ea346"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41b25eaa7d15909cf3ac4c96088c1f266a9a93ec44f87f1d13d4a0e86c81b982"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f058f6963fd82eb143c692cecdc89e075fa0828db2e5b291070485390b2f1c9c"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a7647ebdfb9682b7bb97e2a5e7cb6ae735b1c25008a70b906aecca294ee96cf4"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eef9df1eefada2c09a5e7a40991b9fc6ac6ef20b1372abd48d2794a316dc0449"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e03b8895a6990c9ab2cdcd0f2fe44088ca1c65ae592b8f795c3294af00a461c3"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:ee4006268ed33370957f55bf2e6f4d263eaf4dc3cfc473d1d90baff6ed36ce4a"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c4983bf937209c57240cff65906b18bb35e64ae872da6a0db937d7b4af845dd7"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:3bb7fda7260735efe66d5107fb7e6af6a7c04c7fce9b2514e04b7a74b06bf5dd"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:72814c01533f51d68702802d74f77ea026b5ec52793c791e2da806a3844a46c3"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:70c610f6cbe4b9fce272c407dd9d07e33e6bf7b4aa1b7ffb6f6ded8e634e3592"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-win32.whl", hash = "sha256:a401b4598e5d3f4a9a811f3daf42ee2291790c7f9d74b18d75d6e21dda98a1a1"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-win_amd64.whl", hash = "sha256:c0b21078a4b56965e2b12f247467b234734491897e99c1d51cee628da9786959"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:95eb302ff792e12aba9a8b8f8474ab229a83c103d74a750ec0bd1c1eea32e669"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1a100c6d595a7f316f1b6f01d20815d916e75ff98c27a01ae817439ea7726329"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:6339d047dab2780cc6220f46306628e04d9750f02f983ddb37439ca47ced7149"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4b749b9cc6ee664a3300bb3a273c1ca8068c46be705b6c31cf5d276f8628a94"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a38856a971c602f98472050165cea2cdc97709240373041b69030be15047691f"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f87f746ee241d30d6ed93969de31e5ffd09a2961a051e60ae6bddde9ec3583aa"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:89f1b185a01fe560bc8ae5f619e924407efca2191b56ce749ec84982fc59a32a"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e1c8a2f4c69e08e89632defbfabec2feb8a8d99edc9f89ce33c4b9e36ab63037"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2f4ac36d8e2b4cc1aa71df3dd84ff8efbe3bfb97ac41242fbcfc053c67434f46"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a386ebe437176aab38c041de1260cd3ea459c6ce5263594399880bbc398225b2"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:ccd16eb18a849fd8dcb23e23380e2f0a354e8daa0c984b8a732d9cfaba3a776d"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:e6a5bf2cba5ae1bb80b154ed68a3cfa2fa00fde979a7f50d6598d3e17d9ac20c"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:45de3f87179c1823e6d9e32156fb14c1927fcc9aba21433f088fdfb555b77c10"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-win32.whl", hash = "sha256:1000fba1057b92a65daec275aec30586c3de2401ccdcd41f8a5c1e2c87078706"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:8b2c760cfc7042b27ebdb4a43a4453bd829a5742503599144d54a032c5dc7e9e"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:855eafa5d5a2034b4621c74925d89c5efef61418570e5ef9b37717d9c796419c"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:203f0c8871d5a7987be20c72442488a0b8cfd0f43b7973771640fc593f56321f"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e857a2232ba53ae940d3456f7533ce6ca98b81917d47adc3c7fd55dad8fab858"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5e86d77b090dbddbe78867a0275cb4df08ea195e660f1f7f13435a4649e954e5"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c4fb39a81950ec280984b3a44f5bd12819953dc5fa3a7e6fa7a80db5ee853952"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2dee8e57f052ef5353cf608e0b4c871aee320dd1b87d351c28764fc0ca55f9f4"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8700f06d0ce6f128de3ccdbc1acaea1ee264d2caa9ca05daaf492fde7c2a7200"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1920d4ff15ce893210c1f0c0e9d19bfbecb7983c76b33f046c13a8ffbd570252"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:c1c76a1743432b4b60ab3358c937a3fe1341c828ae6194108a94c69028247f22"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f7560358a6811e52e9c4d142d497f1a6e10103d3a6881f18d04dbce3729c0e2c"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:c8063cf17b19661471ecbdb3df1c84f24ad2e389e326ccaf89e3fb2484d8dd7e"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:cd6dbe0238f7743d0efe563ab46294f54f9bc8f4b9bcf57c3c666cc5bc9d1299"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:1249cbbf3d3b04902ff081ffbb33ce3377fa6e4c7356f759f3cd076cc138d020"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-win32.whl", hash = "sha256:6c409c0deba34f147f77efaa67b8e4bb83d2f11c8806405f76397ae5b8c0d1c9"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:7095f6fbfaa55defb6b733cfeb14efaae7a29f0b59d8cf213be4e7ca0b857b80"}, - {file = "charset_normalizer-3.2.0-py3-none-any.whl", hash = "sha256:8e098148dd37b4ce3baca71fb394c81dc5d9c7728c95df695d2dca218edf40e6"}, + {file = "charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-win32.whl", hash = "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-win32.whl", hash = "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-win32.whl", hash = "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-win32.whl", hash = "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-win32.whl", hash = "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-win32.whl", hash = "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d"}, + {file = "charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc"}, ] [[package]] @@ -296,18 +297,19 @@ files = [ [[package]] name = "filelock" -version = "3.12.2" +version = "3.13.1" description = "A platform independent file lock." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "filelock-3.12.2-py3-none-any.whl", hash = "sha256:cbb791cdea2a72f23da6ac5b5269ab0a0d161e9ef0100e653b69049a7706d1ec"}, - {file = "filelock-3.12.2.tar.gz", hash = "sha256:002740518d8aa59a26b0c76e10fb8c6e15eae825d34b6fdf670333fd7b938d81"}, + {file = "filelock-3.13.1-py3-none-any.whl", hash = "sha256:57dbda9b35157b05fb3e58ee91448612eb674172fab98ee235ccb0b5bee19a1c"}, + {file = "filelock-3.13.1.tar.gz", hash = "sha256:521f5f56c50f8426f5e03ad3b281b490a87ef15bc6c526f168290f0c7148d44e"}, ] [package.extras] -docs = ["furo (>=2023.5.20)", "sphinx (>=7.0.1)", "sphinx-autodoc-typehints (>=1.23,!=1.23.4)"] -testing = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "diff-cover (>=7.5)", "pytest (>=7.3.1)", "pytest-cov (>=4.1)", "pytest-mock (>=3.10)", "pytest-timeout (>=2.1)"] +docs = ["furo (>=2023.9.10)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.24)"] +testing = ["covdefaults (>=2.3)", "coverage (>=7.3.2)", "diff-cover (>=8)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)", "pytest-timeout (>=2.2)"] +typing = ["typing-extensions (>=4.8)"] [[package]] name = "ghp-import" @@ -328,13 +330,13 @@ dev = ["flake8", "markdown", "twine", "wheel"] [[package]] name = "gitdb" -version = "4.0.10" +version = "4.0.11" description = "Git Object Database" optional = false python-versions = ">=3.7" files = [ - {file = "gitdb-4.0.10-py3-none-any.whl", hash = "sha256:c286cf298426064079ed96a9e4a9d39e7f3e9bf15ba60701e95f5492f28415c7"}, - {file = "gitdb-4.0.10.tar.gz", hash = "sha256:6eb990b69df4e15bad899ea868dc46572c3f75339735663b81de79b06f17eb9a"}, + {file = "gitdb-4.0.11-py3-none-any.whl", hash = "sha256:81a3407ddd2ee8df444cbacea00e2d038e40150acfa3001696fe0dcf1d3adfa4"}, + {file = "gitdb-4.0.11.tar.gz", hash = "sha256:bf5421126136d6d0af55bc1e7c1af1c397a34f5b7bd79e776cd3e89785c2b04b"}, ] [package.dependencies] @@ -342,60 +344,60 @@ smmap = ">=3.0.1,<6" [[package]] name = "gitpython" -version = "3.1.36" +version = "3.1.41" description = "GitPython is a Python library used to interact with Git repositories" optional = false python-versions = ">=3.7" files = [ - {file = "GitPython-3.1.36-py3-none-any.whl", hash = "sha256:8d22b5cfefd17c79914226982bb7851d6ade47545b1735a9d010a2a4c26d8388"}, - {file = "GitPython-3.1.36.tar.gz", hash = "sha256:4bb0c2a6995e85064140d31a33289aa5dce80133a23d36fcd372d716c54d3ebf"}, + {file = "GitPython-3.1.41-py3-none-any.whl", hash = "sha256:c36b6634d069b3f719610175020a9aed919421c87552185b085e04fbbdb10b7c"}, + {file = "GitPython-3.1.41.tar.gz", hash = "sha256:ed66e624884f76df22c8e16066d567aaa5a37d5b5fa19db2c6df6f7156db9048"}, ] [package.dependencies] gitdb = ">=4.0.1,<5" [package.extras] -test = ["black", "coverage[toml]", "ddt (>=1.1.1,!=1.4.3)", "mypy", "pre-commit", "pytest", "pytest-cov", "pytest-sugar", "virtualenv"] +test = ["black", "coverage[toml]", "ddt (>=1.1.1,!=1.4.3)", "mock", "mypy", "pre-commit", "pytest (>=7.3.1)", "pytest-cov", "pytest-instafail", "pytest-mock", "pytest-sugar", "sumtypes"] [[package]] name = "idna" -version = "3.4" +version = "3.6" description = "Internationalized Domain Names in Applications (IDNA)" optional = false python-versions = ">=3.5" files = [ - {file = "idna-3.4-py3-none-any.whl", hash = "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"}, - {file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"}, + {file = "idna-3.6-py3-none-any.whl", hash = "sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f"}, + {file = "idna-3.6.tar.gz", hash = "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca"}, ] [[package]] name = "importlib-metadata" -version = "6.8.0" +version = "7.0.1" description = "Read metadata from Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "importlib_metadata-6.8.0-py3-none-any.whl", hash = "sha256:3ebb78df84a805d7698245025b975d9d67053cd94c79245ba4b3eb694abe68bb"}, - {file = "importlib_metadata-6.8.0.tar.gz", hash = "sha256:dbace7892d8c0c4ac1ad096662232f831d4e64f4c4545bd53016a3e9d4654743"}, + {file = "importlib_metadata-7.0.1-py3-none-any.whl", hash = "sha256:4805911c3a4ec7c3966410053e9ec6a1fecd629117df5adee56dfc9432a1081e"}, + {file = "importlib_metadata-7.0.1.tar.gz", hash = "sha256:f238736bb06590ae52ac1fab06a3a9ef1d8dce2b7a35b5ab329371d6c8f5d2cc"}, ] [package.dependencies] zipp = ">=0.5" [package.extras] -docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"] perf = ["ipython"] testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)", "pytest-ruff"] [[package]] name = "jinja2" -version = "3.1.2" +version = "3.1.3" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" files = [ - {file = "Jinja2-3.1.2-py3-none-any.whl", hash = "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"}, - {file = "Jinja2-3.1.2.tar.gz", hash = "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852"}, + {file = "Jinja2-3.1.3-py3-none-any.whl", hash = "sha256:7d6d50dd97d52cbc355597bd845fabfbac3f551e1f99619e39a35ce8c370b5fa"}, + {file = "Jinja2-3.1.3.tar.gz", hash = "sha256:ac8bd6544d4bb2c9792bf3a159e80bba8fda7f07e81bc3aed565432d5925ba90"}, ] [package.dependencies] @@ -406,90 +408,89 @@ i18n = ["Babel (>=2.7)"] [[package]] name = "markdown" -version = "3.4.4" +version = "3.5.2" description = "Python implementation of John Gruber's Markdown." -category = "main" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "Markdown-3.4.4-py3-none-any.whl", hash = "sha256:a4c1b65c0957b4bd9e7d86ddc7b3c9868fb9670660f6f99f6d1bca8954d5a941"}, - {file = "Markdown-3.4.4.tar.gz", hash = "sha256:225c6123522495d4119a90b3a3ba31a1e87a70369e03f14799ea9c0d7183a3d6"}, + {file = "Markdown-3.5.2-py3-none-any.whl", hash = "sha256:d43323865d89fc0cb9b20c75fc8ad313af307cc087e84b657d9eec768eddeadd"}, + {file = "Markdown-3.5.2.tar.gz", hash = "sha256:e1ac7b3dc550ee80e602e71c1d168002f062e49f1b11e26a36264dafd4df2ef8"}, ] [package.dependencies] importlib-metadata = {version = ">=4.4", markers = "python_version < \"3.10\""} [package.extras] -docs = ["mdx-gh-links (>=0.2)", "mkdocs (>=1.0)", "mkdocs-nature (>=0.4)"] +docs = ["mdx-gh-links (>=0.2)", "mkdocs (>=1.5)", "mkdocs-gen-files", "mkdocs-literate-nav", "mkdocs-nature (>=0.6)", "mkdocs-section-index", "mkdocstrings[python]"] testing = ["coverage", "pyyaml"] [[package]] name = "markupsafe" -version = "2.1.3" +version = "2.1.4" description = "Safely add untrusted strings to HTML/XML markup." optional = false python-versions = ">=3.7" files = [ - {file = "MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cd0f502fe016460680cd20aaa5a76d241d6f35a1c3350c474bac1273803893fa"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e09031c87a1e51556fdcb46e5bd4f59dfb743061cf93c4d6831bf894f125eb57"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:68e78619a61ecf91e76aa3e6e8e33fc4894a2bebe93410754bd28fce0a8a4f9f"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65c1a9bcdadc6c28eecee2c119465aebff8f7a584dd719facdd9e825ec61ab52"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:525808b8019e36eb524b8c68acdd63a37e75714eac50e988180b169d64480a00"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:962f82a3086483f5e5f64dbad880d31038b698494799b097bc59c2edf392fce6"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:aa7bd130efab1c280bed0f45501b7c8795f9fdbeb02e965371bbef3523627779"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c9c804664ebe8f83a211cace637506669e7890fec1b4195b505c214e50dd4eb7"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-win32.whl", hash = "sha256:10bbfe99883db80bdbaff2dcf681dfc6533a614f700da1287707e8a5d78a8431"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-win_amd64.whl", hash = "sha256:1577735524cdad32f9f694208aa75e422adba74f1baee7551620e43a3141f559"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ad9e82fb8f09ade1c3e1b996a6337afac2b8b9e365f926f5a61aacc71adc5b3c"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3c0fae6c3be832a0a0473ac912810b2877c8cb9d76ca48de1ed31e1c68386575"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b076b6226fb84157e3f7c971a47ff3a679d837cf338547532ab866c57930dbee"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bfce63a9e7834b12b87c64d6b155fdd9b3b96191b6bd334bf37db7ff1fe457f2"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:338ae27d6b8745585f87218a3f23f1512dbf52c26c28e322dbe54bcede54ccb9"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e4dd52d80b8c83fdce44e12478ad2e85c64ea965e75d66dbeafb0a3e77308fcc"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:df0be2b576a7abbf737b1575f048c23fb1d769f267ec4358296f31c2479db8f9"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5bbe06f8eeafd38e5d0a4894ffec89378b6c6a625ff57e3028921f8ff59318ac"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-win32.whl", hash = "sha256:dd15ff04ffd7e05ffcb7fe79f1b98041b8ea30ae9234aed2a9168b5797c3effb"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-win_amd64.whl", hash = "sha256:134da1eca9ec0ae528110ccc9e48041e0828d79f24121a1a146161103c76e686"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:f698de3fd0c4e6972b92290a45bd9b1536bffe8c6759c62471efaa8acb4c37bc"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:aa57bd9cf8ae831a362185ee444e15a93ecb2e344c8e52e4d721ea3ab6ef1823"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffcc3f7c66b5f5b7931a5aa68fc9cecc51e685ef90282f4a82f0f5e9b704ad11"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47d4f1c5f80fc62fdd7777d0d40a2e9dda0a05883ab11374334f6c4de38adffd"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1f67c7038d560d92149c060157d623c542173016c4babc0c1913cca0564b9939"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:9aad3c1755095ce347e26488214ef77e0485a3c34a50c5a5e2471dff60b9dd9c"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:14ff806850827afd6b07a5f32bd917fb7f45b046ba40c57abdb636674a8b559c"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8f9293864fe09b8149f0cc42ce56e3f0e54de883a9de90cd427f191c346eb2e1"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-win32.whl", hash = "sha256:715d3562f79d540f251b99ebd6d8baa547118974341db04f5ad06d5ea3eb8007"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-win_amd64.whl", hash = "sha256:1b8dd8c3fd14349433c79fa8abeb573a55fc0fdd769133baac1f5e07abf54aeb"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8e254ae696c88d98da6555f5ace2279cf7cd5b3f52be2b5cf97feafe883b58d2"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb0932dc158471523c9637e807d9bfb93e06a95cbf010f1a38b98623b929ef2b"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9402b03f1a1b4dc4c19845e5c749e3ab82d5078d16a2a4c2cd2df62d57bb0707"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca379055a47383d02a5400cb0d110cef0a776fc644cda797db0c5696cfd7e18e"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:b7ff0f54cb4ff66dd38bebd335a38e2c22c41a8ee45aa608efc890ac3e3931bc"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c011a4149cfbcf9f03994ec2edffcb8b1dc2d2aede7ca243746df97a5d41ce48"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:56d9f2ecac662ca1611d183feb03a3fa4406469dafe241673d521dd5ae92a155"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-win32.whl", hash = "sha256:8758846a7e80910096950b67071243da3e5a20ed2546e6392603c096778d48e0"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-win_amd64.whl", hash = "sha256:787003c0ddb00500e49a10f2844fac87aa6ce977b90b0feaaf9de23c22508b24"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:2ef12179d3a291be237280175b542c07a36e7f60718296278d8593d21ca937d4"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2c1b19b3aaacc6e57b7e25710ff571c24d6c3613a45e905b1fde04d691b98ee0"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8afafd99945ead6e075b973fefa56379c5b5c53fd8937dad92c662da5d8fd5ee"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c41976a29d078bb235fea9b2ecd3da465df42a562910f9022f1a03107bd02be"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d080e0a5eb2529460b30190fcfcc4199bd7f827663f858a226a81bc27beaa97e"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:69c0f17e9f5a7afdf2cc9fb2d1ce6aabdb3bafb7f38017c0b77862bcec2bbad8"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:504b320cd4b7eff6f968eddf81127112db685e81f7e36e75f9f84f0df46041c3"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:42de32b22b6b804f42c5d98be4f7e5e977ecdd9ee9b660fda1a3edf03b11792d"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-win32.whl", hash = "sha256:ceb01949af7121f9fc39f7d27f91be8546f3fb112c608bc4029aef0bab86a2a5"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-win_amd64.whl", hash = "sha256:1b40069d487e7edb2676d3fbdb2b0829ffa2cd63a2ec26c4938b2d34391b4ecc"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8023faf4e01efadfa183e863fefde0046de576c6f14659e8782065bcece22198"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6b2b56950d93e41f33b4223ead100ea0fe11f8e6ee5f641eb753ce4b77a7042b"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9dcdfd0eaf283af041973bff14a2e143b8bd64e069f4c383416ecd79a81aab58"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:05fb21170423db021895e1ea1e1f3ab3adb85d1c2333cbc2310f2a26bc77272e"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:282c2cb35b5b673bbcadb33a585408104df04f14b2d9b01d4c345a3b92861c2c"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ab4a0df41e7c16a1392727727e7998a467472d0ad65f3ad5e6e765015df08636"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7ef3cb2ebbf91e330e3bb937efada0edd9003683db6b57bb108c4001f37a02ea"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:0a4e4a1aff6c7ac4cd55792abf96c915634c2b97e3cc1c7129578aa68ebd754e"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-win32.whl", hash = "sha256:fec21693218efe39aa7f8599346e90c705afa52c5b31ae019b2e57e8f6542bb2"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-win_amd64.whl", hash = "sha256:3fd4abcb888d15a94f32b75d8fd18ee162ca0c064f35b11134be77050296d6ba"}, - {file = "MarkupSafe-2.1.3.tar.gz", hash = "sha256:af598ed32d6ae86f1b747b82783958b1a4ab8f617b06fe68795c7f026abbdcad"}, + {file = "MarkupSafe-2.1.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:de8153a7aae3835484ac168a9a9bdaa0c5eee4e0bc595503c95d53b942879c84"}, + {file = "MarkupSafe-2.1.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e888ff76ceb39601c59e219f281466c6d7e66bd375b4ec1ce83bcdc68306796b"}, + {file = "MarkupSafe-2.1.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0b838c37ba596fcbfca71651a104a611543077156cb0a26fe0c475e1f152ee8"}, + {file = "MarkupSafe-2.1.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dac1ebf6983148b45b5fa48593950f90ed6d1d26300604f321c74a9ca1609f8e"}, + {file = "MarkupSafe-2.1.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0fbad3d346df8f9d72622ac71b69565e621ada2ce6572f37c2eae8dacd60385d"}, + {file = "MarkupSafe-2.1.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d5291d98cd3ad9a562883468c690a2a238c4a6388ab3bd155b0c75dd55ece858"}, + {file = "MarkupSafe-2.1.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:a7cc49ef48a3c7a0005a949f3c04f8baa5409d3f663a1b36f0eba9bfe2a0396e"}, + {file = "MarkupSafe-2.1.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b83041cda633871572f0d3c41dddd5582ad7d22f65a72eacd8d3d6d00291df26"}, + {file = "MarkupSafe-2.1.4-cp310-cp310-win32.whl", hash = "sha256:0c26f67b3fe27302d3a412b85ef696792c4a2386293c53ba683a89562f9399b0"}, + {file = "MarkupSafe-2.1.4-cp310-cp310-win_amd64.whl", hash = "sha256:a76055d5cb1c23485d7ddae533229039b850db711c554a12ea64a0fd8a0129e2"}, + {file = "MarkupSafe-2.1.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9e9e3c4020aa2dc62d5dd6743a69e399ce3de58320522948af6140ac959ab863"}, + {file = "MarkupSafe-2.1.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0042d6a9880b38e1dd9ff83146cc3c9c18a059b9360ceae207805567aacccc69"}, + {file = "MarkupSafe-2.1.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:55d03fea4c4e9fd0ad75dc2e7e2b6757b80c152c032ea1d1de487461d8140efc"}, + {file = "MarkupSafe-2.1.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ab3a886a237f6e9c9f4f7d272067e712cdb4efa774bef494dccad08f39d8ae6"}, + {file = "MarkupSafe-2.1.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:abf5ebbec056817057bfafc0445916bb688a255a5146f900445d081db08cbabb"}, + {file = "MarkupSafe-2.1.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e1a0d1924a5013d4f294087e00024ad25668234569289650929ab871231668e7"}, + {file = "MarkupSafe-2.1.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:e7902211afd0af05fbadcc9a312e4cf10f27b779cf1323e78d52377ae4b72bea"}, + {file = "MarkupSafe-2.1.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:c669391319973e49a7c6230c218a1e3044710bc1ce4c8e6eb71f7e6d43a2c131"}, + {file = "MarkupSafe-2.1.4-cp311-cp311-win32.whl", hash = "sha256:31f57d64c336b8ccb1966d156932f3daa4fee74176b0fdc48ef580be774aae74"}, + {file = "MarkupSafe-2.1.4-cp311-cp311-win_amd64.whl", hash = "sha256:54a7e1380dfece8847c71bf7e33da5d084e9b889c75eca19100ef98027bd9f56"}, + {file = "MarkupSafe-2.1.4-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:a76cd37d229fc385738bd1ce4cba2a121cf26b53864c1772694ad0ad348e509e"}, + {file = "MarkupSafe-2.1.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:987d13fe1d23e12a66ca2073b8d2e2a75cec2ecb8eab43ff5624ba0ad42764bc"}, + {file = "MarkupSafe-2.1.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5244324676254697fe5c181fc762284e2c5fceeb1c4e3e7f6aca2b6f107e60dc"}, + {file = "MarkupSafe-2.1.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78bc995e004681246e85e28e068111a4c3f35f34e6c62da1471e844ee1446250"}, + {file = "MarkupSafe-2.1.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a4d176cfdfde84f732c4a53109b293d05883e952bbba68b857ae446fa3119b4f"}, + {file = "MarkupSafe-2.1.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:f9917691f410a2e0897d1ef99619fd3f7dd503647c8ff2475bf90c3cf222ad74"}, + {file = "MarkupSafe-2.1.4-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:f06e5a9e99b7df44640767842f414ed5d7bedaaa78cd817ce04bbd6fd86e2dd6"}, + {file = "MarkupSafe-2.1.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:396549cea79e8ca4ba65525470d534e8a41070e6b3500ce2414921099cb73e8d"}, + {file = "MarkupSafe-2.1.4-cp312-cp312-win32.whl", hash = "sha256:f6be2d708a9d0e9b0054856f07ac7070fbe1754be40ca8525d5adccdbda8f475"}, + {file = "MarkupSafe-2.1.4-cp312-cp312-win_amd64.whl", hash = "sha256:5045e892cfdaecc5b4c01822f353cf2c8feb88a6ec1c0adef2a2e705eef0f656"}, + {file = "MarkupSafe-2.1.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:7a07f40ef8f0fbc5ef1000d0c78771f4d5ca03b4953fc162749772916b298fc4"}, + {file = "MarkupSafe-2.1.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d18b66fe626ac412d96c2ab536306c736c66cf2a31c243a45025156cc190dc8a"}, + {file = "MarkupSafe-2.1.4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:698e84142f3f884114ea8cf83e7a67ca8f4ace8454e78fe960646c6c91c63bfa"}, + {file = "MarkupSafe-2.1.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:49a3b78a5af63ec10d8604180380c13dcd870aba7928c1fe04e881d5c792dc4e"}, + {file = "MarkupSafe-2.1.4-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:15866d7f2dc60cfdde12ebb4e75e41be862348b4728300c36cdf405e258415ec"}, + {file = "MarkupSafe-2.1.4-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:6aa5e2e7fc9bc042ae82d8b79d795b9a62bd8f15ba1e7594e3db243f158b5565"}, + {file = "MarkupSafe-2.1.4-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:54635102ba3cf5da26eb6f96c4b8c53af8a9c0d97b64bdcb592596a6255d8518"}, + {file = "MarkupSafe-2.1.4-cp37-cp37m-win32.whl", hash = "sha256:3583a3a3ab7958e354dc1d25be74aee6228938312ee875a22330c4dc2e41beb0"}, + {file = "MarkupSafe-2.1.4-cp37-cp37m-win_amd64.whl", hash = "sha256:d6e427c7378c7f1b2bef6a344c925b8b63623d3321c09a237b7cc0e77dd98ceb"}, + {file = "MarkupSafe-2.1.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:bf1196dcc239e608605b716e7b166eb5faf4bc192f8a44b81e85251e62584bd2"}, + {file = "MarkupSafe-2.1.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:4df98d4a9cd6a88d6a585852f56f2155c9cdb6aec78361a19f938810aa020954"}, + {file = "MarkupSafe-2.1.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b835aba863195269ea358cecc21b400276747cc977492319fd7682b8cd2c253d"}, + {file = "MarkupSafe-2.1.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:23984d1bdae01bee794267424af55eef4dfc038dc5d1272860669b2aa025c9e3"}, + {file = "MarkupSafe-2.1.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1c98c33ffe20e9a489145d97070a435ea0679fddaabcafe19982fe9c971987d5"}, + {file = "MarkupSafe-2.1.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:9896fca4a8eb246defc8b2a7ac77ef7553b638e04fbf170bff78a40fa8a91474"}, + {file = "MarkupSafe-2.1.4-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:b0fe73bac2fed83839dbdbe6da84ae2a31c11cfc1c777a40dbd8ac8a6ed1560f"}, + {file = "MarkupSafe-2.1.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:c7556bafeaa0a50e2fe7dc86e0382dea349ebcad8f010d5a7dc6ba568eaaa789"}, + {file = "MarkupSafe-2.1.4-cp38-cp38-win32.whl", hash = "sha256:fc1a75aa8f11b87910ffd98de62b29d6520b6d6e8a3de69a70ca34dea85d2a8a"}, + {file = "MarkupSafe-2.1.4-cp38-cp38-win_amd64.whl", hash = "sha256:3a66c36a3864df95e4f62f9167c734b3b1192cb0851b43d7cc08040c074c6279"}, + {file = "MarkupSafe-2.1.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:765f036a3d00395a326df2835d8f86b637dbaf9832f90f5d196c3b8a7a5080cb"}, + {file = "MarkupSafe-2.1.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:21e7af8091007bf4bebf4521184f4880a6acab8df0df52ef9e513d8e5db23411"}, + {file = "MarkupSafe-2.1.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d5c31fe855c77cad679b302aabc42d724ed87c043b1432d457f4976add1c2c3e"}, + {file = "MarkupSafe-2.1.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7653fa39578957bc42e5ebc15cf4361d9e0ee4b702d7d5ec96cdac860953c5b4"}, + {file = "MarkupSafe-2.1.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:47bb5f0142b8b64ed1399b6b60f700a580335c8e1c57f2f15587bd072012decc"}, + {file = "MarkupSafe-2.1.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:fe8512ed897d5daf089e5bd010c3dc03bb1bdae00b35588c49b98268d4a01e00"}, + {file = "MarkupSafe-2.1.4-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:36d7626a8cca4d34216875aee5a1d3d654bb3dac201c1c003d182283e3205949"}, + {file = "MarkupSafe-2.1.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:b6f14a9cd50c3cb100eb94b3273131c80d102e19bb20253ac7bd7336118a673a"}, + {file = "MarkupSafe-2.1.4-cp39-cp39-win32.whl", hash = "sha256:c8f253a84dbd2c63c19590fa86a032ef3d8cc18923b8049d91bcdeeb2581fbf6"}, + {file = "MarkupSafe-2.1.4-cp39-cp39-win_amd64.whl", hash = "sha256:8b570a1537367b52396e53325769608f2a687ec9a4363647af1cded8928af959"}, + {file = "MarkupSafe-2.1.4.tar.gz", hash = "sha256:3aae9af4cac263007fd6309c64c6ab4506dd2b79382d9d19a1994f9240b8db4f"}, ] [[package]] @@ -505,13 +506,13 @@ files = [ [[package]] name = "mkdocs" -version = "1.5.1" +version = "1.5.3" description = "Project documentation with Markdown." optional = false python-versions = ">=3.7" files = [ - {file = "mkdocs-1.5.1-py3-none-any.whl", hash = "sha256:67e889f8d8ba1fe5decdfc59f5f8f21d6a8925a129339e93dede303bdea03a98"}, - {file = "mkdocs-1.5.1.tar.gz", hash = "sha256:f2f323c62fffdf1b71b84849e39aef56d6852b3f0a5571552bca32cefc650209"}, + {file = "mkdocs-1.5.3-py3-none-any.whl", hash = "sha256:3b3a78e736b31158d64dbb2f8ba29bd46a379d0c6e324c2246c3bc3d2189cfc1"}, + {file = "mkdocs-1.5.3.tar.gz", hash = "sha256:eb7c99214dcb945313ba30426c2451b735992c73c2e10838f76d09e39ff4d0e2"}, ] [package.dependencies] @@ -536,16 +537,17 @@ min-versions = ["babel (==2.9.0)", "click (==7.0)", "colorama (==0.4)", "ghp-imp [[package]] name = "mkdocs-include-markdown-plugin" -version = "6.0.1" +version = "6.0.4" description = "Mkdocs Markdown includer plugin." optional = false -python-versions = "<3.13,>=3.8" +python-versions = ">=3.8" files = [ - {file = "mkdocs_include_markdown_plugin-6.0.1-py3-none-any.whl", hash = "sha256:cbb71f06bf6bd03312f0ff79e1aed198ad13c0ff4fcaf5bb7fe5da385fba4849"}, - {file = "mkdocs_include_markdown_plugin-6.0.1.tar.gz", hash = "sha256:eb8832b36a72c1c416baec666eeed057c2e613e8b07b353e86fa518157858b0a"}, + {file = "mkdocs_include_markdown_plugin-6.0.4-py3-none-any.whl", hash = "sha256:e7b8b5ecc41d6a3e16969cff3725ec3a391b68e9dfe1a4b4e36a8508becda835"}, + {file = "mkdocs_include_markdown_plugin-6.0.4.tar.gz", hash = "sha256:523c9c3a1d6a517386dc11bf60b0c0c564af1071bb6de8d213106d54f752dcc1"}, ] [package.dependencies] +mkdocs = ">=1.4" wcmatch = ">=8,<9" [package.extras] @@ -567,25 +569,27 @@ pyyaml = "*" [[package]] name = "mkdocs-material" -version = "9.1.21" +version = "9.5.4" description = "Documentation that simply works" optional = false python-versions = ">=3.8" files = [ - {file = "mkdocs_material-9.1.21-py3-none-any.whl", hash = "sha256:58bb2f11ef240632e176d6f0f7d1cff06be1d11c696a5a1b553b808b4280ed47"}, - {file = "mkdocs_material-9.1.21.tar.gz", hash = "sha256:71940cdfca84ab296b6362889c25395b1621273fb16c93deda257adb7ff44ec8"}, + {file = "mkdocs_material-9.5.4-py3-none-any.whl", hash = "sha256:efd7cc8ae03296d728da9bd38f4db8b07ab61f9738a0cbd0dfaf2a15a50e7343"}, + {file = "mkdocs_material-9.5.4.tar.gz", hash = "sha256:3d196ee67fad16b2df1a458d650a8ac1890294eaae368d26cee71bc24ad41c40"}, ] [package.dependencies] -colorama = ">=0.4" -jinja2 = ">=3.0" -markdown = ">=3.2" -mkdocs = ">=1.5.0" -mkdocs-material-extensions = ">=1.1" -pygments = ">=2.14" -pymdown-extensions = ">=9.9.1" -regex = ">=2022.4.24" -requests = ">=2.26" +babel = ">=2.10,<3.0" +colorama = ">=0.4,<1.0" +jinja2 = ">=3.0,<4.0" +markdown = ">=3.2,<4.0" +mkdocs = ">=1.5.3,<1.6.0" +mkdocs-material-extensions = ">=1.3,<2.0" +paginate = ">=0.5,<1.0" +pygments = ">=2.16,<3.0" +pymdown-extensions = ">=10.2,<11.0" +regex = ">=2022.4" +requests = ">=2.26,<3.0" [package.extras] git = ["mkdocs-git-committers-plugin-2 (>=1.1,<2.0)", "mkdocs-git-revision-date-localized-plugin (>=1.2,<2.0)"] @@ -594,51 +598,54 @@ recommended = ["mkdocs-minify-plugin (>=0.7,<1.0)", "mkdocs-redirects (>=1.2,<2. [[package]] name = "mkdocs-material-extensions" -version = "1.2" +version = "1.3.1" description = "Extension pack for Python Markdown and MkDocs Material." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "mkdocs_material_extensions-1.2-py3-none-any.whl", hash = "sha256:c767bd6d6305f6420a50f0b541b0c9966d52068839af97029be14443849fb8a1"}, - {file = "mkdocs_material_extensions-1.2.tar.gz", hash = "sha256:27e2d1ed2d031426a6e10d5ea06989d67e90bb02acd588bc5673106b5ee5eedf"}, + {file = "mkdocs_material_extensions-1.3.1-py3-none-any.whl", hash = "sha256:adff8b62700b25cb77b53358dad940f3ef973dd6db797907c49e3c2ef3ab4e31"}, + {file = "mkdocs_material_extensions-1.3.1.tar.gz", hash = "sha256:10c9511cea88f568257f960358a467d12b970e1f7b2c0e5fb2bb48cab1928443"}, ] [[package]] name = "mkdocs-rss-plugin" -version = "1.8.0" +version = "1.5.0" description = "MkDocs plugin which generates a static RSS feed using git log and page.meta." optional = false -python-versions = ">=3.8, <4" -files = [ - {file = "mkdocs-rss-plugin-1.8.0.tar.gz", hash = "sha256:475bf4ea05cbe786af38d519b55352b1b2eb87597ad680fcbc309056864ed5c4"}, - {file = "mkdocs_rss_plugin-1.8.0-py2.py3-none-any.whl", hash = "sha256:0fa13c99730c1d3ad9ec05102ff3d148c9849396c40b30be789339d38722fa8f"}, -] +python-versions = ">=3.7, <4" +files = [] +develop = false [package.dependencies] GitPython = ">=3.1,<3.2" mkdocs = ">=1.1,<2" -tzdata = {version = "==2023.*", markers = "python_version >= \"3.9\" and sys_platform == \"win32\""} +tzdata = {version = "==2022.*", markers = "python_version >= \"3.9\" and sys_platform == \"win32\""} [package.extras] -dev = ["black", "feedparser (>=6.0,<6.1)", "flake8 (>=4,<7)", "pre-commit (>=3,<4)", "pytest-cov (>=4,<4.2)", "validator-collection (>=1.5,<1.6)"] -doc = ["mkdocs-bootswatch (>=1,<2)", "mkdocs-minify-plugin (==0.6.*)", "pygments (>=2.5,<3)", "pymdown-extensions (>=10,<11)"] +dev = ["black", "feedparser (>=6.0,<6.1)", "flake8 (>=4,<5.1)", "pre-commit (>=2.10,<2.21)", "pytest-cov (==4.0.*)", "validator-collection (>=1.5,<1.6)"] +doc = ["mkdocs-bootswatch (>=1,<2)", "mkdocs-minify-plugin (==0.5.*)", "pygments (>=2.5,<3)", "pymdown-extensions (>=7,<10)"] + +[package.source] +type = "git" +url = "https://github.com/cachix/mkdocs-rss-plugin" +reference = "no-git" +resolved_reference = "017bdb52095703c79e0632f219b5adf9f212873c" [[package]] name = "packaging" -version = "23.1" +version = "23.2" description = "Core utilities for Python packages" optional = false python-versions = ">=3.7" files = [ - {file = "packaging-23.1-py3-none-any.whl", hash = "sha256:994793af429502c4ea2ebf6bf664629d07c1a9fe974af92966e4b8d2df7edc61"}, - {file = "packaging-23.1.tar.gz", hash = "sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f"}, + {file = "packaging-23.2-py3-none-any.whl", hash = "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"}, + {file = "packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5"}, ] [[package]] name = "paginate" version = "0.5.6" description = "Divides large result sets into pages for easier browsing" -category = "main" optional = false python-versions = "*" files = [ @@ -647,77 +654,88 @@ files = [ [[package]] name = "pathspec" -version = "0.11.2" +version = "0.12.1" description = "Utility library for gitignore style pattern matching of file paths." -category = "main" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "pathspec-0.11.2-py3-none-any.whl", hash = "sha256:1d6ed233af05e679efb96b1851550ea95bbb64b7c490b0f5aa52996c11e92a20"}, - {file = "pathspec-0.11.2.tar.gz", hash = "sha256:e0d8d0ac2f12da61956eb2306b69f9469b42f4deb0f3cb6ed47b9cce9996ced3"}, + {file = "pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08"}, + {file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"}, ] [[package]] name = "pillow" -version = "10.0.1" +version = "9.5.0" description = "Python Imaging Library (Fork)" optional = false -python-versions = ">=3.8" +python-versions = ">=3.7" files = [ - {file = "Pillow-10.0.1-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:8f06be50669087250f319b706decf69ca71fdecd829091a37cc89398ca4dc17a"}, - {file = "Pillow-10.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:50bd5f1ebafe9362ad622072a1d2f5850ecfa44303531ff14353a4059113b12d"}, - {file = "Pillow-10.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e6a90167bcca1216606223a05e2cf991bb25b14695c518bc65639463d7db722d"}, - {file = "Pillow-10.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f11c9102c56ffb9ca87134bd025a43d2aba3f1155f508eff88f694b33a9c6d19"}, - {file = "Pillow-10.0.1-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:186f7e04248103482ea6354af6d5bcedb62941ee08f7f788a1c7707bc720c66f"}, - {file = "Pillow-10.0.1-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:0462b1496505a3462d0f35dc1c4d7b54069747d65d00ef48e736acda2c8cbdff"}, - {file = "Pillow-10.0.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d889b53ae2f030f756e61a7bff13684dcd77e9af8b10c6048fb2c559d6ed6eaf"}, - {file = "Pillow-10.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:552912dbca585b74d75279a7570dd29fa43b6d93594abb494ebb31ac19ace6bd"}, - {file = "Pillow-10.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:787bb0169d2385a798888e1122c980c6eff26bf941a8ea79747d35d8f9210ca0"}, - {file = "Pillow-10.0.1-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:fd2a5403a75b54661182b75ec6132437a181209b901446ee5724b589af8edef1"}, - {file = "Pillow-10.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2d7e91b4379f7a76b31c2dda84ab9e20c6220488e50f7822e59dac36b0cd92b1"}, - {file = "Pillow-10.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:19e9adb3f22d4c416e7cd79b01375b17159d6990003633ff1d8377e21b7f1b21"}, - {file = "Pillow-10.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:93139acd8109edcdeffd85e3af8ae7d88b258b3a1e13a038f542b79b6d255c54"}, - {file = "Pillow-10.0.1-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:92a23b0431941a33242b1f0ce6c88a952e09feeea9af4e8be48236a68ffe2205"}, - {file = "Pillow-10.0.1-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:cbe68deb8580462ca0d9eb56a81912f59eb4542e1ef8f987405e35a0179f4ea2"}, - {file = "Pillow-10.0.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:522ff4ac3aaf839242c6f4e5b406634bfea002469656ae8358644fc6c4856a3b"}, - {file = "Pillow-10.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:84efb46e8d881bb06b35d1d541aa87f574b58e87f781cbba8d200daa835b42e1"}, - {file = "Pillow-10.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:898f1d306298ff40dc1b9ca24824f0488f6f039bc0e25cfb549d3195ffa17088"}, - {file = "Pillow-10.0.1-cp312-cp312-macosx_10_10_x86_64.whl", hash = "sha256:bcf1207e2f2385a576832af02702de104be71301c2696d0012b1b93fe34aaa5b"}, - {file = "Pillow-10.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5d6c9049c6274c1bb565021367431ad04481ebb54872edecfcd6088d27edd6ed"}, - {file = "Pillow-10.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28444cb6ad49726127d6b340217f0627abc8732f1194fd5352dec5e6a0105635"}, - {file = "Pillow-10.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:de596695a75496deb3b499c8c4f8e60376e0516e1a774e7bc046f0f48cd620ad"}, - {file = "Pillow-10.0.1-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:2872f2d7846cf39b3dbff64bc1104cc48c76145854256451d33c5faa55c04d1a"}, - {file = "Pillow-10.0.1-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:4ce90f8a24e1c15465048959f1e94309dfef93af272633e8f37361b824532e91"}, - {file = "Pillow-10.0.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ee7810cf7c83fa227ba9125de6084e5e8b08c59038a7b2c9045ef4dde61663b4"}, - {file = "Pillow-10.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:b1be1c872b9b5fcc229adeadbeb51422a9633abd847c0ff87dc4ef9bb184ae08"}, - {file = "Pillow-10.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:98533fd7fa764e5f85eebe56c8e4094db912ccbe6fbf3a58778d543cadd0db08"}, - {file = "Pillow-10.0.1-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:764d2c0daf9c4d40ad12fbc0abd5da3af7f8aa11daf87e4fa1b834000f4b6b0a"}, - {file = "Pillow-10.0.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:fcb59711009b0168d6ee0bd8fb5eb259c4ab1717b2f538bbf36bacf207ef7a68"}, - {file = "Pillow-10.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:697a06bdcedd473b35e50a7e7506b1d8ceb832dc238a336bd6f4f5aa91a4b500"}, - {file = "Pillow-10.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f665d1e6474af9f9da5e86c2a3a2d2d6204e04d5af9c06b9d42afa6ebde3f21"}, - {file = "Pillow-10.0.1-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:2fa6dd2661838c66f1a5473f3b49ab610c98a128fc08afbe81b91a1f0bf8c51d"}, - {file = "Pillow-10.0.1-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:3a04359f308ebee571a3127fdb1bd01f88ba6f6fb6d087f8dd2e0d9bff43f2a7"}, - {file = "Pillow-10.0.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:723bd25051454cea9990203405fa6b74e043ea76d4968166dfd2569b0210886a"}, - {file = "Pillow-10.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:71671503e3015da1b50bd18951e2f9daf5b6ffe36d16f1eb2c45711a301521a7"}, - {file = "Pillow-10.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:44e7e4587392953e5e251190a964675f61e4dae88d1e6edbe9f36d6243547ff3"}, - {file = "Pillow-10.0.1-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:3855447d98cced8670aaa63683808df905e956f00348732448b5a6df67ee5849"}, - {file = "Pillow-10.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ed2d9c0704f2dc4fa980b99d565c0c9a543fe5101c25b3d60488b8ba80f0cce1"}, - {file = "Pillow-10.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f5bb289bb835f9fe1a1e9300d011eef4d69661bb9b34d5e196e5e82c4cb09b37"}, - {file = "Pillow-10.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a0d3e54ab1df9df51b914b2233cf779a5a10dfd1ce339d0421748232cea9876"}, - {file = "Pillow-10.0.1-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:2cc6b86ece42a11f16f55fe8903595eff2b25e0358dec635d0a701ac9586588f"}, - {file = "Pillow-10.0.1-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:ca26ba5767888c84bf5a0c1a32f069e8204ce8c21d00a49c90dabeba00ce0145"}, - {file = "Pillow-10.0.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:f0b4b06da13275bc02adfeb82643c4a6385bd08d26f03068c2796f60d125f6f2"}, - {file = "Pillow-10.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:bc2e3069569ea9dbe88d6b8ea38f439a6aad8f6e7a6283a38edf61ddefb3a9bf"}, - {file = "Pillow-10.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:8b451d6ead6e3500b6ce5c7916a43d8d8d25ad74b9102a629baccc0808c54971"}, - {file = "Pillow-10.0.1-pp310-pypy310_pp73-macosx_10_10_x86_64.whl", hash = "sha256:32bec7423cdf25c9038fef614a853c9d25c07590e1a870ed471f47fb80b244db"}, - {file = "Pillow-10.0.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b7cf63d2c6928b51d35dfdbda6f2c1fddbe51a6bc4a9d4ee6ea0e11670dd981e"}, - {file = "Pillow-10.0.1-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:f6d3d4c905e26354e8f9d82548475c46d8e0889538cb0657aa9c6f0872a37aa4"}, - {file = "Pillow-10.0.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:847e8d1017c741c735d3cd1883fa7b03ded4f825a6e5fcb9378fd813edee995f"}, - {file = "Pillow-10.0.1-pp39-pypy39_pp73-macosx_10_10_x86_64.whl", hash = "sha256:7f771e7219ff04b79e231d099c0a28ed83aa82af91fd5fa9fdb28f5b8d5addaf"}, - {file = "Pillow-10.0.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:459307cacdd4138edee3875bbe22a2492519e060660eaf378ba3b405d1c66317"}, - {file = "Pillow-10.0.1-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:b059ac2c4c7a97daafa7dc850b43b2d3667def858a4f112d1aa082e5c3d6cf7d"}, - {file = "Pillow-10.0.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:d6caf3cd38449ec3cd8a68b375e0c6fe4b6fd04edb6c9766b55ef84a6e8ddf2d"}, - {file = "Pillow-10.0.1.tar.gz", hash = "sha256:d72967b06be9300fed5cfbc8b5bafceec48bf7cdc7dab66b1d2549035287191d"}, + {file = "Pillow-9.5.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:ace6ca218308447b9077c14ea4ef381ba0b67ee78d64046b3f19cf4e1139ad16"}, + {file = "Pillow-9.5.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d3d403753c9d5adc04d4694d35cf0391f0f3d57c8e0030aac09d7678fa8030aa"}, + {file = "Pillow-9.5.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5ba1b81ee69573fe7124881762bb4cd2e4b6ed9dd28c9c60a632902fe8db8b38"}, + {file = "Pillow-9.5.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fe7e1c262d3392afcf5071df9afa574544f28eac825284596ac6db56e6d11062"}, + {file = "Pillow-9.5.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f36397bf3f7d7c6a3abdea815ecf6fd14e7fcd4418ab24bae01008d8d8ca15e"}, + {file = "Pillow-9.5.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:252a03f1bdddce077eff2354c3861bf437c892fb1832f75ce813ee94347aa9b5"}, + {file = "Pillow-9.5.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:85ec677246533e27770b0de5cf0f9d6e4ec0c212a1f89dfc941b64b21226009d"}, + {file = "Pillow-9.5.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b416f03d37d27290cb93597335a2f85ed446731200705b22bb927405320de903"}, + {file = "Pillow-9.5.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:1781a624c229cb35a2ac31cc4a77e28cafc8900733a864870c49bfeedacd106a"}, + {file = "Pillow-9.5.0-cp310-cp310-win32.whl", hash = "sha256:8507eda3cd0608a1f94f58c64817e83ec12fa93a9436938b191b80d9e4c0fc44"}, + {file = "Pillow-9.5.0-cp310-cp310-win_amd64.whl", hash = "sha256:d3c6b54e304c60c4181da1c9dadf83e4a54fd266a99c70ba646a9baa626819eb"}, + {file = "Pillow-9.5.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:7ec6f6ce99dab90b52da21cf0dc519e21095e332ff3b399a357c187b1a5eee32"}, + {file = "Pillow-9.5.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:560737e70cb9c6255d6dcba3de6578a9e2ec4b573659943a5e7e4af13f298f5c"}, + {file = "Pillow-9.5.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:96e88745a55b88a7c64fa49bceff363a1a27d9a64e04019c2281049444a571e3"}, + {file = "Pillow-9.5.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d9c206c29b46cfd343ea7cdfe1232443072bbb270d6a46f59c259460db76779a"}, + {file = "Pillow-9.5.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cfcc2c53c06f2ccb8976fb5c71d448bdd0a07d26d8e07e321c103416444c7ad1"}, + {file = "Pillow-9.5.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:a0f9bb6c80e6efcde93ffc51256d5cfb2155ff8f78292f074f60f9e70b942d99"}, + {file = "Pillow-9.5.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:8d935f924bbab8f0a9a28404422da8af4904e36d5c33fc6f677e4c4485515625"}, + {file = "Pillow-9.5.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:fed1e1cf6a42577953abbe8e6cf2fe2f566daebde7c34724ec8803c4c0cda579"}, + {file = "Pillow-9.5.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:c1170d6b195555644f0616fd6ed929dfcf6333b8675fcca044ae5ab110ded296"}, + {file = "Pillow-9.5.0-cp311-cp311-win32.whl", hash = "sha256:54f7102ad31a3de5666827526e248c3530b3a33539dbda27c6843d19d72644ec"}, + {file = "Pillow-9.5.0-cp311-cp311-win_amd64.whl", hash = "sha256:cfa4561277f677ecf651e2b22dc43e8f5368b74a25a8f7d1d4a3a243e573f2d4"}, + {file = "Pillow-9.5.0-cp311-cp311-win_arm64.whl", hash = "sha256:965e4a05ef364e7b973dd17fc765f42233415974d773e82144c9bbaaaea5d089"}, + {file = "Pillow-9.5.0-cp312-cp312-win32.whl", hash = "sha256:22baf0c3cf0c7f26e82d6e1adf118027afb325e703922c8dfc1d5d0156bb2eeb"}, + {file = "Pillow-9.5.0-cp312-cp312-win_amd64.whl", hash = "sha256:432b975c009cf649420615388561c0ce7cc31ce9b2e374db659ee4f7d57a1f8b"}, + {file = "Pillow-9.5.0-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:5d4ebf8e1db4441a55c509c4baa7a0587a0210f7cd25fcfe74dbbce7a4bd1906"}, + {file = "Pillow-9.5.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:375f6e5ee9620a271acb6820b3d1e94ffa8e741c0601db4c0c4d3cb0a9c224bf"}, + {file = "Pillow-9.5.0-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:99eb6cafb6ba90e436684e08dad8be1637efb71c4f2180ee6b8f940739406e78"}, + {file = "Pillow-9.5.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2dfaaf10b6172697b9bceb9a3bd7b951819d1ca339a5ef294d1f1ac6d7f63270"}, + {file = "Pillow-9.5.0-cp37-cp37m-manylinux_2_28_aarch64.whl", hash = "sha256:763782b2e03e45e2c77d7779875f4432e25121ef002a41829d8868700d119392"}, + {file = "Pillow-9.5.0-cp37-cp37m-manylinux_2_28_x86_64.whl", hash = "sha256:35f6e77122a0c0762268216315bf239cf52b88865bba522999dc38f1c52b9b47"}, + {file = "Pillow-9.5.0-cp37-cp37m-win32.whl", hash = "sha256:aca1c196f407ec7cf04dcbb15d19a43c507a81f7ffc45b690899d6a76ac9fda7"}, + {file = "Pillow-9.5.0-cp37-cp37m-win_amd64.whl", hash = "sha256:322724c0032af6692456cd6ed554bb85f8149214d97398bb80613b04e33769f6"}, + {file = "Pillow-9.5.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:a0aa9417994d91301056f3d0038af1199eb7adc86e646a36b9e050b06f526597"}, + {file = "Pillow-9.5.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f8286396b351785801a976b1e85ea88e937712ee2c3ac653710a4a57a8da5d9c"}, + {file = "Pillow-9.5.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c830a02caeb789633863b466b9de10c015bded434deb3ec87c768e53752ad22a"}, + {file = "Pillow-9.5.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fbd359831c1657d69bb81f0db962905ee05e5e9451913b18b831febfe0519082"}, + {file = "Pillow-9.5.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8fc330c3370a81bbf3f88557097d1ea26cd8b019d6433aa59f71195f5ddebbf"}, + {file = "Pillow-9.5.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:7002d0797a3e4193c7cdee3198d7c14f92c0836d6b4a3f3046a64bd1ce8df2bf"}, + {file = "Pillow-9.5.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:229e2c79c00e85989a34b5981a2b67aa079fd08c903f0aaead522a1d68d79e51"}, + {file = "Pillow-9.5.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:9adf58f5d64e474bed00d69bcd86ec4bcaa4123bfa70a65ce72e424bfb88ed96"}, + {file = "Pillow-9.5.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:662da1f3f89a302cc22faa9f14a262c2e3951f9dbc9617609a47521c69dd9f8f"}, + {file = "Pillow-9.5.0-cp38-cp38-win32.whl", hash = "sha256:6608ff3bf781eee0cd14d0901a2b9cc3d3834516532e3bd673a0a204dc8615fc"}, + {file = "Pillow-9.5.0-cp38-cp38-win_amd64.whl", hash = "sha256:e49eb4e95ff6fd7c0c402508894b1ef0e01b99a44320ba7d8ecbabefddcc5569"}, + {file = "Pillow-9.5.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:482877592e927fd263028c105b36272398e3e1be3269efda09f6ba21fd83ec66"}, + {file = "Pillow-9.5.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3ded42b9ad70e5f1754fb7c2e2d6465a9c842e41d178f262e08b8c85ed8a1d8e"}, + {file = "Pillow-9.5.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c446d2245ba29820d405315083d55299a796695d747efceb5717a8b450324115"}, + {file = "Pillow-9.5.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8aca1152d93dcc27dc55395604dcfc55bed5f25ef4c98716a928bacba90d33a3"}, + {file = "Pillow-9.5.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:608488bdcbdb4ba7837461442b90ea6f3079397ddc968c31265c1e056964f1ef"}, + {file = "Pillow-9.5.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:60037a8db8750e474af7ffc9faa9b5859e6c6d0a50e55c45576bf28be7419705"}, + {file = "Pillow-9.5.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:07999f5834bdc404c442146942a2ecadd1cb6292f5229f4ed3b31e0a108746b1"}, + {file = "Pillow-9.5.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:a127ae76092974abfbfa38ca2d12cbeddcdeac0fb71f9627cc1135bedaf9d51a"}, + {file = "Pillow-9.5.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:489f8389261e5ed43ac8ff7b453162af39c3e8abd730af8363587ba64bb2e865"}, + {file = "Pillow-9.5.0-cp39-cp39-win32.whl", hash = "sha256:9b1af95c3a967bf1da94f253e56b6286b50af23392a886720f563c547e48e964"}, + {file = "Pillow-9.5.0-cp39-cp39-win_amd64.whl", hash = "sha256:77165c4a5e7d5a284f10a6efaa39a0ae8ba839da344f20b111d62cc932fa4e5d"}, + {file = "Pillow-9.5.0-pp38-pypy38_pp73-macosx_10_10_x86_64.whl", hash = "sha256:833b86a98e0ede388fa29363159c9b1a294b0905b5128baf01db683672f230f5"}, + {file = "Pillow-9.5.0-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aaf305d6d40bd9632198c766fb64f0c1a83ca5b667f16c1e79e1661ab5060140"}, + {file = "Pillow-9.5.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0852ddb76d85f127c135b6dd1f0bb88dbb9ee990d2cd9aa9e28526c93e794fba"}, + {file = "Pillow-9.5.0-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:91ec6fe47b5eb5a9968c79ad9ed78c342b1f97a091677ba0e012701add857829"}, + {file = "Pillow-9.5.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:cb841572862f629b99725ebaec3287fc6d275be9b14443ea746c1dd325053cbd"}, + {file = "Pillow-9.5.0-pp39-pypy39_pp73-macosx_10_10_x86_64.whl", hash = "sha256:c380b27d041209b849ed246b111b7c166ba36d7933ec6e41175fd15ab9eb1572"}, + {file = "Pillow-9.5.0-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7c9af5a3b406a50e313467e3565fc99929717f780164fe6fbb7704edba0cebbe"}, + {file = "Pillow-9.5.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5671583eab84af046a397d6d0ba25343c00cd50bce03787948e0fff01d4fd9b1"}, + {file = "Pillow-9.5.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:84a6f19ce086c1bf894644b43cd129702f781ba5751ca8572f08aa40ef0ab7b7"}, + {file = "Pillow-9.5.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:1e7723bd90ef94eda669a3c2c19d549874dd5badaeefabefd26053304abe5799"}, + {file = "Pillow-9.5.0.tar.gz", hash = "sha256:bf548479d336726d7a0eceb6e767e179fbde37833ae42794602631a070d630f1"}, ] [package.extras] @@ -726,14 +744,13 @@ tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "pa [[package]] name = "platformdirs" -version = "3.10.0" +version = "4.1.0" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." -category = "main" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "platformdirs-3.10.0-py3-none-any.whl", hash = "sha256:d7c24979f292f916dc9cbf8648319032f551ea8c49a4c9bf2fb556a02070ec1d"}, - {file = "platformdirs-3.10.0.tar.gz", hash = "sha256:b45696dab2d7cc691a3226759c0d3b00c47c8b6e293d96f6436f733303f77f6d"}, + {file = "platformdirs-4.1.0-py3-none-any.whl", hash = "sha256:11c8f37bcca40db96d8144522d925583bdb7a31f7b0e37e3ed4318400a8e2380"}, + {file = "platformdirs-4.1.0.tar.gz", hash = "sha256:906d548203468492d432bcb294d4bc2fff751bf84971fbb2c10918cc206ee420"}, ] [package.extras] @@ -753,31 +770,32 @@ files = [ [[package]] name = "pygments" -version = "2.16.1" +version = "2.17.2" description = "Pygments is a syntax highlighting package written in Python." optional = false python-versions = ">=3.7" files = [ - {file = "Pygments-2.16.1-py3-none-any.whl", hash = "sha256:13fc09fa63bc8d8671a6d247e1eb303c4b343eaee81d861f3404db2935653692"}, - {file = "Pygments-2.16.1.tar.gz", hash = "sha256:1daff0494820c69bc8941e407aa20f577374ee88364ee10a98fdbe0aece96e29"}, + {file = "pygments-2.17.2-py3-none-any.whl", hash = "sha256:b27c2826c47d0f3219f29554824c30c5e8945175d888647acd804ddd04af846c"}, + {file = "pygments-2.17.2.tar.gz", hash = "sha256:da46cec9fd2de5be3a8a784f434e4c4ab670b4ff54d605c4c2717e9d49c4c367"}, ] [package.extras] plugins = ["importlib-metadata"] +windows-terminal = ["colorama (>=0.4.6)"] [[package]] name = "pymdown-extensions" -version = "10.3" +version = "10.7" description = "Extension pack for Python Markdown." optional = false python-versions = ">=3.8" files = [ - {file = "pymdown_extensions-10.3-py3-none-any.whl", hash = "sha256:77a82c621c58a83efc49a389159181d570e370fff9f810d3a4766a75fc678b66"}, - {file = "pymdown_extensions-10.3.tar.gz", hash = "sha256:94a0d8a03246712b64698af223848fd80aaf1ae4c4be29c8c61939b0467b5722"}, + {file = "pymdown_extensions-10.7-py3-none-any.whl", hash = "sha256:6ca215bc57bc12bf32b414887a68b810637d039124ed9b2e5bd3325cbb2c050c"}, + {file = "pymdown_extensions-10.7.tar.gz", hash = "sha256:c0d64d5cf62566f59e6b2b690a4095c931107c250a8c8e1351c1de5f6b036deb"}, ] [package.dependencies] -markdown = ">=3.2" +markdown = ">=3.5" pyyaml = "*" [package.extras] @@ -822,6 +840,7 @@ files = [ {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, + {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"}, {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, @@ -872,99 +891,104 @@ pyyaml = "*" [[package]] name = "regex" -version = "2022.10.31" +version = "2023.12.25" description = "Alternative regular expression module, to replace re." optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" files = [ - {file = "regex-2022.10.31-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a8ff454ef0bb061e37df03557afda9d785c905dab15584860f982e88be73015f"}, - {file = "regex-2022.10.31-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1eba476b1b242620c266edf6325b443a2e22b633217a9835a52d8da2b5c051f9"}, - {file = "regex-2022.10.31-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d0e5af9a9effb88535a472e19169e09ce750c3d442fb222254a276d77808620b"}, - {file = "regex-2022.10.31-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d03fe67b2325cb3f09be029fd5da8df9e6974f0cde2c2ac6a79d2634e791dd57"}, - {file = "regex-2022.10.31-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a9d0b68ac1743964755ae2d89772c7e6fb0118acd4d0b7464eaf3921c6b49dd4"}, - {file = "regex-2022.10.31-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8a45b6514861916c429e6059a55cf7db74670eaed2052a648e3e4d04f070e001"}, - {file = "regex-2022.10.31-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8b0886885f7323beea6f552c28bff62cbe0983b9fbb94126531693ea6c5ebb90"}, - {file = "regex-2022.10.31-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:5aefb84a301327ad115e9d346c8e2760009131d9d4b4c6b213648d02e2abe144"}, - {file = "regex-2022.10.31-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:702d8fc6f25bbf412ee706bd73019da5e44a8400861dfff7ff31eb5b4a1276dc"}, - {file = "regex-2022.10.31-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:a3c1ebd4ed8e76e886507c9eddb1a891673686c813adf889b864a17fafcf6d66"}, - {file = "regex-2022.10.31-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:50921c140561d3db2ab9f5b11c5184846cde686bb5a9dc64cae442926e86f3af"}, - {file = "regex-2022.10.31-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:7db345956ecce0c99b97b042b4ca7326feeec6b75facd8390af73b18e2650ffc"}, - {file = "regex-2022.10.31-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:763b64853b0a8f4f9cfb41a76a4a85a9bcda7fdda5cb057016e7706fde928e66"}, - {file = "regex-2022.10.31-cp310-cp310-win32.whl", hash = "sha256:44136355e2f5e06bf6b23d337a75386371ba742ffa771440b85bed367c1318d1"}, - {file = "regex-2022.10.31-cp310-cp310-win_amd64.whl", hash = "sha256:bfff48c7bd23c6e2aec6454aaf6edc44444b229e94743b34bdcdda2e35126cf5"}, - {file = "regex-2022.10.31-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4b4b1fe58cd102d75ef0552cf17242705ce0759f9695334a56644ad2d83903fe"}, - {file = "regex-2022.10.31-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:542e3e306d1669b25936b64917285cdffcd4f5c6f0247636fec037187bd93542"}, - {file = "regex-2022.10.31-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c27cc1e4b197092e50ddbf0118c788d9977f3f8f35bfbbd3e76c1846a3443df7"}, - {file = "regex-2022.10.31-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8e38472739028e5f2c3a4aded0ab7eadc447f0d84f310c7a8bb697ec417229e"}, - {file = "regex-2022.10.31-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:76c598ca73ec73a2f568e2a72ba46c3b6c8690ad9a07092b18e48ceb936e9f0c"}, - {file = "regex-2022.10.31-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c28d3309ebd6d6b2cf82969b5179bed5fefe6142c70f354ece94324fa11bf6a1"}, - {file = "regex-2022.10.31-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9af69f6746120998cd9c355e9c3c6aec7dff70d47247188feb4f829502be8ab4"}, - {file = "regex-2022.10.31-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a5f9505efd574d1e5b4a76ac9dd92a12acb2b309551e9aa874c13c11caefbe4f"}, - {file = "regex-2022.10.31-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:5ff525698de226c0ca743bfa71fc6b378cda2ddcf0d22d7c37b1cc925c9650a5"}, - {file = "regex-2022.10.31-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:4fe7fda2fe7c8890d454f2cbc91d6c01baf206fbc96d89a80241a02985118c0c"}, - {file = "regex-2022.10.31-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:2cdc55ca07b4e70dda898d2ab7150ecf17c990076d3acd7a5f3b25cb23a69f1c"}, - {file = "regex-2022.10.31-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:44a6c2f6374e0033873e9ed577a54a3602b4f609867794c1a3ebba65e4c93ee7"}, - {file = "regex-2022.10.31-cp311-cp311-win32.whl", hash = "sha256:d8716f82502997b3d0895d1c64c3b834181b1eaca28f3f6336a71777e437c2af"}, - {file = "regex-2022.10.31-cp311-cp311-win_amd64.whl", hash = "sha256:61edbca89aa3f5ef7ecac8c23d975fe7261c12665f1d90a6b1af527bba86ce61"}, - {file = "regex-2022.10.31-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:0a069c8483466806ab94ea9068c34b200b8bfc66b6762f45a831c4baaa9e8cdd"}, - {file = "regex-2022.10.31-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d26166acf62f731f50bdd885b04b38828436d74e8e362bfcb8df221d868b5d9b"}, - {file = "regex-2022.10.31-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ac741bf78b9bb432e2d314439275235f41656e189856b11fb4e774d9f7246d81"}, - {file = "regex-2022.10.31-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75f591b2055523fc02a4bbe598aa867df9e953255f0b7f7715d2a36a9c30065c"}, - {file = "regex-2022.10.31-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b30bddd61d2a3261f025ad0f9ee2586988c6a00c780a2fb0a92cea2aa702c54"}, - {file = "regex-2022.10.31-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ef4163770525257876f10e8ece1cf25b71468316f61451ded1a6f44273eedeb5"}, - {file = "regex-2022.10.31-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:7b280948d00bd3973c1998f92e22aa3ecb76682e3a4255f33e1020bd32adf443"}, - {file = "regex-2022.10.31-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:d0213671691e341f6849bf33cd9fad21f7b1cb88b89e024f33370733fec58742"}, - {file = "regex-2022.10.31-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:22e7ebc231d28393dfdc19b185d97e14a0f178bedd78e85aad660e93b646604e"}, - {file = "regex-2022.10.31-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:8ad241da7fac963d7573cc67a064c57c58766b62a9a20c452ca1f21050868dfa"}, - {file = "regex-2022.10.31-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:586b36ebda81e6c1a9c5a5d0bfdc236399ba6595e1397842fd4a45648c30f35e"}, - {file = "regex-2022.10.31-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:0653d012b3bf45f194e5e6a41df9258811ac8fc395579fa82958a8b76286bea4"}, - {file = "regex-2022.10.31-cp36-cp36m-win32.whl", hash = "sha256:144486e029793a733e43b2e37df16a16df4ceb62102636ff3db6033994711066"}, - {file = "regex-2022.10.31-cp36-cp36m-win_amd64.whl", hash = "sha256:c14b63c9d7bab795d17392c7c1f9aaabbffd4cf4387725a0ac69109fb3b550c6"}, - {file = "regex-2022.10.31-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4cac3405d8dda8bc6ed499557625585544dd5cbf32072dcc72b5a176cb1271c8"}, - {file = "regex-2022.10.31-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:23cbb932cc53a86ebde0fb72e7e645f9a5eec1a5af7aa9ce333e46286caef783"}, - {file = "regex-2022.10.31-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:74bcab50a13960f2a610cdcd066e25f1fd59e23b69637c92ad470784a51b1347"}, - {file = "regex-2022.10.31-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:78d680ef3e4d405f36f0d6d1ea54e740366f061645930072d39bca16a10d8c93"}, - {file = "regex-2022.10.31-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce6910b56b700bea7be82c54ddf2e0ed792a577dfaa4a76b9af07d550af435c6"}, - {file = "regex-2022.10.31-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:659175b2144d199560d99a8d13b2228b85e6019b6e09e556209dfb8c37b78a11"}, - {file = "regex-2022.10.31-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:1ddf14031a3882f684b8642cb74eea3af93a2be68893901b2b387c5fd92a03ec"}, - {file = "regex-2022.10.31-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:b683e5fd7f74fb66e89a1ed16076dbab3f8e9f34c18b1979ded614fe10cdc4d9"}, - {file = "regex-2022.10.31-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:2bde29cc44fa81c0a0c8686992c3080b37c488df167a371500b2a43ce9f026d1"}, - {file = "regex-2022.10.31-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:4919899577ba37f505aaebdf6e7dc812d55e8f097331312db7f1aab18767cce8"}, - {file = "regex-2022.10.31-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:9c94f7cc91ab16b36ba5ce476f1904c91d6c92441f01cd61a8e2729442d6fcf5"}, - {file = "regex-2022.10.31-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ae1e96785696b543394a4e3f15f3f225d44f3c55dafe3f206493031419fedf95"}, - {file = "regex-2022.10.31-cp37-cp37m-win32.whl", hash = "sha256:c670f4773f2f6f1957ff8a3962c7dd12e4be54d05839b216cb7fd70b5a1df394"}, - {file = "regex-2022.10.31-cp37-cp37m-win_amd64.whl", hash = "sha256:8e0caeff18b96ea90fc0eb6e3bdb2b10ab5b01a95128dfeccb64a7238decf5f0"}, - {file = "regex-2022.10.31-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:131d4be09bea7ce2577f9623e415cab287a3c8e0624f778c1d955ec7c281bd4d"}, - {file = "regex-2022.10.31-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:e613a98ead2005c4ce037c7b061f2409a1a4e45099edb0ef3200ee26ed2a69a8"}, - {file = "regex-2022.10.31-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:052b670fafbe30966bbe5d025e90b2a491f85dfe5b2583a163b5e60a85a321ad"}, - {file = "regex-2022.10.31-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aa62a07ac93b7cb6b7d0389d8ef57ffc321d78f60c037b19dfa78d6b17c928ee"}, - {file = "regex-2022.10.31-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5352bea8a8f84b89d45ccc503f390a6be77917932b1c98c4cdc3565137acc714"}, - {file = "regex-2022.10.31-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:20f61c9944f0be2dc2b75689ba409938c14876c19d02f7585af4460b6a21403e"}, - {file = "regex-2022.10.31-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:29c04741b9ae13d1e94cf93fca257730b97ce6ea64cfe1eba11cf9ac4e85afb6"}, - {file = "regex-2022.10.31-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:543883e3496c8b6d58bd036c99486c3c8387c2fc01f7a342b760c1ea3158a318"}, - {file = "regex-2022.10.31-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b7a8b43ee64ca8f4befa2bea4083f7c52c92864d8518244bfa6e88c751fa8fff"}, - {file = "regex-2022.10.31-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:6a9a19bea8495bb419dc5d38c4519567781cd8d571c72efc6aa959473d10221a"}, - {file = "regex-2022.10.31-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:6ffd55b5aedc6f25fd8d9f905c9376ca44fcf768673ffb9d160dd6f409bfda73"}, - {file = "regex-2022.10.31-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:4bdd56ee719a8f751cf5a593476a441c4e56c9b64dc1f0f30902858c4ef8771d"}, - {file = "regex-2022.10.31-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8ca88da1bd78990b536c4a7765f719803eb4f8f9971cc22d6ca965c10a7f2c4c"}, - {file = "regex-2022.10.31-cp38-cp38-win32.whl", hash = "sha256:5a260758454580f11dd8743fa98319bb046037dfab4f7828008909d0aa5292bc"}, - {file = "regex-2022.10.31-cp38-cp38-win_amd64.whl", hash = "sha256:5e6a5567078b3eaed93558842346c9d678e116ab0135e22eb72db8325e90b453"}, - {file = "regex-2022.10.31-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5217c25229b6a85049416a5c1e6451e9060a1edcf988641e309dbe3ab26d3e49"}, - {file = "regex-2022.10.31-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4bf41b8b0a80708f7e0384519795e80dcb44d7199a35d52c15cc674d10b3081b"}, - {file = "regex-2022.10.31-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0cf0da36a212978be2c2e2e2d04bdff46f850108fccc1851332bcae51c8907cc"}, - {file = "regex-2022.10.31-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d403d781b0e06d2922435ce3b8d2376579f0c217ae491e273bab8d092727d244"}, - {file = "regex-2022.10.31-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a37d51fa9a00d265cf73f3de3930fa9c41548177ba4f0faf76e61d512c774690"}, - {file = "regex-2022.10.31-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4f781ffedd17b0b834c8731b75cce2639d5a8afe961c1e58ee7f1f20b3af185"}, - {file = "regex-2022.10.31-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d243b36fbf3d73c25e48014961e83c19c9cc92530516ce3c43050ea6276a2ab7"}, - {file = "regex-2022.10.31-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:370f6e97d02bf2dd20d7468ce4f38e173a124e769762d00beadec3bc2f4b3bc4"}, - {file = "regex-2022.10.31-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:597f899f4ed42a38df7b0e46714880fb4e19a25c2f66e5c908805466721760f5"}, - {file = "regex-2022.10.31-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7dbdce0c534bbf52274b94768b3498abdf675a691fec5f751b6057b3030f34c1"}, - {file = "regex-2022.10.31-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:22960019a842777a9fa5134c2364efaed5fbf9610ddc5c904bd3a400973b0eb8"}, - {file = "regex-2022.10.31-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:7f5a3ffc731494f1a57bd91c47dc483a1e10048131ffb52d901bfe2beb6102e8"}, - {file = "regex-2022.10.31-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7ef6b5942e6bfc5706301a18a62300c60db9af7f6368042227ccb7eeb22d0892"}, - {file = "regex-2022.10.31-cp39-cp39-win32.whl", hash = "sha256:395161bbdbd04a8333b9ff9763a05e9ceb4fe210e3c7690f5e68cedd3d65d8e1"}, - {file = "regex-2022.10.31-cp39-cp39-win_amd64.whl", hash = "sha256:957403a978e10fb3ca42572a23e6f7badff39aa1ce2f4ade68ee452dc6807692"}, - {file = "regex-2022.10.31.tar.gz", hash = "sha256:a3a98921da9a1bf8457aeee6a551948a83601689e5ecdd736894ea9bbec77e83"}, + {file = "regex-2023.12.25-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0694219a1d54336fd0445ea382d49d36882415c0134ee1e8332afd1529f0baa5"}, + {file = "regex-2023.12.25-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b014333bd0217ad3d54c143de9d4b9a3ca1c5a29a6d0d554952ea071cff0f1f8"}, + {file = "regex-2023.12.25-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d865984b3f71f6d0af64d0d88f5733521698f6c16f445bb09ce746c92c97c586"}, + {file = "regex-2023.12.25-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1e0eabac536b4cc7f57a5f3d095bfa557860ab912f25965e08fe1545e2ed8b4c"}, + {file = "regex-2023.12.25-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c25a8ad70e716f96e13a637802813f65d8a6760ef48672aa3502f4c24ea8b400"}, + {file = "regex-2023.12.25-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a9b6d73353f777630626f403b0652055ebfe8ff142a44ec2cf18ae470395766e"}, + {file = "regex-2023.12.25-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a9cc99d6946d750eb75827cb53c4371b8b0fe89c733a94b1573c9dd16ea6c9e4"}, + {file = "regex-2023.12.25-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:88d1f7bef20c721359d8675f7d9f8e414ec5003d8f642fdfd8087777ff7f94b5"}, + {file = "regex-2023.12.25-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:cb3fe77aec8f1995611f966d0c656fdce398317f850d0e6e7aebdfe61f40e1cd"}, + {file = "regex-2023.12.25-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:7aa47c2e9ea33a4a2a05f40fcd3ea36d73853a2aae7b4feab6fc85f8bf2c9704"}, + {file = "regex-2023.12.25-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:df26481f0c7a3f8739fecb3e81bc9da3fcfae34d6c094563b9d4670b047312e1"}, + {file = "regex-2023.12.25-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:c40281f7d70baf6e0db0c2f7472b31609f5bc2748fe7275ea65a0b4601d9b392"}, + {file = "regex-2023.12.25-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:d94a1db462d5690ebf6ae86d11c5e420042b9898af5dcf278bd97d6bda065423"}, + {file = "regex-2023.12.25-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:ba1b30765a55acf15dce3f364e4928b80858fa8f979ad41f862358939bdd1f2f"}, + {file = "regex-2023.12.25-cp310-cp310-win32.whl", hash = "sha256:150c39f5b964e4d7dba46a7962a088fbc91f06e606f023ce57bb347a3b2d4630"}, + {file = "regex-2023.12.25-cp310-cp310-win_amd64.whl", hash = "sha256:09da66917262d9481c719599116c7dc0c321ffcec4b1f510c4f8a066f8768105"}, + {file = "regex-2023.12.25-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:1b9d811f72210fa9306aeb88385b8f8bcef0dfbf3873410413c00aa94c56c2b6"}, + {file = "regex-2023.12.25-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d902a43085a308cef32c0d3aea962524b725403fd9373dea18110904003bac97"}, + {file = "regex-2023.12.25-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d166eafc19f4718df38887b2bbe1467a4f74a9830e8605089ea7a30dd4da8887"}, + {file = "regex-2023.12.25-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c7ad32824b7f02bb3c9f80306d405a1d9b7bb89362d68b3c5a9be53836caebdb"}, + {file = "regex-2023.12.25-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:636ba0a77de609d6510235b7f0e77ec494d2657108f777e8765efc060094c98c"}, + {file = "regex-2023.12.25-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0fda75704357805eb953a3ee15a2b240694a9a514548cd49b3c5124b4e2ad01b"}, + {file = "regex-2023.12.25-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f72cbae7f6b01591f90814250e636065850c5926751af02bb48da94dfced7baa"}, + {file = "regex-2023.12.25-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:db2a0b1857f18b11e3b0e54ddfefc96af46b0896fb678c85f63fb8c37518b3e7"}, + {file = "regex-2023.12.25-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:7502534e55c7c36c0978c91ba6f61703faf7ce733715ca48f499d3dbbd7657e0"}, + {file = "regex-2023.12.25-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:e8c7e08bb566de4faaf11984af13f6bcf6a08f327b13631d41d62592681d24fe"}, + {file = "regex-2023.12.25-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:283fc8eed679758de38fe493b7d7d84a198b558942b03f017b1f94dda8efae80"}, + {file = "regex-2023.12.25-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:f44dd4d68697559d007462b0a3a1d9acd61d97072b71f6d1968daef26bc744bd"}, + {file = "regex-2023.12.25-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:67d3ccfc590e5e7197750fcb3a2915b416a53e2de847a728cfa60141054123d4"}, + {file = "regex-2023.12.25-cp311-cp311-win32.whl", hash = "sha256:68191f80a9bad283432385961d9efe09d783bcd36ed35a60fb1ff3f1ec2efe87"}, + {file = "regex-2023.12.25-cp311-cp311-win_amd64.whl", hash = "sha256:7d2af3f6b8419661a0c421584cfe8aaec1c0e435ce7e47ee2a97e344b98f794f"}, + {file = "regex-2023.12.25-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8a0ccf52bb37d1a700375a6b395bff5dd15c50acb745f7db30415bae3c2b0715"}, + {file = "regex-2023.12.25-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c3c4a78615b7762740531c27cf46e2f388d8d727d0c0c739e72048beb26c8a9d"}, + {file = "regex-2023.12.25-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ad83e7545b4ab69216cef4cc47e344d19622e28aabec61574b20257c65466d6a"}, + {file = "regex-2023.12.25-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b7a635871143661feccce3979e1727c4e094f2bdfd3ec4b90dfd4f16f571a87a"}, + {file = "regex-2023.12.25-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d498eea3f581fbe1b34b59c697512a8baef88212f92e4c7830fcc1499f5b45a5"}, + {file = "regex-2023.12.25-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:43f7cd5754d02a56ae4ebb91b33461dc67be8e3e0153f593c509e21d219c5060"}, + {file = "regex-2023.12.25-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:51f4b32f793812714fd5307222a7f77e739b9bc566dc94a18126aba3b92b98a3"}, + {file = "regex-2023.12.25-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba99d8077424501b9616b43a2d208095746fb1284fc5ba490139651f971d39d9"}, + {file = "regex-2023.12.25-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:4bfc2b16e3ba8850e0e262467275dd4d62f0d045e0e9eda2bc65078c0110a11f"}, + {file = "regex-2023.12.25-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8c2c19dae8a3eb0ea45a8448356ed561be843b13cbc34b840922ddf565498c1c"}, + {file = "regex-2023.12.25-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:60080bb3d8617d96f0fb7e19796384cc2467447ef1c491694850ebd3670bc457"}, + {file = "regex-2023.12.25-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b77e27b79448e34c2c51c09836033056a0547aa360c45eeeb67803da7b0eedaf"}, + {file = "regex-2023.12.25-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:518440c991f514331f4850a63560321f833979d145d7d81186dbe2f19e27ae3d"}, + {file = "regex-2023.12.25-cp312-cp312-win32.whl", hash = "sha256:e2610e9406d3b0073636a3a2e80db05a02f0c3169b5632022b4e81c0364bcda5"}, + {file = "regex-2023.12.25-cp312-cp312-win_amd64.whl", hash = "sha256:cc37b9aeebab425f11f27e5e9e6cf580be7206c6582a64467a14dda211abc232"}, + {file = "regex-2023.12.25-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:da695d75ac97cb1cd725adac136d25ca687da4536154cdc2815f576e4da11c69"}, + {file = "regex-2023.12.25-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d126361607b33c4eb7b36debc173bf25d7805847346dd4d99b5499e1fef52bc7"}, + {file = "regex-2023.12.25-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4719bb05094d7d8563a450cf8738d2e1061420f79cfcc1fa7f0a44744c4d8f73"}, + {file = "regex-2023.12.25-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5dd58946bce44b53b06d94aa95560d0b243eb2fe64227cba50017a8d8b3cd3e2"}, + {file = "regex-2023.12.25-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:22a86d9fff2009302c440b9d799ef2fe322416d2d58fc124b926aa89365ec482"}, + {file = "regex-2023.12.25-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2aae8101919e8aa05ecfe6322b278f41ce2994c4a430303c4cd163fef746e04f"}, + {file = "regex-2023.12.25-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:e692296c4cc2873967771345a876bcfc1c547e8dd695c6b89342488b0ea55cd8"}, + {file = "regex-2023.12.25-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:263ef5cc10979837f243950637fffb06e8daed7f1ac1e39d5910fd29929e489a"}, + {file = "regex-2023.12.25-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:d6f7e255e5fa94642a0724e35406e6cb7001c09d476ab5fce002f652b36d0c39"}, + {file = "regex-2023.12.25-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:88ad44e220e22b63b0f8f81f007e8abbb92874d8ced66f32571ef8beb0643b2b"}, + {file = "regex-2023.12.25-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:3a17d3ede18f9cedcbe23d2daa8a2cd6f59fe2bf082c567e43083bba3fb00347"}, + {file = "regex-2023.12.25-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:d15b274f9e15b1a0b7a45d2ac86d1f634d983ca40d6b886721626c47a400bf39"}, + {file = "regex-2023.12.25-cp37-cp37m-win32.whl", hash = "sha256:ed19b3a05ae0c97dd8f75a5d8f21f7723a8c33bbc555da6bbe1f96c470139d3c"}, + {file = "regex-2023.12.25-cp37-cp37m-win_amd64.whl", hash = "sha256:a6d1047952c0b8104a1d371f88f4ab62e6275567d4458c1e26e9627ad489b445"}, + {file = "regex-2023.12.25-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:b43523d7bc2abd757119dbfb38af91b5735eea45537ec6ec3a5ec3f9562a1c53"}, + {file = "regex-2023.12.25-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:efb2d82f33b2212898f1659fb1c2e9ac30493ac41e4d53123da374c3b5541e64"}, + {file = "regex-2023.12.25-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b7fca9205b59c1a3d5031f7e64ed627a1074730a51c2a80e97653e3e9fa0d415"}, + {file = "regex-2023.12.25-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:086dd15e9435b393ae06f96ab69ab2d333f5d65cbe65ca5a3ef0ec9564dfe770"}, + {file = "regex-2023.12.25-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e81469f7d01efed9b53740aedd26085f20d49da65f9c1f41e822a33992cb1590"}, + {file = "regex-2023.12.25-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:34e4af5b27232f68042aa40a91c3b9bb4da0eeb31b7632e0091afc4310afe6cb"}, + {file = "regex-2023.12.25-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9852b76ab558e45b20bf1893b59af64a28bd3820b0c2efc80e0a70a4a3ea51c1"}, + {file = "regex-2023.12.25-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ff100b203092af77d1a5a7abe085b3506b7eaaf9abf65b73b7d6905b6cb76988"}, + {file = "regex-2023.12.25-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:cc038b2d8b1470364b1888a98fd22d616fba2b6309c5b5f181ad4483e0017861"}, + {file = "regex-2023.12.25-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:094ba386bb5c01e54e14434d4caabf6583334090865b23ef58e0424a6286d3dc"}, + {file = "regex-2023.12.25-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:5cd05d0f57846d8ba4b71d9c00f6f37d6b97d5e5ef8b3c3840426a475c8f70f4"}, + {file = "regex-2023.12.25-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:9aa1a67bbf0f957bbe096375887b2505f5d8ae16bf04488e8b0f334c36e31360"}, + {file = "regex-2023.12.25-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:98a2636994f943b871786c9e82bfe7883ecdaba2ef5df54e1450fa9869d1f756"}, + {file = "regex-2023.12.25-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:37f8e93a81fc5e5bd8db7e10e62dc64261bcd88f8d7e6640aaebe9bc180d9ce2"}, + {file = "regex-2023.12.25-cp38-cp38-win32.whl", hash = "sha256:d78bd484930c1da2b9679290a41cdb25cc127d783768a0369d6b449e72f88beb"}, + {file = "regex-2023.12.25-cp38-cp38-win_amd64.whl", hash = "sha256:b521dcecebc5b978b447f0f69b5b7f3840eac454862270406a39837ffae4e697"}, + {file = "regex-2023.12.25-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:f7bc09bc9c29ebead055bcba136a67378f03d66bf359e87d0f7c759d6d4ffa31"}, + {file = "regex-2023.12.25-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e14b73607d6231f3cc4622809c196b540a6a44e903bcfad940779c80dffa7be7"}, + {file = "regex-2023.12.25-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9eda5f7a50141291beda3edd00abc2d4a5b16c29c92daf8d5bd76934150f3edc"}, + {file = "regex-2023.12.25-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cc6bb9aa69aacf0f6032c307da718f61a40cf970849e471254e0e91c56ffca95"}, + {file = "regex-2023.12.25-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:298dc6354d414bc921581be85695d18912bea163a8b23cac9a2562bbcd5088b1"}, + {file = "regex-2023.12.25-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2f4e475a80ecbd15896a976aa0b386c5525d0ed34d5c600b6d3ebac0a67c7ddf"}, + {file = "regex-2023.12.25-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:531ac6cf22b53e0696f8e1d56ce2396311254eb806111ddd3922c9d937151dae"}, + {file = "regex-2023.12.25-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:22f3470f7524b6da61e2020672df2f3063676aff444db1daa283c2ea4ed259d6"}, + {file = "regex-2023.12.25-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:89723d2112697feaa320c9d351e5f5e7b841e83f8b143dba8e2d2b5f04e10923"}, + {file = "regex-2023.12.25-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0ecf44ddf9171cd7566ef1768047f6e66975788258b1c6c6ca78098b95cf9a3d"}, + {file = "regex-2023.12.25-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:905466ad1702ed4acfd67a902af50b8db1feeb9781436372261808df7a2a7bca"}, + {file = "regex-2023.12.25-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:4558410b7a5607a645e9804a3e9dd509af12fb72b9825b13791a37cd417d73a5"}, + {file = "regex-2023.12.25-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:7e316026cc1095f2a3e8cc012822c99f413b702eaa2ca5408a513609488cb62f"}, + {file = "regex-2023.12.25-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:3b1de218d5375cd6ac4b5493e0b9f3df2be331e86520f23382f216c137913d20"}, + {file = "regex-2023.12.25-cp39-cp39-win32.whl", hash = "sha256:11a963f8e25ab5c61348d090bf1b07f1953929c13bd2309a0662e9ff680763c9"}, + {file = "regex-2023.12.25-cp39-cp39-win_amd64.whl", hash = "sha256:e693e233ac92ba83a87024e1d32b5f9ab15ca55ddd916d878146f4e3406b5c91"}, + {file = "regex-2023.12.25.tar.gz", hash = "sha256:29171aa128da69afdf4bde412d5bedc335f2ca8fcfe4489038577d05f16181e5"}, ] [[package]] @@ -1055,29 +1079,28 @@ test = ["flake8", "isort", "pytest"] [[package]] name = "tzdata" -version = "2023.3" +version = "2022.7" description = "Provider of IANA time zone data" optional = false python-versions = ">=2" files = [ - {file = "tzdata-2023.3-py2.py3-none-any.whl", hash = "sha256:7e65763eef3120314099b6939b5546db7adce1e7d6f2e179e3df563c70511eda"}, - {file = "tzdata-2023.3.tar.gz", hash = "sha256:11ef1e08e54acb0d4f95bdb1be05da659673de4acbd21bf9c69e94cc5e907a3a"}, + {file = "tzdata-2022.7-py2.py3-none-any.whl", hash = "sha256:2b88858b0e3120792a3c0635c23daf36a7d7eeeca657c323da299d2094402a0d"}, + {file = "tzdata-2022.7.tar.gz", hash = "sha256:fe5f866eddd8b96e9fcba978f8e503c909b19ea7efda11e52e39494bad3a7bfa"}, ] [[package]] name = "urllib3" -version = "2.0.5" +version = "2.1.0" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "urllib3-2.0.5-py3-none-any.whl", hash = "sha256:ef16afa8ba34a1f989db38e1dbbe0c302e4289a47856990d0682e374563ce35e"}, - {file = "urllib3-2.0.5.tar.gz", hash = "sha256:13abf37382ea2ce6fb744d4dad67838eec857c9f4f57009891805e0b5e123594"}, + {file = "urllib3-2.1.0-py3-none-any.whl", hash = "sha256:55901e917a5896a349ff771be919f8bd99aff50b79fe58fec595eb37bbc56bb3"}, + {file = "urllib3-2.1.0.tar.gz", hash = "sha256:df7aa8afb0148fa78488e7899b2c59b5f4ffcfa82e6c54ccb9dd37c1d7b52d54"}, ] [package.extras] brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] -secure = ["certifi", "cryptography (>=1.9)", "idna (>=2.0.0)", "pyopenssl (>=17.1.0)", "urllib3-secure-extra"] socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] zstd = ["zstandard (>=0.18.0)"] @@ -1124,7 +1147,6 @@ watchmedo = ["PyYAML (>=3.10)"] name = "wcmatch" version = "8.5" description = "Wildcard/glob file name matcher." -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1164,4 +1186,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p [metadata] lock-version = "2.0" python-versions = ">=3.9,<3.12" -content-hash = "ce967b04c0d8c2818599d333bdcf495f9932b7771fcd151f41c6579c22c1e812" +content-hash = "8b3c5630efc528583af82f6d7aa9d3d28e5f892e7af717e2ceb72676f91f757d" From caf1a2ea564c31f2ee70bc67af56f77a2758848a Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Tue, 23 Jan 2024 19:40:55 -0500 Subject: [PATCH 051/146] pre-commit run -a --- src/devenv/cli.py | 8 ++++---- src/modules/languages/python.nix | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/devenv/cli.py b/src/devenv/cli.py index 7cdf25b7c..977883d43 100644 --- a/src/devenv/cli.py +++ b/src/devenv/cli.py @@ -681,11 +681,11 @@ def add(ctx, name, url, follows): ) @click.argument("names", nargs=-1) @click.option("--debug", is_flag=True, help="Run tests in debug mode.") +@click.option("--keep-going", is_flag=True, help="Continue running tests if one fails.") @click.option( - "--keep-going", is_flag=True, help="Continue running tests if one fails.") -@click.option( - "--exclude", multiple=True, - help="A test name to exclude, may be specified multiple times" + "--exclude", + multiple=True, + help="A test name to exclude, may be specified multiple times", ) @click.pass_context def test(ctx, debug, keep_going, exclude, names): diff --git a/src/modules/languages/python.nix b/src/modules/languages/python.nix index ecf7b19ef..e391d195b 100644 --- a/src/modules/languages/python.nix +++ b/src/modules/languages/python.nix @@ -7,7 +7,7 @@ let ++ (lib.optional cfg.manylinux.enable pkgs.pythonManylinuxPackages.manylinux2014Package) # see https://matrix.to/#/!kjdutkOsheZdjqYmqp:nixos.org/$XJ5CO4bKMevYzZq_rrNo64YycknVFJIJTy6hVCJjRlA?via=nixos.org&via=matrix.org&via=nixos.dev ++ [ pkgs.stdenv.cc.cc.lib ] - ); + ); readlink = "${pkgs.coreutils}/bin/readlink -f "; package = pkgs.callPackage "${pkgs.path}/pkgs/development/interpreters/python/wrapper.nix" { From da4589b7b11962e71efb9e438d727cb63f81f744 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Tue, 23 Jan 2024 19:51:49 -0500 Subject: [PATCH 052/146] mark phoenix as broken --- examples/phoenix/.test.sh | 21 +++++++++++---------- examples/phoenix/devenv.nix | 2 ++ 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/examples/phoenix/.test.sh b/examples/phoenix/.test.sh index 75f3c0b25..b687eac17 100755 --- a/examples/phoenix/.test.sh +++ b/examples/phoenix/.test.sh @@ -1,12 +1,13 @@ #!/usr/bin/env bash set -ex -mkdir hello -mix local.hex --force -mix local.rebar --force -echo Y | mix archive.install hex phx_new -echo Y | mix phx.new hello -sed -i.bak -e "s/username: \"postgres\",/socket_dir: System.get_env(\"PGDATA\"),/" \ - ./hello/config/dev.exs && rm ./hello/config/dev.exs.bak -devenv up& -timeout 20 bash -c 'until echo > /dev/tcp/localhost/4000; do sleep 0.5; done' -curl -s http://localhost:4000/ | grep "Phoenix Framework" +# mix local.hex --force +# mix local.rebar --force +# echo Y | mix archive.install hex phx_new +# echo Y | mix phx.new hello +# sed -i.bak -e "s/username: \"postgres\",/socket_dir: System.get_env(\"PGDATA\"),/" \ +# ./hello/config/dev.exs && rm ./hello/config/dev.exs.bak +# devenv up& +# timeout 20 bash -c 'until echo > /dev/tcp/localhost/4000; do sleep 0.5; done' +# curl -s http://localhost:4000/ | grep "Phoenix Framework" +echo "this example is currently broken" +exit 2 diff --git a/examples/phoenix/devenv.nix b/examples/phoenix/devenv.nix index e6d6a4241..a5ce5f7b3 100644 --- a/examples/phoenix/devenv.nix +++ b/examples/phoenix/devenv.nix @@ -1,6 +1,8 @@ { pkgs, lib, ... }: { + # this example is currently broken + packages = lib.optionals pkgs.stdenv.isLinux [ pkgs.inotify-tools ]; languages.elixir.enable = true; From fb1c7e2d9763cef3c6dc9c5fd869182e3489c065 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 27 Jan 2024 22:21:20 -0500 Subject: [PATCH 053/146] print the command being run so we can run it by hand if it fails MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (cherry picked from commit f294626643ab640ee3b980f1b5ac4c25ab498b6e) Signed-off-by: Domen Kožar --- src/devenv/cli.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/devenv/cli.py b/src/devenv/cli.py index 977883d43..ccce925a2 100644 --- a/src/devenv/cli.py +++ b/src/devenv/cli.py @@ -507,8 +507,12 @@ def container(ctx, registry, copy, copy_args, docker_run, container_name): if docker_run: registry = "docker-daemon:" + cp = f"{copy_script} {spec} {registry or 'false'} {copy_args or ''}" + + log(f"Running '{cp}'", level="info") + subprocess.run( - f"{copy_script} {spec} {registry or 'false'} {copy_args or ''}", + cp, shell=True, check=True, ) From ac2e743b492d0ad4fa11f6a0babd279d179fbf01 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sun, 28 Jan 2024 00:58:52 -0500 Subject: [PATCH 054/146] allow builtins (like set and if) within container exec commands MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (cherry picked from commit d2bd250d3f868ff287833fe291f80c27361aae9c) Signed-off-by: Domen Kožar --- src/modules/containers.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/containers.nix b/src/modules/containers.nix index 06d0b5be0..43b7ddca3 100644 --- a/src/modules/containers.nix +++ b/src/modules/containers.nix @@ -31,7 +31,7 @@ let # expand any envvars before exec cmd="`echo "$@"|${pkgs.envsubst}/bin/envsubst`" - exec $cmd + ${pkgs.bash}/bin/bash -c "$cmd" ''; mkDerivation = cfg: nix2container.nix2container.buildImage { name = cfg.name; From 2fad7a808da08737fdf66e705b7f065866624d62 Mon Sep 17 00:00:00 2001 From: Juozas Norkus Date: Sun, 28 Jan 2024 13:08:32 +0000 Subject: [PATCH 055/146] Support allowBroken MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (cherry picked from commit e3d3ae02c9ef67791aa38ec8697354ba6cbc2619) Signed-off-by: Domen Kožar --- docs/reference/yaml-options.md | 1 + src/devenv/yaml.py | 1 + src/modules/flake.tmpl.nix | 1 + 3 files changed, 3 insertions(+) diff --git a/docs/reference/yaml-options.md b/docs/reference/yaml-options.md index edde6fde1..16cd7557f 100644 --- a/docs/reference/yaml-options.md +++ b/docs/reference/yaml-options.md @@ -2,6 +2,7 @@ | Key | Value | | ---------------------------- | ----------------------------------------------------------------------------- | | allowUnfree | Allow unfree packages. Defaults to `false`. | +| allowBroken | Allow packages marked as broken. Defaults to `false`. | | inputs | Defaults to `inputs.nixpkgs.url: github:NixOS/nixpkgs/nixpkgs-unstable`. | | inputs.<name> | Identifier name used when passing the input in your ``devenv.nix`` function. | | inputs.<name>.url | URI specification of the input, see below for possible values. | diff --git a/src/devenv/yaml.py b/src/devenv/yaml.py index 825dbccf9..634a20e1d 100644 --- a/src/devenv/yaml.py +++ b/src/devenv/yaml.py @@ -23,6 +23,7 @@ { Optional("inputs", default=None): inputsSchema, Optional("allowUnfree", default=False): Bool(), + Optional("allowBroken", default=False): Bool(), Optional("imports", default=None): Seq(Str()), Optional("permittedInsecurePackages", default=None): Seq(Str()), } diff --git a/src/modules/flake.tmpl.nix b/src/modules/flake.tmpl.nix index 92f403721..61c9b0a75 100644 --- a/src/modules/flake.tmpl.nix +++ b/src/modules/flake.tmpl.nix @@ -28,6 +28,7 @@ inherit system; config = { allowUnfree = devenv.allowUnfree or false; + allowBroken = devenv.allowBroken or false; permittedInsecurePackages = devenv.permittedInsecurePackages or [ ]; }; inherit overlays; From 64f270df002d6e78b7344fd544671a541e94600e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Fri, 16 Feb 2024 18:22:41 +0000 Subject: [PATCH 056/146] update nix to 2.21 (dev) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (cherry picked from commit 42b54847a4fc64586f020568a2f3cb2828ba1eee) Signed-off-by: Domen Kožar --- devenv.lock | 25 ++++--------------------- devenv.yaml | 2 +- flake.lock | 25 ++++--------------------- flake.nix | 2 +- 4 files changed, 10 insertions(+), 44 deletions(-) diff --git a/devenv.lock b/devenv.lock index b8057944f..a8c6a23c1 100644 --- a/devenv.lock +++ b/devenv.lock @@ -82,42 +82,25 @@ "type": "github" } }, - "lowdown-src": { - "flake": false, - "locked": { - "lastModified": 1633514407, - "narHash": "sha256-Dw32tiMjdK9t3ETl5fzGrutQTzh2rufgZV4A/BbxuD4=", - "owner": "kristapsdz", - "repo": "lowdown", - "rev": "d2c2b44ff6c27b936ec27358a2653caaef8f73b8", - "type": "github" - }, - "original": { - "owner": "kristapsdz", - "repo": "lowdown", - "type": "github" - } - }, "nix": { "inputs": { "flake-compat": "flake-compat", - "lowdown-src": "lowdown-src", "nixpkgs": [ "nixpkgs" ], "nixpkgs-regression": "nixpkgs-regression" }, "locked": { - "lastModified": 1692627130, + "lastModified": 1708106917, "owner": "domenkozar", "repo": "nix", - "rev": "96e8d6a3f33fa0c770ad421463ab168239dc921b", - "treeHash": "8ce5bd7323dd5d1a7015cb7f5fcf0cefb0047069", + "rev": "d250aad325d4060a6bf6d24f613f4a9b2d8419f9", + "treeHash": "df402ee7b74f4bf0de9b174f42df34e31b9880bc", "type": "github" }, "original": { "owner": "domenkozar", - "ref": "devenv-2.17", + "ref": "devenv-2.21", "repo": "nix", "type": "github" } diff --git a/devenv.yaml b/devenv.yaml index 9ce3974f9..01be806ad 100644 --- a/devenv.yaml +++ b/devenv.yaml @@ -2,7 +2,7 @@ inputs: nixpkgs: url: github:NixOS/nixpkgs/nixpkgs-unstable nix: - url: github:domenkozar/nix/devenv-2.17 + url: github:domenkozar/nix/devenv-2.21 inputs: nixpkgs: follows: nixpkgs diff --git a/flake.lock b/flake.lock index dd642d65d..f528296cf 100644 --- a/flake.lock +++ b/flake.lock @@ -89,42 +89,25 @@ "type": "github" } }, - "lowdown-src": { - "flake": false, - "locked": { - "lastModified": 1633514407, - "narHash": "sha256-Dw32tiMjdK9t3ETl5fzGrutQTzh2rufgZV4A/BbxuD4=", - "owner": "kristapsdz", - "repo": "lowdown", - "rev": "d2c2b44ff6c27b936ec27358a2653caaef8f73b8", - "type": "github" - }, - "original": { - "owner": "kristapsdz", - "repo": "lowdown", - "type": "github" - } - }, "nix": { "inputs": { "flake-compat": "flake-compat_2", - "lowdown-src": "lowdown-src", "nixpkgs": [ "nixpkgs" ], "nixpkgs-regression": "nixpkgs-regression" }, "locked": { - "lastModified": 1692895818, - "narHash": "sha256-lfIz37c24QpkwAHJCDHrDNtQyMBdxq7RWG5sojbtARU=", + "lastModified": 1708106917, + "narHash": "sha256-T2xF+MwHGt7yUW4WfExavF7DODIELI/hSi+IHDKlNEY=", "owner": "domenkozar", "repo": "nix", - "rev": "ca8a41cfc176dc7adad02ab756f6faef6e90ff1f", + "rev": "d250aad325d4060a6bf6d24f613f4a9b2d8419f9", "type": "github" }, "original": { "owner": "domenkozar", - "ref": "devenv-2.17", + "ref": "devenv-2.21", "repo": "nix", "type": "github" } diff --git a/flake.nix b/flake.nix index e38499094..b548f0091 100644 --- a/flake.nix +++ b/flake.nix @@ -19,7 +19,7 @@ flake = false; }; inputs.nix = { - url = "github:domenkozar/nix/devenv-2.17"; + url = "github:domenkozar/nix/devenv-2.21"; inputs.nixpkgs.follows = "nixpkgs"; }; inputs.poetry2nix = { From 748ff8b895ce5cc6e537e6e15b7f124a7e1eb3d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Sat, 17 Feb 2024 03:30:27 +0000 Subject: [PATCH 057/146] search: fix missing default MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (cherry picked from commit 48e8b02221fd1a05372472bda5adcc88f8d73738) Signed-off-by: Domen Kožar --- src/devenv/cli.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/devenv/cli.py b/src/devenv/cli.py index ccce925a2..baadbefc0 100644 --- a/src/devenv/cli.py +++ b/src/devenv/cli.py @@ -427,7 +427,12 @@ def search(ctx, name): for key, value in json.load(f).items(): if name in key: options_results.append( - (key, value["type"], value["default"], value["description"][:80]) + ( + key, + value["type"], + value.get("default", ""), + value["description"][:80], + ) ) results_options_count = len(options_results) From 9bd8d1a7c78eb7cc158215f8cbe92437be5849f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Thu, 14 Dec 2023 10:51:30 +0100 Subject: [PATCH 058/146] use self-hosted arm/linux --- .github/workflows/buildtest.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/buildtest.yml b/.github/workflows/buildtest.yml index 73b273468..7283c3064 100644 --- a/.github/workflows/buildtest.yml +++ b/.github/workflows/buildtest.yml @@ -13,7 +13,7 @@ jobs: strategy: fail-fast: false matrix: - os: [[ubuntu-latest], [self-hosted, macOS], [nscloud-arm64]] + os: [[ubuntu-latest], [macos-latest], [self-hosted, macOS], [self-hosted, linux, ARM64]] runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v4 From 3697204b9d0188aa5063c95e9eb2d25b51b83208 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Sat, 17 Feb 2024 07:44:00 +0000 Subject: [PATCH 059/146] fix cloudflare --- build_cloudflare.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build_cloudflare.sh b/build_cloudflare.sh index 2ab00ad26..4b6b8353c 100755 --- a/build_cloudflare.sh +++ b/build_cloudflare.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash set -xe -poetry install +poetry install --with docs poetry run -- mkdocs build From ff0400d55d8141eb669aea380ca4c53624959d7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Sat, 17 Feb 2024 14:26:48 +0000 Subject: [PATCH 060/146] bump nix --- flake.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/flake.lock b/flake.lock index f528296cf..f8d91dfae 100644 --- a/flake.lock +++ b/flake.lock @@ -98,11 +98,11 @@ "nixpkgs-regression": "nixpkgs-regression" }, "locked": { - "lastModified": 1708106917, - "narHash": "sha256-T2xF+MwHGt7yUW4WfExavF7DODIELI/hSi+IHDKlNEY=", + "lastModified": 1708228001, + "narHash": "sha256-rvwgIrmmjdmAkShFDJVBuXMjePyi7id7VylnbC9gE/E=", "owner": "domenkozar", "repo": "nix", - "rev": "d250aad325d4060a6bf6d24f613f4a9b2d8419f9", + "rev": "46ffacbdfd829eb480c50e4d42b42081d98d47f8", "type": "github" }, "original": { From f60f26e9f57e6e84d402e4c6f3c01e8288566d33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Mon, 19 Feb 2024 17:28:03 +0000 Subject: [PATCH 061/146] .devenv.flake.nix -> .devenv/flake.nix --- flake.lock | 6 +++--- src/devenv/cli.py | 5 +++-- src/modules/integrations/pre-commit.nix | 1 - 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/flake.lock b/flake.lock index f8d91dfae..1ac23b87e 100644 --- a/flake.lock +++ b/flake.lock @@ -98,11 +98,11 @@ "nixpkgs-regression": "nixpkgs-regression" }, "locked": { - "lastModified": 1708228001, - "narHash": "sha256-rvwgIrmmjdmAkShFDJVBuXMjePyi7id7VylnbC9gE/E=", + "lastModified": 1708363659, + "narHash": "sha256-cFdUGJXVUNcrFkMwaxWEf1LJ1gdkJCuQDLL+Dhvw8uM=", "owner": "domenkozar", "repo": "nix", - "rev": "46ffacbdfd829eb480c50e4d42b42081d98d47f8", + "rev": "cbd29b1d160f7bc71d850efb357346e0664895ad", "type": "github" }, "original": { diff --git a/src/devenv/cli.py b/src/devenv/cli.py index baadbefc0..6c949be97 100644 --- a/src/devenv/cli.py +++ b/src/devenv/cli.py @@ -43,9 +43,11 @@ SRC_DIR = Path(FILE, "..", "..", "src") else: SRC_DIR = Path(FILE, "..", "..") +DEVENV_DIR = Path(os.getcwd()) / ".devenv" +DEVENV_DIR.mkdir(parents=True, exist_ok=True) MODULES_DIR = (SRC_DIR / "modules").resolve() FLAKE_FILE_TEMPL = Path(MODULES_DIR) / "flake.tmpl.nix" -FLAKE_FILE = Path(".devenv.flake.nix") +FLAKE_FILE = DEVENV_DIR / "flake.nix" FLAKE_LOCK = "devenv.lock" # home vars @@ -183,7 +185,6 @@ def processes(): pass -DEVENV_DIR = Path(os.getcwd()) / ".devenv" os.environ["DEVENV_DIR"] = str(DEVENV_DIR) DEVENV_GC = DEVENV_DIR / "gc" os.environ["DEVENV_GC"] = str(DEVENV_GC) diff --git a/src/modules/integrations/pre-commit.nix b/src/modules/integrations/pre-commit.nix index c2b9bb8f5..3dcbbae06 100644 --- a/src/modules/integrations/pre-commit.nix +++ b/src/modules/integrations/pre-commit.nix @@ -9,7 +9,6 @@ rootSrc = self; package = pkgs.pre-commit; tools = import (pre-commit-hooks + "/nix/call-tools.nix") pkgs; - excludes = [ ".devenv.flake.nix" ]; } ]; specialArgs = { inherit pkgs; }; From 461c9ef3bbdf4bbb69898f6fe99047ecfea7b9a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Mon, 19 Feb 2024 19:28:33 +0000 Subject: [PATCH 062/146] bump --- devenv.lock | 14 +++++++------- flake.lock | 6 +++--- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/devenv.lock b/devenv.lock index a8c6a23c1..7575a9f1e 100644 --- a/devenv.lock +++ b/devenv.lock @@ -30,11 +30,11 @@ "flake-compat_2": { "flake": false, "locked": { - "lastModified": 1673956053, - "narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=", + "lastModified": 1696426674, "owner": "edolstra", "repo": "flake-compat", - "rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9", + "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", + "treeHash": "2addb7b71a20a25ea74feeaf5c2f6a6b30898ecb", "type": "github" }, "original": { @@ -139,16 +139,16 @@ }, "nixpkgs-stable": { "locked": { - "lastModified": 1685801374, - "narHash": "sha256-otaSUoFEMM+LjBI1XL/xGB5ao6IwnZOXc47qhIgJe8U=", + "lastModified": 1708294118, "owner": "NixOS", "repo": "nixpkgs", - "rev": "c37ca420157f4abc31e26f436c1145f8951ff373", + "rev": "e0da498ad77ac8909a980f07eff060862417ccf7", + "treeHash": "6080d79e20d8f9fce719e518f10143595514df54", "type": "github" }, "original": { "owner": "NixOS", - "ref": "nixos-23.05", + "ref": "nixos-23.11", "repo": "nixpkgs", "type": "github" } diff --git a/flake.lock b/flake.lock index 1ac23b87e..6c9fbc3ee 100644 --- a/flake.lock +++ b/flake.lock @@ -98,11 +98,11 @@ "nixpkgs-regression": "nixpkgs-regression" }, "locked": { - "lastModified": 1708363659, - "narHash": "sha256-cFdUGJXVUNcrFkMwaxWEf1LJ1gdkJCuQDLL+Dhvw8uM=", + "lastModified": 1708370782, + "narHash": "sha256-kzlnSGScvfNbawzFp6jClFIEo/RJzzmJbnEWItOnkQc=", "owner": "domenkozar", "repo": "nix", - "rev": "cbd29b1d160f7bc71d850efb357346e0664895ad", + "rev": "3b944df09a1d3606f094bd4b32c56846efc99ddf", "type": "github" }, "original": { From 7de2eac3728bf9ba8c02a57e4e060670d1805a99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Tue, 20 Feb 2024 04:39:19 +0000 Subject: [PATCH 063/146] bump --- devenv.lock | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/devenv.lock b/devenv.lock index 7575a9f1e..182c4450a 100644 --- a/devenv.lock +++ b/devenv.lock @@ -14,11 +14,11 @@ "flake-compat": { "flake": false, "locked": { - "lastModified": 1673956053, - "narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=", + "lastModified": 1696426674, "owner": "edolstra", "repo": "flake-compat", - "rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9", + "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", + "treeHash": "2addb7b71a20a25ea74feeaf5c2f6a6b30898ecb", "type": "github" }, "original": { @@ -48,11 +48,11 @@ "systems": "systems" }, "locked": { - "lastModified": 1685518550, - "narHash": "sha256-o2d0KcvaXzTrPRIo0kOLV0/QXHhDQ5DTi+OxcjO8xqY=", + "lastModified": 1705309234, "owner": "numtide", "repo": "flake-utils", - "rev": "a1720a10a6cfe8234c0e93907ffe81be440f4cef", + "rev": "1ef2e671c3b0c19053962c07dbda38332dcebf26", + "treeHash": "80a852cb0f5bf29497a20ca4f37ba97b0e85c721", "type": "github" }, "original": { @@ -69,11 +69,11 @@ ] }, "locked": { - "lastModified": 1660459072, - "narHash": "sha256-8DFJjXG8zqoONA1vXtgeKXy68KdJL5UaXR8NtVMUbx8=", + "lastModified": 1703887061, "owner": "hercules-ci", "repo": "gitignore.nix", - "rev": "a20de23b925fd8264fd7fad6454652e142fd7f73", + "rev": "43e1aa1308018f37118e34d3a9cb4f5e75dc11d5", + "treeHash": "2dd7f68f94467b298f778300ce0248117d6c500e", "type": "github" }, "original": { @@ -91,11 +91,11 @@ "nixpkgs-regression": "nixpkgs-regression" }, "locked": { - "lastModified": 1708106917, + "lastModified": 1708370782, "owner": "domenkozar", "repo": "nix", - "rev": "d250aad325d4060a6bf6d24f613f4a9b2d8419f9", - "treeHash": "df402ee7b74f4bf0de9b174f42df34e31b9880bc", + "rev": "3b944df09a1d3606f094bd4b32c56846efc99ddf", + "treeHash": "401993a9735c08297eff0a593f6ac5adac68c8b9", "type": "github" }, "original": { @@ -107,11 +107,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1692494774, + "lastModified": 1708373374, "owner": "NixOS", "repo": "nixpkgs", - "rev": "3476a10478587dec90acb14ec6bde0966c545cc0", - "treeHash": "96162525b38e424adc09e55f362302401e9f1762", + "rev": "93e1c2d08467d1117ebac45689469613a9fe8453", + "treeHash": "a71be29ec9a1d906373bc8e8feac400a1bc378bf", "type": "github" }, "original": { @@ -124,10 +124,10 @@ "nixpkgs-regression": { "locked": { "lastModified": 1643052045, - "narHash": "sha256-uGJ0VXIhWKGXxkeNnq4TvV3CIOkUJ3PAoLZ3HMzNVMw=", "owner": "NixOS", "repo": "nixpkgs", "rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2", + "treeHash": "749c7b11668286627143f45b3f9078561a91980a", "type": "github" }, "original": { @@ -164,11 +164,11 @@ "nixpkgs-stable": "nixpkgs-stable" }, "locked": { - "lastModified": 1692274144, + "lastModified": 1708018599, "owner": "cachix", "repo": "pre-commit-hooks.nix", - "rev": "7e3517c03d46159fdbf8c0e5c97f82d5d4b0c8fa", - "treeHash": "afa8541829678435ff40faa2141bbe85bc567a75", + "rev": "5df5a70ad7575f6601d91f0efec95dd9bc619431", + "treeHash": "6b6519c2b58ad1e106d9633f0d1b490a70fc6980", "type": "github" }, "original": { @@ -188,10 +188,10 @@ "systems": { "locked": { "lastModified": 1681028828, - "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", "owner": "nix-systems", "repo": "default", "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "treeHash": "cce81f2a0f0743b2eb61bc2eb6c7adbe2f2c6beb", "type": "github" }, "original": { From 05ec1516dbd356b97cfc2b02420fdfe49eb3b858 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Tue, 20 Feb 2024 06:29:05 +0000 Subject: [PATCH 064/146] revert .devenv/flake.nix --- src/devenv/cli.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/devenv/cli.py b/src/devenv/cli.py index 6c949be97..a7a26deb9 100644 --- a/src/devenv/cli.py +++ b/src/devenv/cli.py @@ -47,7 +47,7 @@ DEVENV_DIR.mkdir(parents=True, exist_ok=True) MODULES_DIR = (SRC_DIR / "modules").resolve() FLAKE_FILE_TEMPL = Path(MODULES_DIR) / "flake.tmpl.nix" -FLAKE_FILE = DEVENV_DIR / "flake.nix" +FLAKE_FILE = Path(os.getcwd()) / ".devenv.flake.nix" FLAKE_LOCK = "devenv.lock" # home vars From f7aa880dad2c921d0609ac7a85345af026631030 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Fri, 21 Jul 2023 19:12:04 +0100 Subject: [PATCH 065/146] unpin python 3.7 for cloudflare & fix build --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index e2c5f21ed..23de520f3 100644 --- a/poetry.lock +++ b/poetry.lock @@ -627,9 +627,9 @@ doc = ["mkdocs-bootswatch (>=1,<2)", "mkdocs-minify-plugin (==0.5.*)", "pygments [package.source] type = "git" -url = "https://github.com/cachix/mkdocs-rss-plugin" -reference = "no-git" -resolved_reference = "017bdb52095703c79e0632f219b5adf9f212873c" +url = "https://github.com/Guts/mkdocs-rss-plugin" +reference = "feature/no-git-no-cry" +resolved_reference = "bac5e8935196011b4fb16c5076113d5e3ff13806" [[package]] name = "packaging" From 30c804551307d8d94ba066cc115273b299d63c96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Mon, 10 Jul 2023 11:27:33 +0100 Subject: [PATCH 066/146] Rewrite CLI in Python --- flake.nix | 4 ++++ poetry.lock | 22 +++++++++------------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/flake.nix b/flake.nix index b548f0091..0de7f0fad 100644 --- a/flake.nix +++ b/flake.nix @@ -26,6 +26,10 @@ url = "github:nix-community/poetry2nix"; inputs.nixpkgs.follows = "nixpkgs"; }; + inputs.poetry2nix = { + url = "github:nix-community/poetry2nix"; + inputs.nixpkgs.follows = "nixpkgs"; + }; outputs = { self, nixpkgs, pre-commit-hooks, nix, ... }@inputs: let diff --git a/poetry.lock b/poetry.lock index 23de520f3..4460fa52c 100644 --- a/poetry.lock +++ b/poetry.lock @@ -609,12 +609,14 @@ files = [ [[package]] name = "mkdocs-rss-plugin" -version = "1.5.0" +version = "1.8.0" description = "MkDocs plugin which generates a static RSS feed using git log and page.meta." optional = false -python-versions = ">=3.7, <4" -files = [] -develop = false +python-versions = ">=3.8, <4" +files = [ + {file = "mkdocs-rss-plugin-1.8.0.tar.gz", hash = "sha256:475bf4ea05cbe786af38d519b55352b1b2eb87597ad680fcbc309056864ed5c4"}, + {file = "mkdocs_rss_plugin-1.8.0-py2.py3-none-any.whl", hash = "sha256:0fa13c99730c1d3ad9ec05102ff3d148c9849396c40b30be789339d38722fa8f"}, +] [package.dependencies] GitPython = ">=3.1,<3.2" @@ -625,12 +627,6 @@ tzdata = {version = "==2022.*", markers = "python_version >= \"3.9\" and sys_pla dev = ["black", "feedparser (>=6.0,<6.1)", "flake8 (>=4,<5.1)", "pre-commit (>=2.10,<2.21)", "pytest-cov (==4.0.*)", "validator-collection (>=1.5,<1.6)"] doc = ["mkdocs-bootswatch (>=1,<2)", "mkdocs-minify-plugin (==0.5.*)", "pygments (>=2.5,<3)", "pymdown-extensions (>=7,<10)"] -[package.source] -type = "git" -url = "https://github.com/Guts/mkdocs-rss-plugin" -reference = "feature/no-git-no-cry" -resolved_reference = "bac5e8935196011b4fb16c5076113d5e3ff13806" - [[package]] name = "packaging" version = "23.2" @@ -1079,13 +1075,13 @@ test = ["flake8", "isort", "pytest"] [[package]] name = "tzdata" -version = "2022.7" +version = "2023.3" description = "Provider of IANA time zone data" optional = false python-versions = ">=2" files = [ - {file = "tzdata-2022.7-py2.py3-none-any.whl", hash = "sha256:2b88858b0e3120792a3c0635c23daf36a7d7eeeca657c323da299d2094402a0d"}, - {file = "tzdata-2022.7.tar.gz", hash = "sha256:fe5f866eddd8b96e9fcba978f8e503c909b19ea7efda11e52e39494bad3a7bfa"}, + {file = "tzdata-2023.3-py2.py3-none-any.whl", hash = "sha256:7e65763eef3120314099b6939b5546db7adce1e7d6f2e179e3df563c70511eda"}, + {file = "tzdata-2023.3.tar.gz", hash = "sha256:11ef1e08e54acb0d4f95bdb1be05da659673de4acbd21bf9c69e94cc5e907a3a"}, ] [[package]] From f75c105b401be5c56065af8a325ba1f9917ccc8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Thu, 27 Jul 2023 14:06:46 +0100 Subject: [PATCH 067/146] devenv inputs add --- src/modules/devenv-lib.nix | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 src/modules/devenv-lib.nix diff --git a/src/modules/devenv-lib.nix b/src/modules/devenv-lib.nix new file mode 100644 index 000000000..0dee070f5 --- /dev/null +++ b/src/modules/devenv-lib.nix @@ -0,0 +1,27 @@ +{ pkgs, lib, config, inputs }: + +{ + getInput = { name, url, attribute, follows ? [ ] }: + let + flags = lib.concatStringsSep " " (map (i: "--follows ${i}") follows); + yaml_follows = lib.concatStringsSep "\n " (map (i: "${i}:\n follows: ${i}") follows); + command = + if lib.versionAtLeast config.devenv.cliVersion "1.0" + then '' + run the following command: + + $ devenv inputs add ${name} ${url} ${flags} + '' + else '' + add the following to your devenv.yaml: + + ✨ devenv 1.0 made this easier: https://devenv.sh/getting-started/#installation ✨ + + inputs: + ${name}: + url: ${url} + ${if follows != [] then "inputs:\n ${yaml_follows}" else ""} + ''; + in + inputs.${name} or (throw "To use '${attribute}', ${command}\n\n"); +} From be14084f920afb7cdad78467a48b84516716d394 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Thu, 27 Jul 2023 14:10:32 +0100 Subject: [PATCH 068/146] cli --- src/devenv/cli.py | 3 +++ src/modules/devenv-lib.nix | 27 --------------------------- 2 files changed, 3 insertions(+), 27 deletions(-) delete mode 100644 src/modules/devenv-lib.nix diff --git a/src/devenv/cli.py b/src/devenv/cli.py index a7a26deb9..e7b77804f 100644 --- a/src/devenv/cli.py +++ b/src/devenv/cli.py @@ -179,6 +179,9 @@ def cli(ctx, offline, system, debugger, nix_flags, verbose): ctx.obj["gc_root"] = DEVENV_HOME_GC ctx.obj["gc_project"] = DEVENV_HOME_GC / str(int(time.time() * 1000)) +@cli.group() +def processes(): + pass @cli.group() def processes(): diff --git a/src/modules/devenv-lib.nix b/src/modules/devenv-lib.nix deleted file mode 100644 index 0dee070f5..000000000 --- a/src/modules/devenv-lib.nix +++ /dev/null @@ -1,27 +0,0 @@ -{ pkgs, lib, config, inputs }: - -{ - getInput = { name, url, attribute, follows ? [ ] }: - let - flags = lib.concatStringsSep " " (map (i: "--follows ${i}") follows); - yaml_follows = lib.concatStringsSep "\n " (map (i: "${i}:\n follows: ${i}") follows); - command = - if lib.versionAtLeast config.devenv.cliVersion "1.0" - then '' - run the following command: - - $ devenv inputs add ${name} ${url} ${flags} - '' - else '' - add the following to your devenv.yaml: - - ✨ devenv 1.0 made this easier: https://devenv.sh/getting-started/#installation ✨ - - inputs: - ${name}: - url: ${url} - ${if follows != [] then "inputs:\n ${yaml_follows}" else ""} - ''; - in - inputs.${name} or (throw "To use '${attribute}', ${command}\n\n"); -} From ced9ccffe78eaebe2a3bca349f0d8fc40050db3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Sat, 19 Aug 2023 12:25:56 +0100 Subject: [PATCH 069/146] Debug --- .github/workflows/buildtest.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/buildtest.yml b/.github/workflows/buildtest.yml index 7283c3064..600f16948 100644 --- a/.github/workflows/buildtest.yml +++ b/.github/workflows/buildtest.yml @@ -29,6 +29,8 @@ jobs: run: | nix profile remove '.*' nix profile install --accept-flake-config . + - name: Setup tmate session + uses: mxschmitt/action-tmate@v3 - name: Run tests run: | devenv ci From 1f9f741ea1f1631f387a878533927b2d58ba8983 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Sat, 19 Aug 2023 19:18:12 +0100 Subject: [PATCH 070/146] Disable macos-latest for now --- .github/workflows/buildtest.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/buildtest.yml b/.github/workflows/buildtest.yml index 600f16948..7283c3064 100644 --- a/.github/workflows/buildtest.yml +++ b/.github/workflows/buildtest.yml @@ -29,8 +29,6 @@ jobs: run: | nix profile remove '.*' nix profile install --accept-flake-config . - - name: Setup tmate session - uses: mxschmitt/action-tmate@v3 - name: Run tests run: | devenv ci From 226da3723741f62d1cbe8774bd71dfb69280532e Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 19 Feb 2024 00:19:24 -0500 Subject: [PATCH 071/146] sync with upstream --- flake.nix | 4 ---- poetry.lock | 22 +++++++++++++--------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/flake.nix b/flake.nix index 0de7f0fad..b548f0091 100644 --- a/flake.nix +++ b/flake.nix @@ -26,10 +26,6 @@ url = "github:nix-community/poetry2nix"; inputs.nixpkgs.follows = "nixpkgs"; }; - inputs.poetry2nix = { - url = "github:nix-community/poetry2nix"; - inputs.nixpkgs.follows = "nixpkgs"; - }; outputs = { self, nixpkgs, pre-commit-hooks, nix, ... }@inputs: let diff --git a/poetry.lock b/poetry.lock index 4460fa52c..e2c5f21ed 100644 --- a/poetry.lock +++ b/poetry.lock @@ -609,14 +609,12 @@ files = [ [[package]] name = "mkdocs-rss-plugin" -version = "1.8.0" +version = "1.5.0" description = "MkDocs plugin which generates a static RSS feed using git log and page.meta." optional = false -python-versions = ">=3.8, <4" -files = [ - {file = "mkdocs-rss-plugin-1.8.0.tar.gz", hash = "sha256:475bf4ea05cbe786af38d519b55352b1b2eb87597ad680fcbc309056864ed5c4"}, - {file = "mkdocs_rss_plugin-1.8.0-py2.py3-none-any.whl", hash = "sha256:0fa13c99730c1d3ad9ec05102ff3d148c9849396c40b30be789339d38722fa8f"}, -] +python-versions = ">=3.7, <4" +files = [] +develop = false [package.dependencies] GitPython = ">=3.1,<3.2" @@ -627,6 +625,12 @@ tzdata = {version = "==2022.*", markers = "python_version >= \"3.9\" and sys_pla dev = ["black", "feedparser (>=6.0,<6.1)", "flake8 (>=4,<5.1)", "pre-commit (>=2.10,<2.21)", "pytest-cov (==4.0.*)", "validator-collection (>=1.5,<1.6)"] doc = ["mkdocs-bootswatch (>=1,<2)", "mkdocs-minify-plugin (==0.5.*)", "pygments (>=2.5,<3)", "pymdown-extensions (>=7,<10)"] +[package.source] +type = "git" +url = "https://github.com/cachix/mkdocs-rss-plugin" +reference = "no-git" +resolved_reference = "017bdb52095703c79e0632f219b5adf9f212873c" + [[package]] name = "packaging" version = "23.2" @@ -1075,13 +1079,13 @@ test = ["flake8", "isort", "pytest"] [[package]] name = "tzdata" -version = "2023.3" +version = "2022.7" description = "Provider of IANA time zone data" optional = false python-versions = ">=2" files = [ - {file = "tzdata-2023.3-py2.py3-none-any.whl", hash = "sha256:7e65763eef3120314099b6939b5546db7adce1e7d6f2e179e3df563c70511eda"}, - {file = "tzdata-2023.3.tar.gz", hash = "sha256:11ef1e08e54acb0d4f95bdb1be05da659673de4acbd21bf9c69e94cc5e907a3a"}, + {file = "tzdata-2022.7-py2.py3-none-any.whl", hash = "sha256:2b88858b0e3120792a3c0635c23daf36a7d7eeeca657c323da299d2094402a0d"}, + {file = "tzdata-2022.7.tar.gz", hash = "sha256:fe5f866eddd8b96e9fcba978f8e503c909b19ea7efda11e52e39494bad3a7bfa"}, ] [[package]] From 617acc62260ddbd3f3ed84d3a808ff350f83f9d1 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Tue, 20 Feb 2024 03:19:14 -0500 Subject: [PATCH 072/146] container devenv is now owned and procs started by a nonroot user --- docs/reference/options.md | 15 ++++ src/modules/containers.nix | 145 +++++++++++++++++++++++++++++-------- 2 files changed, 129 insertions(+), 31 deletions(-) diff --git a/docs/reference/options.md b/docs/reference/options.md index d127dbaaf..2609a089f 100644 --- a/docs/reference/options.md +++ b/docs/reference/options.md @@ -430,6 +430,21 @@ signed integer +## containers.\.maxLayers + +The maximum number of layers created when the container is created. + +*Type:* +int + +*Default:* +` 1 ` + +*Declared by:* + - [https://github.com/cachix/devenv/blob/main/src/modules/containers.nix](https://github.com/cachix/devenv/blob/main/src/modules/containers.nix) + + + ## containers.\.name Name of the container. diff --git a/src/modules/containers.nix b/src/modules/containers.nix index 43b7ddca3..b98bd42c5 100644 --- a/src/modules/containers.nix +++ b/src/modules/containers.nix @@ -21,8 +21,9 @@ let attribute = "containers"; }; shell = mk-shell-bin.lib.mkShellBin { drv = config.shell; nixpkgs = pkgs; }; + bash = "${pkgs.bashInteractive}/bin/bash"; mkEntrypoint = cfg: pkgs.writeScript "entrypoint" '' - #!${pkgs.bash}/bin/bash + #!${bash} export PATH=/bin @@ -31,45 +32,128 @@ let # expand any envvars before exec cmd="`echo "$@"|${pkgs.envsubst}/bin/envsubst`" - ${pkgs.bash}/bin/bash -c "$cmd" + ${bash} -c "$cmd" ''; + user = "user"; + group = "user"; + uid = "1000"; + gid = "1000"; + homeDir = "/env"; + + mkHome = path: (pkgs.runCommand "devenv-container-home" { } '' + mkdir -p $out${homeDir} + cp -R ${path}/* $out${homeDir}/ + ''); + + mkMultiHome = paths: map mkHome paths; + + homeRoots = cfg: ( + if (builtins.typeOf cfg.copyToRoot == "list") + then cfg.copyToRoot + else [ cfg.copyToRoot ] + ); + + mkTmp = (pkgs.runCommand "devenv-container-tmp" { } '' + mkdir -p $out/tmp + ''); + + mkEtc = (pkgs.runCommand "devenv-container-etc" { } '' + mkdir -p $out/etc/pam.d + + echo "root:x:0:0:System administrator:/root:${bash}" > \ + $out/etc/passwd + echo "${user}:x:${uid}:${gid}::${homeDir}:${bash}" >> \ + $out/etc/passwd + + echo "root:!x:::::::" > $out/etc/shadow + echo "${user}:!x:::::::" >> $out/etc/shadow + + echo "root:x:0:" > $out/etc/group + echo "${group}:x:${gid}:" >> $out/etc/group + + cat > $out/etc/pam.d/other < + # mkCopyScript = cfg: pkgs.writeScript "copy-container" '' container=$1 shift - - if [[ "$1" == "" ]]; then + if [[ "$1" == false ]]; then registry=${cfg.registry} else registry="$1" @@ -141,6 +225,12 @@ let default = "docker://"; }; + maxLayers = lib.mkOption { + type = types.nullOr types.int; + description = "Maximum number of container layers created."; + default = 1; + }; + isBuilding = lib.mkOption { type = types.bool; default = false; @@ -163,18 +253,11 @@ let type = types.package; internal = true; default = pkgs.writeScript "docker-run" '' - #!${pkgs.bash}/bin/bash + #!${bash} docker run -it ${config.name}:${config.version} "$@" ''; }; - - maxLayers = lib.mkOption { - type = types.int; - description = "the maximum number of layers to create."; - defaultText = lib.literalExpression "1"; - default = 1; - }; }; }); in @@ -201,7 +284,7 @@ in containers.shell = { name = lib.mkDefault "shell"; - startupCommand = lib.mkDefault "bash"; + startupCommand = lib.mkDefault bash; }; containers.processes = { @@ -213,7 +296,7 @@ in containers.${envContainerName}.isBuilding = true; }) (lib.mkIf config.container.isBuilding { - devenv.root = lib.mkForce "/"; + devenv.root = lib.mkForce "${homeDir}"; }) ]; } From 0a2ddff2cbe462f7fca88e0c26e36e45ea862881 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Tue, 20 Feb 2024 03:22:50 -0500 Subject: [PATCH 073/146] remove shadowed function --- src/devenv/cli.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/devenv/cli.py b/src/devenv/cli.py index e7b77804f..b093b09d2 100644 --- a/src/devenv/cli.py +++ b/src/devenv/cli.py @@ -183,10 +183,6 @@ def cli(ctx, offline, system, debugger, nix_flags, verbose): def processes(): pass -@cli.group() -def processes(): - pass - os.environ["DEVENV_DIR"] = str(DEVENV_DIR) DEVENV_GC = DEVENV_DIR / "gc" From 94dc937ff398034aa7214f1997fe55d0fe4d15d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Tue, 20 Feb 2024 10:03:51 +0000 Subject: [PATCH 074/146] format --- src/devenv/cli.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/devenv/cli.py b/src/devenv/cli.py index b093b09d2..a7a26deb9 100644 --- a/src/devenv/cli.py +++ b/src/devenv/cli.py @@ -179,6 +179,7 @@ def cli(ctx, offline, system, debugger, nix_flags, verbose): ctx.obj["gc_root"] = DEVENV_HOME_GC ctx.obj["gc_project"] = DEVENV_HOME_GC / str(int(time.time() * 1000)) + @cli.group() def processes(): pass From 5ea46ef0f4508a5b22e45e08ff7024e8c1d89bf4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Tue, 20 Feb 2024 11:02:09 +0000 Subject: [PATCH 075/146] debug --- .github/workflows/buildtest.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/buildtest.yml b/.github/workflows/buildtest.yml index 7283c3064..8849bcd1b 100644 --- a/.github/workflows/buildtest.yml +++ b/.github/workflows/buildtest.yml @@ -29,6 +29,9 @@ jobs: run: | nix profile remove '.*' nix profile install --accept-flake-config . + nix profile list + echo $PATH + which devenv - name: Run tests run: | devenv ci From 078554c41c0f29c0475064e269c6e51dffbf05fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Thu, 22 Feb 2024 07:05:44 +0000 Subject: [PATCH 076/146] fix ci? --- .github/workflows/buildtest.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/buildtest.yml b/.github/workflows/buildtest.yml index 8849bcd1b..ac39dbffe 100644 --- a/.github/workflows/buildtest.yml +++ b/.github/workflows/buildtest.yml @@ -104,7 +104,7 @@ jobs: { print } /^inputs:$/ { print " devenv:"; - print " url: path:../../src/modules"; + print " url: path:../../?dir=src/modules"; } ' ./examples/simple/devenv.yaml.orig > ./examples/simple/devenv.yaml nix profile remove '.*' From e0587373db368899c018aea5c819f3941762728a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Thu, 22 Feb 2024 07:06:38 +0000 Subject: [PATCH 077/146] bump nix --- flake.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/flake.lock b/flake.lock index 6c9fbc3ee..1ac91e162 100644 --- a/flake.lock +++ b/flake.lock @@ -98,11 +98,11 @@ "nixpkgs-regression": "nixpkgs-regression" }, "locked": { - "lastModified": 1708370782, - "narHash": "sha256-kzlnSGScvfNbawzFp6jClFIEo/RJzzmJbnEWItOnkQc=", + "lastModified": 1708577783, + "narHash": "sha256-92xq7eXlxIT5zFNccLpjiP7sdQqQI30Gyui2p/PfKZM=", "owner": "domenkozar", "repo": "nix", - "rev": "3b944df09a1d3606f094bd4b32c56846efc99ddf", + "rev": "ecd0af0c1f56de32cbad14daa1d82a132bf298f8", "type": "github" }, "original": { From de506ee364da82244255120d3f8164ba60caa2d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Fri, 23 Feb 2024 03:53:14 +0000 Subject: [PATCH 078/146] containers are only supported on linux --- devenv.nix | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/devenv.nix b/devenv.nix index 220372d33..eccd4a528 100644 --- a/devenv.nix +++ b/devenv.nix @@ -43,7 +43,7 @@ tmp="$(mktemp -d)" devenv init "$tmp" pushd "$tmp" - echo -e " devenv:\n url: path:${config.devenv.root}/src/modules" >> devenv.yaml + echo -e " devenv:\n url: path:${config.devenv.root}?dir=src/modules" >> devenv.yaml cat devenv.yaml devenv version devenv ci @@ -81,7 +81,10 @@ grep -F 'nix-develop started succesfully' <./console grep -F "$(${lib.getExe pkgs.hello})" <./console # Test that a container can be built - nix build --impure --accept-flake-config .#container-processes + if $(uname) == "Linux" + then + nix build --impure --accept-flake-config --show-trace .#container-processes + fi popd rm -rf "$tmp" ''; From 46acff0a44db6a5627b01b7a3e457a838f4f5c57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Fri, 23 Feb 2024 15:37:00 +0000 Subject: [PATCH 079/146] don't rely on profiles on ci --- .envrc | 4 ++++ .github/workflows/buildtest.yml | 29 ++++++++++------------------- 2 files changed, 14 insertions(+), 19 deletions(-) diff --git a/.envrc b/.envrc index 53b74fc41..648c747af 100755 --- a/.envrc +++ b/.envrc @@ -3,6 +3,10 @@ # Used by https://direnv.net set -euo pipefail +# Use our own last built devenv/nix in CLI +devenv_bin=$(nix build --print-out-paths --accept-flake-config) +PATH_add "$devenv_bin/bin" + # External users should use `source_url` to load this file source_env ./direnvrc diff --git a/.github/workflows/buildtest.yml b/.github/workflows/buildtest.yml index ac39dbffe..de08975bb 100644 --- a/.github/workflows/buildtest.yml +++ b/.github/workflows/buildtest.yml @@ -25,18 +25,12 @@ jobs: with: name: devenv authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}' - - name: "Reinstall devenv" - run: | - nix profile remove '.*' - nix profile install --accept-flake-config . - nix profile list - echo $PATH - which devenv + - run: nix build - name: Run tests run: | - devenv ci - devenv shell devenv-run-tests - devenv search ncdu | grep "pkgs\.ncdu" + ./result/bin/devenv ci + ./result/bin/devenv shell devenv-run-tests + ./result/bin/devenv search ncdu | grep "pkgs\.ncdu" pin: needs: build if: startsWith(github.ref, 'refs/tags/v') @@ -73,14 +67,13 @@ jobs: with: name: devenv authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}' - - run: | - nix profile remove '.*' - nix profile install --accept-flake-config . - name: Disable package aliases run: | mkdir -p ~/.config/nixpkgs echo '{ allowAliases = false; }' > ~/.config/nixpkgs/config.nix - - run: devenv test ${{ matrix.example }} + - run: | + nix build + ./result/bin/devenv test ${{ matrix.example }} direnv: name: direnv (${{ join(matrix.os) }}) needs: build @@ -133,9 +126,7 @@ jobs: with: name: devenv authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}' + - run: nix build - run: | - nix profile remove '.*' - nix profile install --accept-flake-config . - - run: | - nix shell nixpkgs#zsh -c zsh -c "$(which devenv) version" - nix shell nixpkgs#fish -c fish -c "$(which devenv) version" + nix shell nixpkgs#zsh -c zsh -c "./result/bin/devenv version" + nix shell nixpkgs#fish -c fish -c "./result/bin/devenv version" From 9b30c73f5d4efbed55dfd024a696096e6370f52f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Fri, 23 Feb 2024 16:10:32 +0000 Subject: [PATCH 080/146] fix ci? --- src/devenv/cli.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/devenv/cli.py b/src/devenv/cli.py index a7a26deb9..a2a245dc9 100644 --- a/src/devenv/cli.py +++ b/src/devenv/cli.py @@ -764,7 +764,6 @@ def test(ctx, debug, keep_going, exclude, names): level="info", ) - modules = os.path.join(pwd, "src/modules") if not os.path.exists("devenv.yaml"): write_yaml( strictyaml.as_document({"inputs": {}}, schema=schema) @@ -772,7 +771,7 @@ def test(ctx, debug, keep_going, exclude, names): os.chmod("devenv.yaml", 0o644) yaml = read_yaml() inputs = yaml.get("inputs", {}) - inputs["devenv"] = {"url": f"path:{modules}"} + inputs["devenv"] = {"url": f"path:{pwd}?dir=src/modules"} yaml["inputs"] = inputs write_yaml(yaml) From baeadb3065f735bf8893dcd33a954ff0039817dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Wed, 28 Feb 2024 06:45:17 +0000 Subject: [PATCH 081/146] Rewrite in Rust --- .devcontainer.json | 2 +- .envrc | 6 +- .github/workflows/buildtest.yml | 4 +- .gitignore | 6 +- Cargo.lock | 1961 +++++++++++++++++++ Cargo.toml | 6 + README.md | 40 +- build_cloudflare.sh | 4 +- devenv-run-tests/Cargo.toml | 7 + devenv-run-tests/src/main.rs | 110 ++ devenv.lock | 99 +- devenv.nix | 32 +- devenv.yaml | 13 +- devenv/Cargo.toml | 25 + devenv/init/.envrc | 3 + devenv/init/.gitignore | 9 + devenv/init/devenv.nix | 28 + {examples/gleam => devenv/init}/devenv.yaml | 0 devenv/src/command.rs | 160 ++ devenv/src/config.rs | 144 ++ devenv/src/flake.tmpl.nix | 103 + devenv/src/log.rs | 100 + devenv/src/main.rs | 1225 ++++++++++++ docs/getting-started.md | 4 +- docs/integrations/github-actions.md | 8 +- docs/pre-commit-hooks.md | 2 +- docs/reference/yaml-options.md | 6 + docs/tests.md | 86 +- examples/clickhouse/.test.sh | 6 +- examples/compose/devenv.nix | 8 + examples/compose/devenv.yaml | 3 + examples/compose/projectA/devenv.nix | 3 + examples/compose/projectB/devenv.nix | 3 + examples/compose/projectB/devenv.yaml | 6 + examples/dotenv/.env | 3 - examples/elasticmq/.test.sh | 2 +- examples/influxdb/.test.sh | 3 +- examples/mailpit/.test.sh | 2 +- examples/minio/.test.sh | 2 +- examples/phoenix/.test.sh | 21 +- examples/postgres-timescale/.test.sh | 2 +- examples/postgres/.test.sh | 5 +- examples/postgres/devenv.nix | 4 - examples/rabbitmq/.test.sh | 12 +- examples/rubyonrails/.test.sh | 2 +- examples/rust/app/Cargo.toml | 3 + examples/simple/.gitignore | 9 + examples/varnish/.test.sh | 2 +- flake.lock | 123 +- flake.nix | 4 - mkdocs.yml | 1 + package.nix | 51 +- poetry.lock | 1189 ----------- pyproject.toml | 38 - requirements.txt | 5 + src/devenv/__init__.py | 0 src/devenv/cli.py | 904 --------- src/devenv/log.py | 56 - src/devenv/yaml.py | 63 - src/modules/flake.tmpl.nix | 95 - src/modules/integrations/devcontainer.nix | 2 +- src/modules/integrations/dotenv.nix | 8 +- src/modules/integrations/pre-commit.nix | 3 + src/modules/languages/python.nix | 4 +- src/modules/processes.nix | 2 +- src/modules/tests.nix | 88 +- src/modules/top-level.nix | 1 - tests/clean/devenv.nix | 14 + tests/clean/devenv.yaml | 7 + tests/cli/.test.sh | 20 +- tests/cli/devenv.nix | 2 +- tests/cli/devenv.yaml | 11 + tests/dotenv/.setup.sh | 1 + {examples => tests}/dotenv/.test.sh | 0 {examples => tests}/dotenv/bar.env | 0 {examples => tests}/dotenv/devenv.nix | 0 {examples => tests}/dotenv/devenv.yaml | 0 tests/gitignore/.setup.sh | 2 + tests/gitignore/.test.sh | 7 + tests/gitignore/devenv.nix | 5 + tests/gitignore/devenv.yaml | 3 + tests/glibcLocales/devenv.lock | 156 ++ tests/glibcLocales/devenv.nix | 5 + tests/impure/devenv.nix | 5 + tests/impure/devenv.yaml | 1 + tests/permit-insecure/devenv.nix | 9 + tests/permit-insecure/devenv.yaml | 10 + tests/python-native-libs/.test.sh | 4 - tests/python-native-libs/devenv.nix | 8 - tests/python-native-libs/devenv.yaml | 4 +- tests/up-uses-shell/devenv.lock | 156 ++ tests/up-uses-shell/devenv.nix | 14 + 92 files changed, 4678 insertions(+), 2697 deletions(-) create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 devenv-run-tests/Cargo.toml create mode 100644 devenv-run-tests/src/main.rs create mode 100644 devenv/Cargo.toml create mode 100644 devenv/init/.envrc create mode 100644 devenv/init/.gitignore create mode 100644 devenv/init/devenv.nix rename {examples/gleam => devenv/init}/devenv.yaml (100%) create mode 100644 devenv/src/command.rs create mode 100644 devenv/src/config.rs create mode 100644 devenv/src/flake.tmpl.nix create mode 100644 devenv/src/log.rs create mode 100644 devenv/src/main.rs create mode 100644 examples/compose/devenv.nix create mode 100644 examples/compose/devenv.yaml create mode 100644 examples/compose/projectA/devenv.nix create mode 100644 examples/compose/projectB/devenv.nix create mode 100644 examples/compose/projectB/devenv.yaml delete mode 100644 examples/dotenv/.env create mode 100644 examples/simple/.gitignore delete mode 100644 poetry.lock delete mode 100644 pyproject.toml create mode 100644 requirements.txt delete mode 100644 src/devenv/__init__.py delete mode 100644 src/devenv/cli.py delete mode 100644 src/devenv/log.py delete mode 100644 src/devenv/yaml.py delete mode 100644 src/modules/flake.tmpl.nix create mode 100644 tests/clean/devenv.nix create mode 100644 tests/clean/devenv.yaml create mode 100644 tests/cli/devenv.yaml create mode 100755 tests/dotenv/.setup.sh rename {examples => tests}/dotenv/.test.sh (100%) rename {examples => tests}/dotenv/bar.env (100%) rename {examples => tests}/dotenv/devenv.nix (100%) rename {examples => tests}/dotenv/devenv.yaml (100%) create mode 100644 tests/gitignore/.setup.sh create mode 100755 tests/gitignore/.test.sh create mode 100644 tests/gitignore/devenv.nix create mode 100644 tests/gitignore/devenv.yaml create mode 100644 tests/glibcLocales/devenv.lock create mode 100644 tests/glibcLocales/devenv.nix create mode 100644 tests/impure/devenv.nix create mode 100644 tests/impure/devenv.yaml create mode 100644 tests/permit-insecure/devenv.nix create mode 100644 tests/permit-insecure/devenv.yaml create mode 100644 tests/up-uses-shell/devenv.lock create mode 100644 tests/up-uses-shell/devenv.nix diff --git a/.devcontainer.json b/.devcontainer.json index e3c39242c..a0ba06dc2 100644 --- a/.devcontainer.json +++ b/.devcontainer.json @@ -8,5 +8,5 @@ }, "image": "ghcr.io/cachix/devenv:latest", "overrideCommand": false, - "updateContentCommand": "devenv ci" + "updateContentCommand": "devenv test" } diff --git a/.envrc b/.envrc index 648c747af..cf905f7c4 100755 --- a/.envrc +++ b/.envrc @@ -4,10 +4,10 @@ set -euo pipefail # Use our own last built devenv/nix in CLI -devenv_bin=$(nix build --print-out-paths --accept-flake-config) -PATH_add "$devenv_bin/bin" +nix build --print-out-paths --accept-flake-config || echo "nix build failed, using previous build" +PATH_add "result/bin" # External users should use `source_url` to load this file source_env ./direnvrc -use devenv \ No newline at end of file +use devenv diff --git a/.github/workflows/buildtest.yml b/.github/workflows/buildtest.yml index de08975bb..4bc5343c6 100644 --- a/.github/workflows/buildtest.yml +++ b/.github/workflows/buildtest.yml @@ -13,7 +13,7 @@ jobs: strategy: fail-fast: false matrix: - os: [[ubuntu-latest], [macos-latest], [self-hosted, macOS], [self-hosted, linux, ARM64]] + os: [[self-hosted, linux, X64], [macos-latest], [self-hosted, macOS], [self-hosted, linux, ARM64]] runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v4 @@ -28,7 +28,7 @@ jobs: - run: nix build - name: Run tests run: | - ./result/bin/devenv ci + ./result/bin/devenv test ./result/bin/devenv shell devenv-run-tests ./result/bin/devenv search ncdu | grep "pkgs\.ncdu" pin: diff --git a/.gitignore b/.gitignore index 8de6048b7..ba54410a6 100644 --- a/.gitignore +++ b/.gitignore @@ -3,12 +3,12 @@ result .env .env.* .devenv* +.direnv* /.cache /.pre-commit-config.yaml # examples examples/rust/app/target -# Python -/.venv -*.pyc +# Rust +target diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 000000000..80784216c --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,1961 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "aho-corasick" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +dependencies = [ + "memchr", +] + +[[package]] +name = "ansiterm" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ab587f5395da16dd2e6939adf53dede583221b320cadfb94e02b5b7b9bf24cc" +dependencies = [ + "winapi", +] + +[[package]] +name = "anstream" +version = "0.6.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d96bd03f33fe50a863e394ee9718a706f988b9079b20c3784fb726e7678b62fb" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" + +[[package]] +name = "anstyle-parse" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" +dependencies = [ + "anstyle", + "windows-sys 0.52.0", +] + +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi 0.1.19", + "libc", + "winapi", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "backtrace" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "backtrace-ext" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "537beee3be4a18fb023b570f80e3ae28003db9167a751266b259926e25539d50" +dependencies = [ + "backtrace", +] + +[[package]] +name = "base64" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" + +[[package]] +name = "bumpalo" +version = "3.15.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ea184aa71bb362a1157c896979544cc23974e08fd265f29ea96b59f0b4a555b" + +[[package]] +name = "bytes" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" + +[[package]] +name = "castaway" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a17ed5635fc8536268e5d4de1e22e81ac34419e5f052d4d51f4e01dcc263fcc" +dependencies = [ + "rustversion", +] + +[[package]] +name = "cc" +version = "1.0.88" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02f341c093d19155a6e41631ce5971aac4e9a868262212153124c15fa22d1cdc" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "cfg_aliases" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" + +[[package]] +name = "clap" +version = "3.2.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123" +dependencies = [ + "atty", + "bitflags 1.3.2", + "clap_derive 3.2.25", + "clap_lex 0.2.4", + "indexmap 1.9.3", + "once_cell", + "strsim 0.10.0", + "termcolor", + "textwrap", +] + +[[package]] +name = "clap" +version = "4.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c918d541ef2913577a0f9566e9ce27cb35b6df072075769e0b26cb5a554520da" +dependencies = [ + "clap_builder", + "clap_derive 4.5.0", +] + +[[package]] +name = "clap_builder" +version = "4.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f3e7391dad68afb0c2ede1bf619f579a3dc9c2ec67f089baa397123a2f3d1eb" +dependencies = [ + "anstream", + "anstyle", + "clap_lex 0.7.0", + "strsim 0.11.0", +] + +[[package]] +name = "clap_derive" +version = "3.2.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae6371b8bdc8b7d3959e9cf7b22d4435ef3e79e138688421ec654acf8c81b008" +dependencies = [ + "heck", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "clap_derive" +version = "4.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "307bc0538d5f0f83b8248db3087aa92fe504e4691294d0c96c0eabc33f47ba47" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.51", +] + +[[package]] +name = "clap_lex" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" +dependencies = [ + "os_str_bytes", +] + +[[package]] +name = "clap_lex" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" + +[[package]] +name = "cli-table" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adfbb116d9e2c4be7011360d0c0bee565712c11e969c9609b25b619366dc379d" +dependencies = [ + "cli-table-derive", + "csv", + "termcolor", + "unicode-width", +] + +[[package]] +name = "cli-table-derive" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2af3bfb9da627b0a6c467624fb7963921433774ed435493b5c08a3053e829ad4" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "colorchoice" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" + +[[package]] +name = "compact_str" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f86b9c4c00838774a6d902ef931eff7470720c51d90c2e32cfe15dc304737b3f" +dependencies = [ + "castaway", + "cfg-if", + "itoa", + "ryu", + "static_assertions", +] + +[[package]] +name = "convert_case" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" + +[[package]] +name = "csv" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac574ff4d437a7b5ad237ef331c17ccca63c46479e5b5453eb8e10bb99a759fe" +dependencies = [ + "csv-core", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "csv-core" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5efa2b3d7902f4b634a20cae3c9c4e6209dc4779feb6863329607560143efa70" +dependencies = [ + "memchr", +] + +[[package]] +name = "darling" +version = "0.20.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54e36fcd13ed84ffdfda6f5be89b31287cbb80c439841fe69e04841435464391" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.20.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c2cf1c23a687a1feeb728783b993c4e1ad83d99f351801977dd809b48d0a70f" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim 0.10.0", + "syn 2.0.51", +] + +[[package]] +name = "darling_macro" +version = "0.20.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a668eda54683121533a393014d8692171709ff57a7d61f187b6e782719f8933f" +dependencies = [ + "darling_core", + "quote", + "syn 2.0.51", +] + +[[package]] +name = "devenv" +version = "1.0.0" +dependencies = [ + "ansiterm", + "clap 4.5.1", + "cli-table", + "dotlock", + "fs2", + "include_dir", + "indoc", + "miette", + "nix", + "regex", + "schematic", + "serde", + "serde_json", + "serde_yaml", + "tempdir", + "tracing", + "which", + "xdg", +] + +[[package]] +name = "devenv-run-tests" +version = "0.1.0" +dependencies = [ + "clap 3.2.25", +] + +[[package]] +name = "dirs" +version = "5.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" +dependencies = [ + "libc", + "option-ext", + "redox_users", + "windows-sys 0.48.0", +] + +[[package]] +name = "dotlock" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30c541575b952e53113caddb5be24869705052591b534ea11a81a3d4743416a3" +dependencies = [ + "tempfile", +] + +[[package]] +name = "dyn-clone" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" + +[[package]] +name = "either" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" + +[[package]] +name = "encoding_rs" +version = "0.8.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "errno" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "fastrand" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "form_urlencoded" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "fs2" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "fuchsia-cprng" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" + +[[package]] +name = "futures-channel" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +dependencies = [ + "futures-core", +] + +[[package]] +name = "futures-core" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" + +[[package]] +name = "futures-io" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" + +[[package]] +name = "futures-sink" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" + +[[package]] +name = "futures-task" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" + +[[package]] +name = "futures-util" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +dependencies = [ + "futures-core", + "futures-io", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "garde" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5fa8fb3ffe035745c6194540b2064b2fe275f32367fbb4eb026024b7921e2e5" +dependencies = [ + "compact_str", + "garde_derive", + "once_cell", + "regex", + "smallvec", +] + +[[package]] +name = "garde_derive" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cf62650515830c41553b72bd49ec20fb120226f9277c7f2847f071cf998325b" +dependencies = [ + "proc-macro2", + "quote", + "regex", + "syn 2.0.51", +] + +[[package]] +name = "getrandom" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "gimli" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" + +[[package]] +name = "h2" +version = "0.3.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb2c4422095b67ee78da96fbb51a4cc413b3b25883c7717ff7ca1ab31022c9c9" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap 2.2.3", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "hashbrown" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "hermit-abi" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "379dada1584ad501b383485dd706b8afb7a70fcbc7f4da7d780638a5a6124a60" + +[[package]] +name = "home" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "http" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" +dependencies = [ + "bytes", + "http", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "hyper" +version = "0.14.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "idna" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "include_dir" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18762faeff7122e89e0857b02f7ce6fcc0d101d5e9ad2ad7846cc01d61b7f19e" +dependencies = [ + "include_dir_macros", +] + +[[package]] +name = "include_dir_macros" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b139284b5cf57ecfa712bcc66950bb635b31aff41c188e8a4cfc758eca374a3f" +dependencies = [ + "proc-macro2", + "quote", +] + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", +] + +[[package]] +name = "indexmap" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "233cf39063f058ea2caae4091bf4a3ef70a653afbc026f5c4a4135d114e3c177" +dependencies = [ + "equivalent", + "hashbrown 0.14.3", + "serde", +] + +[[package]] +name = "indoc" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e186cfbae8084e513daff4240b4797e342f988cecda4fb6c939150f96315fd8" + +[[package]] +name = "ipnet" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" + +[[package]] +name = "is_ci" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7655c9839580ee829dfacba1d1278c2b7883e50a277ff7541299489d6bdfdc45" + +[[package]] +name = "itoa" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" + +[[package]] +name = "js-sys" +version = "0.3.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "406cda4b368d531c842222cf9d2600a9a4acce8d29423695379c6868a143a9ee" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "libc" +version = "0.2.153" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" + +[[package]] +name = "libredox" +version = "0.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8" +dependencies = [ + "bitflags 2.4.2", + "libc", + "redox_syscall", +] + +[[package]] +name = "linux-raw-sys" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" + +[[package]] +name = "log" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" + +[[package]] +name = "markdown" +version = "1.0.0-alpha.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b0f0025e8c0d89b84d6dc63e859475e40e8e82ab1a08be0a93ad5731513a508" +dependencies = [ + "unicode-id", +] + +[[package]] +name = "memchr" +version = "2.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" + +[[package]] +name = "miette" +version = "7.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baed61d13cc3723ee6dbed730a82bfacedc60a85d81da2d77e9c3e8ebc0b504a" +dependencies = [ + "backtrace", + "backtrace-ext", + "miette-derive", + "owo-colors", + "supports-color", + "supports-hyperlinks", + "supports-unicode", + "terminal_size", + "textwrap", + "thiserror", + "unicode-width", +] + +[[package]] +name = "miette-derive" +version = "7.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f301c3f54f98abc6c212ee722f5e5c62e472a334415840669e356f04850051ec" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.51", +] + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "miniz_oxide" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" +dependencies = [ + "adler", +] + +[[package]] +name = "mio" +version = "0.8.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09" +dependencies = [ + "libc", + "wasi", + "windows-sys 0.48.0", +] + +[[package]] +name = "nix" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab2156c4fce2f8df6c499cc1c763e4394b7482525bf2a9701c9d79d215f519e4" +dependencies = [ + "bitflags 2.4.2", + "cfg-if", + "cfg_aliases", + "libc", +] + +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi 0.3.8", + "libc", +] + +[[package]] +name = "object" +version = "0.32.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "option-ext" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" + +[[package]] +name = "os_str_bytes" +version = "6.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2355d85b9a3786f481747ced0e0ff2ba35213a1f9bd406ed906554d7af805a1" + +[[package]] +name = "owo-colors" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "caff54706df99d2a78a5a4e3455ff45448d81ef1bb63c22cd14052ca0e993a3f" + +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "pin-project-lite" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro2" +version = "1.0.78" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293" +dependencies = [ + "fuchsia-cprng", + "libc", + "rand_core 0.3.1", + "rdrand", + "winapi", +] + +[[package]] +name = "rand_core" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" +dependencies = [ + "rand_core 0.4.2", +] + +[[package]] +name = "rand_core" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" + +[[package]] +name = "rdrand" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" +dependencies = [ + "rand_core 0.3.1", +] + +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "redox_users" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a18479200779601e498ada4e8c1e1f50e3ee19deb0259c25825a98b5603b2cb4" +dependencies = [ + "getrandom", + "libredox", + "thiserror", +] + +[[package]] +name = "regex" +version = "1.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5bb987efffd3c6d0d8f5f89510bb458559eab11e4f869acb20bf845e016259cd" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" + +[[package]] +name = "remove_dir_all" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" +dependencies = [ + "winapi", +] + +[[package]] +name = "reqwest" +version = "0.11.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6920094eb85afde5e4a138be3f2de8bbdf28000f0029e72c45025a56b042251" +dependencies = [ + "base64", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "ipnet", + "js-sys", + "log", + "mime", + "once_cell", + "percent-encoding", + "pin-project-lite", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "system-configuration", + "tokio", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "winreg", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + +[[package]] +name = "rustix" +version = "0.38.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949" +dependencies = [ + "bitflags 2.4.2", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.52.0", +] + +[[package]] +name = "rustversion" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" + +[[package]] +name = "ryu" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" + +[[package]] +name = "schemars" +version = "0.8.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45a28f4c49489add4ce10783f7911893516f15afe45d015608d41faca6bc4d29" +dependencies = [ + "dyn-clone", + "serde", + "serde_json", +] + +[[package]] +name = "schematic" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "709e1f0b0a3db267a98da09c89a7818e307cc8daea841e1079eb5f5a02591d54" +dependencies = [ + "garde", + "indexmap 2.2.3", + "markdown", + "miette", + "reqwest", + "schemars", + "schematic_macros", + "schematic_types", + "serde", + "serde_json", + "serde_path_to_error", + "serde_yaml", + "starbase_styles", + "thiserror", + "tracing", +] + +[[package]] +name = "schematic_macros" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31af7347544d97d00870a5865d2077dac07c069a5290c26215ddd1138b302590" +dependencies = [ + "convert_case", + "darling", + "proc-macro2", + "quote", + "syn 2.0.51", +] + +[[package]] +name = "schematic_types" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f3adfbe1c90a6a9643433e490ef1605c6a99f93be37e4c83fe5149fca9698c6" + +[[package]] +name = "serde" +version = "1.0.197" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.197" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.51", +] + +[[package]] +name = "serde_json" +version = "1.0.114" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0" +dependencies = [ + "indexmap 2.2.3", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_path_to_error" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebd154a240de39fdebcf5775d2675c204d7c13cf39a4c697be6493c8e734337c" +dependencies = [ + "itoa", + "serde", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_yaml" +version = "0.9.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fd075d994154d4a774f95b51fb96bdc2832b0ea48425c92546073816cda1f2f" +dependencies = [ + "indexmap 2.2.3", + "itoa", + "ryu", + "serde", + "unsafe-libyaml", +] + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "smallvec" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" + +[[package]] +name = "smawk" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7c388c1b5e93756d0c740965c41e8822f866621d41acbdf6336a6a168f8840c" + +[[package]] +name = "socket2" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05ffd9c0a93b7543e062e759284fcf5f5e3b098501104bfbdde4d404db792871" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "starbase_styles" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e06fa37c027e48ef341787d8c3d26cfbe8507aa4e2e8c61fcba82fe931bb598" +dependencies = [ + "dirs", + "owo-colors", + "supports-color", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "strsim" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01" + +[[package]] +name = "supports-color" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9829b314621dfc575df4e409e79f9d6a66a3bd707ab73f23cb4aa3a854ac854f" +dependencies = [ + "is_ci", +] + +[[package]] +name = "supports-hyperlinks" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c0a1e5168041f5f3ff68ff7d95dcb9c8749df29f6e7e89ada40dd4c9de404ee" + +[[package]] +name = "supports-unicode" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7401a30af6cb5818bb64852270bb722533397edcfc7344954a38f420819ece2" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.51" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ab617d94515e94ae53b8406c628598680aa0c9587474ecbe58188f7b345d66c" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + +[[package]] +name = "system-configuration" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "tempdir" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8" +dependencies = [ + "rand", + "remove_dir_all", +] + +[[package]] +name = "tempfile" +version = "3.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" +dependencies = [ + "cfg-if", + "fastrand", + "rustix", + "windows-sys 0.52.0", +] + +[[package]] +name = "termcolor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "terminal_size" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21bebf2b7c9e0a515f6e0f8c51dc0f8e4696391e6f1ff30379559f8365fb0df7" +dependencies = [ + "rustix", + "windows-sys 0.48.0", +] + +[[package]] +name = "textwrap" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9" +dependencies = [ + "smawk", + "unicode-linebreak", + "unicode-width", +] + +[[package]] +name = "thiserror" +version = "1.0.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e45bcbe8ed29775f228095caf2cd67af7a4ccf756ebff23a306bf3e8b47b24b" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a953cb265bef375dae3de6663da4d3804eee9682ea80d8e2542529b73c531c81" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.51", +] + +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.36.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "num_cpus", + "pin-project-lite", + "socket2", + "windows-sys 0.48.0", +] + +[[package]] +name = "tokio-util" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", + "tracing", +] + +[[package]] +name = "tower-service" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" + +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.51", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + +[[package]] +name = "unicode-bidi" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" + +[[package]] +name = "unicode-id" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1b6def86329695390197b82c1e244a54a131ceb66c996f2088a3876e2ae083f" + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-linebreak" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f" + +[[package]] +name = "unicode-normalization" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-segmentation" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" + +[[package]] +name = "unicode-width" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" + +[[package]] +name = "unsafe-libyaml" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab4c90930b95a82d00dc9e9ac071b4991924390d46cbd0dfe566148667605e4b" + +[[package]] +name = "url" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + +[[package]] +name = "utf8parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.91" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1e124130aee3fb58c5bdd6b639a0509486b0338acaaae0c84a5124b0f588b7f" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.91" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9e7e1900c352b609c8488ad12639a311045f40a35491fb69ba8c12f758af70b" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.51", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877b9c3f61ceea0e56331985743b13f3d25c406a7098d45180fb5f09bc19ed97" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.91" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b30af9e2d358182b5c7449424f017eba305ed32a7010509ede96cdc4696c46ed" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.91" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "642f325be6301eb8107a83d12a8ac6c1e1c54345a7ef1a9261962dfefda09e66" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.51", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.91" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f186bd2dcf04330886ce82d6f33dd75a7bfcf69ecf5763b89fcde53b6ac9838" + +[[package]] +name = "web-sys" +version = "0.3.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96565907687f7aceb35bc5fc03770a8a0471d82e479f25832f54a0e3f4b28446" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "which" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fa5e0c10bf77f44aac573e498d1a82d5fbd5e91f6fc0a99e7be4b38e85e101c" +dependencies = [ + "either", + "home", + "once_cell", + "rustix", + "windows-sys 0.52.0", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.3", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d380ba1dc7187569a8a9e91ed34b8ccfc33123bbacb8c0aed2d1ad7f3ef2dc5f" +dependencies = [ + "windows_aarch64_gnullvm 0.52.3", + "windows_aarch64_msvc 0.52.3", + "windows_i686_gnu 0.52.3", + "windows_i686_msvc 0.52.3", + "windows_x86_64_gnu 0.52.3", + "windows_x86_64_gnullvm 0.52.3", + "windows_x86_64_msvc 0.52.3", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68e5dcfb9413f53afd9c8f86e56a7b4d86d9a2fa26090ea2dc9e40fba56c6ec6" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8dab469ebbc45798319e69eebf92308e541ce46760b49b18c6b3fe5e8965b30f" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a4e9b6a7cac734a8b4138a4e1044eac3404d8326b6c0f939276560687a033fb" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28b0ec9c422ca95ff34a78755cfa6ad4a51371da2a5ace67500cf7ca5f232c58" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "704131571ba93e89d7cd43482277d6632589b18ecf4468f591fbae0a8b101614" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42079295511643151e98d61c38c0acc444e52dd42ab456f7ccfd5152e8ecf21c" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0770833d60a970638e989b3fa9fd2bb1aaadcf88963d1659fd7d9990196ed2d6" + +[[package]] +name = "winreg" +version = "0.50.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] + +[[package]] +name = "xdg" +version = "2.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "213b7324336b53d2414b2db8537e56544d981803139155afa84f76eeebb7a546" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 000000000..6e0add60e --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,6 @@ +[workspace] +resolver = "2" +members = [ + "devenv", + "devenv-run-tests", +] \ No newline at end of file diff --git a/README.md b/README.md index 5bd450ec8..b35be99e6 100644 --- a/README.md +++ b/README.md @@ -44,13 +44,39 @@ And ``devenv shell`` activates the environment. ## Commands -- ``devenv init``: Scaffold devenv.yaml, devenv.nix, and .envrc. -- ``devenv shell``: Activate the developer environment. -- ``devenv shell CMD ARGS``: Run CMD with ARGS in the developer environment. -- ``devenv update``: Update devenv.lock from devenv.yaml inputs. See http://devenv.sh/inputs/#locking-and-updating-inputs. -- ``devenv up``: Start processes in foreground. See http://devenv.sh/processes. -- ``devenv gc``: Remove old devenv generations. See http://devenv.sh/garbage-collection. -- ``devenv ci``: Build your developer environment and make sure all checks pass. +``` +$ devenv + +Usage: devenv [OPTIONS] + +Commands: + init Scaffold devenv.yaml, devenv.nix, .gitignore and .envrc. + shell Activate the developer environment. https://devenv.sh/basics/ + update Update devenv.lock from devenv.yaml inputs. http://devenv.sh/inputs/ + search Search for packages and options in nixpkgs. https://devenv.sh/packages/#searching-for-a-file + info Print information about this developer environment. + up Start processes in the foreground. https://devenv.sh/processes/ + processes Start or stop processes. + test Run tests. http://devenv.sh/tests/ + container Build, copy, or run a container. https://devenv.sh/containers/ + inputs Add an input to devenv.yaml. https://devenv.sh/inputs/ + gc Deletes previous shell generations. See http://devenv.sh/garbage-collection + build Build any attribute in devenv.nix. + version Print the version of devenv. + help Print this message or the help of the given subcommand(s) + +Options: + -v, --verbose + Enable debug log level. + -s, --system + [default: x86_64-linux] + -d, --nix-debugger + Enter Nix debugger on failure. + -n, --nix-option + Pass additional options to nix commands, see `man nix.conf` for full list. + -h, --help + Print help +``` ## Documentation diff --git a/build_cloudflare.sh b/build_cloudflare.sh index 4b6b8353c..923f5e6f5 100755 --- a/build_cloudflare.sh +++ b/build_cloudflare.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash set -xe -poetry install --with docs -poetry run -- mkdocs build +pip install -r requirements.txt +mkdocs build \ No newline at end of file diff --git a/devenv-run-tests/Cargo.toml b/devenv-run-tests/Cargo.toml new file mode 100644 index 000000000..8f3258ed6 --- /dev/null +++ b/devenv-run-tests/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "devenv-run-tests" +version = "0.1.0" +edition = "2018" + +[dependencies] +clap = { version = "3", features = ["derive"] } \ No newline at end of file diff --git a/devenv-run-tests/src/main.rs b/devenv-run-tests/src/main.rs new file mode 100644 index 000000000..a53b3fba9 --- /dev/null +++ b/devenv-run-tests/src/main.rs @@ -0,0 +1,110 @@ +use clap::Parser; +use std::fs; +use std::path::{Path, PathBuf}; + +#[derive(Parser, Debug)] +#[clap(author, version, about, long_about = None)] +struct Args { + #[clap(long, value_parser, help = "Exclude these tests.")] + exclude: Vec, + + #[clap(long, value_parser, help = "Only run these tests.")] + only: Vec, + + #[clap(value_parser, required = true)] + directories: Vec, +} + +struct TestResult { + name: String, + passed: bool, +} + +fn run_tests_in_directory(args: &Args) -> Result, Box> { + let cwd = std::env::current_dir()?; + let cwd = cwd.display(); + + let mut test_results = vec![]; + + for directory in &args.directories { + println!("Running in directory {}", directory.display()); + let paths = fs::read_dir(directory)?; + + for path in paths { + let path = path?.path(); + if path.is_dir() { + let dir_name_path = path.file_name().unwrap(); + let dir_name = dir_name_path.to_str().unwrap(); + + if !args.only.is_empty() { + let mut found = false; + for only in &args.only { + if path.as_path().ends_with(only) { + found = true; + break; + } + } + if !found { + continue; + } + } else { + for exclude in &args.exclude { + if path.as_path().ends_with(exclude) { + println!("Skipping {}", dir_name); + continue; + } + } + } + + println!(" Running {}", dir_name); + // if .setup.sh exists, run it + let setup_script = path.join(".setup.sh"); + if setup_script.exists() { + println!(" Running .setup.sh"); + let _ = std::process::Command::new("bash") + .arg(".setup.sh") + .current_dir(&path) + .status()?; + } + // TODO: use as a library + let status = std::process::Command::new("devenv") + .args([ + "--override-input", + "devenv", + &format!("path:{cwd}?dir=src/modules"), + ]) + .arg("test") + .current_dir(&path) + .status()?; + + let result = TestResult { + name: dir_name.to_string(), + passed: status.success(), + }; + test_results.push(result); + } + } + } + + Ok(test_results) +} + +fn main() -> Result<(), Box> { + let args = Args::parse(); + + let test_results = run_tests_in_directory(&args)?; + let num_tests = test_results.len(); + let num_failed_tests = test_results.iter().filter(|r| !r.passed).count(); + + println!(); + + for result in test_results { + if !result.passed { + println!("{}: Failed", result.name); + }; + } + + println!(); + println!("Ran {} tests, {} failed.", num_tests, num_failed_tests); + Ok(()) +} diff --git a/devenv.lock b/devenv.lock index 182c4450a..fd6e746b8 100644 --- a/devenv.lock +++ b/devenv.lock @@ -2,11 +2,13 @@ "nodes": { "devenv": { "locked": { - "path": "./src/modules", + "dir": "src/modules", + "path": ".", "type": "path" }, "original": { - "path": "./src/modules", + "dir": "src/modules", + "path": ".", "type": "path" }, "parent": [] @@ -48,11 +50,29 @@ "systems": "systems" }, "locked": { - "lastModified": 1705309234, + "lastModified": 1709126324, "owner": "numtide", "repo": "flake-utils", - "rev": "1ef2e671c3b0c19053962c07dbda38332dcebf26", - "treeHash": "80a852cb0f5bf29497a20ca4f37ba97b0e85c721", + "rev": "d465f4819400de7c8d874d50b982301f28a84605", + "treeHash": "f52cf07f5dc7208c6379eb10b7505fda4c429b88", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_2": { + "inputs": { + "systems": "systems_2" + }, + "locked": { + "lastModified": 1709126324, + "owner": "numtide", + "repo": "flake-utils", + "rev": "d465f4819400de7c8d874d50b982301f28a84605", + "treeHash": "f52cf07f5dc7208c6379eb10b7505fda4c429b88", "type": "github" }, "original": { @@ -69,11 +89,11 @@ ] }, "locked": { - "lastModified": 1703887061, + "lastModified": 1709087332, "owner": "hercules-ci", "repo": "gitignore.nix", - "rev": "43e1aa1308018f37118e34d3a9cb4f5e75dc11d5", - "treeHash": "2dd7f68f94467b298f778300ce0248117d6c500e", + "rev": "637db329424fd7e46cf4185293b9cc8c88c95394", + "treeHash": "ca14199cabdfe1a06a7b1654c76ed49100a689f9", "type": "github" }, "original": { @@ -91,11 +111,11 @@ "nixpkgs-regression": "nixpkgs-regression" }, "locked": { - "lastModified": 1708370782, + "lastModified": 1709513008, "owner": "domenkozar", "repo": "nix", - "rev": "3b944df09a1d3606f094bd4b32c56846efc99ddf", - "treeHash": "401993a9735c08297eff0a593f6ac5adac68c8b9", + "rev": "d61bd1c0dda0ec7466079531547bbafdf538ed71", + "treeHash": "450086431140936247448766aecc37b90f4ff39e", "type": "github" }, "original": { @@ -105,19 +125,40 @@ "type": "github" } }, + "nix2container": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1708764364, + "owner": "nlewo", + "repo": "nix2container", + "rev": "c891f90d2e3c48a6b33466c96e4851e0fc0cf455", + "treeHash": "747af167fd4350bd81b11ce824a756bb85b1757c", + "type": "github" + }, + "original": { + "owner": "nlewo", + "repo": "nix2container", + "type": "github" + } + }, "nixpkgs": { "locked": { - "lastModified": 1708373374, - "owner": "NixOS", + "lastModified": 1709280738, + "owner": "domenkozar", "repo": "nixpkgs", - "rev": "93e1c2d08467d1117ebac45689469613a9fe8453", - "treeHash": "a71be29ec9a1d906373bc8e8feac400a1bc378bf", + "rev": "0e172b739ff09c9dc652f2c9175ac0cf745cca81", + "treeHash": "ac7b46db5871ff29667646a328f426b945d3013c", "type": "github" }, "original": { - "owner": "NixOS", - "ref": "nixpkgs-unstable", + "owner": "domenkozar", "repo": "nixpkgs", + "rev": "0e172b739ff09c9dc652f2c9175ac0cf745cca81", "type": "github" } }, @@ -139,11 +180,11 @@ }, "nixpkgs-stable": { "locked": { - "lastModified": 1708294118, + "lastModified": 1709128929, "owner": "NixOS", "repo": "nixpkgs", - "rev": "e0da498ad77ac8909a980f07eff060862417ccf7", - "treeHash": "6080d79e20d8f9fce719e518f10143595514df54", + "rev": "c8e74c2f83fe12b4e5a8bd1abbc090575b0f7611", + "treeHash": "087dfee039daa2a8e336580010af1f20c03569d0", "type": "github" }, "original": { @@ -156,7 +197,7 @@ "pre-commit-hooks": { "inputs": { "flake-compat": "flake-compat_2", - "flake-utils": "flake-utils", + "flake-utils": "flake-utils_2", "gitignore": "gitignore", "nixpkgs": [ "nixpkgs" @@ -181,6 +222,7 @@ "inputs": { "devenv": "devenv", "nix": "nix", + "nix2container": "nix2container", "nixpkgs": "nixpkgs", "pre-commit-hooks": "pre-commit-hooks" } @@ -199,6 +241,21 @@ "repo": "default", "type": "github" } + }, + "systems_2": { + "locked": { + "lastModified": 1681028828, + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "treeHash": "cce81f2a0f0743b2eb61bc2eb6c7adbe2f2c6beb", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } } }, "root": "root", diff --git a/devenv.nix b/devenv.nix index eccd4a528..f7117e187 100644 --- a/devenv.nix +++ b/devenv.nix @@ -8,14 +8,17 @@ pkgs.xorg.libxcb pkgs.yaml2json pkgs.tesh - pkgs.python3Packages.black - ]; - - languages.nix.enable = true; + ] ++ lib.optionals pkgs.stdenv.isDarwin (with pkgs.darwin.apple_sdk; [ + frameworks.SystemConfiguration + ]); + + #languages.nix.enable = true; + # for cli + languages.rust.enable = true; + # for docs languages.python.enable = true; - languages.python.poetry.enable = true; - languages.python.poetry.install.installRootPackage = true; - languages.python.poetry.install.groups = [ "docs" ]; + languages.python.venv.enable = true; + languages.python.venv.requirements = ./requirements.txt; devcontainer.enable = true; devcontainer.settings.customizations.vscode.extensions = [ "jnoortheen.nix-ide" ]; @@ -31,7 +34,7 @@ echo assuming you bumped the version in mkdocs.yml, populating src/modules/latest-version cat mkdocs.yml | yaml2json | jq -r '.extra.devenv.version' > src/modules/latest-version ''; - scripts.devenv-run-tests.exec = '' + scripts.devenv-test-cli.exec = '' set -xe set -o pipefail @@ -43,11 +46,8 @@ tmp="$(mktemp -d)" devenv init "$tmp" pushd "$tmp" - echo -e " devenv:\n url: path:${config.devenv.root}?dir=src/modules" >> devenv.yaml - cat devenv.yaml devenv version - devenv ci - devenv test + devenv test --override-input devenv path:${config.devenv.root}?dir=src/modules popd rm -rf "$tmp" @@ -121,8 +121,9 @@ pre-commit.hooks = { nixpkgs-fmt.enable = true; - shellcheck.enable = true; - black.enable = true; + #shellcheck.enable = true; + clippy.enable = true; + rustfmt.enable = true; #markdownlint.enable = true; }; pre-commit.settings.markdownlint.config = { @@ -132,7 +133,4 @@ MD033 = false; MD034 = false; }; - - tests = config.lib.mkTests ./examples - // config.lib.mkTests ./tests; } diff --git a/devenv.yaml b/devenv.yaml index 01be806ad..4ba91d45e 100644 --- a/devenv.yaml +++ b/devenv.yaml @@ -1,13 +1,18 @@ inputs: - nixpkgs: - url: github:NixOS/nixpkgs/nixpkgs-unstable + nix2container: + url: github:nlewo/nix2container + inputs: + nixpkgs: + follows: nixpkgs + devenv: + url: path:.?dir=src/modules nix: url: github:domenkozar/nix/devenv-2.21 inputs: nixpkgs: follows: nixpkgs - devenv: - url: path:./src/modules + nixpkgs: + url: github:domenkozar/nixpkgs/0e172b739ff09c9dc652f2c9175ac0cf745cca81 pre-commit-hooks: url: github:cachix/pre-commit-hooks.nix inputs: diff --git a/devenv/Cargo.toml b/devenv/Cargo.toml new file mode 100644 index 000000000..e6dfcda3e --- /dev/null +++ b/devenv/Cargo.toml @@ -0,0 +1,25 @@ +[package] +name = "devenv" +version = "1.0.0" +edition = "2021" +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +ansiterm = "0.12.2" +clap = { version = "4.5.1", features = ["derive", "cargo"] } +cli-table = "0.4.7" +dotlock = "0.5.0" +fs2 = "0.4.3" +include_dir = "0.7.3" +indoc = "2.0.4" +miette = { version = "7.1.0", features = ["fancy"] } +nix = { version = "0.28.0", features = ["signal"] } +regex = "1.10.3" +schematic = { version = "0.14.3", features = ["schema", "yaml", "renderer_template", "renderer_json_schema"] } +serde = "1.0.197" +serde_json = "1.0.114" +serde_yaml = "0.9.32" +tempdir = "0.3.7" +tracing = "0.1.40" +which = "6.0.0" +xdg = "2.5.2" diff --git a/devenv/init/.envrc b/devenv/init/.envrc new file mode 100644 index 000000000..6de8a8acd --- /dev/null +++ b/devenv/init/.envrc @@ -0,0 +1,3 @@ +source_url "https://raw.githubusercontent.com/cachix/devenv/d1f7b48e35e6dee421cfd0f51481d17f77586997/direnvrc" "sha256-YBzqskFZxmNb3kYVoKD9ZixoPXJh1C9ZvTLGFRkauZ0=" + +use devenv \ No newline at end of file diff --git a/devenv/init/.gitignore b/devenv/init/.gitignore new file mode 100644 index 000000000..4d058db7d --- /dev/null +++ b/devenv/init/.gitignore @@ -0,0 +1,9 @@ +# Devenv +.devenv* +devenv.local.nix + +# direnv +.direnv + +# pre-commit +.pre-commit-config.yaml diff --git a/devenv/init/devenv.nix b/devenv/init/devenv.nix new file mode 100644 index 000000000..ea2220e91 --- /dev/null +++ b/devenv/init/devenv.nix @@ -0,0 +1,28 @@ +{ pkgs, ... }: + +{ + # https://devenv.sh/basics/ + env.GREET = "devenv"; + + # https://devenv.sh/packages/ + packages = [ pkgs.git ]; + + # https://devenv.sh/scripts/ + scripts.hello.exec = "echo hello from $GREET"; + + enterShell = '' + hello + git --version + ''; + + # https://devenv.sh/languages/ + # languages.nix.enable = true; + + # https://devenv.sh/pre-commit-hooks/ + # pre-commit.hooks.shellcheck.enable = true; + + # https://devenv.sh/processes/ + # processes.ping.exec = "ping example.com"; + + # See full reference at https://devenv.sh/reference/options/ +} diff --git a/examples/gleam/devenv.yaml b/devenv/init/devenv.yaml similarity index 100% rename from examples/gleam/devenv.yaml rename to devenv/init/devenv.yaml diff --git a/devenv/src/command.rs b/devenv/src/command.rs new file mode 100644 index 000000000..99f47d9af --- /dev/null +++ b/devenv/src/command.rs @@ -0,0 +1,160 @@ +use crate::App; +use miette::{bail, Result}; +use std::env; +use std::os::unix::process::CommandExt; + +const NIX_FLAGS: [&str; 11] = [ + "--show-trace", + "--extra-experimental-features", + "nix-command", + "--extra-experimental-features", + "flakes", + // remove unnecessary warnings + "--option", + "warn-dirty", + "false", + // flake caching is too aggressive + "--option", + "eval-cache", + "false", +]; + +pub struct Options { + pub replace_shell: bool, + pub use_cachix: bool, + pub logging: bool, + pub dont_exit: bool, +} + +impl Default for Options { + fn default() -> Self { + Options { + replace_shell: false, + use_cachix: false, + logging: true, + dont_exit: false, + } + } +} + +impl App { + pub fn run_nix( + &mut self, + command: &str, + args: &[&str], + options: &Options, + ) -> Result { + let mut cmd = self.prepare_command(command, args)?; + + if options.replace_shell { + if self.cli.nix_debugger && command.ends_with("bin/nix") { + cmd.arg("--debugger"); + } + let error = cmd.exec(); + self.logger.error(&format!( + "Failed to replace shell with `{} {}`: {error}", + cmd.get_program().to_string_lossy(), + cmd.get_args() + .map(|arg| arg.to_str().unwrap()) + .collect::>() + .join(" ") + )); + bail!("Failed to replace shell") + } else { + let result = if options.logging { + cmd.stdin(std::process::Stdio::inherit()) + .stderr(std::process::Stdio::inherit()) + .output() + .expect("Failed to run command") + } else { + cmd.output().expect("Failed to run command") + }; + if !result.status.success() { + if options.logging { + println!(); + let code = match result.status.code() { + Some(code) => format!("with exit code {}", code), + None => "without exit code".to_string(), + }; + self.logger.error(&format!( + "Command `{} {}` failed {code} and produced the following output:\n{}\n{}", + cmd.get_program().to_string_lossy(), + cmd.get_args() + .map(|arg| arg.to_str().unwrap()) + .collect::>() + .join(" "), + String::from_utf8_lossy(&result.stdout), + String::from_utf8_lossy(&result.stderr), + )); + } + if self.cli.nix_debugger && command.ends_with("bin/nix") { + self.logger.info("Starting Nix debugger ..."); + cmd.arg("--debugger").exec(); + } + if !options.dont_exit { + bail!("Command failed") + } else { + Ok(result) + } + } else { + Ok(result) + } + } + } + + pub fn prepare_command( + &mut self, + command: &str, + args: &[&str], + ) -> Result { + let cmd = if command.starts_with("nix") { + let mut flags = NIX_FLAGS.to_vec(); + + // handle --nix-option key value + for chunk in self.cli.nix_option.chunks_exact(2) { + flags.push("--option"); + flags.push(&chunk[0]); + flags.push(&chunk[1]); + } + + flags.extend_from_slice(args); + + let mut cmd = match env::var("DEVENV_NIX") { + Ok(devenv_nix) => std::process::Command::new(format!("{devenv_nix}/bin/{command}")), + Err(_) => { + self.logger.error( + "$DEVENV_NIX is not set, but required as devenv doesn't work without a few Nix patches." + ); + self.logger.error( + "Please follow https://devenv.sh/getting-started/ to install devenv.", + ); + bail!("$DEVENV_NIX is not set") + } + }; + + if self.cli.impure || self.config.impure { + flags.push("--impure"); + } + + cmd.args(flags); + cmd + } else { + let mut cmd = std::process::Command::new(command); + cmd.args(args); + cmd + }; + + if self.cli.verbose { + self.logger.debug(&format!( + "Running command: {} {}", + command, + cmd.get_args() + .map(|arg| arg.to_str().unwrap()) + .collect::>() + .join(" ") + )); + } + + Ok(cmd) + } +} diff --git a/devenv/src/config.rs b/devenv/src/config.rs new file mode 100644 index 000000000..61383b801 --- /dev/null +++ b/devenv/src/config.rs @@ -0,0 +1,144 @@ +use miette::{IntoDiagnostic, Result}; +use schematic::{schema::JsonSchemaRenderer, schema::SchemaGenerator, ConfigLoader}; +use serde::{Deserialize, Serialize}; +use std::{collections::HashMap, path::Path}; + +const YAML_CONFIG: &str = "devenv.yaml"; + +#[derive(schematic::Config, Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] +#[config(rename_all = "camelCase")] +#[serde(rename_all = "camelCase")] +pub struct Input { + #[serde(skip_serializing_if = "Option::is_none", default)] + pub url: Option, + #[serde(skip_serializing_if = "is_true", default = "true_default")] + #[setting(default = true)] + pub flake: bool, + #[serde(skip_serializing_if = "Option::is_none", default)] + pub follows: Option, + #[serde(skip_serializing_if = "HashMap::is_empty", default)] + pub inputs: HashMap, + #[serde(skip_serializing_if = "Vec::is_empty", default)] + pub overlays: Vec, +} + +impl Input { + pub fn new() -> Self { + Input { + url: None, + flake: true, + follows: None, + inputs: HashMap::new(), + overlays: Vec::new(), + } + } +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct FlakeInput { + pub url: Option, + pub inputs: HashMap, + pub flake: bool, +} + +impl From<&Input> for FlakeInput { + fn from(input: &Input) -> Self { + FlakeInput { + url: input.url.clone(), + inputs: input.inputs.clone(), + flake: input.flake, + } + } +} + +fn true_default() -> bool { + true +} +fn false_default() -> bool { + false +} +fn is_true(b: &bool) -> bool { + *b +} + +fn is_false(b: &bool) -> bool { + !*b +} + +#[derive(schematic::Config, Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] +pub struct Clean { + pub enabled: bool, + pub keep: Vec, + // TODO: executables? +} + +#[derive(schematic::Config, Clone, Serialize, Debug)] +#[config(rename_all = "camelCase")] +#[serde(rename_all = "camelCase")] +pub struct Config { + #[serde(skip_serializing_if = "HashMap::is_empty", default)] + #[setting(nested)] + pub inputs: HashMap, + #[serde(skip_serializing_if = "is_false", default = "false_default")] + pub allow_unfree: bool, + #[serde(skip_serializing_if = "is_false", default = "false_default")] + pub allow_broken: bool, + #[serde(skip_serializing_if = "Vec::is_empty", default)] + pub imports: Vec, + #[serde(skip_serializing_if = "Vec::is_empty", default)] + pub permitted_insecure_packages: Vec, + #[serde(skip_serializing_if = "Option::is_none", default = "std::option::None")] + #[setting(nested)] + pub clean: Option, + #[serde(skip_serializing_if = "is_false", default = "false_default")] + pub impure: bool, +} + +pub fn write_json_schema() { + let mut generator = SchemaGenerator::default(); + generator.add::(); + generator + .generate("devenv.schema.json", JsonSchemaRenderer::default()) + .expect("can't generate schema"); +} + +impl Config { + pub fn load() -> Result { + let mut loader = ConfigLoader::::new(); + let file = Path::new(YAML_CONFIG); + let _ = loader.file_optional(file); + let result = loader.load().into_diagnostic(); + Ok(result?.config) + } + + pub fn write(&self) { + let yaml = serde_yaml::to_string(&self).unwrap(); + std::fs::write(YAML_CONFIG, yaml).expect("Failed to write devenv.yaml"); + } + + pub fn add_input(&mut self, name: &str, url: &str, follows: &[String]) { + let mut inputs = HashMap::new(); + + let mut input_names = self.inputs.clone(); + // we know we have a default for this one + input_names.insert(String::from("nixpkgs"), Input::new()); + + for follow in follows { + // check if it's not in self.inputs + match input_names.get(follow) { + Some(_) => { + let mut input = Input::new(); + input.follows = Some(follow.to_string()); + inputs.insert(follow.to_string(), input); + } + None => { + panic!("Input {follow} does not exist so it can't be followed."); + } + } + } + let mut input = Input::new(); + input.url = Some(url.to_string()); + input.inputs = inputs; + self.inputs.insert(name.to_string(), input); + } +} diff --git a/devenv/src/flake.tmpl.nix b/devenv/src/flake.tmpl.nix new file mode 100644 index 000000000..6d7d0ec30 --- /dev/null +++ b/devenv/src/flake.tmpl.nix @@ -0,0 +1,103 @@ +{ + inputs = + let + __DEVENV_VARS__ + in { + pre-commit-hooks.url = "github:cachix/pre-commit-hooks.nix"; + pre-commit-hooks.inputs.nixpkgs.follows = "nixpkgs"; + nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; + devenv.url = "github:cachix/devenv?dir=src/modules"; + } // (if builtins.pathExists (devenv_dotfile + "/flake.json") + then builtins.fromJSON (builtins.readFile (devenv_dotfile + "/flake.json")) + else { }); + + outputs = { nixpkgs, ... }@inputs: + let + __DEVENV_VARS__ + devenv = + if builtins.pathExists (devenv_dotfile + "/devenv.json") + then builtins.fromJSON (builtins.readFile (devenv_dotfile + "/devenv.json")) + else { }; + getOverlays = inputName: inputAttrs: + map + (overlay: + let + input = inputs.${inputName} or (throw "No such input `${inputName}` while trying to configure overlays."); + in + input.overlays.${overlay} or (throw "Input `${inputName}` has no overlay called `${overlay}`. Supported overlays: ${nixpkgs.lib.concatStringsSep ", " (builtins.attrNames input.overlays)}")) + inputAttrs.overlays or [ ]; + overlays = nixpkgs.lib.flatten (nixpkgs.lib.mapAttrsToList getOverlays (devenv.inputs or { })); + pkgs = import nixpkgs { + inherit system; + config = { + allowUnfree = devenv.allowUnfree or false; + allowBroken = devenv.allowBroken or false; + permittedInsecurePackages = devenv.permittedInsecurePackages or [ ]; + }; + inherit overlays; + }; + lib = pkgs.lib; + importModule = path: + if lib.hasPrefix "./" path + then if lib.hasSuffix ".nix" path + then ./. + (builtins.substring 1 255 path) + else ./. + (builtins.substring 1 255 path) + "/devenv.nix" + else if lib.hasPrefix "../" path + then throw "devenv: ../ is not supported for imports" + else + let + paths = lib.splitString "/" path; + name = builtins.head paths; + input = inputs.${name} or (throw "Unknown input ${name}"); + subpath = "/${lib.concatStringsSep "/" (builtins.tail paths)}"; + devenvpath = "${input}" + subpath + "/devenv.nix"; + in + if builtins.pathExists devenvpath + then devenvpath + else throw (devenvpath + " file does not exist for input ${name}."); + project = pkgs.lib.evalModules { + specialArgs = inputs // { inherit inputs pkgs; }; + modules = [ + (inputs.devenv.modules + /top-level.nix) + { + devenv.cliVersion = version; + devenv.root = devenv_root; + devenv.dotfile = pkgs.lib.mkForce (devenv_root + "/" + devenv_dotfile_string); + } + (if container_name != null then { + container.isBuilding = pkgs.lib.mkForce true; + containers.${container_name}.isBuilding = true; + } else { }) + ] ++ (map importModule (devenv.imports or [ ])) ++ [ + ./devenv.nix + (devenv.devenv or { }) + (if builtins.pathExists ./devenv.local.nix then ./devenv.local.nix else { }) + ]; + }; + config = project.config; + + options = pkgs.nixosOptionsDoc { + options = builtins.removeAttrs project.options [ "_module" ]; + # Unpack Nix types, e.g. literalExpression, mDoc. + transformOptions = + let isDocType = v: builtins.elem v [ "literalDocBook" "literalExpression" "literalMD" "mdDoc" ]; + in lib.attrsets.mapAttrs (_: v: + if v ? _type && isDocType v._type then + v.text + else if v ? _type && v._type == "derivation" then + v.name + else + v + ); + }; + in + { + packages."${system}" = { + optionsJSON = options.optionsJSON; + inherit (config) info procfileScript procfileEnv procfile; + ci = config.ciDerivation; + }; + devenv = config; + devShell."${system}" = config.shell; + }; + } diff --git a/devenv/src/log.rs b/devenv/src/log.rs new file mode 100644 index 000000000..2a028729e --- /dev/null +++ b/devenv/src/log.rs @@ -0,0 +1,100 @@ +use ansiterm::Colour::{Blue, DarkGray, Green, Red, Yellow}; +use std::io::Write; +use std::time::Instant; + +pub struct LogProgress { + message: String, + start: Option, + pub failed: bool, +} + +impl LogProgress { + pub fn new(message: &str, newline: bool) -> LogProgress { + let prefix = Blue.paint("•"); + print!("{} {} ...", prefix, message); + if newline { + println!(); + } + std::io::stdout().flush().unwrap(); + LogProgress { + message: message.to_string(), + start: Some(Instant::now()), + failed: false, + } + } +} + +impl Drop for LogProgress { + fn drop(&mut self) { + let duration = self.start.unwrap_or_else(Instant::now).elapsed(); + let prefix = if self.failed { + Red.paint("✖") + } else { + Green.paint("✔") + }; + println!( + "\r{} {} in {:.1}s.", + prefix, + self.message, + duration.as_secs_f32() + ); + } +} + +#[derive(PartialEq, Eq, PartialOrd, Ord)] +pub enum Level { + Error, + Warn, + Info, + Debug, +} + +pub struct Logger { + level: Level, +} + +impl Logger { + pub fn new(level: Level) -> Logger { + Logger { level } + } + + pub fn info(&self, message: &str) { + self.log(message, Level::Info); + } + + pub fn error(&self, message: &str) { + self.log(message, Level::Error); + } + + pub fn debug(&self, message: &str) { + self.log(message, Level::Debug); + } + + pub fn warn(&self, message: &str) { + self.log(message, Level::Warn); + } + + fn log(&self, message: &str, level: Level) { + if level > self.level { + return; + } + match level { + Level::Info => { + let prefix = Blue.paint("•"); + println!("{} {}", prefix, message); + } + Level::Error => { + let prefix = Red.paint("✖"); + println!("{} {}", prefix, message); + } + Level::Warn => { + let prefix = Yellow.paint("•"); + println!("{} {}", prefix, message); + } + Level::Debug => { + let prefix = DarkGray.paint("•"); + println!("{} {}", prefix, message); + } + } + } +} diff --git a/devenv/src/main.rs b/devenv/src/main.rs new file mode 100644 index 000000000..d671b3295 --- /dev/null +++ b/devenv/src/main.rs @@ -0,0 +1,1225 @@ +mod command; +mod config; +mod log; + +use clap::{crate_version, Parser, Subcommand}; +use cli_table::{print_stderr, Table, WithTitle}; +use include_dir::{include_dir, Dir}; +use miette::{bail, Result}; +use serde::Deserialize; +use std::collections::HashMap; +use std::os::unix::fs::symlink; +use std::str::FromStr; +use std::time::{SystemTime, UNIX_EPOCH}; +use std::{ + fs, + os::unix::{fs::PermissionsExt, process::CommandExt}, + path::{Path, PathBuf}, +}; + +// templates +const FLAKE_TMP: &str = include_str!("flake.tmpl.nix"); +const REQUIRED_FILES: [&str; 4] = ["devenv.nix", "devenv.yaml", ".envrc", ".gitignore"]; +const PROJECT_DIR: Dir = include_dir!("$CARGO_MANIFEST_DIR/init"); +// project vars +const DEVENV_FLAKE: &str = ".devenv.flake.nix"; + +#[derive(Parser)] +#[command( + color = clap::ColorChoice::Auto, + dont_delimit_trailing_values = true, + about = format!("https://devenv.sh {}: Fast, Declarative, Reproducible, and Composable Developer Environments", crate_version!()) +)] +struct Cli { + #[arg(short, long, help = "Enable debug log level.")] + verbose: bool, + + #[arg(short, long, default_value_t = default_system())] + system: String, + + #[arg(short, long, help = "Relax the hermeticity of the environment.")] + impure: bool, + + // TODO: --no-clean? + #[arg( + short, + long, + num_args = 0.., + value_delimiter = ',', + help = "Ignore existing environment variables when entering the shell. Pass a list of comma-separated environment variables to let through." + )] + clean: Option>, + + #[arg(short = 'd', long, help = "Enter Nix debugger on failure.")] + nix_debugger: bool, + + #[arg( + short, + long, + num_args = 2, + value_delimiter = ' ', + help = "Pass additional options to nix commands, see `man nix.conf` for full list." + )] + nix_option: Vec, + + #[arg( + short, + long, + num_args = 2, + value_delimiter = ' ', + help = "Override inputs in devenv.yaml." + )] + override_input: Vec, + + #[command(subcommand)] + command: Commands, +} + +#[derive(Subcommand, Clone)] +enum Commands { + #[command(about = "Scaffold devenv.yaml, devenv.nix, .gitignore and .envrc.")] + Init { target: Option }, + + #[command(about = "Activate the developer environment. https://devenv.sh/basics/")] + Shell { + cmd: Option, + args: Vec, + }, + + #[command(about = "Update devenv.lock from devenv.yaml inputs. http://devenv.sh/inputs/")] + Update { name: Option }, + + #[command( + about = "Search for packages and options in nixpkgs. https://devenv.sh/packages/#searching-for-a-file" + )] + Search { name: String }, + + #[command( + alias = "show", + about = "Print information about this developer environment." + )] + Info {}, + + #[command(about = "Start processes in the foreground. https://devenv.sh/processes/")] + Up { + #[arg(help = "Start a specific process.")] + process: Option, + + #[arg(short, long, help = "Start processes in the background.")] + detach: bool, + }, + + Processes { + #[command(subcommand)] + command: ProcessesCommand, + }, + + #[command(about = "Run tests. http://devenv.sh/tests/", alias = "ci")] + Test { + #[arg(short, long, help = "Don't override .devenv to a temporary directory.")] + dont_override_dotfile: bool, + }, + + Container { + #[arg(short, long)] + registry: Option, + + #[arg(long, hide = true)] + copy: bool, + + #[arg(long, hide = true)] + docker_run: bool, + + #[arg(short, long)] + copy_args: Vec, + + #[arg(hide = true)] + name: Option, + + #[command(subcommand)] + command: Option, + }, + + Inputs { + #[command(subcommand)] + command: InputsCommand, + }, + + #[command( + about = "Deletes previous shell generations. See http://devenv.sh/garbage-collection" + )] + Gc {}, + + #[command(about = "Build any attribute in devenv.nix.")] + Build { + #[arg(num_args=1..)] + attributes: Vec, + }, + + #[command(about = "Print the version of devenv.")] + Version {}, + + #[clap(hide = true)] + Assemble, + + #[clap(hide = true)] + PrintDevEnv { + #[arg(short, long)] + json: bool, + }, + + #[clap(hide = true)] + GenerateJSONSchema, +} + +#[derive(Subcommand, Clone)] +#[clap(about = "Start or stop processes.")] +enum ProcessesCommand { + #[command(alias = "start")] + Up { + process: Option, + + #[arg(short, long)] + detach: bool, + }, + + #[command(alias = "stop")] + Down {}, + // TODO: Status/Attach +} + +#[derive(Subcommand, Clone)] +#[clap(about = "Build, copy, or run a container. https://devenv.sh/containers/")] +enum ContainerCommand { + #[clap(about = "Build a container.")] + Build { name: String }, + + #[clap(about = "Copy a container.")] + Copy { name: String }, + + #[clap(about = "Run a container.")] + Run { name: String }, +} + +#[derive(Subcommand, Clone)] +#[clap(about = "Add an input to devenv.yaml. https://devenv.sh/inputs/")] +enum InputsCommand { + #[clap(about = "Add an input to devenv.yaml.")] + Add { + #[arg(help = "The name of the input.")] + name: String, + + #[arg( + help = "See https://devenv.sh/reference/yaml-options/#inputsnameurl for possible values." + )] + url: String, + + #[arg(short, long, help = "What inputs should follow your inputs?")] + follows: Vec, + }, +} + +struct App { + cli: Cli, + config: config::Config, + logger: log::Logger, + has_processes: Option, + container_name: Option, + // all kinds of paths + devenv_root: PathBuf, + devenv_dotfile: PathBuf, + devenv_dot_gc: PathBuf, + devenv_home_gc: PathBuf, +} + +fn main() -> Result<()> { + let cli = Cli::parse(); + + let level = if cli.verbose { + log::Level::Debug + } else { + log::Level::Info + }; + + let xdg_dirs = xdg::BaseDirectories::with_prefix("devenv").unwrap(); + xdg_dirs + .create_data_directory(Path::new("devenv")) + .expect("Failed to create DEVENV_HOME directory"); + let devenv_home = xdg_dirs.get_data_home(); + let devenv_home_gc = devenv_home.join("gc"); + std::fs::create_dir_all(&devenv_home_gc).expect("Failed to create DEVENV_HOME_GC directory"); + let devenv_root = std::env::current_dir().expect("Failed to get current directory"); + let devenv_dot_gc = devenv_root.join(".devenv").join("gc"); + std::fs::create_dir_all(&devenv_dot_gc).expect("Failed to create .devenv/gc directory"); + let devenv_dotfile = devenv_root.join(".devenv"); + let logger = log::Logger::new(level); + let mut config = config::Config::load()?; + for input in cli.override_input.chunks_exact(2) { + config.add_input(&input[0].clone(), &input[1].clone(), &[]); + } + + let mut app = App { + cli, + config, + has_processes: None, + logger, + container_name: None, + devenv_root, + devenv_dotfile, + devenv_dot_gc, + devenv_home_gc, + }; + + match app.cli.command.clone() { + Commands::Shell { cmd, args } => app.shell(&cmd, &args, true), + Commands::Test { + dont_override_dotfile, + } => app.test(dont_override_dotfile), + Commands::Version {} => Ok(println!("devenv {} ({})", crate_version!(), app.cli.system)), + Commands::Container { + registry, + copy, + docker_run, + copy_args, + name, + command, + } => { + app.container_name = name.clone(); + match name { + None => { + if let Some(c) = command { + match c { + ContainerCommand::Build { name } => { + app.container_name = Some(name.clone()); + let _ = app.container_build(&name)?; + } + ContainerCommand::Copy { name } => { + app.container_name = Some(name.clone()); + app.container_copy(&name, ©_args, registry.as_deref())?; + } + ContainerCommand::Run { name } => { + app.container_name = Some(name.clone()); + app.container_run(&name, ©_args, registry.as_deref())?; + } + } + } + } + Some(name) => { + match (copy, docker_run) { + (true, false) => { + app.logger.warn( + "--copy flag is deprecated, use `devenv container copy` instead", + ); + app.container_copy(&name, ©_args, registry.as_deref())?; + } + (_, true) => { + app.logger.warn( + "--docker-run flag is deprecated, use `devenv container run` instead", + ); + app.container_run(&name, ©_args, registry.as_deref())?; + } + _ => { + app.logger.warn("Calling without a subcommand is deprecated, use `devenv container build` instead"); + let _ = app.container_build(&name)?; + } + }; + } + }; + Ok(()) + } + Commands::Init { target } => app.init(&target), + Commands::Search { name } => app.search(&name), + Commands::Gc {} => app.gc(), + Commands::Info {} => app.info(), + Commands::Build { attributes } => app.build(&attributes), + Commands::Update { name } => app.update(&name), + Commands::Up { process, detach } => app.up(process.as_deref(), &detach), + Commands::Processes { command } => match command { + ProcessesCommand::Up { process, detach } => app.up(process.as_deref(), &detach), + ProcessesCommand::Down {} => app.down(), + }, + Commands::Inputs { command } => match command { + InputsCommand::Add { name, url, follows } => app.inputs_add(&name, &url, &follows), + }, + // hidden + Commands::Assemble => app.assemble(), + Commands::PrintDevEnv { json } => app.print_dev_env(json), + Commands::GenerateJSONSchema => { + config::write_json_schema(); + Ok(()) + } + } +} + +impl App { + fn processes_log(&self) -> PathBuf { + self.devenv_dotfile.join("processes.log") + } + + fn processes_pid(&self) -> PathBuf { + self.devenv_dotfile.join("processes.pid") + } + + fn init(&self, target: &Option) -> Result<()> { + let target = target + .clone() + .unwrap_or_else(|| fs::canonicalize(".").expect("Failed to get current directory")); + + // create directory target if not exists + if !target.exists() { + std::fs::create_dir_all(&target).expect("Failed to create target directory"); + } + + // fails if any of the required files already exists + for filename in REQUIRED_FILES { + let file_path = target.join(filename); + if file_path.exists() { + panic!("File already exists {}", file_path.display()); + } + } + + for filename in REQUIRED_FILES { + let path = PROJECT_DIR + .get_file(filename) + .unwrap_or_else(|| panic!("missing {} in the executable", filename)); + + // write path.contents to target/filename + let target_path = target.join(filename); + std::fs::write(target_path, path.contents()).expect("Failed to write file"); + + // check if direnv executable is available + let Ok(direnv) = which::which("direnv") else { + return Ok(()); + }; + + // run direnv allow + let status = std::process::Command::new(direnv) + .arg("allow") + .current_dir(&target) + .status() + .expect("Failed to run direnv allow"); + + if !status.success() { + match status.code() { + Some(code) => { + panic!("direnv allow failed with code: {code}!"); + } + None => { + panic!("direnv allow failed!"); + } + } + } + } + Ok(()) + } + + fn inputs_add(&mut self, name: &str, url: &str, follows: &[String]) -> Result<()> { + self.config.add_input(name, url, follows); + self.config.write(); + Ok(()) + } + + fn print_dev_env(&mut self, json: bool) -> Result<()> { + let (env, _) = self.get_dev_environment(json, false)?; + print!( + "{}", + String::from_utf8(env).expect("Failed to convert env to utf-8") + ); + Ok(()) + } + + fn shell(&mut self, cmd: &Option, args: &[String], replace_shell: bool) -> Result<()> { + let develop_args = self.prepare_shell(cmd, args)?; + + let options = command::Options { + replace_shell, + ..command::Options::default() + }; + + let develop_args = develop_args + .iter() + .map(|s| s.as_str()) + .collect::>(); + + self.run_nix("nix", &develop_args, &options)?; + Ok(()) + } + + fn prepare_shell(&mut self, cmd: &Option, args: &[String]) -> Result> { + self.assemble()?; + let (_, gc_root) = self.get_dev_environment(false, true)?; + + let mut develop_args = vec![ + "develop", + gc_root.to_str().expect("gc root should be utf-8"), + ]; + + let default_clean = config::Clean { + enabled: false, + keep: vec![], + }; + let config_clean = self.config.clean.as_ref().unwrap_or(&default_clean); + if self.cli.clean.is_some() || config_clean.enabled { + develop_args.push("--ignore-environment"); + + let keep = match &self.cli.clean { + Some(clean) => clean, + None => &config_clean.keep, + }; + + for env in keep { + develop_args.push("--keep"); + develop_args.push(env); + } + + develop_args.push("-c"); + develop_args.push("bash"); + develop_args.push("--norc"); + develop_args.push("--noprofile") + } + + match cmd { + Some(cmd) => { + develop_args.push("-c"); + develop_args.push(cmd); + let args = args.iter().map(|s| s.as_str()).collect::>(); + develop_args.extend_from_slice(&args); + } + None => { + self.logger.info("Entering shell"); + } + }; + + Ok(develop_args.into_iter().map(|s| s.to_string()).collect()) + } + + fn update(&mut self, input_name: &Option) -> Result<()> { + let msg = match input_name { + Some(input_name) => format!("Updating devenv.lock with input {input_name}"), + None => "Updating devenv.lock".to_string(), + }; + let _logprogress = log::LogProgress::new(&msg, true); + self.assemble()?; + + match input_name { + Some(input_name) => { + self.run_nix( + "nix", + &["flake", "lock", "--update-input", input_name], + &command::Options::default(), + )?; + } + None => { + self.run_nix("nix", &["flake", "update"], &command::Options::default())?; + } + } + Ok(()) + } + + fn container_build(&mut self, name: &str) -> Result { + let options = command::Options { + use_cachix: true, + ..command::Options::default() + }; + + let _logprogress = log::LogProgress::new(&format!("Building {name} container"), true); + + self.assemble()?; + + let container_store_path = self.run_nix( + "nix", + &[ + "build", + "--print-out-paths", + "--no-link", + &format!(".#devenv.containers.{name}.derivation"), + ], + &options, + )?; + + let container_store_path_string = String::from_utf8_lossy(&container_store_path.stdout) + .to_string() + .trim() + .to_string(); + println!("{}", container_store_path_string); + Ok(container_store_path_string) + } + + fn container_copy( + &mut self, + name: &str, + copy_args: &[String], + registry: Option<&str>, + ) -> Result<()> { + let spec = self.container_build(name)?; + + let options = command::Options { + use_cachix: true, + ..command::Options::default() + }; + + let _logprogress = log::LogProgress::new(&format!("Copying {name} container"), false); + + let copy_script = self.run_nix( + "nix", + &[ + "build", + "--print-out-paths", + "--no-link", + &format!(".#devenv.containers.{name}.copyScript"), + ], + &options, + )?; + + let copy_script = String::from_utf8_lossy(©_script.stdout) + .to_string() + .trim() + .to_string(); + + let copy_args = [ + spec, + registry.unwrap_or("false").to_string(), + copy_args.join(" "), + ]; + + self.logger + .info(&format!("Running {copy_script} {}", copy_args.join(" "))); + + let status = std::process::Command::new(copy_script) + .args(copy_args) + .status() + .expect("Failed to run copy script"); + + if !status.success() { + bail!("Failed to copy container") + } else { + Ok(()) + } + } + + fn container_run( + &mut self, + name: &str, + copy_args: &[String], + registry: Option<&str>, + ) -> Result<()> { + if registry.is_some() { + self.logger + .warn("Ignoring --registry flag when running container"); + }; + self.container_copy(name, copy_args, Some("docker-daemon:"))?; + + let options = command::Options { + use_cachix: true, + ..command::Options::default() + }; + + let _logprogress = log::LogProgress::new(&format!("Running {name} container"), false); + + let run_script = self.run_nix( + "nix", + &[ + "build", + "--print-out-paths", + "--no-link", + &format!(".#devenv.containers.{name}.dockerRun"), + ], + &options, + )?; + + let run_script = String::from_utf8_lossy(&run_script.stdout) + .to_string() + .trim() + .to_string(); + + let status = std::process::Command::new(run_script) + .status() + .expect("Failed to run container script"); + + if !status.success() { + bail!("Failed to run container") + } else { + Ok(()) + } + } + + fn gc(&mut self) -> Result<()> { + let start = std::time::Instant::now(); + + let (to_gc, removed_symlinks) = { + let _logprogress = log::LogProgress::new( + &format!( + "Removing non-existings symlinks in {} ...", + &self.devenv_home_gc.display() + ), + false, + ); + cleanup_symlinks(&self.devenv_home_gc) + }; + + self.logger + .info(&format!("Found {} active environments.", to_gc.len())); + self.logger.info(&format!( + "Deleted {} dangling environments (most likely due to previous GC).", + removed_symlinks.len() + )); + + { + let _logprogress = log::LogProgress::new( + "Running garbage collection (this process may take some time) ...", + false, + ); + let paths: Vec<&str> = to_gc + .iter() + .filter_map(|path_buf| path_buf.to_str()) + .collect(); + let args: Vec<&str> = ["store", "gc"] + .iter() + .chain(paths.iter()) + .copied() + .collect(); + self.run_nix("nix", &args, &command::Options::default())?; + } + + let (after_gc, _) = cleanup_symlinks(&self.devenv_home_gc); + let end = std::time::Instant::now(); + + println!(); + self.logger.info(&format!( + "Done. Successfully removed {} symlinks in {}s.", + to_gc.len() - after_gc.len(), + (end - start).as_secs_f32() + )); + Ok(()) + } + + fn search(&mut self, name: &str) -> Result<()> { + self.assemble()?; + + let options = self.run_nix( + "nix", + &[ + "--offline", + "build", + "--no-link", + "--print-out-paths", + ".#optionsJSON", + ], + &command::Options { + use_cachix: true, + ..command::Options::default() + }, + )?; + + let options_str = std::str::from_utf8(&options.stdout).unwrap().trim(); + let options_path = PathBuf::from_str(options_str) + .expect("options store path should be a utf-8") + .join("share") + .join("doc") + .join("nixos") + .join("options.json"); + let options_contents = fs::read(options_path).expect("Failed to read options.json"); + let options_json: OptionResults = + serde_json::from_slice(&options_contents).expect("Failed to parse options.json"); + + let options_results = options_json + .0 + .into_iter() + .filter(|(key, _)| key.contains(name)) + .map(|(key, value)| DevenvOptionResult { + name: key, + type_: value.type_, + default: value.default.unwrap_or_default(), + description: value.description, + }) + .collect::>(); + let results_options_count = options_results.len(); + + let search = self.run_nix( + "nix", + &["search", "--json", "nixpkgs", name], + &command::Options::default(), + )?; + let search_json: PackageResults = + serde_json::from_slice(&search.stdout).expect("Failed to parse search results"); + let search_results = search_json + .0 + .into_iter() + .map(|(key, value)| DevenvPackageResult { + name: format!( + "pkgs.{}", + key.split('.').skip(2).collect::>().join(".") + ), + version: value.version, + description: value.description.chars().take(80).collect::(), + }) + .collect::>(); + let search_results_count = search_results.len(); + + if !search_results.is_empty() { + print_stderr(search_results.with_title()).expect("Failed to print search results"); + } + + if !options_results.is_empty() { + print_stderr(options_results.with_title()).expect("Failed to print options results"); + } + + self.logger.info(&format!("Found {search_results_count} packages and {results_options_count} options for '{name}'.")); + Ok(()) + } + + fn has_processes(&mut self) -> Result { + if self.has_processes.is_none() { + let result = self.run_nix( + "nix", + &["eval", ".#devenv.processes", "--json"], + &command::Options::default(), + )?; + let processes = String::from_utf8_lossy(&result.stdout).to_string(); + self.has_processes = Some(processes.trim() != "{}"); + } + Ok(self.has_processes.unwrap()) + } + + fn test(&mut self, dont_override_dotfile: bool) -> Result<()> { + let tmpdir = tempdir::TempDir::new_in(&self.devenv_root, ".devenv") + .expect("Failed to create temporary directory"); + if !dont_override_dotfile { + self.logger.info(&format!( + "Overriding .devenv to {}", + tmpdir.path().file_name().unwrap().to_str().unwrap() + )); + self.devenv_dotfile = tmpdir.as_ref().to_path_buf(); + // TODO: don't add gc roots for tests + self.devenv_dot_gc = self.devenv_dotfile.join("gc"); + } + self.assemble()?; + + // collect tests + let test_script = { + let _logprogress = log::LogProgress::new("Building tests", false); + self.run_nix( + "nix", + &["build", ".#devenv.test", "--no-link", "--print-out-paths"], + &command::Options::default(), + )? + }; + + let test_script_string = String::from_utf8_lossy(&test_script.stdout) + .to_string() + .trim() + .to_string(); + if test_script_string.is_empty() { + self.logger.error("No tests found."); + tmpdir + .close() + .expect("Failed to remove temporary directory"); + bail!("No tests found"); + } + + if self.has_processes()? { + self.up(None, &true)?; + } + + let result = { + let _logprogress = log::LogProgress::new("Running tests", true); + + self.logger + .debug(&format!("Running command: {test_script_string}")); + + let develop_args = self.prepare_shell(&Some(test_script_string), &[])?; + let develop_args = develop_args + .iter() + .map(|s| s.as_str()) + .collect::>(); + let mut cmd = self.prepare_command("nix", &develop_args)?; + cmd.stdin(std::process::Stdio::inherit()); + cmd.stderr(std::process::Stdio::inherit()); + cmd.stdout(std::process::Stdio::inherit()); + cmd.output().expect("Failed to run tests") + }; + + if self.has_processes()? { + self.down()?; + } + + tmpdir + .close() + .expect("Failed to remove temporary directory"); + + if !result.status.success() { + self.logger.error("Tests failed :("); + bail!("Tests failed"); + } else { + self.logger.info("Tests passed :)"); + Ok(()) + } + } + + fn info(&mut self) -> Result<()> { + self.assemble()?; + + // TODO: use --json + let metadata = self.run_nix("nix", &["flake", "metadata"], &command::Options::default())?; + + let re = regex::Regex::new(r"(Inputs:.+)$").unwrap(); + let metadata_str = String::from_utf8_lossy(&metadata.stdout); + let inputs = match re.captures(&metadata_str) { + Some(captures) => captures.get(1).unwrap().as_str(), + None => "", + }; + + let info_ = self.run_nix( + "nix", + &["eval", "--raw", ".#info"], + &command::Options::default(), + )?; + println!("{}\n{}", inputs, &String::from_utf8_lossy(&info_.stdout)); + Ok(()) + } + + fn build(&mut self, attributes: &[String]) -> Result<()> { + self.assemble()?; + + let formatted_strings: Vec = attributes + .iter() + .map(|attr| format!("#.devenv.{}", attr)) + .collect(); + + let mut args: Vec<&str> = formatted_strings.iter().map(|s| s.as_str()).collect(); + + args.insert(0, "build"); + self.run_nix("nix", &args, &command::Options::default())?; + Ok(()) + } + + fn add_gc(&mut self, name: &str, path: &Path) -> Result<()> { + self.run_nix( + "nix-store", + &[ + "--add-root", + self.devenv_dot_gc.join(name).to_str().unwrap(), + "-r", + path.to_str().unwrap(), + ], + &command::Options::default(), + )?; + let link_path = self + .devenv_dot_gc + .join(format!("{}-{}", name, get_now_with_nanoseconds())); + symlink_force(&self.logger, path, &link_path); + Ok(()) + } + + fn up(&mut self, process: Option<&str>, detach: &bool) -> Result<()> { + self.assemble()?; + if !self.has_processes()? { + self.logger + .error("No 'processes' option defined: https://devenv.sh/processes/"); + bail!("No processes defined"); + } + + let proc_script_string: String; + { + let _logprogress = log::LogProgress::new("Building processes", true); + + let options = command::Options { + use_cachix: true, + ..command::Options::default() + }; + let proc_script = self.run_nix( + "nix", + &[ + "build", + "--no-link", + "--print-out-paths", + ".#procfileScript", + ], + &options, + )?; + + proc_script_string = String::from_utf8_lossy(&proc_script.stdout) + .to_string() + .trim() + .to_string(); + self.add_gc("procfilescript", Path::new(&proc_script_string))?; + } + + { + let _logprogress = log::LogProgress::new("Starting processes", false); + + let process = process.unwrap_or(""); + + let processes_script = self.devenv_dotfile.join("processes"); + let tui_enabled = if *detach { "0" } else { "1" }; + fs::write( + &processes_script, + indoc::formatdoc! {" + #!/usr/bin/env bash + export PC_TUI_ENABLED={tui_enabled} + exec {proc_script_string} {process} + "}, + ) + .expect("Failed to write PROCESSES_SCRIPT"); + + std::fs::set_permissions(&processes_script, std::fs::Permissions::from_mode(0o755)) + .expect("Failed to set permissions"); + + let args = + self.prepare_shell(&Some(processes_script.to_str().unwrap().to_string()), &[])?; + let args = args.iter().map(|s| s.as_str()).collect::>(); + let mut cmd = self.prepare_command("nix", &args)?; + + if *detach { + let log_file = std::fs::File::create(self.processes_log()) + .expect("Failed to create PROCESSES_LOG"); + let process = cmd + .stdout(log_file.try_clone().expect("Failed to clone Stdio")) + .stderr(log_file) + .spawn() + .expect("Failed to spawn process"); + + std::fs::write(self.processes_pid(), process.id().to_string()) + .expect("Failed to write PROCESSES_PID"); + self.logger.info(&format!("PID is {}", process.id())); + self.logger.info(&format!( + "See logs: $ tail -f {}", + self.processes_log().display() + )); + self.logger.info("Stop: $ devenv processes stop"); + } else { + cmd.exec(); + } + Ok(()) + } + } + + fn down(&self) -> Result<()> { + if !PathBuf::from(&self.processes_pid()).exists() { + self.logger.error("No processes running."); + bail!("No processes running"); + } + + let pid = std::fs::read_to_string(self.processes_pid()) + .expect("Failed to read PROCESSES_PID") + .parse::() + .expect("Failed to parse PROCESSES_PID"); + + self.logger + .info(&format!("Stopping process with PID {}", pid)); + + let pid = nix::unistd::Pid::from_raw(pid); + match nix::sys::signal::kill(pid, nix::sys::signal::Signal::SIGTERM) { + Ok(_) => {} + Err(_) => { + self.logger + .error(&format!("Process with PID {} not found.", pid)); + bail!("Process not found"); + } + } + + std::fs::remove_file(self.processes_pid()).expect("Failed to remove PROCESSES_PID"); + Ok(()) + } + + fn assemble(&mut self) -> Result<()> { + if !PathBuf::from("devenv.nix").exists() { + panic!(indoc::indoc! {" + File devenv.nix does not exist. To get started, run: + + $ devenv init + "}); + } + std::fs::create_dir_all(&self.devenv_dot_gc) + .unwrap_or_else(|_| panic!("Failed to create {}", self.devenv_dot_gc.display())); + + let mut flake_inputs = HashMap::new(); + for (input, attrs) in self.config.inputs.iter() { + flake_inputs.insert(input.clone(), config::FlakeInput::from(attrs)); + } + fs::write( + self.devenv_dotfile.join("flake.json"), + serde_json::to_string(&flake_inputs).unwrap(), + ) + .expect("Failed to write flake.json"); + fs::write( + self.devenv_dotfile.join("devenv.json"), + serde_json::to_string(&self.config).unwrap(), + ) + .expect("Failed to write devenv.json"); + fs::write( + self.devenv_dotfile.join("imports.txt"), + self.config.imports.join("\n"), + ) + .expect("Failed to write imports.txt"); + + // create flake.devenv.nix + let vars = indoc::formatdoc!( + "version = \"{}\"; + system = \"{}\"; + devenv_root = \"{}\"; + devenv_dotfile = ./{}; + devenv_dotfile_string = \"{}\"; + container_name = {}; + ", + crate_version!(), + self.cli.system, + self.devenv_root.display(), + self.devenv_dotfile.file_name().unwrap().to_str().unwrap(), + self.devenv_dotfile.file_name().unwrap().to_str().unwrap(), + self.container_name + .as_deref() + .map(|s| format!("\"{}\"", s)) + .unwrap_or_else(|| "null".to_string()) + ); + let flake = FLAKE_TMP.replace("__DEVENV_VARS__", &vars); + std::fs::write(DEVENV_FLAKE, flake).expect("Failed to write flake.nix"); + Ok(()) + } + + fn get_dev_environment(&mut self, json: bool, logging: bool) -> Result<(Vec, PathBuf)> { + self.assemble()?; + let _logprogress = if logging { + Some(log::LogProgress::new("Building shell", false)) + } else { + None + }; + let gc_root = self.devenv_dot_gc.join("shell"); + let gc_root_str = gc_root.to_str().expect("gc root should be utf-8"); + + let mut args: Vec<&str> = vec!["print-dev-env", "--profile", gc_root_str]; + if json { + args.push("--json"); + } + + let env_ = self.run_nix("nix", &args, &command::Options::default())?; + + let options = command::Options { + logging: false, + ..command::Options::default() + }; + let args: Vec<&str> = vec!["-p", gc_root_str, "--delete-generations", "old"]; + self.run_nix("nix-env", &args, &options)?; + let now_ns = get_now_with_nanoseconds(); + let target = format!("{}-shell", now_ns); + symlink_force( + &self.logger, + &fs::canonicalize(&gc_root).expect("to resolve gc_root"), + &self.devenv_home_gc.join(target), + ); + + Ok((env_.stdout, gc_root)) + } +} + +fn symlink_force(logger: &log::Logger, link_path: &Path, target: &Path) { + let _lock = dotlock::Dotlock::create(target.with_extension("lock")).unwrap(); + logger.debug(&format!( + "Creating symlink {} -> {}", + link_path.display(), + target.display() + )); + + if target.exists() { + fs::remove_file(target).unwrap_or_else(|_| panic!("Failed to remove {}", target.display())); + } + + symlink(link_path, target).unwrap_or_else(|_| { + panic!( + "Failed to create symlink: {} -> {}", + link_path.display(), + target.display() + ) + }); +} + +fn default_system() -> String { + let arch = if cfg!(target_arch = "aarch64") { + "aarch64" + } else if cfg!(target_arch = "x86_64") { + "x86_64" + } else { + "unknown architecture" + }; + + let os = if cfg!(target_os = "linux") { + "linux" + } else if cfg!(target_os = "windows") { + "windows" + } else if cfg!(target_os = "macos") { + "darwin" // macOS is referred to as "darwin" in target triples + } else { + "unknown OS" + }; + format!("{arch}-{os}") +} + +fn get_now_with_nanoseconds() -> String { + let now = SystemTime::now(); + let duration = now.duration_since(UNIX_EPOCH).expect("Time went backwards"); + let secs = duration.as_secs(); + let nanos = duration.subsec_nanos(); + format!("{}.{}", secs, nanos) +} + +#[derive(Deserialize)] +struct PackageResults(HashMap); + +#[derive(Deserialize)] +struct PackageResult { + version: String, + description: String, +} + +#[derive(Deserialize)] +struct OptionResults(HashMap); + +#[derive(Deserialize)] +struct OptionResult { + #[serde(rename = "type")] + type_: String, + default: Option, + description: String, +} + +#[derive(Table)] +struct DevenvOptionResult { + #[table(title = "Option")] + name: String, + #[table(title = "Type")] + type_: String, + #[table(title = "Default")] + default: String, + #[table(title = "Description")] + description: String, +} + +#[derive(Table)] +struct DevenvPackageResult { + #[table(title = "Package")] + name: String, + #[table(title = "Version")] + version: String, + #[table(title = "Description")] + description: String, +} + +fn cleanup_symlinks(root: &Path) -> (Vec, Vec) { + let mut to_gc = Vec::new(); + let mut removed_symlinks = Vec::new(); + + for entry in fs::read_dir(root).expect("Failed to read directory") { + let entry = entry.expect("Failed to read entry"); + let path = entry.path(); + if path.is_symlink() { + let target = fs::canonicalize(&path).expect("Failed to read link"); + if !target.exists() { + removed_symlinks.push(path.clone()); + } else { + to_gc.push(target); + } + } + } + + (to_gc, removed_symlinks) +} diff --git a/docs/getting-started.md b/docs/getting-started.md index 7e48c63e1..493f0412d 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -91,9 +91,9 @@ Done. ## Commands -- ``devenv ci`` builds your developer environment and makes sure that all checks pass. Useful to run in your continuous integration environment. +- ``devenv test`` builds your developer environment and makes sure that all checks pass. Useful to run in your continuous integration environment. - ``devenv shell`` activates your developer environment. -- ``devenv search NAME`` searches packages matching NAME in Nixpkgs input. +- ``devenv search `` searches packages matching NAME in Nixpkgs input. - ``devenv update`` updates and pins inputs from ``devenv.yaml`` into ``devenv.lock``. - ``devenv gc`` [deletes unused environments](garbage-collection.md) to save disk space. - ``devenv up`` starts [processes](processes.md). diff --git a/docs/integrations/github-actions.md b/docs/integrations/github-actions.md index 319ff6916..923aa92cd 100644 --- a/docs/integrations/github-actions.md +++ b/docs/integrations/github-actions.md @@ -55,15 +55,15 @@ The above snippet does the following: If you're using a [self-hosted runner](https://docs.github.com/en/actions/hosting-your-own-runners/managing-self-hosted-runners/about-self-hosted-runners), you can pre-install both Nix and devenv, and skip the associated steps. -### Built-in CI command +### `devenv test` -Devenv provides a convenient built-in `devenv ci` command. +Devenv provides a convenient built-in `devenv test` command. It builds the shell and runs any defined [pre-commit hooks](../pre-commit-hooks.md) against your repository. This is a quick and easy way to test that your development environment works as expected and lint your code at the same time. ```yaml - name: Build the devenv shell and run any pre-commit hooks - run: devenv ci + run: devenv test ``` ### Run a single command @@ -139,7 +139,7 @@ jobs: run: nix profile install --accept-flake-config tarball+https://install.devenv.sh/latest - name: Build the devenv shell and run any pre-commit hooks - run: devenv ci + run: devenv test - name: Run a single command in the devenv shell run: devenv shell hello diff --git a/docs/pre-commit-hooks.md b/docs/pre-commit-hooks.md index 524a86256..a2dd0299a 100644 --- a/docs/pre-commit-hooks.md +++ b/docs/pre-commit-hooks.md @@ -35,7 +35,7 @@ If you commit a Python or Markdown file or a script, these hooks will run at com ### 2) Verify formatting in CI -Run ``devenv ci``. +Run ``devenv test``. See [the list of all available hooks](reference/options.md#pre-commithooks). diff --git a/docs/reference/yaml-options.md b/docs/reference/yaml-options.md index 16cd7557f..fbb5e1a72 100644 --- a/docs/reference/yaml-options.md +++ b/docs/reference/yaml-options.md @@ -10,10 +10,16 @@ | inputs.<name>.overlays | A list of overlays to include from the input. | | imports | A list of relative paths or references to inputs to import ``devenv.nix``. | | permittedInsecurePackages | A list of insecure permitted packages. | +| clean.enabled | Clean the environment when entering the shell. Defaults to `false`. | +| clean.keep | A list of environment variables to keep when cleaning the environment. | +| impure | Relax the hermeticity of the environment. | !!! note "Added in 1.0" - relative file support in imports: `./mymodule.nix` + - `clean` + - `impure` + - `allowBroken` ## inputs.<name>.url diff --git a/docs/tests.md b/docs/tests.md index 6c1f53ff7..2b765034d 100644 --- a/docs/tests.md +++ b/docs/tests.md @@ -1,55 +1,77 @@ -To ease testing of your environments, -we provide a way to define the tests and to run them. +# Tests -## Writing devenv tests +Tests are a way to ensure that your development environment is working as expected. + +Running `devenv test` will build your environment and run the tests defined in `enterTest`. + +If you have [processes](/processes.md) defined in your environment, they will be started and stopped for you. + +## Writing your first test A simple test would look like: ```nix title="devenv.nix" { pkgs, ... }: { - tests.basic = { - nix = '' - { pkgs, ... }: { - packages = [ pkgs.ncdu ]; - } - ''; - test = '' - ncdu --version | grep "ncdu 2.2" - ''; - }; + packages = [ pkgs.ncdu ]; + + enterTest = '' + ncdu --version | grep "ncdu 2.2" + ''; } ``` ```shell-session $ devenv test -✔ Gathering tests in 0.3s. -• Found 1 test(s), running 1: -• Testing basic ... -• Running $ devenv ci -• Running .test.sh. -✔ Running basic in 16.7s. +✔ Building tests in 2.5s. +• Running tests ... +Setting up shell environment... +Running test... +ncdu 2.2 +✔ Running tests in 4.7s. +✔ Tests passed. in 0.0s. ``` -## Defining tests in a folder +By default, the `enterTest` detects if `.test.sh` file exists and runs it. -A simple test with a test script: +## Testing with processes -```shell-session -$ ls tests/mytest/ -.test.sh devenv.nix devenv.yaml -``` - -Define tests: +If you have [processes](/processes.md) defined in your environment, +they will be started and stopped for you. ```nix title="devenv.nix" -{ config, ... }: { - tests = config.lib.mkTests ./tests; +{ pkgs, ... }: { + services.nginx = { + enable = true; + httpConfig = '' + server { + listen 8080; + location / { + return 200 "Hello, world!"; + } + } + ''; + }; + + enterTest = '' + wait_for_port 8080 + curl -s localhost:8080 | grep "Hello, world!" + ''; } ``` -Run tests: - ```shell-session $ devenv test -... +✔ Building tests in 2.5s. +✔ Building processes in 15.7s. +• Starting processes ...• PID is 113105 +• See logs: $ tail -f /run/user/1000/nix-shell.upTad4/.tmpv25BxA/processes.log +• Stop: $ devenv processes stop +✔ Starting processes in 0.0s. +• Running tests ... +Setting up shell environment... +Running test... +ncdu 2.2 +✔ Running tests in 4.7s. +• Stopping process with PID 113105 +✔ Tests passed. in 0.0s. ``` \ No newline at end of file diff --git a/examples/clickhouse/.test.sh b/examples/clickhouse/.test.sh index 4fb1ced15..4670607e7 100755 --- a/examples/clickhouse/.test.sh +++ b/examples/clickhouse/.test.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -set -xe -timeout 20 bash -c 'until echo > /dev/tcp/localhost/9000; do sleep 0.5; done' -sleep 2 +set -xe +wait_for_port 9000 +sleep 2 clickhouse-client --query "SELECT 1" \ No newline at end of file diff --git a/examples/compose/devenv.nix b/examples/compose/devenv.nix new file mode 100644 index 000000000..27b38bda0 --- /dev/null +++ b/examples/compose/devenv.nix @@ -0,0 +1,8 @@ +{ + enterTest = '' + pushd projectB + devenv shell python -- --version + devenv shell cargo -- --version + popd + ''; +} diff --git a/examples/compose/devenv.yaml b/examples/compose/devenv.yaml new file mode 100644 index 000000000..bfc720c95 --- /dev/null +++ b/examples/compose/devenv.yaml @@ -0,0 +1,3 @@ +imports: +- ./projectA +- ./projectB \ No newline at end of file diff --git a/examples/compose/projectA/devenv.nix b/examples/compose/projectA/devenv.nix new file mode 100644 index 000000000..6a5634106 --- /dev/null +++ b/examples/compose/projectA/devenv.nix @@ -0,0 +1,3 @@ +{ + languages.python.enable = true; +} diff --git a/examples/compose/projectB/devenv.nix b/examples/compose/projectB/devenv.nix new file mode 100644 index 000000000..eb6020be4 --- /dev/null +++ b/examples/compose/projectB/devenv.nix @@ -0,0 +1,3 @@ +{ + languages.rust.enable = true; +} diff --git a/examples/compose/projectB/devenv.yaml b/examples/compose/projectB/devenv.yaml new file mode 100644 index 000000000..aff49e1ff --- /dev/null +++ b/examples/compose/projectB/devenv.yaml @@ -0,0 +1,6 @@ +inputs: + root: + url: git+file://. + flake: false +imports: +- root/examples/compose/projectA \ No newline at end of file diff --git a/examples/dotenv/.env b/examples/dotenv/.env deleted file mode 100644 index 118be34b6..000000000 --- a/examples/dotenv/.env +++ /dev/null @@ -1,3 +0,0 @@ -FOO=1 -BAR=2 -BAZ=3 diff --git a/examples/elasticmq/.test.sh b/examples/elasticmq/.test.sh index 8607368d1..e7030c09f 100755 --- a/examples/elasticmq/.test.sh +++ b/examples/elasticmq/.test.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash set -ex -timeout 60 bash -c 'until echo > /dev/tcp/localhost/9325; do sleep 0.5; done' +wait_for_port 9325 60 QUEUE_NAME=$(curl http://localhost:9325/statistics/queues -s | jq .[].name -r) diff --git a/examples/influxdb/.test.sh b/examples/influxdb/.test.sh index 270ec901e..14eec02f5 100755 --- a/examples/influxdb/.test.sh +++ b/examples/influxdb/.test.sh @@ -1,8 +1,7 @@ #!/usr/bin/env bash set -ex -# We test for the none-default port, configured in the nix file -timeout 60 bash -c 'until echo > /dev/tcp/localhost/8087; do sleep 0.5; done' +wait_for_port 8087 60 influx --port 8087 --execute "CREATE DATABASE devenv" DATABASES=$(influx --port 8087 --execute "SHOW DATABASES" | grep devenv) diff --git a/examples/mailpit/.test.sh b/examples/mailpit/.test.sh index 812751e5f..bb9cd59e1 100755 --- a/examples/mailpit/.test.sh +++ b/examples/mailpit/.test.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash set -ex -timeout 20 bash -c 'until echo > /dev/tcp/localhost/1025; do sleep 0.5; done' +wait_for_port 1025 sendmail john@example.com < /dev/tcp/localhost/9000; do sleep 0.5; done' +wait_for_port 9000 mc admin info local \ No newline at end of file diff --git a/examples/phoenix/.test.sh b/examples/phoenix/.test.sh index b687eac17..95a374e03 100755 --- a/examples/phoenix/.test.sh +++ b/examples/phoenix/.test.sh @@ -1,13 +1,12 @@ #!/usr/bin/env bash set -ex -# mix local.hex --force -# mix local.rebar --force -# echo Y | mix archive.install hex phx_new -# echo Y | mix phx.new hello -# sed -i.bak -e "s/username: \"postgres\",/socket_dir: System.get_env(\"PGDATA\"),/" \ -# ./hello/config/dev.exs && rm ./hello/config/dev.exs.bak -# devenv up& -# timeout 20 bash -c 'until echo > /dev/tcp/localhost/4000; do sleep 0.5; done' -# curl -s http://localhost:4000/ | grep "Phoenix Framework" -echo "this example is currently broken" -exit 2 + +mix local.hex --force +mix local.rebar --force +echo Y | mix archive.install hex phx_new +echo Y | mix phx.new hello +sed -i.bak -e "s/username: \"postgres\",/socket_dir: System.get_env(\"PGDATA\"),/" \ + ./hello/config/dev.exs && rm ./hello/config/dev.exs.bak + +wait_for_port 4000 +curl -s http://localhost:4000/ | grep "Phoenix Framework" diff --git a/examples/postgres-timescale/.test.sh b/examples/postgres-timescale/.test.sh index fc2497fb1..cdcefb437 100755 --- a/examples/postgres-timescale/.test.sh +++ b/examples/postgres-timescale/.test.sh @@ -1,4 +1,4 @@ #!/usr/bin/env bash set -ex -devenv up& + timeout 20 bash -c 'until psql -c "SELECT 1" mydb; do sleep 0.5; done' diff --git a/examples/postgres/.test.sh b/examples/postgres/.test.sh index 36f49e3d8..3fee75f8d 100755 --- a/examples/postgres/.test.sh +++ b/examples/postgres/.test.sh @@ -1,3 +1,6 @@ #!/usr/bin/env bash set -ex -timeout 20 bash -c 'until psql -h /tmp -c "SELECT 1" mydb 2>/dev/null; do sleep 0.5; done' + +echo $PGHOST + +timeout 20 bash -c 'until psql -c "SELECT 1" mydb 2>/dev/null; do sleep 0.5; done' \ No newline at end of file diff --git a/examples/postgres/devenv.nix b/examples/postgres/devenv.nix index 7c43ce11b..46b277893 100644 --- a/examples/postgres/devenv.nix +++ b/examples/postgres/devenv.nix @@ -8,10 +8,6 @@ initialDatabases = [{ name = "mydb"; }]; - settings = { - unix_socket_directories = "/tmp"; - }; - initialScript = '' CREATE EXTENSION IF NOT EXISTS postgis; ''; diff --git a/examples/rabbitmq/.test.sh b/examples/rabbitmq/.test.sh index 13a5b4bd2..c9959f62c 100755 --- a/examples/rabbitmq/.test.sh +++ b/examples/rabbitmq/.test.sh @@ -1,14 +1,4 @@ #!/usr/bin/env bash set -ex -devenv up & -DEVENV_PID=$! -export DEVENV_PID - -devenv_stop() { - pkill -P "$DEVENV_PID" -} - -trap devenv_stop EXIT - -timeout 20 bash -c 'until rabbitmqctl -q status 2>/dev/null; do sleep 0.5; done' +timeout 20 bash -c 'until rabbitmqctl -q status 2>/dev/null; do sleep 0.5; done' \ No newline at end of file diff --git a/examples/rubyonrails/.test.sh b/examples/rubyonrails/.test.sh index 2e03dd625..a055c6b04 100755 --- a/examples/rubyonrails/.test.sh +++ b/examples/rubyonrails/.test.sh @@ -2,7 +2,7 @@ set -ex pushd blog - timeout 20 bash -c 'until echo > /dev/tcp/localhost/5100; do sleep 0.5; done' + wait_for_port 5100 rails db:create curl -s http://localhost:5100/ | grep "version" popd diff --git a/examples/rust/app/Cargo.toml b/examples/rust/app/Cargo.toml index a79ae575f..df0d217e6 100644 --- a/examples/rust/app/Cargo.toml +++ b/examples/rust/app/Cargo.toml @@ -6,3 +6,6 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] + + +[workspace] \ No newline at end of file diff --git a/examples/simple/.gitignore b/examples/simple/.gitignore new file mode 100644 index 000000000..4d058db7d --- /dev/null +++ b/examples/simple/.gitignore @@ -0,0 +1,9 @@ +# Devenv +.devenv* +devenv.local.nix + +# direnv +.direnv + +# pre-commit +.pre-commit-config.yaml diff --git a/examples/varnish/.test.sh b/examples/varnish/.test.sh index 3c7e21296..b35bc9c94 100755 --- a/examples/varnish/.test.sh +++ b/examples/varnish/.test.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash set -ex -timeout 20 bash -c 'until echo > /dev/tcp/localhost/6081; do sleep 0.5; done' +wait_for_port 6081 caddy=$(curl http://localhost:8001) varnish=$(curl http://localhost:6081) diff --git a/flake.lock b/flake.lock index 1ac91e162..97cfaca12 100644 --- a/flake.lock +++ b/flake.lock @@ -3,11 +3,11 @@ "flake-compat": { "flake": false, "locked": { - "lastModified": 1673956053, - "narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=", + "lastModified": 1696426674, + "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=", "owner": "edolstra", "repo": "flake-compat", - "rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9", + "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", "type": "github" }, "original": { @@ -37,29 +37,11 @@ "systems": "systems" }, "locked": { - "lastModified": 1689068808, - "narHash": "sha256-6ixXo3wt24N/melDWjq70UuHQLxGV8jZvooRanIHXw0=", - "owner": "numtide", - "repo": "flake-utils", - "rev": "919d646de7be200f3bf08cb76ae1f09402b6f9b4", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "flake-utils", - "type": "github" - } - }, - "flake-utils_2": { - "inputs": { - "systems": "systems_2" - }, - "locked": { - "lastModified": 1685518550, - "narHash": "sha256-o2d0KcvaXzTrPRIo0kOLV0/QXHhDQ5DTi+OxcjO8xqY=", + "lastModified": 1701680307, + "narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=", "owner": "numtide", "repo": "flake-utils", - "rev": "a1720a10a6cfe8234c0e93907ffe81be440f4cef", + "rev": "4022d587cbbfd70fe950c1e2083a02621806a725", "type": "github" }, "original": { @@ -76,11 +58,11 @@ ] }, "locked": { - "lastModified": 1660459072, - "narHash": "sha256-8DFJjXG8zqoONA1vXtgeKXy68KdJL5UaXR8NtVMUbx8=", + "lastModified": 1703887061, + "narHash": "sha256-gGPa9qWNc6eCXT/+Z5/zMkyYOuRZqeFZBDbopNZQkuY=", "owner": "hercules-ci", "repo": "gitignore.nix", - "rev": "a20de23b925fd8264fd7fad6454652e142fd7f73", + "rev": "43e1aa1308018f37118e34d3a9cb4f5e75dc11d5", "type": "github" }, "original": { @@ -98,11 +80,11 @@ "nixpkgs-regression": "nixpkgs-regression" }, "locked": { - "lastModified": 1708577783, - "narHash": "sha256-92xq7eXlxIT5zFNccLpjiP7sdQqQI30Gyui2p/PfKZM=", + "lastModified": 1709963241, + "narHash": "sha256-8RGoqq9ApGLGh6lNJfBRzqHy/S3u53HL8mDtmI7y9Hc=", "owner": "domenkozar", "repo": "nix", - "rev": "ecd0af0c1f56de32cbad14daa1d82a132bf298f8", + "rev": "e92c1fb8a57fe2e0bee725b1e7c68cfd8ffd55dc", "type": "github" }, "original": { @@ -112,34 +94,13 @@ "type": "github" } }, - "nix-github-actions": { - "inputs": { - "nixpkgs": [ - "poetry2nix", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1688870561, - "narHash": "sha256-4UYkifnPEw1nAzqqPOTL2MvWtm3sNGw1UTYTalkTcGY=", - "owner": "nix-community", - "repo": "nix-github-actions", - "rev": "165b1650b753316aa7f1787f3005a8d2da0f5301", - "type": "github" - }, - "original": { - "owner": "nix-community", - "repo": "nix-github-actions", - "type": "github" - } - }, "nixpkgs": { "locked": { - "lastModified": 1692808169, - "narHash": "sha256-x9Opq06rIiwdwGeK2Ykj69dNc2IvUH1fY55Wm7atwrE=", + "lastModified": 1709069307, + "narHash": "sha256-ER6N232jucnqu4+AK80RdmgBDuk61FAqmp36EMqkQns=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "9201b5ff357e781bf014d0330d18555695df7ba8", + "rev": "9c1ea5e3a2a2578792438cba233f2763593e19c5", "type": "github" }, "original": { @@ -167,48 +128,26 @@ }, "nixpkgs-stable": { "locked": { - "lastModified": 1685801374, - "narHash": "sha256-otaSUoFEMM+LjBI1XL/xGB5ao6IwnZOXc47qhIgJe8U=", + "lastModified": 1704874635, + "narHash": "sha256-YWuCrtsty5vVZvu+7BchAxmcYzTMfolSPP5io8+WYCg=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "c37ca420157f4abc31e26f436c1145f8951ff373", + "rev": "3dc440faeee9e889fe2d1b4d25ad0f430d449356", "type": "github" }, "original": { "owner": "NixOS", - "ref": "nixos-23.05", + "ref": "nixos-23.11", "repo": "nixpkgs", "type": "github" } }, - "poetry2nix": { - "inputs": { - "flake-utils": "flake-utils", - "nix-github-actions": "nix-github-actions", - "nixpkgs": [ - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1692876271, - "narHash": "sha256-IXfZEkI0Mal5y1jr6IRWMqK8GW2/f28xJenZIPQqkY0=", - "owner": "nix-community", - "repo": "poetry2nix", - "rev": "d5006be9c2c2417dafb2e2e5034d83fabd207ee3", - "type": "github" - }, - "original": { - "owner": "nix-community", - "repo": "poetry2nix", - "type": "github" - } - }, "pre-commit-hooks": { "inputs": { "flake-compat": [ "flake-compat" ], - "flake-utils": "flake-utils_2", + "flake-utils": "flake-utils", "gitignore": "gitignore", "nixpkgs": [ "nixpkgs" @@ -216,11 +155,11 @@ "nixpkgs-stable": "nixpkgs-stable" }, "locked": { - "lastModified": 1692274144, - "narHash": "sha256-BxTQuRUANQ81u8DJznQyPmRsg63t4Yc+0kcyq6OLz8s=", + "lastModified": 1708018599, + "narHash": "sha256-M+Ng6+SePmA8g06CmUZWi1AjG2tFBX9WCXElBHEKnyM=", "owner": "cachix", "repo": "pre-commit-hooks.nix", - "rev": "7e3517c03d46159fdbf8c0e5c97f82d5d4b0c8fa", + "rev": "5df5a70ad7575f6601d91f0efec95dd9bc619431", "type": "github" }, "original": { @@ -234,7 +173,6 @@ "flake-compat": "flake-compat", "nix": "nix", "nixpkgs": "nixpkgs", - "poetry2nix": "poetry2nix", "pre-commit-hooks": "pre-commit-hooks" } }, @@ -252,21 +190,6 @@ "repo": "default", "type": "github" } - }, - "systems_2": { - "locked": { - "lastModified": 1681028828, - "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", - "owner": "nix-systems", - "repo": "default", - "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", - "type": "github" - }, - "original": { - "owner": "nix-systems", - "repo": "default", - "type": "github" - } } }, "root": "root", diff --git a/flake.nix b/flake.nix index b548f0091..82eb06a3b 100644 --- a/flake.nix +++ b/flake.nix @@ -22,10 +22,6 @@ url = "github:domenkozar/nix/devenv-2.21"; inputs.nixpkgs.follows = "nixpkgs"; }; - inputs.poetry2nix = { - url = "github:nix-community/poetry2nix"; - inputs.nixpkgs.follows = "nixpkgs"; - }; outputs = { self, nixpkgs, pre-commit-hooks, nix, ... }@inputs: let diff --git a/mkdocs.yml b/mkdocs.yml index c0dc9b34d..f9689b979 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -82,6 +82,7 @@ plugins: background_color: "#FBFBFB" color: "#425C82" rss: + use_git: false match_path: blog/posts/.* date_from_meta: as_creation: date diff --git a/package.nix b/package.nix index 61c4f7d5a..6a6cf019d 100644 --- a/package.nix +++ b/package.nix @@ -1,33 +1,26 @@ { pkgs, inputs }: -let - python_slim = pkgs.python311.override { - mimetypesSupport = false; - x11Support = false; - stripConfig = true; - stripIdlelib = true; - stripTests = true; - stripTkinter = true; - enableLTO = false; - rebuildBytecode = false; - stripBytecode = true; - includeSiteCustomize = false; - enableOptimizations = false; - bzip2 = null; - gdbm = null; - xz = null; - ncurses = null; - readline = null; - sqlite = null; - tzdata = null; - self = python_slim; +pkgs.rustPlatform.buildRustPackage { + pname = "devenv"; + version = "1.0.0"; + + src = builtins.path { + path = ./.; + filter = path: type: + path != "Cargo.lock" || path != "Cargo.toml" || path != "src/devenv"; + }; + + cargoLock = { + lockFile = ./Cargo.lock; }; -in -(inputs.poetry2nix.legacyPackages.${pkgs.stdenv.system}.mkPoetryApplication { - projectDir = ./.; - python = python_slim; -}).overrideAttrs (old: { - makeWrapperArgs = [ - "--set DEVENV_NIX ${inputs.nix.packages.${pkgs.stdenv.system}.nix}" + + nativeBuildInputs = [ pkgs.makeWrapper ]; + + buildInputs = pkgs.lib.optionals pkgs.stdenv.isDarwin [ + pkgs.darwin.apple_sdk.frameworks.SystemConfiguration ]; -}) + + postInstall = '' + wrapProgram $out/bin/devenv --set DEVENV_NIX ${inputs.nix.packages.${pkgs.stdenv.system}.nix} + ''; +} diff --git a/poetry.lock b/poetry.lock deleted file mode 100644 index e2c5f21ed..000000000 --- a/poetry.lock +++ /dev/null @@ -1,1189 +0,0 @@ -# This file is automatically @generated by Poetry 1.5.1 and should not be changed by hand. - -[[package]] -name = "babel" -version = "2.14.0" -description = "Internationalization utilities" -optional = false -python-versions = ">=3.7" -files = [ - {file = "Babel-2.14.0-py3-none-any.whl", hash = "sha256:efb1a25b7118e67ce3a259bed20545c29cb68be8ad2c784c83689981b7a57287"}, - {file = "Babel-2.14.0.tar.gz", hash = "sha256:6919867db036398ba21eb5c7a0f6b28ab8cbc3ae7a73a44ebe34ae74a4e7d363"}, -] - -[package.extras] -dev = ["freezegun (>=1.0,<2.0)", "pytest (>=6.0)", "pytest-cov"] - -[[package]] -name = "bracex" -version = "2.4" -description = "Bash style brace expander." -optional = false -python-versions = ">=3.8" -files = [ - {file = "bracex-2.4-py3-none-any.whl", hash = "sha256:efdc71eff95eaff5e0f8cfebe7d01adf2c8637c8c92edaf63ef348c241a82418"}, - {file = "bracex-2.4.tar.gz", hash = "sha256:a27eaf1df42cf561fed58b7a8f3fdf129d1ea16a81e1fadd1d17989bc6384beb"}, -] - -[[package]] -name = "cairocffi" -version = "1.6.1" -description = "cffi-based cairo bindings for Python" -optional = false -python-versions = ">=3.7" -files = [ - {file = "cairocffi-1.6.1-py3-none-any.whl", hash = "sha256:aa78ee52b9069d7475eeac457389b6275aa92111895d78fbaa2202a52dac112e"}, - {file = "cairocffi-1.6.1.tar.gz", hash = "sha256:78e6bbe47357640c453d0be929fa49cd05cce2e1286f3d2a1ca9cbda7efdb8b7"}, -] - -[package.dependencies] -cffi = ">=1.1.0" - -[package.extras] -doc = ["sphinx", "sphinx_rtd_theme"] -test = ["flake8", "isort", "numpy", "pikepdf", "pytest"] -xcb = ["xcffib (>=1.4.0)"] - -[[package]] -name = "cairosvg" -version = "2.7.1" -description = "A Simple SVG Converter based on Cairo" -optional = false -python-versions = ">=3.5" -files = [ - {file = "CairoSVG-2.7.1-py3-none-any.whl", hash = "sha256:8a5222d4e6c3f86f1f7046b63246877a63b49923a1cd202184c3a634ef546b3b"}, - {file = "CairoSVG-2.7.1.tar.gz", hash = "sha256:432531d72347291b9a9ebfb6777026b607563fd8719c46ee742db0aef7271ba0"}, -] - -[package.dependencies] -cairocffi = "*" -cssselect2 = "*" -defusedxml = "*" -pillow = "*" -tinycss2 = "*" - -[package.extras] -doc = ["sphinx", "sphinx-rtd-theme"] -test = ["flake8", "isort", "pytest"] - -[[package]] -name = "certifi" -version = "2023.11.17" -description = "Python package for providing Mozilla's CA Bundle." -optional = false -python-versions = ">=3.6" -files = [ - {file = "certifi-2023.11.17-py3-none-any.whl", hash = "sha256:e036ab49d5b79556f99cfc2d9320b34cfbe5be05c5871b51de9329f0603b0474"}, - {file = "certifi-2023.11.17.tar.gz", hash = "sha256:9b469f3a900bf28dc19b8cfbf8019bf47f7fdd1a65a1d4ffb98fc14166beb4d1"}, -] - -[[package]] -name = "cffi" -version = "1.16.0" -description = "Foreign Function Interface for Python calling C code." -optional = false -python-versions = ">=3.8" -files = [ - {file = "cffi-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6b3d6606d369fc1da4fd8c357d026317fbb9c9b75d36dc16e90e84c26854b088"}, - {file = "cffi-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ac0f5edd2360eea2f1daa9e26a41db02dd4b0451b48f7c318e217ee092a213e9"}, - {file = "cffi-1.16.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7e61e3e4fa664a8588aa25c883eab612a188c725755afff6289454d6362b9673"}, - {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a72e8961a86d19bdb45851d8f1f08b041ea37d2bd8d4fd19903bc3083d80c896"}, - {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5b50bf3f55561dac5438f8e70bfcdfd74543fd60df5fa5f62d94e5867deca684"}, - {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7651c50c8c5ef7bdb41108b7b8c5a83013bfaa8a935590c5d74627c047a583c7"}, - {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4108df7fe9b707191e55f33efbcb2d81928e10cea45527879a4749cbe472614"}, - {file = "cffi-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:32c68ef735dbe5857c810328cb2481e24722a59a2003018885514d4c09af9743"}, - {file = "cffi-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:673739cb539f8cdaa07d92d02efa93c9ccf87e345b9a0b556e3ecc666718468d"}, - {file = "cffi-1.16.0-cp310-cp310-win32.whl", hash = "sha256:9f90389693731ff1f659e55c7d1640e2ec43ff725cc61b04b2f9c6d8d017df6a"}, - {file = "cffi-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:e6024675e67af929088fda399b2094574609396b1decb609c55fa58b028a32a1"}, - {file = "cffi-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b84834d0cf97e7d27dd5b7f3aca7b6e9263c56308ab9dc8aae9784abb774d404"}, - {file = "cffi-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1b8ebc27c014c59692bb2664c7d13ce7a6e9a629be20e54e7271fa696ff2b417"}, - {file = "cffi-1.16.0-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ee07e47c12890ef248766a6e55bd38ebfb2bb8edd4142d56db91b21ea68b7627"}, - {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8a9d3ebe49f084ad71f9269834ceccbf398253c9fac910c4fd7053ff1386936"}, - {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e70f54f1796669ef691ca07d046cd81a29cb4deb1e5f942003f401c0c4a2695d"}, - {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5bf44d66cdf9e893637896c7faa22298baebcd18d1ddb6d2626a6e39793a1d56"}, - {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7b78010e7b97fef4bee1e896df8a4bbb6712b7f05b7ef630f9d1da00f6444d2e"}, - {file = "cffi-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c6a164aa47843fb1b01e941d385aab7215563bb8816d80ff3a363a9f8448a8dc"}, - {file = "cffi-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e09f3ff613345df5e8c3667da1d918f9149bd623cd9070c983c013792a9a62eb"}, - {file = "cffi-1.16.0-cp311-cp311-win32.whl", hash = "sha256:2c56b361916f390cd758a57f2e16233eb4f64bcbeee88a4881ea90fca14dc6ab"}, - {file = "cffi-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:db8e577c19c0fda0beb7e0d4e09e0ba74b1e4c092e0e40bfa12fe05b6f6d75ba"}, - {file = "cffi-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:fa3a0128b152627161ce47201262d3140edb5a5c3da88d73a1b790a959126956"}, - {file = "cffi-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:68e7c44931cc171c54ccb702482e9fc723192e88d25a0e133edd7aff8fcd1f6e"}, - {file = "cffi-1.16.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:abd808f9c129ba2beda4cfc53bde801e5bcf9d6e0f22f095e45327c038bfe68e"}, - {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88e2b3c14bdb32e440be531ade29d3c50a1a59cd4e51b1dd8b0865c54ea5d2e2"}, - {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fcc8eb6d5902bb1cf6dc4f187ee3ea80a1eba0a89aba40a5cb20a5087d961357"}, - {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b7be2d771cdba2942e13215c4e340bfd76398e9227ad10402a8767ab1865d2e6"}, - {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e715596e683d2ce000574bae5d07bd522c781a822866c20495e52520564f0969"}, - {file = "cffi-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:2d92b25dbf6cae33f65005baf472d2c245c050b1ce709cc4588cdcdd5495b520"}, - {file = "cffi-1.16.0-cp312-cp312-win32.whl", hash = "sha256:b2ca4e77f9f47c55c194982e10f058db063937845bb2b7a86c84a6cfe0aefa8b"}, - {file = "cffi-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:68678abf380b42ce21a5f2abde8efee05c114c2fdb2e9eef2efdb0257fba1235"}, - {file = "cffi-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0c9ef6ff37e974b73c25eecc13952c55bceed9112be2d9d938ded8e856138bcc"}, - {file = "cffi-1.16.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a09582f178759ee8128d9270cd1344154fd473bb77d94ce0aeb2a93ebf0feaf0"}, - {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e760191dd42581e023a68b758769e2da259b5d52e3103c6060ddc02c9edb8d7b"}, - {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:80876338e19c951fdfed6198e70bc88f1c9758b94578d5a7c4c91a87af3cf31c"}, - {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a6a14b17d7e17fa0d207ac08642c8820f84f25ce17a442fd15e27ea18d67c59b"}, - {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6602bc8dc6f3a9e02b6c22c4fc1e47aa50f8f8e6d3f78a5e16ac33ef5fefa324"}, - {file = "cffi-1.16.0-cp38-cp38-win32.whl", hash = "sha256:131fd094d1065b19540c3d72594260f118b231090295d8c34e19a7bbcf2e860a"}, - {file = "cffi-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:31d13b0f99e0836b7ff893d37af07366ebc90b678b6664c955b54561fc36ef36"}, - {file = "cffi-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:582215a0e9adbe0e379761260553ba11c58943e4bbe9c36430c4ca6ac74b15ed"}, - {file = "cffi-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b29ebffcf550f9da55bec9e02ad430c992a87e5f512cd63388abb76f1036d8d2"}, - {file = "cffi-1.16.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dc9b18bf40cc75f66f40a7379f6a9513244fe33c0e8aa72e2d56b0196a7ef872"}, - {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cb4a35b3642fc5c005a6755a5d17c6c8b6bcb6981baf81cea8bfbc8903e8ba8"}, - {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b86851a328eedc692acf81fb05444bdf1891747c25af7529e39ddafaf68a4f3f"}, - {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c0f31130ebc2d37cdd8e44605fb5fa7ad59049298b3f745c74fa74c62fbfcfc4"}, - {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f8e709127c6c77446a8c0a8c8bf3c8ee706a06cd44b1e827c3e6a2ee6b8c098"}, - {file = "cffi-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:748dcd1e3d3d7cd5443ef03ce8685043294ad6bd7c02a38d1bd367cfd968e000"}, - {file = "cffi-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8895613bcc094d4a1b2dbe179d88d7fb4a15cee43c052e8885783fac397d91fe"}, - {file = "cffi-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed86a35631f7bfbb28e108dd96773b9d5a6ce4811cf6ea468bb6a359b256b1e4"}, - {file = "cffi-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:3686dffb02459559c74dd3d81748269ffb0eb027c39a6fc99502de37d501faa8"}, - {file = "cffi-1.16.0.tar.gz", hash = "sha256:bcb3ef43e58665bbda2fb198698fcae6776483e0c4a631aa5647806c25e02cc0"}, -] - -[package.dependencies] -pycparser = "*" - -[[package]] -name = "charset-normalizer" -version = "3.3.2" -description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." -optional = false -python-versions = ">=3.7.0" -files = [ - {file = "charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-win32.whl", hash = "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-win32.whl", hash = "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-win32.whl", hash = "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-win32.whl", hash = "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-win32.whl", hash = "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-win32.whl", hash = "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d"}, - {file = "charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc"}, -] - -[[package]] -name = "click" -version = "8.1.7" -description = "Composable command line interface toolkit" -optional = false -python-versions = ">=3.7" -files = [ - {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, - {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, -] - -[package.dependencies] -colorama = {version = "*", markers = "platform_system == \"Windows\""} - -[[package]] -name = "colorama" -version = "0.4.6" -description = "Cross-platform colored terminal text." -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" -files = [ - {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, - {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, -] - -[[package]] -name = "cssselect2" -version = "0.7.0" -description = "CSS selectors for Python ElementTree" -optional = false -python-versions = ">=3.7" -files = [ - {file = "cssselect2-0.7.0-py3-none-any.whl", hash = "sha256:fd23a65bfd444595913f02fc71f6b286c29261e354c41d722ca7a261a49b5969"}, - {file = "cssselect2-0.7.0.tar.gz", hash = "sha256:1ccd984dab89fc68955043aca4e1b03e0cf29cad9880f6e28e3ba7a74b14aa5a"}, -] - -[package.dependencies] -tinycss2 = "*" -webencodings = "*" - -[package.extras] -doc = ["sphinx", "sphinx_rtd_theme"] -test = ["flake8", "isort", "pytest"] - -[[package]] -name = "defusedxml" -version = "0.7.1" -description = "XML bomb protection for Python stdlib modules" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -files = [ - {file = "defusedxml-0.7.1-py2.py3-none-any.whl", hash = "sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61"}, - {file = "defusedxml-0.7.1.tar.gz", hash = "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69"}, -] - -[[package]] -name = "filelock" -version = "3.13.1" -description = "A platform independent file lock." -optional = false -python-versions = ">=3.8" -files = [ - {file = "filelock-3.13.1-py3-none-any.whl", hash = "sha256:57dbda9b35157b05fb3e58ee91448612eb674172fab98ee235ccb0b5bee19a1c"}, - {file = "filelock-3.13.1.tar.gz", hash = "sha256:521f5f56c50f8426f5e03ad3b281b490a87ef15bc6c526f168290f0c7148d44e"}, -] - -[package.extras] -docs = ["furo (>=2023.9.10)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.24)"] -testing = ["covdefaults (>=2.3)", "coverage (>=7.3.2)", "diff-cover (>=8)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)", "pytest-timeout (>=2.2)"] -typing = ["typing-extensions (>=4.8)"] - -[[package]] -name = "ghp-import" -version = "2.1.0" -description = "Copy your docs directly to the gh-pages branch." -optional = false -python-versions = "*" -files = [ - {file = "ghp-import-2.1.0.tar.gz", hash = "sha256:9c535c4c61193c2df8871222567d7fd7e5014d835f97dc7b7439069e2413d343"}, - {file = "ghp_import-2.1.0-py3-none-any.whl", hash = "sha256:8337dd7b50877f163d4c0289bc1f1c7f127550241988d568c1db512c4324a619"}, -] - -[package.dependencies] -python-dateutil = ">=2.8.1" - -[package.extras] -dev = ["flake8", "markdown", "twine", "wheel"] - -[[package]] -name = "gitdb" -version = "4.0.11" -description = "Git Object Database" -optional = false -python-versions = ">=3.7" -files = [ - {file = "gitdb-4.0.11-py3-none-any.whl", hash = "sha256:81a3407ddd2ee8df444cbacea00e2d038e40150acfa3001696fe0dcf1d3adfa4"}, - {file = "gitdb-4.0.11.tar.gz", hash = "sha256:bf5421126136d6d0af55bc1e7c1af1c397a34f5b7bd79e776cd3e89785c2b04b"}, -] - -[package.dependencies] -smmap = ">=3.0.1,<6" - -[[package]] -name = "gitpython" -version = "3.1.41" -description = "GitPython is a Python library used to interact with Git repositories" -optional = false -python-versions = ">=3.7" -files = [ - {file = "GitPython-3.1.41-py3-none-any.whl", hash = "sha256:c36b6634d069b3f719610175020a9aed919421c87552185b085e04fbbdb10b7c"}, - {file = "GitPython-3.1.41.tar.gz", hash = "sha256:ed66e624884f76df22c8e16066d567aaa5a37d5b5fa19db2c6df6f7156db9048"}, -] - -[package.dependencies] -gitdb = ">=4.0.1,<5" - -[package.extras] -test = ["black", "coverage[toml]", "ddt (>=1.1.1,!=1.4.3)", "mock", "mypy", "pre-commit", "pytest (>=7.3.1)", "pytest-cov", "pytest-instafail", "pytest-mock", "pytest-sugar", "sumtypes"] - -[[package]] -name = "idna" -version = "3.6" -description = "Internationalized Domain Names in Applications (IDNA)" -optional = false -python-versions = ">=3.5" -files = [ - {file = "idna-3.6-py3-none-any.whl", hash = "sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f"}, - {file = "idna-3.6.tar.gz", hash = "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca"}, -] - -[[package]] -name = "importlib-metadata" -version = "7.0.1" -description = "Read metadata from Python packages" -optional = false -python-versions = ">=3.8" -files = [ - {file = "importlib_metadata-7.0.1-py3-none-any.whl", hash = "sha256:4805911c3a4ec7c3966410053e9ec6a1fecd629117df5adee56dfc9432a1081e"}, - {file = "importlib_metadata-7.0.1.tar.gz", hash = "sha256:f238736bb06590ae52ac1fab06a3a9ef1d8dce2b7a35b5ab329371d6c8f5d2cc"}, -] - -[package.dependencies] -zipp = ">=0.5" - -[package.extras] -docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"] -perf = ["ipython"] -testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)", "pytest-ruff"] - -[[package]] -name = "jinja2" -version = "3.1.3" -description = "A very fast and expressive template engine." -optional = false -python-versions = ">=3.7" -files = [ - {file = "Jinja2-3.1.3-py3-none-any.whl", hash = "sha256:7d6d50dd97d52cbc355597bd845fabfbac3f551e1f99619e39a35ce8c370b5fa"}, - {file = "Jinja2-3.1.3.tar.gz", hash = "sha256:ac8bd6544d4bb2c9792bf3a159e80bba8fda7f07e81bc3aed565432d5925ba90"}, -] - -[package.dependencies] -MarkupSafe = ">=2.0" - -[package.extras] -i18n = ["Babel (>=2.7)"] - -[[package]] -name = "markdown" -version = "3.5.2" -description = "Python implementation of John Gruber's Markdown." -optional = false -python-versions = ">=3.8" -files = [ - {file = "Markdown-3.5.2-py3-none-any.whl", hash = "sha256:d43323865d89fc0cb9b20c75fc8ad313af307cc087e84b657d9eec768eddeadd"}, - {file = "Markdown-3.5.2.tar.gz", hash = "sha256:e1ac7b3dc550ee80e602e71c1d168002f062e49f1b11e26a36264dafd4df2ef8"}, -] - -[package.dependencies] -importlib-metadata = {version = ">=4.4", markers = "python_version < \"3.10\""} - -[package.extras] -docs = ["mdx-gh-links (>=0.2)", "mkdocs (>=1.5)", "mkdocs-gen-files", "mkdocs-literate-nav", "mkdocs-nature (>=0.6)", "mkdocs-section-index", "mkdocstrings[python]"] -testing = ["coverage", "pyyaml"] - -[[package]] -name = "markupsafe" -version = "2.1.4" -description = "Safely add untrusted strings to HTML/XML markup." -optional = false -python-versions = ">=3.7" -files = [ - {file = "MarkupSafe-2.1.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:de8153a7aae3835484ac168a9a9bdaa0c5eee4e0bc595503c95d53b942879c84"}, - {file = "MarkupSafe-2.1.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e888ff76ceb39601c59e219f281466c6d7e66bd375b4ec1ce83bcdc68306796b"}, - {file = "MarkupSafe-2.1.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0b838c37ba596fcbfca71651a104a611543077156cb0a26fe0c475e1f152ee8"}, - {file = "MarkupSafe-2.1.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dac1ebf6983148b45b5fa48593950f90ed6d1d26300604f321c74a9ca1609f8e"}, - {file = "MarkupSafe-2.1.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0fbad3d346df8f9d72622ac71b69565e621ada2ce6572f37c2eae8dacd60385d"}, - {file = "MarkupSafe-2.1.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d5291d98cd3ad9a562883468c690a2a238c4a6388ab3bd155b0c75dd55ece858"}, - {file = "MarkupSafe-2.1.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:a7cc49ef48a3c7a0005a949f3c04f8baa5409d3f663a1b36f0eba9bfe2a0396e"}, - {file = "MarkupSafe-2.1.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b83041cda633871572f0d3c41dddd5582ad7d22f65a72eacd8d3d6d00291df26"}, - {file = "MarkupSafe-2.1.4-cp310-cp310-win32.whl", hash = "sha256:0c26f67b3fe27302d3a412b85ef696792c4a2386293c53ba683a89562f9399b0"}, - {file = "MarkupSafe-2.1.4-cp310-cp310-win_amd64.whl", hash = "sha256:a76055d5cb1c23485d7ddae533229039b850db711c554a12ea64a0fd8a0129e2"}, - {file = "MarkupSafe-2.1.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9e9e3c4020aa2dc62d5dd6743a69e399ce3de58320522948af6140ac959ab863"}, - {file = "MarkupSafe-2.1.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0042d6a9880b38e1dd9ff83146cc3c9c18a059b9360ceae207805567aacccc69"}, - {file = "MarkupSafe-2.1.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:55d03fea4c4e9fd0ad75dc2e7e2b6757b80c152c032ea1d1de487461d8140efc"}, - {file = "MarkupSafe-2.1.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ab3a886a237f6e9c9f4f7d272067e712cdb4efa774bef494dccad08f39d8ae6"}, - {file = "MarkupSafe-2.1.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:abf5ebbec056817057bfafc0445916bb688a255a5146f900445d081db08cbabb"}, - {file = "MarkupSafe-2.1.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e1a0d1924a5013d4f294087e00024ad25668234569289650929ab871231668e7"}, - {file = "MarkupSafe-2.1.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:e7902211afd0af05fbadcc9a312e4cf10f27b779cf1323e78d52377ae4b72bea"}, - {file = "MarkupSafe-2.1.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:c669391319973e49a7c6230c218a1e3044710bc1ce4c8e6eb71f7e6d43a2c131"}, - {file = "MarkupSafe-2.1.4-cp311-cp311-win32.whl", hash = "sha256:31f57d64c336b8ccb1966d156932f3daa4fee74176b0fdc48ef580be774aae74"}, - {file = "MarkupSafe-2.1.4-cp311-cp311-win_amd64.whl", hash = "sha256:54a7e1380dfece8847c71bf7e33da5d084e9b889c75eca19100ef98027bd9f56"}, - {file = "MarkupSafe-2.1.4-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:a76cd37d229fc385738bd1ce4cba2a121cf26b53864c1772694ad0ad348e509e"}, - {file = "MarkupSafe-2.1.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:987d13fe1d23e12a66ca2073b8d2e2a75cec2ecb8eab43ff5624ba0ad42764bc"}, - {file = "MarkupSafe-2.1.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5244324676254697fe5c181fc762284e2c5fceeb1c4e3e7f6aca2b6f107e60dc"}, - {file = "MarkupSafe-2.1.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78bc995e004681246e85e28e068111a4c3f35f34e6c62da1471e844ee1446250"}, - {file = "MarkupSafe-2.1.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a4d176cfdfde84f732c4a53109b293d05883e952bbba68b857ae446fa3119b4f"}, - {file = "MarkupSafe-2.1.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:f9917691f410a2e0897d1ef99619fd3f7dd503647c8ff2475bf90c3cf222ad74"}, - {file = "MarkupSafe-2.1.4-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:f06e5a9e99b7df44640767842f414ed5d7bedaaa78cd817ce04bbd6fd86e2dd6"}, - {file = "MarkupSafe-2.1.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:396549cea79e8ca4ba65525470d534e8a41070e6b3500ce2414921099cb73e8d"}, - {file = "MarkupSafe-2.1.4-cp312-cp312-win32.whl", hash = "sha256:f6be2d708a9d0e9b0054856f07ac7070fbe1754be40ca8525d5adccdbda8f475"}, - {file = "MarkupSafe-2.1.4-cp312-cp312-win_amd64.whl", hash = "sha256:5045e892cfdaecc5b4c01822f353cf2c8feb88a6ec1c0adef2a2e705eef0f656"}, - {file = "MarkupSafe-2.1.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:7a07f40ef8f0fbc5ef1000d0c78771f4d5ca03b4953fc162749772916b298fc4"}, - {file = "MarkupSafe-2.1.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d18b66fe626ac412d96c2ab536306c736c66cf2a31c243a45025156cc190dc8a"}, - {file = "MarkupSafe-2.1.4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:698e84142f3f884114ea8cf83e7a67ca8f4ace8454e78fe960646c6c91c63bfa"}, - {file = "MarkupSafe-2.1.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:49a3b78a5af63ec10d8604180380c13dcd870aba7928c1fe04e881d5c792dc4e"}, - {file = "MarkupSafe-2.1.4-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:15866d7f2dc60cfdde12ebb4e75e41be862348b4728300c36cdf405e258415ec"}, - {file = "MarkupSafe-2.1.4-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:6aa5e2e7fc9bc042ae82d8b79d795b9a62bd8f15ba1e7594e3db243f158b5565"}, - {file = "MarkupSafe-2.1.4-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:54635102ba3cf5da26eb6f96c4b8c53af8a9c0d97b64bdcb592596a6255d8518"}, - {file = "MarkupSafe-2.1.4-cp37-cp37m-win32.whl", hash = "sha256:3583a3a3ab7958e354dc1d25be74aee6228938312ee875a22330c4dc2e41beb0"}, - {file = "MarkupSafe-2.1.4-cp37-cp37m-win_amd64.whl", hash = "sha256:d6e427c7378c7f1b2bef6a344c925b8b63623d3321c09a237b7cc0e77dd98ceb"}, - {file = "MarkupSafe-2.1.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:bf1196dcc239e608605b716e7b166eb5faf4bc192f8a44b81e85251e62584bd2"}, - {file = "MarkupSafe-2.1.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:4df98d4a9cd6a88d6a585852f56f2155c9cdb6aec78361a19f938810aa020954"}, - {file = "MarkupSafe-2.1.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b835aba863195269ea358cecc21b400276747cc977492319fd7682b8cd2c253d"}, - {file = "MarkupSafe-2.1.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:23984d1bdae01bee794267424af55eef4dfc038dc5d1272860669b2aa025c9e3"}, - {file = "MarkupSafe-2.1.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1c98c33ffe20e9a489145d97070a435ea0679fddaabcafe19982fe9c971987d5"}, - {file = "MarkupSafe-2.1.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:9896fca4a8eb246defc8b2a7ac77ef7553b638e04fbf170bff78a40fa8a91474"}, - {file = "MarkupSafe-2.1.4-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:b0fe73bac2fed83839dbdbe6da84ae2a31c11cfc1c777a40dbd8ac8a6ed1560f"}, - {file = "MarkupSafe-2.1.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:c7556bafeaa0a50e2fe7dc86e0382dea349ebcad8f010d5a7dc6ba568eaaa789"}, - {file = "MarkupSafe-2.1.4-cp38-cp38-win32.whl", hash = "sha256:fc1a75aa8f11b87910ffd98de62b29d6520b6d6e8a3de69a70ca34dea85d2a8a"}, - {file = "MarkupSafe-2.1.4-cp38-cp38-win_amd64.whl", hash = "sha256:3a66c36a3864df95e4f62f9167c734b3b1192cb0851b43d7cc08040c074c6279"}, - {file = "MarkupSafe-2.1.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:765f036a3d00395a326df2835d8f86b637dbaf9832f90f5d196c3b8a7a5080cb"}, - {file = "MarkupSafe-2.1.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:21e7af8091007bf4bebf4521184f4880a6acab8df0df52ef9e513d8e5db23411"}, - {file = "MarkupSafe-2.1.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d5c31fe855c77cad679b302aabc42d724ed87c043b1432d457f4976add1c2c3e"}, - {file = "MarkupSafe-2.1.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7653fa39578957bc42e5ebc15cf4361d9e0ee4b702d7d5ec96cdac860953c5b4"}, - {file = "MarkupSafe-2.1.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:47bb5f0142b8b64ed1399b6b60f700a580335c8e1c57f2f15587bd072012decc"}, - {file = "MarkupSafe-2.1.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:fe8512ed897d5daf089e5bd010c3dc03bb1bdae00b35588c49b98268d4a01e00"}, - {file = "MarkupSafe-2.1.4-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:36d7626a8cca4d34216875aee5a1d3d654bb3dac201c1c003d182283e3205949"}, - {file = "MarkupSafe-2.1.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:b6f14a9cd50c3cb100eb94b3273131c80d102e19bb20253ac7bd7336118a673a"}, - {file = "MarkupSafe-2.1.4-cp39-cp39-win32.whl", hash = "sha256:c8f253a84dbd2c63c19590fa86a032ef3d8cc18923b8049d91bcdeeb2581fbf6"}, - {file = "MarkupSafe-2.1.4-cp39-cp39-win_amd64.whl", hash = "sha256:8b570a1537367b52396e53325769608f2a687ec9a4363647af1cded8928af959"}, - {file = "MarkupSafe-2.1.4.tar.gz", hash = "sha256:3aae9af4cac263007fd6309c64c6ab4506dd2b79382d9d19a1994f9240b8db4f"}, -] - -[[package]] -name = "mergedeep" -version = "1.3.4" -description = "A deep merge function for 🐍." -optional = false -python-versions = ">=3.6" -files = [ - {file = "mergedeep-1.3.4-py3-none-any.whl", hash = "sha256:70775750742b25c0d8f36c55aed03d24c3384d17c951b3175d898bd778ef0307"}, - {file = "mergedeep-1.3.4.tar.gz", hash = "sha256:0096d52e9dad9939c3d975a774666af186eda617e6ca84df4c94dec30004f2a8"}, -] - -[[package]] -name = "mkdocs" -version = "1.5.3" -description = "Project documentation with Markdown." -optional = false -python-versions = ">=3.7" -files = [ - {file = "mkdocs-1.5.3-py3-none-any.whl", hash = "sha256:3b3a78e736b31158d64dbb2f8ba29bd46a379d0c6e324c2246c3bc3d2189cfc1"}, - {file = "mkdocs-1.5.3.tar.gz", hash = "sha256:eb7c99214dcb945313ba30426c2451b735992c73c2e10838f76d09e39ff4d0e2"}, -] - -[package.dependencies] -click = ">=7.0" -colorama = {version = ">=0.4", markers = "platform_system == \"Windows\""} -ghp-import = ">=1.0" -importlib-metadata = {version = ">=4.3", markers = "python_version < \"3.10\""} -jinja2 = ">=2.11.1" -markdown = ">=3.2.1" -markupsafe = ">=2.0.1" -mergedeep = ">=1.3.4" -packaging = ">=20.5" -pathspec = ">=0.11.1" -platformdirs = ">=2.2.0" -pyyaml = ">=5.1" -pyyaml-env-tag = ">=0.1" -watchdog = ">=2.0" - -[package.extras] -i18n = ["babel (>=2.9.0)"] -min-versions = ["babel (==2.9.0)", "click (==7.0)", "colorama (==0.4)", "ghp-import (==1.0)", "importlib-metadata (==4.3)", "jinja2 (==2.11.1)", "markdown (==3.2.1)", "markupsafe (==2.0.1)", "mergedeep (==1.3.4)", "packaging (==20.5)", "pathspec (==0.11.1)", "platformdirs (==2.2.0)", "pyyaml (==5.1)", "pyyaml-env-tag (==0.1)", "typing-extensions (==3.10)", "watchdog (==2.0)"] - -[[package]] -name = "mkdocs-include-markdown-plugin" -version = "6.0.4" -description = "Mkdocs Markdown includer plugin." -optional = false -python-versions = ">=3.8" -files = [ - {file = "mkdocs_include_markdown_plugin-6.0.4-py3-none-any.whl", hash = "sha256:e7b8b5ecc41d6a3e16969cff3725ec3a391b68e9dfe1a4b4e36a8508becda835"}, - {file = "mkdocs_include_markdown_plugin-6.0.4.tar.gz", hash = "sha256:523c9c3a1d6a517386dc11bf60b0c0c564af1071bb6de8d213106d54f752dcc1"}, -] - -[package.dependencies] -mkdocs = ">=1.4" -wcmatch = ">=8,<9" - -[package.extras] -cache = ["platformdirs"] - -[[package]] -name = "mkdocs-markdownextradata-plugin" -version = "0.2.5" -description = "A MkDocs plugin that injects the mkdocs.yml extra variables into the markdown template" -optional = false -python-versions = ">=2.7.9,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*" -files = [ - {file = "mkdocs-markdownextradata-plugin-0.2.5.tar.gz", hash = "sha256:9c562e8fe375647d5692d11dfe369a7bdd50302174d35995fce2aeca58036ec6"}, -] - -[package.dependencies] -mkdocs = "*" -pyyaml = "*" - -[[package]] -name = "mkdocs-material" -version = "9.5.4" -description = "Documentation that simply works" -optional = false -python-versions = ">=3.8" -files = [ - {file = "mkdocs_material-9.5.4-py3-none-any.whl", hash = "sha256:efd7cc8ae03296d728da9bd38f4db8b07ab61f9738a0cbd0dfaf2a15a50e7343"}, - {file = "mkdocs_material-9.5.4.tar.gz", hash = "sha256:3d196ee67fad16b2df1a458d650a8ac1890294eaae368d26cee71bc24ad41c40"}, -] - -[package.dependencies] -babel = ">=2.10,<3.0" -colorama = ">=0.4,<1.0" -jinja2 = ">=3.0,<4.0" -markdown = ">=3.2,<4.0" -mkdocs = ">=1.5.3,<1.6.0" -mkdocs-material-extensions = ">=1.3,<2.0" -paginate = ">=0.5,<1.0" -pygments = ">=2.16,<3.0" -pymdown-extensions = ">=10.2,<11.0" -regex = ">=2022.4" -requests = ">=2.26,<3.0" - -[package.extras] -git = ["mkdocs-git-committers-plugin-2 (>=1.1,<2.0)", "mkdocs-git-revision-date-localized-plugin (>=1.2,<2.0)"] -imaging = ["cairosvg (>=2.6,<3.0)", "pillow (>=9.4,<10.0)"] -recommended = ["mkdocs-minify-plugin (>=0.7,<1.0)", "mkdocs-redirects (>=1.2,<2.0)", "mkdocs-rss-plugin (>=1.6,<2.0)"] - -[[package]] -name = "mkdocs-material-extensions" -version = "1.3.1" -description = "Extension pack for Python Markdown and MkDocs Material." -optional = false -python-versions = ">=3.8" -files = [ - {file = "mkdocs_material_extensions-1.3.1-py3-none-any.whl", hash = "sha256:adff8b62700b25cb77b53358dad940f3ef973dd6db797907c49e3c2ef3ab4e31"}, - {file = "mkdocs_material_extensions-1.3.1.tar.gz", hash = "sha256:10c9511cea88f568257f960358a467d12b970e1f7b2c0e5fb2bb48cab1928443"}, -] - -[[package]] -name = "mkdocs-rss-plugin" -version = "1.5.0" -description = "MkDocs plugin which generates a static RSS feed using git log and page.meta." -optional = false -python-versions = ">=3.7, <4" -files = [] -develop = false - -[package.dependencies] -GitPython = ">=3.1,<3.2" -mkdocs = ">=1.1,<2" -tzdata = {version = "==2022.*", markers = "python_version >= \"3.9\" and sys_platform == \"win32\""} - -[package.extras] -dev = ["black", "feedparser (>=6.0,<6.1)", "flake8 (>=4,<5.1)", "pre-commit (>=2.10,<2.21)", "pytest-cov (==4.0.*)", "validator-collection (>=1.5,<1.6)"] -doc = ["mkdocs-bootswatch (>=1,<2)", "mkdocs-minify-plugin (==0.5.*)", "pygments (>=2.5,<3)", "pymdown-extensions (>=7,<10)"] - -[package.source] -type = "git" -url = "https://github.com/cachix/mkdocs-rss-plugin" -reference = "no-git" -resolved_reference = "017bdb52095703c79e0632f219b5adf9f212873c" - -[[package]] -name = "packaging" -version = "23.2" -description = "Core utilities for Python packages" -optional = false -python-versions = ">=3.7" -files = [ - {file = "packaging-23.2-py3-none-any.whl", hash = "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"}, - {file = "packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5"}, -] - -[[package]] -name = "paginate" -version = "0.5.6" -description = "Divides large result sets into pages for easier browsing" -optional = false -python-versions = "*" -files = [ - {file = "paginate-0.5.6.tar.gz", hash = "sha256:5e6007b6a9398177a7e1648d04fdd9f8c9766a1a945bceac82f1929e8c78af2d"}, -] - -[[package]] -name = "pathspec" -version = "0.12.1" -description = "Utility library for gitignore style pattern matching of file paths." -optional = false -python-versions = ">=3.8" -files = [ - {file = "pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08"}, - {file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"}, -] - -[[package]] -name = "pillow" -version = "9.5.0" -description = "Python Imaging Library (Fork)" -optional = false -python-versions = ">=3.7" -files = [ - {file = "Pillow-9.5.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:ace6ca218308447b9077c14ea4ef381ba0b67ee78d64046b3f19cf4e1139ad16"}, - {file = "Pillow-9.5.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d3d403753c9d5adc04d4694d35cf0391f0f3d57c8e0030aac09d7678fa8030aa"}, - {file = "Pillow-9.5.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5ba1b81ee69573fe7124881762bb4cd2e4b6ed9dd28c9c60a632902fe8db8b38"}, - {file = "Pillow-9.5.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fe7e1c262d3392afcf5071df9afa574544f28eac825284596ac6db56e6d11062"}, - {file = "Pillow-9.5.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f36397bf3f7d7c6a3abdea815ecf6fd14e7fcd4418ab24bae01008d8d8ca15e"}, - {file = "Pillow-9.5.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:252a03f1bdddce077eff2354c3861bf437c892fb1832f75ce813ee94347aa9b5"}, - {file = "Pillow-9.5.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:85ec677246533e27770b0de5cf0f9d6e4ec0c212a1f89dfc941b64b21226009d"}, - {file = "Pillow-9.5.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b416f03d37d27290cb93597335a2f85ed446731200705b22bb927405320de903"}, - {file = "Pillow-9.5.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:1781a624c229cb35a2ac31cc4a77e28cafc8900733a864870c49bfeedacd106a"}, - {file = "Pillow-9.5.0-cp310-cp310-win32.whl", hash = "sha256:8507eda3cd0608a1f94f58c64817e83ec12fa93a9436938b191b80d9e4c0fc44"}, - {file = "Pillow-9.5.0-cp310-cp310-win_amd64.whl", hash = "sha256:d3c6b54e304c60c4181da1c9dadf83e4a54fd266a99c70ba646a9baa626819eb"}, - {file = "Pillow-9.5.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:7ec6f6ce99dab90b52da21cf0dc519e21095e332ff3b399a357c187b1a5eee32"}, - {file = "Pillow-9.5.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:560737e70cb9c6255d6dcba3de6578a9e2ec4b573659943a5e7e4af13f298f5c"}, - {file = "Pillow-9.5.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:96e88745a55b88a7c64fa49bceff363a1a27d9a64e04019c2281049444a571e3"}, - {file = "Pillow-9.5.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d9c206c29b46cfd343ea7cdfe1232443072bbb270d6a46f59c259460db76779a"}, - {file = "Pillow-9.5.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cfcc2c53c06f2ccb8976fb5c71d448bdd0a07d26d8e07e321c103416444c7ad1"}, - {file = "Pillow-9.5.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:a0f9bb6c80e6efcde93ffc51256d5cfb2155ff8f78292f074f60f9e70b942d99"}, - {file = "Pillow-9.5.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:8d935f924bbab8f0a9a28404422da8af4904e36d5c33fc6f677e4c4485515625"}, - {file = "Pillow-9.5.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:fed1e1cf6a42577953abbe8e6cf2fe2f566daebde7c34724ec8803c4c0cda579"}, - {file = "Pillow-9.5.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:c1170d6b195555644f0616fd6ed929dfcf6333b8675fcca044ae5ab110ded296"}, - {file = "Pillow-9.5.0-cp311-cp311-win32.whl", hash = "sha256:54f7102ad31a3de5666827526e248c3530b3a33539dbda27c6843d19d72644ec"}, - {file = "Pillow-9.5.0-cp311-cp311-win_amd64.whl", hash = "sha256:cfa4561277f677ecf651e2b22dc43e8f5368b74a25a8f7d1d4a3a243e573f2d4"}, - {file = "Pillow-9.5.0-cp311-cp311-win_arm64.whl", hash = "sha256:965e4a05ef364e7b973dd17fc765f42233415974d773e82144c9bbaaaea5d089"}, - {file = "Pillow-9.5.0-cp312-cp312-win32.whl", hash = "sha256:22baf0c3cf0c7f26e82d6e1adf118027afb325e703922c8dfc1d5d0156bb2eeb"}, - {file = "Pillow-9.5.0-cp312-cp312-win_amd64.whl", hash = "sha256:432b975c009cf649420615388561c0ce7cc31ce9b2e374db659ee4f7d57a1f8b"}, - {file = "Pillow-9.5.0-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:5d4ebf8e1db4441a55c509c4baa7a0587a0210f7cd25fcfe74dbbce7a4bd1906"}, - {file = "Pillow-9.5.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:375f6e5ee9620a271acb6820b3d1e94ffa8e741c0601db4c0c4d3cb0a9c224bf"}, - {file = "Pillow-9.5.0-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:99eb6cafb6ba90e436684e08dad8be1637efb71c4f2180ee6b8f940739406e78"}, - {file = "Pillow-9.5.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2dfaaf10b6172697b9bceb9a3bd7b951819d1ca339a5ef294d1f1ac6d7f63270"}, - {file = "Pillow-9.5.0-cp37-cp37m-manylinux_2_28_aarch64.whl", hash = "sha256:763782b2e03e45e2c77d7779875f4432e25121ef002a41829d8868700d119392"}, - {file = "Pillow-9.5.0-cp37-cp37m-manylinux_2_28_x86_64.whl", hash = "sha256:35f6e77122a0c0762268216315bf239cf52b88865bba522999dc38f1c52b9b47"}, - {file = "Pillow-9.5.0-cp37-cp37m-win32.whl", hash = "sha256:aca1c196f407ec7cf04dcbb15d19a43c507a81f7ffc45b690899d6a76ac9fda7"}, - {file = "Pillow-9.5.0-cp37-cp37m-win_amd64.whl", hash = "sha256:322724c0032af6692456cd6ed554bb85f8149214d97398bb80613b04e33769f6"}, - {file = "Pillow-9.5.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:a0aa9417994d91301056f3d0038af1199eb7adc86e646a36b9e050b06f526597"}, - {file = "Pillow-9.5.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f8286396b351785801a976b1e85ea88e937712ee2c3ac653710a4a57a8da5d9c"}, - {file = "Pillow-9.5.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c830a02caeb789633863b466b9de10c015bded434deb3ec87c768e53752ad22a"}, - {file = "Pillow-9.5.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fbd359831c1657d69bb81f0db962905ee05e5e9451913b18b831febfe0519082"}, - {file = "Pillow-9.5.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8fc330c3370a81bbf3f88557097d1ea26cd8b019d6433aa59f71195f5ddebbf"}, - {file = "Pillow-9.5.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:7002d0797a3e4193c7cdee3198d7c14f92c0836d6b4a3f3046a64bd1ce8df2bf"}, - {file = "Pillow-9.5.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:229e2c79c00e85989a34b5981a2b67aa079fd08c903f0aaead522a1d68d79e51"}, - {file = "Pillow-9.5.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:9adf58f5d64e474bed00d69bcd86ec4bcaa4123bfa70a65ce72e424bfb88ed96"}, - {file = "Pillow-9.5.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:662da1f3f89a302cc22faa9f14a262c2e3951f9dbc9617609a47521c69dd9f8f"}, - {file = "Pillow-9.5.0-cp38-cp38-win32.whl", hash = "sha256:6608ff3bf781eee0cd14d0901a2b9cc3d3834516532e3bd673a0a204dc8615fc"}, - {file = "Pillow-9.5.0-cp38-cp38-win_amd64.whl", hash = "sha256:e49eb4e95ff6fd7c0c402508894b1ef0e01b99a44320ba7d8ecbabefddcc5569"}, - {file = "Pillow-9.5.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:482877592e927fd263028c105b36272398e3e1be3269efda09f6ba21fd83ec66"}, - {file = "Pillow-9.5.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3ded42b9ad70e5f1754fb7c2e2d6465a9c842e41d178f262e08b8c85ed8a1d8e"}, - {file = "Pillow-9.5.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c446d2245ba29820d405315083d55299a796695d747efceb5717a8b450324115"}, - {file = "Pillow-9.5.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8aca1152d93dcc27dc55395604dcfc55bed5f25ef4c98716a928bacba90d33a3"}, - {file = "Pillow-9.5.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:608488bdcbdb4ba7837461442b90ea6f3079397ddc968c31265c1e056964f1ef"}, - {file = "Pillow-9.5.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:60037a8db8750e474af7ffc9faa9b5859e6c6d0a50e55c45576bf28be7419705"}, - {file = "Pillow-9.5.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:07999f5834bdc404c442146942a2ecadd1cb6292f5229f4ed3b31e0a108746b1"}, - {file = "Pillow-9.5.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:a127ae76092974abfbfa38ca2d12cbeddcdeac0fb71f9627cc1135bedaf9d51a"}, - {file = "Pillow-9.5.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:489f8389261e5ed43ac8ff7b453162af39c3e8abd730af8363587ba64bb2e865"}, - {file = "Pillow-9.5.0-cp39-cp39-win32.whl", hash = "sha256:9b1af95c3a967bf1da94f253e56b6286b50af23392a886720f563c547e48e964"}, - {file = "Pillow-9.5.0-cp39-cp39-win_amd64.whl", hash = "sha256:77165c4a5e7d5a284f10a6efaa39a0ae8ba839da344f20b111d62cc932fa4e5d"}, - {file = "Pillow-9.5.0-pp38-pypy38_pp73-macosx_10_10_x86_64.whl", hash = "sha256:833b86a98e0ede388fa29363159c9b1a294b0905b5128baf01db683672f230f5"}, - {file = "Pillow-9.5.0-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aaf305d6d40bd9632198c766fb64f0c1a83ca5b667f16c1e79e1661ab5060140"}, - {file = "Pillow-9.5.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0852ddb76d85f127c135b6dd1f0bb88dbb9ee990d2cd9aa9e28526c93e794fba"}, - {file = "Pillow-9.5.0-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:91ec6fe47b5eb5a9968c79ad9ed78c342b1f97a091677ba0e012701add857829"}, - {file = "Pillow-9.5.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:cb841572862f629b99725ebaec3287fc6d275be9b14443ea746c1dd325053cbd"}, - {file = "Pillow-9.5.0-pp39-pypy39_pp73-macosx_10_10_x86_64.whl", hash = "sha256:c380b27d041209b849ed246b111b7c166ba36d7933ec6e41175fd15ab9eb1572"}, - {file = "Pillow-9.5.0-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7c9af5a3b406a50e313467e3565fc99929717f780164fe6fbb7704edba0cebbe"}, - {file = "Pillow-9.5.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5671583eab84af046a397d6d0ba25343c00cd50bce03787948e0fff01d4fd9b1"}, - {file = "Pillow-9.5.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:84a6f19ce086c1bf894644b43cd129702f781ba5751ca8572f08aa40ef0ab7b7"}, - {file = "Pillow-9.5.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:1e7723bd90ef94eda669a3c2c19d549874dd5badaeefabefd26053304abe5799"}, - {file = "Pillow-9.5.0.tar.gz", hash = "sha256:bf548479d336726d7a0eceb6e767e179fbde37833ae42794602631a070d630f1"}, -] - -[package.extras] -docs = ["furo", "olefile", "sphinx (>=2.4)", "sphinx-copybutton", "sphinx-inline-tabs", "sphinx-removed-in", "sphinxext-opengraph"] -tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout"] - -[[package]] -name = "platformdirs" -version = "4.1.0" -description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." -optional = false -python-versions = ">=3.8" -files = [ - {file = "platformdirs-4.1.0-py3-none-any.whl", hash = "sha256:11c8f37bcca40db96d8144522d925583bdb7a31f7b0e37e3ed4318400a8e2380"}, - {file = "platformdirs-4.1.0.tar.gz", hash = "sha256:906d548203468492d432bcb294d4bc2fff751bf84971fbb2c10918cc206ee420"}, -] - -[package.extras] -docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.1)", "sphinx-autodoc-typehints (>=1.24)"] -test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4)", "pytest-cov (>=4.1)", "pytest-mock (>=3.11.1)"] - -[[package]] -name = "pycparser" -version = "2.21" -description = "C parser in Python" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -files = [ - {file = "pycparser-2.21-py2.py3-none-any.whl", hash = "sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9"}, - {file = "pycparser-2.21.tar.gz", hash = "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206"}, -] - -[[package]] -name = "pygments" -version = "2.17.2" -description = "Pygments is a syntax highlighting package written in Python." -optional = false -python-versions = ">=3.7" -files = [ - {file = "pygments-2.17.2-py3-none-any.whl", hash = "sha256:b27c2826c47d0f3219f29554824c30c5e8945175d888647acd804ddd04af846c"}, - {file = "pygments-2.17.2.tar.gz", hash = "sha256:da46cec9fd2de5be3a8a784f434e4c4ab670b4ff54d605c4c2717e9d49c4c367"}, -] - -[package.extras] -plugins = ["importlib-metadata"] -windows-terminal = ["colorama (>=0.4.6)"] - -[[package]] -name = "pymdown-extensions" -version = "10.7" -description = "Extension pack for Python Markdown." -optional = false -python-versions = ">=3.8" -files = [ - {file = "pymdown_extensions-10.7-py3-none-any.whl", hash = "sha256:6ca215bc57bc12bf32b414887a68b810637d039124ed9b2e5bd3325cbb2c050c"}, - {file = "pymdown_extensions-10.7.tar.gz", hash = "sha256:c0d64d5cf62566f59e6b2b690a4095c931107c250a8c8e1351c1de5f6b036deb"}, -] - -[package.dependencies] -markdown = ">=3.5" -pyyaml = "*" - -[package.extras] -extra = ["pygments (>=2.12)"] - -[[package]] -name = "python-dateutil" -version = "2.8.2" -description = "Extensions to the standard Python datetime module" -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" -files = [ - {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"}, - {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"}, -] - -[package.dependencies] -six = ">=1.5" - -[[package]] -name = "pyyaml" -version = "6.0.1" -description = "YAML parser and emitter for Python" -optional = false -python-versions = ">=3.6" -files = [ - {file = "PyYAML-6.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a"}, - {file = "PyYAML-6.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"}, - {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, - {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, - {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, - {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"}, - {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, - {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, - {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, - {file = "PyYAML-6.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab"}, - {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, - {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, - {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, - {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"}, - {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, - {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, - {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, - {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, - {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"}, - {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, - {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, - {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, - {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"}, - {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, - {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, - {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, - {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd"}, - {file = "PyYAML-6.0.1-cp36-cp36m-win32.whl", hash = "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585"}, - {file = "PyYAML-6.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa"}, - {file = "PyYAML-6.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3"}, - {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27"}, - {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3"}, - {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c"}, - {file = "PyYAML-6.0.1-cp37-cp37m-win32.whl", hash = "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba"}, - {file = "PyYAML-6.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867"}, - {file = "PyYAML-6.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595"}, - {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, - {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, - {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, - {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"}, - {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, - {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, - {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, - {file = "PyYAML-6.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859"}, - {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, - {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, - {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, - {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"}, - {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, - {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, - {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, -] - -[[package]] -name = "pyyaml-env-tag" -version = "0.1" -description = "A custom YAML tag for referencing environment variables in YAML files. " -optional = false -python-versions = ">=3.6" -files = [ - {file = "pyyaml_env_tag-0.1-py3-none-any.whl", hash = "sha256:af31106dec8a4d68c60207c1886031cbf839b68aa7abccdb19868200532c2069"}, - {file = "pyyaml_env_tag-0.1.tar.gz", hash = "sha256:70092675bda14fdec33b31ba77e7543de9ddc88f2e5b99160396572d11525bdb"}, -] - -[package.dependencies] -pyyaml = "*" - -[[package]] -name = "regex" -version = "2023.12.25" -description = "Alternative regular expression module, to replace re." -optional = false -python-versions = ">=3.7" -files = [ - {file = "regex-2023.12.25-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0694219a1d54336fd0445ea382d49d36882415c0134ee1e8332afd1529f0baa5"}, - {file = "regex-2023.12.25-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b014333bd0217ad3d54c143de9d4b9a3ca1c5a29a6d0d554952ea071cff0f1f8"}, - {file = "regex-2023.12.25-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d865984b3f71f6d0af64d0d88f5733521698f6c16f445bb09ce746c92c97c586"}, - {file = "regex-2023.12.25-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1e0eabac536b4cc7f57a5f3d095bfa557860ab912f25965e08fe1545e2ed8b4c"}, - {file = "regex-2023.12.25-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c25a8ad70e716f96e13a637802813f65d8a6760ef48672aa3502f4c24ea8b400"}, - {file = "regex-2023.12.25-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a9b6d73353f777630626f403b0652055ebfe8ff142a44ec2cf18ae470395766e"}, - {file = "regex-2023.12.25-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a9cc99d6946d750eb75827cb53c4371b8b0fe89c733a94b1573c9dd16ea6c9e4"}, - {file = "regex-2023.12.25-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:88d1f7bef20c721359d8675f7d9f8e414ec5003d8f642fdfd8087777ff7f94b5"}, - {file = "regex-2023.12.25-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:cb3fe77aec8f1995611f966d0c656fdce398317f850d0e6e7aebdfe61f40e1cd"}, - {file = "regex-2023.12.25-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:7aa47c2e9ea33a4a2a05f40fcd3ea36d73853a2aae7b4feab6fc85f8bf2c9704"}, - {file = "regex-2023.12.25-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:df26481f0c7a3f8739fecb3e81bc9da3fcfae34d6c094563b9d4670b047312e1"}, - {file = "regex-2023.12.25-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:c40281f7d70baf6e0db0c2f7472b31609f5bc2748fe7275ea65a0b4601d9b392"}, - {file = "regex-2023.12.25-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:d94a1db462d5690ebf6ae86d11c5e420042b9898af5dcf278bd97d6bda065423"}, - {file = "regex-2023.12.25-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:ba1b30765a55acf15dce3f364e4928b80858fa8f979ad41f862358939bdd1f2f"}, - {file = "regex-2023.12.25-cp310-cp310-win32.whl", hash = "sha256:150c39f5b964e4d7dba46a7962a088fbc91f06e606f023ce57bb347a3b2d4630"}, - {file = "regex-2023.12.25-cp310-cp310-win_amd64.whl", hash = "sha256:09da66917262d9481c719599116c7dc0c321ffcec4b1f510c4f8a066f8768105"}, - {file = "regex-2023.12.25-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:1b9d811f72210fa9306aeb88385b8f8bcef0dfbf3873410413c00aa94c56c2b6"}, - {file = "regex-2023.12.25-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d902a43085a308cef32c0d3aea962524b725403fd9373dea18110904003bac97"}, - {file = "regex-2023.12.25-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d166eafc19f4718df38887b2bbe1467a4f74a9830e8605089ea7a30dd4da8887"}, - {file = "regex-2023.12.25-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c7ad32824b7f02bb3c9f80306d405a1d9b7bb89362d68b3c5a9be53836caebdb"}, - {file = "regex-2023.12.25-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:636ba0a77de609d6510235b7f0e77ec494d2657108f777e8765efc060094c98c"}, - {file = "regex-2023.12.25-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0fda75704357805eb953a3ee15a2b240694a9a514548cd49b3c5124b4e2ad01b"}, - {file = "regex-2023.12.25-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f72cbae7f6b01591f90814250e636065850c5926751af02bb48da94dfced7baa"}, - {file = "regex-2023.12.25-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:db2a0b1857f18b11e3b0e54ddfefc96af46b0896fb678c85f63fb8c37518b3e7"}, - {file = "regex-2023.12.25-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:7502534e55c7c36c0978c91ba6f61703faf7ce733715ca48f499d3dbbd7657e0"}, - {file = "regex-2023.12.25-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:e8c7e08bb566de4faaf11984af13f6bcf6a08f327b13631d41d62592681d24fe"}, - {file = "regex-2023.12.25-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:283fc8eed679758de38fe493b7d7d84a198b558942b03f017b1f94dda8efae80"}, - {file = "regex-2023.12.25-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:f44dd4d68697559d007462b0a3a1d9acd61d97072b71f6d1968daef26bc744bd"}, - {file = "regex-2023.12.25-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:67d3ccfc590e5e7197750fcb3a2915b416a53e2de847a728cfa60141054123d4"}, - {file = "regex-2023.12.25-cp311-cp311-win32.whl", hash = "sha256:68191f80a9bad283432385961d9efe09d783bcd36ed35a60fb1ff3f1ec2efe87"}, - {file = "regex-2023.12.25-cp311-cp311-win_amd64.whl", hash = "sha256:7d2af3f6b8419661a0c421584cfe8aaec1c0e435ce7e47ee2a97e344b98f794f"}, - {file = "regex-2023.12.25-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8a0ccf52bb37d1a700375a6b395bff5dd15c50acb745f7db30415bae3c2b0715"}, - {file = "regex-2023.12.25-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c3c4a78615b7762740531c27cf46e2f388d8d727d0c0c739e72048beb26c8a9d"}, - {file = "regex-2023.12.25-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ad83e7545b4ab69216cef4cc47e344d19622e28aabec61574b20257c65466d6a"}, - {file = "regex-2023.12.25-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b7a635871143661feccce3979e1727c4e094f2bdfd3ec4b90dfd4f16f571a87a"}, - {file = "regex-2023.12.25-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d498eea3f581fbe1b34b59c697512a8baef88212f92e4c7830fcc1499f5b45a5"}, - {file = "regex-2023.12.25-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:43f7cd5754d02a56ae4ebb91b33461dc67be8e3e0153f593c509e21d219c5060"}, - {file = "regex-2023.12.25-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:51f4b32f793812714fd5307222a7f77e739b9bc566dc94a18126aba3b92b98a3"}, - {file = "regex-2023.12.25-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba99d8077424501b9616b43a2d208095746fb1284fc5ba490139651f971d39d9"}, - {file = "regex-2023.12.25-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:4bfc2b16e3ba8850e0e262467275dd4d62f0d045e0e9eda2bc65078c0110a11f"}, - {file = "regex-2023.12.25-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8c2c19dae8a3eb0ea45a8448356ed561be843b13cbc34b840922ddf565498c1c"}, - {file = "regex-2023.12.25-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:60080bb3d8617d96f0fb7e19796384cc2467447ef1c491694850ebd3670bc457"}, - {file = "regex-2023.12.25-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b77e27b79448e34c2c51c09836033056a0547aa360c45eeeb67803da7b0eedaf"}, - {file = "regex-2023.12.25-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:518440c991f514331f4850a63560321f833979d145d7d81186dbe2f19e27ae3d"}, - {file = "regex-2023.12.25-cp312-cp312-win32.whl", hash = "sha256:e2610e9406d3b0073636a3a2e80db05a02f0c3169b5632022b4e81c0364bcda5"}, - {file = "regex-2023.12.25-cp312-cp312-win_amd64.whl", hash = "sha256:cc37b9aeebab425f11f27e5e9e6cf580be7206c6582a64467a14dda211abc232"}, - {file = "regex-2023.12.25-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:da695d75ac97cb1cd725adac136d25ca687da4536154cdc2815f576e4da11c69"}, - {file = "regex-2023.12.25-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d126361607b33c4eb7b36debc173bf25d7805847346dd4d99b5499e1fef52bc7"}, - {file = "regex-2023.12.25-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4719bb05094d7d8563a450cf8738d2e1061420f79cfcc1fa7f0a44744c4d8f73"}, - {file = "regex-2023.12.25-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5dd58946bce44b53b06d94aa95560d0b243eb2fe64227cba50017a8d8b3cd3e2"}, - {file = "regex-2023.12.25-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:22a86d9fff2009302c440b9d799ef2fe322416d2d58fc124b926aa89365ec482"}, - {file = "regex-2023.12.25-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2aae8101919e8aa05ecfe6322b278f41ce2994c4a430303c4cd163fef746e04f"}, - {file = "regex-2023.12.25-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:e692296c4cc2873967771345a876bcfc1c547e8dd695c6b89342488b0ea55cd8"}, - {file = "regex-2023.12.25-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:263ef5cc10979837f243950637fffb06e8daed7f1ac1e39d5910fd29929e489a"}, - {file = "regex-2023.12.25-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:d6f7e255e5fa94642a0724e35406e6cb7001c09d476ab5fce002f652b36d0c39"}, - {file = "regex-2023.12.25-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:88ad44e220e22b63b0f8f81f007e8abbb92874d8ced66f32571ef8beb0643b2b"}, - {file = "regex-2023.12.25-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:3a17d3ede18f9cedcbe23d2daa8a2cd6f59fe2bf082c567e43083bba3fb00347"}, - {file = "regex-2023.12.25-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:d15b274f9e15b1a0b7a45d2ac86d1f634d983ca40d6b886721626c47a400bf39"}, - {file = "regex-2023.12.25-cp37-cp37m-win32.whl", hash = "sha256:ed19b3a05ae0c97dd8f75a5d8f21f7723a8c33bbc555da6bbe1f96c470139d3c"}, - {file = "regex-2023.12.25-cp37-cp37m-win_amd64.whl", hash = "sha256:a6d1047952c0b8104a1d371f88f4ab62e6275567d4458c1e26e9627ad489b445"}, - {file = "regex-2023.12.25-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:b43523d7bc2abd757119dbfb38af91b5735eea45537ec6ec3a5ec3f9562a1c53"}, - {file = "regex-2023.12.25-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:efb2d82f33b2212898f1659fb1c2e9ac30493ac41e4d53123da374c3b5541e64"}, - {file = "regex-2023.12.25-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b7fca9205b59c1a3d5031f7e64ed627a1074730a51c2a80e97653e3e9fa0d415"}, - {file = "regex-2023.12.25-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:086dd15e9435b393ae06f96ab69ab2d333f5d65cbe65ca5a3ef0ec9564dfe770"}, - {file = "regex-2023.12.25-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e81469f7d01efed9b53740aedd26085f20d49da65f9c1f41e822a33992cb1590"}, - {file = "regex-2023.12.25-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:34e4af5b27232f68042aa40a91c3b9bb4da0eeb31b7632e0091afc4310afe6cb"}, - {file = "regex-2023.12.25-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9852b76ab558e45b20bf1893b59af64a28bd3820b0c2efc80e0a70a4a3ea51c1"}, - {file = "regex-2023.12.25-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ff100b203092af77d1a5a7abe085b3506b7eaaf9abf65b73b7d6905b6cb76988"}, - {file = "regex-2023.12.25-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:cc038b2d8b1470364b1888a98fd22d616fba2b6309c5b5f181ad4483e0017861"}, - {file = "regex-2023.12.25-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:094ba386bb5c01e54e14434d4caabf6583334090865b23ef58e0424a6286d3dc"}, - {file = "regex-2023.12.25-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:5cd05d0f57846d8ba4b71d9c00f6f37d6b97d5e5ef8b3c3840426a475c8f70f4"}, - {file = "regex-2023.12.25-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:9aa1a67bbf0f957bbe096375887b2505f5d8ae16bf04488e8b0f334c36e31360"}, - {file = "regex-2023.12.25-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:98a2636994f943b871786c9e82bfe7883ecdaba2ef5df54e1450fa9869d1f756"}, - {file = "regex-2023.12.25-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:37f8e93a81fc5e5bd8db7e10e62dc64261bcd88f8d7e6640aaebe9bc180d9ce2"}, - {file = "regex-2023.12.25-cp38-cp38-win32.whl", hash = "sha256:d78bd484930c1da2b9679290a41cdb25cc127d783768a0369d6b449e72f88beb"}, - {file = "regex-2023.12.25-cp38-cp38-win_amd64.whl", hash = "sha256:b521dcecebc5b978b447f0f69b5b7f3840eac454862270406a39837ffae4e697"}, - {file = "regex-2023.12.25-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:f7bc09bc9c29ebead055bcba136a67378f03d66bf359e87d0f7c759d6d4ffa31"}, - {file = "regex-2023.12.25-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e14b73607d6231f3cc4622809c196b540a6a44e903bcfad940779c80dffa7be7"}, - {file = "regex-2023.12.25-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9eda5f7a50141291beda3edd00abc2d4a5b16c29c92daf8d5bd76934150f3edc"}, - {file = "regex-2023.12.25-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cc6bb9aa69aacf0f6032c307da718f61a40cf970849e471254e0e91c56ffca95"}, - {file = "regex-2023.12.25-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:298dc6354d414bc921581be85695d18912bea163a8b23cac9a2562bbcd5088b1"}, - {file = "regex-2023.12.25-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2f4e475a80ecbd15896a976aa0b386c5525d0ed34d5c600b6d3ebac0a67c7ddf"}, - {file = "regex-2023.12.25-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:531ac6cf22b53e0696f8e1d56ce2396311254eb806111ddd3922c9d937151dae"}, - {file = "regex-2023.12.25-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:22f3470f7524b6da61e2020672df2f3063676aff444db1daa283c2ea4ed259d6"}, - {file = "regex-2023.12.25-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:89723d2112697feaa320c9d351e5f5e7b841e83f8b143dba8e2d2b5f04e10923"}, - {file = "regex-2023.12.25-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0ecf44ddf9171cd7566ef1768047f6e66975788258b1c6c6ca78098b95cf9a3d"}, - {file = "regex-2023.12.25-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:905466ad1702ed4acfd67a902af50b8db1feeb9781436372261808df7a2a7bca"}, - {file = "regex-2023.12.25-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:4558410b7a5607a645e9804a3e9dd509af12fb72b9825b13791a37cd417d73a5"}, - {file = "regex-2023.12.25-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:7e316026cc1095f2a3e8cc012822c99f413b702eaa2ca5408a513609488cb62f"}, - {file = "regex-2023.12.25-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:3b1de218d5375cd6ac4b5493e0b9f3df2be331e86520f23382f216c137913d20"}, - {file = "regex-2023.12.25-cp39-cp39-win32.whl", hash = "sha256:11a963f8e25ab5c61348d090bf1b07f1953929c13bd2309a0662e9ff680763c9"}, - {file = "regex-2023.12.25-cp39-cp39-win_amd64.whl", hash = "sha256:e693e233ac92ba83a87024e1d32b5f9ab15ca55ddd916d878146f4e3406b5c91"}, - {file = "regex-2023.12.25.tar.gz", hash = "sha256:29171aa128da69afdf4bde412d5bedc335f2ca8fcfe4489038577d05f16181e5"}, -] - -[[package]] -name = "requests" -version = "2.31.0" -description = "Python HTTP for Humans." -optional = false -python-versions = ">=3.7" -files = [ - {file = "requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f"}, - {file = "requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"}, -] - -[package.dependencies] -certifi = ">=2017.4.17" -charset-normalizer = ">=2,<4" -idna = ">=2.5,<4" -urllib3 = ">=1.21.1,<3" - -[package.extras] -socks = ["PySocks (>=1.5.6,!=1.5.7)"] -use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] - -[[package]] -name = "six" -version = "1.16.0" -description = "Python 2 and 3 compatibility utilities" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" -files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, -] - -[[package]] -name = "smmap" -version = "5.0.1" -description = "A pure Python implementation of a sliding window memory map manager" -optional = false -python-versions = ">=3.7" -files = [ - {file = "smmap-5.0.1-py3-none-any.whl", hash = "sha256:e6d8668fa5f93e706934a62d7b4db19c8d9eb8cf2adbb75ef1b675aa332b69da"}, - {file = "smmap-5.0.1.tar.gz", hash = "sha256:dceeb6c0028fdb6734471eb07c0cd2aae706ccaecab45965ee83f11c8d3b1f62"}, -] - -[[package]] -name = "strictyaml" -version = "1.7.3" -description = "Strict, typed YAML parser" -optional = false -python-versions = ">=3.7.0" -files = [ - {file = "strictyaml-1.7.3-py3-none-any.whl", hash = "sha256:fb5c8a4edb43bebb765959e420f9b3978d7f1af88c80606c03fb420888f5d1c7"}, - {file = "strictyaml-1.7.3.tar.gz", hash = "sha256:22f854a5fcab42b5ddba8030a0e4be51ca89af0267961c8d6cfa86395586c407"}, -] - -[package.dependencies] -python-dateutil = ">=2.6.0" - -[[package]] -name = "terminaltables" -version = "3.1.10" -description = "Generate simple tables in terminals from a nested list of strings." -optional = false -python-versions = ">=2.6" -files = [ - {file = "terminaltables-3.1.10-py2.py3-none-any.whl", hash = "sha256:e4fdc4179c9e4aab5f674d80f09d76fa436b96fdc698a8505e0a36bf0804a874"}, - {file = "terminaltables-3.1.10.tar.gz", hash = "sha256:ba6eca5cb5ba02bba4c9f4f985af80c54ec3dccf94cfcd190154386255e47543"}, -] - -[[package]] -name = "tinycss2" -version = "1.2.1" -description = "A tiny CSS parser" -optional = false -python-versions = ">=3.7" -files = [ - {file = "tinycss2-1.2.1-py3-none-any.whl", hash = "sha256:2b80a96d41e7c3914b8cda8bc7f705a4d9c49275616e886103dd839dfc847847"}, - {file = "tinycss2-1.2.1.tar.gz", hash = "sha256:8cff3a8f066c2ec677c06dbc7b45619804a6938478d9d73c284b29d14ecb0627"}, -] - -[package.dependencies] -webencodings = ">=0.4" - -[package.extras] -doc = ["sphinx", "sphinx_rtd_theme"] -test = ["flake8", "isort", "pytest"] - -[[package]] -name = "tzdata" -version = "2022.7" -description = "Provider of IANA time zone data" -optional = false -python-versions = ">=2" -files = [ - {file = "tzdata-2022.7-py2.py3-none-any.whl", hash = "sha256:2b88858b0e3120792a3c0635c23daf36a7d7eeeca657c323da299d2094402a0d"}, - {file = "tzdata-2022.7.tar.gz", hash = "sha256:fe5f866eddd8b96e9fcba978f8e503c909b19ea7efda11e52e39494bad3a7bfa"}, -] - -[[package]] -name = "urllib3" -version = "2.1.0" -description = "HTTP library with thread-safe connection pooling, file post, and more." -optional = false -python-versions = ">=3.8" -files = [ - {file = "urllib3-2.1.0-py3-none-any.whl", hash = "sha256:55901e917a5896a349ff771be919f8bd99aff50b79fe58fec595eb37bbc56bb3"}, - {file = "urllib3-2.1.0.tar.gz", hash = "sha256:df7aa8afb0148fa78488e7899b2c59b5f4ffcfa82e6c54ccb9dd37c1d7b52d54"}, -] - -[package.extras] -brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] -socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] -zstd = ["zstandard (>=0.18.0)"] - -[[package]] -name = "watchdog" -version = "3.0.0" -description = "Filesystem events monitoring" -optional = false -python-versions = ">=3.7" -files = [ - {file = "watchdog-3.0.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:336adfc6f5cc4e037d52db31194f7581ff744b67382eb6021c868322e32eef41"}, - {file = "watchdog-3.0.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a70a8dcde91be523c35b2bf96196edc5730edb347e374c7de7cd20c43ed95397"}, - {file = "watchdog-3.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:adfdeab2da79ea2f76f87eb42a3ab1966a5313e5a69a0213a3cc06ef692b0e96"}, - {file = "watchdog-3.0.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2b57a1e730af3156d13b7fdddfc23dea6487fceca29fc75c5a868beed29177ae"}, - {file = "watchdog-3.0.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7ade88d0d778b1b222adebcc0927428f883db07017618a5e684fd03b83342bd9"}, - {file = "watchdog-3.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7e447d172af52ad204d19982739aa2346245cc5ba6f579d16dac4bfec226d2e7"}, - {file = "watchdog-3.0.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:9fac43a7466eb73e64a9940ac9ed6369baa39b3bf221ae23493a9ec4d0022674"}, - {file = "watchdog-3.0.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:8ae9cda41fa114e28faf86cb137d751a17ffd0316d1c34ccf2235e8a84365c7f"}, - {file = "watchdog-3.0.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:25f70b4aa53bd743729c7475d7ec41093a580528b100e9a8c5b5efe8899592fc"}, - {file = "watchdog-3.0.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4f94069eb16657d2c6faada4624c39464f65c05606af50bb7902e036e3219be3"}, - {file = "watchdog-3.0.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7c5f84b5194c24dd573fa6472685b2a27cc5a17fe5f7b6fd40345378ca6812e3"}, - {file = "watchdog-3.0.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3aa7f6a12e831ddfe78cdd4f8996af9cf334fd6346531b16cec61c3b3c0d8da0"}, - {file = "watchdog-3.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:233b5817932685d39a7896b1090353fc8efc1ef99c9c054e46c8002561252fb8"}, - {file = "watchdog-3.0.0-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:13bbbb462ee42ec3c5723e1205be8ced776f05b100e4737518c67c8325cf6100"}, - {file = "watchdog-3.0.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:8f3ceecd20d71067c7fd4c9e832d4e22584318983cabc013dbf3f70ea95de346"}, - {file = "watchdog-3.0.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:c9d8c8ec7efb887333cf71e328e39cffbf771d8f8f95d308ea4125bf5f90ba64"}, - {file = "watchdog-3.0.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:0e06ab8858a76e1219e68c7573dfeba9dd1c0219476c5a44d5333b01d7e1743a"}, - {file = "watchdog-3.0.0-py3-none-manylinux2014_armv7l.whl", hash = "sha256:d00e6be486affb5781468457b21a6cbe848c33ef43f9ea4a73b4882e5f188a44"}, - {file = "watchdog-3.0.0-py3-none-manylinux2014_i686.whl", hash = "sha256:c07253088265c363d1ddf4b3cdb808d59a0468ecd017770ed716991620b8f77a"}, - {file = "watchdog-3.0.0-py3-none-manylinux2014_ppc64.whl", hash = "sha256:5113334cf8cf0ac8cd45e1f8309a603291b614191c9add34d33075727a967709"}, - {file = "watchdog-3.0.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:51f90f73b4697bac9c9a78394c3acbbd331ccd3655c11be1a15ae6fe289a8c83"}, - {file = "watchdog-3.0.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:ba07e92756c97e3aca0912b5cbc4e5ad802f4557212788e72a72a47ff376950d"}, - {file = "watchdog-3.0.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:d429c2430c93b7903914e4db9a966c7f2b068dd2ebdd2fa9b9ce094c7d459f33"}, - {file = "watchdog-3.0.0-py3-none-win32.whl", hash = "sha256:3ed7c71a9dccfe838c2f0b6314ed0d9b22e77d268c67e015450a29036a81f60f"}, - {file = "watchdog-3.0.0-py3-none-win_amd64.whl", hash = "sha256:4c9956d27be0bb08fc5f30d9d0179a855436e655f046d288e2bcc11adfae893c"}, - {file = "watchdog-3.0.0-py3-none-win_ia64.whl", hash = "sha256:5d9f3a10e02d7371cd929b5d8f11e87d4bad890212ed3901f9b4d68767bee759"}, - {file = "watchdog-3.0.0.tar.gz", hash = "sha256:4d98a320595da7a7c5a18fc48cb633c2e73cda78f93cac2ef42d42bf609a33f9"}, -] - -[package.extras] -watchmedo = ["PyYAML (>=3.10)"] - -[[package]] -name = "wcmatch" -version = "8.5" -description = "Wildcard/glob file name matcher." -optional = false -python-versions = ">=3.8" -files = [ - {file = "wcmatch-8.5-py3-none-any.whl", hash = "sha256:14554e409b142edeefab901dc68ad570b30a72a8ab9a79106c5d5e9a6d241bd5"}, - {file = "wcmatch-8.5.tar.gz", hash = "sha256:86c17572d0f75cbf3bcb1a18f3bf2f9e72b39a9c08c9b4a74e991e1882a8efb3"}, -] - -[package.dependencies] -bracex = ">=2.1.1" - -[[package]] -name = "webencodings" -version = "0.5.1" -description = "Character encoding aliases for legacy web content" -optional = false -python-versions = "*" -files = [ - {file = "webencodings-0.5.1-py2.py3-none-any.whl", hash = "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78"}, - {file = "webencodings-0.5.1.tar.gz", hash = "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923"}, -] - -[[package]] -name = "zipp" -version = "3.17.0" -description = "Backport of pathlib-compatible object wrapper for zip files" -optional = false -python-versions = ">=3.8" -files = [ - {file = "zipp-3.17.0-py3-none-any.whl", hash = "sha256:0e923e726174922dce09c53c59ad483ff7bbb8e572e00c7f7c46b88556409f31"}, - {file = "zipp-3.17.0.tar.gz", hash = "sha256:84e64a1c28cf7e91ed2078bb8cc8c259cb19b76942096c8d7b84947690cabaf0"}, -] - -[package.extras] -docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"] -testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy (>=0.9.1)", "pytest-ruff"] - -[metadata] -lock-version = "2.0" -python-versions = ">=3.9,<3.12" -content-hash = "8b3c5630efc528583af82f6d7aa9d3d28e5f892e7af717e2ceb72676f91f757d" diff --git a/pyproject.toml b/pyproject.toml deleted file mode 100644 index 3f9931caf..000000000 --- a/pyproject.toml +++ /dev/null @@ -1,38 +0,0 @@ -[tool.poetry] -name = "devenv" -version = "1.0" -description = "Fast, Declarative, Reproducible, and Composable Developer Environments using Nix" -authors = ["Domen Kožar "] -readme = "README.md" -repository = "https://github.com/cachix/devenv" -packages = [{include = "devenv", from = "src"}] -include = [ - { path = "src", format = ["sdist", "wheel"] }, - { path = "examples/simple", format = ["sdist", "wheel"] } -] - -[tool.poetry.dependencies] -python = ">=3.9,<3.12" -click = "^8.1.4" -strictyaml = "^1.7.3" -terminaltables = "^3.1.10" -filelock = "^3.12.0" -requests = "^2.31.0" - -[tool.poetry.group.docs] -optional = true - -[tool.poetry.group.docs.dependencies] -pillow = "^9.5.0" -cairosvg = "^2.7.0" -mkdocs-markdownextradata-plugin = "^0.2.5" -mkdocs-include-markdown-plugin = "^6.0.1" -mkdocs-material = "^9.4.0" -mkdocs-rss-plugin = {git = "https://github.com/cachix/mkdocs-rss-plugin", rev = "no-git"} - -[tool.poetry.scripts] -devenv = "devenv.cli:cli" - -[build-system] -requires = ["poetry-core"] -build-backend = "poetry.core.masonry.api" diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 000000000..e36f98f22 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,5 @@ +mkdocs +mkdocs-material[imaging] +mkdocs-rss-plugin +mkdocs-include-markdown-plugin +mkdocs-markdownextradata-plugin diff --git a/src/devenv/__init__.py b/src/devenv/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/devenv/cli.py b/src/devenv/cli.py deleted file mode 100644 index a2a245dc9..000000000 --- a/src/devenv/cli.py +++ /dev/null @@ -1,904 +0,0 @@ -import functools -import os -import shlex -import shutil -import signal -import subprocess -import tempfile -import time -import re -import sys -import pkgutil -import json -from filelock import FileLock -from contextlib import suppress -from pathlib import Path - -import click -import terminaltables -import strictyaml -import requests - -from .yaml import validate_and_parse_yaml, read_yaml, write_yaml, schema -from .log import log, log_task, log_error, log_warning, log_info - - -NIX_FLAGS = [ - "--show-trace", - "--extra-experimental-features", - "nix-command", - "--extra-experimental-features", - "flakes", - # remove unnecessary warnings - "--option", - "warn-dirty", - "false", - # flake caching is too aggressive - "--option", - "eval-cache", - "false", -] -FILE = pkgutil.get_loader(__package__).load_module(__package__).__file__ -if "site-packages" in FILE: - SRC_DIR = Path(FILE, "..", "..", "src") -else: - SRC_DIR = Path(FILE, "..", "..") -DEVENV_DIR = Path(os.getcwd()) / ".devenv" -DEVENV_DIR.mkdir(parents=True, exist_ok=True) -MODULES_DIR = (SRC_DIR / "modules").resolve() -FLAKE_FILE_TEMPL = Path(MODULES_DIR) / "flake.tmpl.nix" -FLAKE_FILE = Path(os.getcwd()) / ".devenv.flake.nix" -FLAKE_LOCK = "devenv.lock" - -# home vars -if "XDG_DATA_HOME" not in os.environ: - DEVENV_HOME = Path(os.environ["HOME"]) / ".devenv" -else: - DEVENV_HOME = Path(os.environ["XDG_DATA_HOME"]) / ".devenv" -DEVENV_HOME_GC = DEVENV_HOME / "gc" -DEVENV_HOME_GC.mkdir(parents=True, exist_ok=True) -CACHIX_KNOWN_PUBKEYS = DEVENV_HOME / "cachix_pubkeys.json" - -# define system like x86_64-linux -SYSTEM = ( - os.uname().machine.lower().replace("arm", "aarch") - + "-" - + os.uname().sysname.lower() -) - - -def run_nix(command: str, **kwargs) -> str: - ctx = click.get_current_context() - nix_flags = ctx.obj["nix_flags"] - flags = " ".join(NIX_FLAGS) + " " + " ".join(nix_flags) - command_flags = " ".join(ctx.obj["command_flags"]) - return run_command(f"nix {flags} {command} {command_flags}", **kwargs) - - -def run_command( - command: str, - disable_stderr=False, - replace_shell=False, - use_cachix=False, - logging=True, - dont_exit=False, -) -> str: - nix = "" - if command.startswith("nix"): - if os.environ.get("DEVENV_NIX"): - nix = os.path.join(os.environ["DEVENV_NIX"], "bin") - command = f"{nix}/{command}" - else: - log( - "$DEVENV_NIX is not set, but required as devenv doesn't work without a few Nix patches.", - level="error", - ) - log( - "Please follow https://devenv.sh/getting-started/ to install devenv.", - level="error", - ) - exit(1) - if use_cachix: - caches, known_keys = get_cachix_caches(logging) - pull_caches = " ".join( - map(lambda cache: f"https://{cache}.cachix.org", caches.get("pull")) - ) - command = f"{command} --option extra-trusted-public-keys '{' '.join(known_keys.values())}'" - command = f"{command} --option extra-substituters '{pull_caches}'" - push_cache = caches.get("push") - if push_cache and os.environ.get("CACHIX_AUTH_TOKEN"): - if shutil.which("cachix") is None: - if logging: - log_warning( - "cachix is not installed, skipping pushing. Please follow https://devenv.sh/getting-started/#2-install-cachix to install cachix.", - level="error", - ) - else: - command = f"cachix watch-exec {push_cache} {command}" - - try: - if click.get_current_context().obj["verbose"]: - log(f"Running command: {command}", level="debug") - if replace_shell: - splitted_command = shlex.split(command.strip()) - os.execv(splitted_command[0], splitted_command) - else: - return subprocess.run( - command, - shell=True, - check=True, - env=os.environ.copy(), - stdout=subprocess.PIPE, - stdin=subprocess.PIPE, - stderr=None if not disable_stderr else subprocess.DEVNULL, - universal_newlines=True, - ).stdout.strip() - except subprocess.CalledProcessError as e: - if logging: - click.echo("\n", err=True) - log( - f"Following command exited with code {e.returncode}:\n\n {e.cmd}", - level="error", - ) - if dont_exit: - raise e - else: - exit(e.returncode) - - -CONTEXT_SETTINGS = dict(max_content_width=120) - - -@click.group(context_settings=CONTEXT_SETTINGS) -@click.option("--verbose", "-v", help="Enable verbose output.", is_flag=True) -@click.option( - "--nix-flags", - "-n", - help='Flags to pass to Nix. See `man nix.conf 5`. Example: --nix-flags "--option bash-prompt >"', - metavar="NIX-FLAGS", - multiple=True, -) -@click.option("--debugger", "-d", help="Enable Nix debugger.", is_flag=True) -@click.option("--system", "-s", help="Nix system to use.", default=SYSTEM) -@click.option("--offline", "-o", help="Disable network access.", is_flag=True) -@click.pass_context -def cli(ctx, offline, system, debugger, nix_flags, verbose): - """https://devenv.sh: Fast, Declarative, Reproducible, and Composable Developer Environments.""" - ctx.ensure_object(dict) - ctx.obj["system"] = system - ctx.obj["verbose"] = verbose - ctx.obj["command_flags"] = [] - ctx.obj["nix_flags"] = list(nix_flags) - ctx.obj["nix_flags"] += ["--system", system] - if offline: - ctx.obj["nix_flags"] += ["--offline"] - if debugger: - # ignore-try is needed to avoid catching unrelated errors - ctx.obj["command_flags"] += ["--debugger", "--ignore-try"] - - ctx.obj["gc_root"] = DEVENV_HOME_GC - ctx.obj["gc_project"] = DEVENV_HOME_GC / str(int(time.time() * 1000)) - - -@cli.group() -def processes(): - pass - - -os.environ["DEVENV_DIR"] = str(DEVENV_DIR) -DEVENV_GC = DEVENV_DIR / "gc" -os.environ["DEVENV_GC"] = str(DEVENV_GC) - -PROCESSES_PID = DEVENV_DIR / "processes.pid" -PROCESSES_LOG = DEVENV_DIR / "processes.log" - - -def add_gc(name, store_path): - """Register a GC root""" - ctx = click.get_current_context() - run_command( - f'nix-store --add-root "{os.environ["DEVENV_GC"]}/{name}" -r {store_path} >/dev/null' - ) - symlink_force(store_path, f'{ctx.obj["gc_project"]}-{name}') - - -@cli.command(hidden=True) -@click.pass_context -def assemble(ctx): - if not os.path.exists("devenv.nix"): - log("File devenv.nix does not exist. To get started, run:", level="error") - log(" $ devenv init", level="error") - exit(1) - - DEVENV_GC.mkdir(parents=True, exist_ok=True) - - if os.path.exists("devenv.yaml"): - validate_and_parse_yaml(DEVENV_DIR) - else: - for file in ["devenv.json", "flake.json", "imports.txt"]: - file_path = DEVENV_DIR / file - file_path.unlink(missing_ok=True) - - with open(FLAKE_FILE_TEMPL) as f: - flake = f.read() - system = ctx.obj["system"] - - with open(FLAKE_FILE, "w") as f: - devenv_vars = f""" - version = "{get_version()}"; - system = "{system}"; - devenv_root = "{os.getcwd()}"; - """ - # replace __DEVENV_VARS__ in flake using regex - flake = re.sub(r"__DEVENV_VARS__", devenv_vars, flake) - f.write(flake) - - -@cli.command( - help="Deletes previous devenv generations. See http://devenv.sh/garbage-collection", - short_help="Deletes previous devenv generations. See http://devenv.sh/garbage-collection", -) -@click.pass_context -def gc(ctx): - GC_ROOTS = ctx.obj["gc_root"] - start = time.time() - - # remove dangling symlinks - with log_task(f"Removing non-existings symlinks in {GC_ROOTS} ..."): - to_gc, removed_symlinks = cleanup_symlinks(GC_ROOTS) - - click.echo(f" Found {len(to_gc)} active symlinks.") - click.echo(f" Deleted {len(removed_symlinks)} dangling symlinks.") - click.echo() - - log( - "Running garbage collection (this process may take some time) ...", level="info" - ) - # TODO: ideally nix would report some statistics about the GC as JSON - run_nix(f'store delete --recursive {" ".join(to_gc)}') - - after_gc, removed_symlinks = cleanup_symlinks(GC_ROOTS) - end = time.time() - - click.echo() - log( - f"Done. Successfully removed {len(to_gc) - len(after_gc)} symlinks in {end - start:.0f} seconds.", - level="info", - ) - - -def cleanup_symlinks(folder): - to_gc = [] - removed_symlinks = [] - for root, dirs, files in os.walk(folder): - for name in files: - full_path = os.path.join(root, name) - if os.path.islink(full_path): - if not os.path.isfile(full_path): - os.unlink(full_path) - removed_symlinks.append(full_path) - else: - to_gc.append(full_path) - return to_gc, removed_symlinks - - -def get_dev_environment(ctx, json=False, logging=True): - ctx.invoke(assemble) - if logging: - action = log_task("Building shell") - else: - action = suppress() - with action: - gc_root = DEVENV_GC / "shell" - cmd = f"print-dev-env --profile '{gc_root}'" - if json: - cmd += " --json" - env = run_nix(cmd, logging=False, use_cachix=True) - run_command( - f"nix-env -p '{gc_root}' --delete-generations old", - logging=False, - disable_stderr=True, - ) - symlink_force(gc_root, Path(f'{ctx.obj["gc_project"]}-shell')) - return env, gc_root - - -@cli.command( - help="Activate the developer environment.", - short_help="Activate the developer environment.", - context_settings=dict( - ignore_unknown_options=True, - ), -) -@click.argument("cmd", required=False) -@click.argument("extra_args", nargs=-1, type=click.UNPROCESSED) -@click.pass_context -def shell(ctx, cmd, extra_args): - env, gc_root = get_dev_environment(ctx) - if cmd: - run_nix( - f"develop '{gc_root}' -c {cmd} {' '.join(extra_args)}", replace_shell=True - ) - else: - log("Entering shell", level="info") - run_nix(f"develop '{gc_root}'", replace_shell=True) - - -def symlink_force(src, dst): - src = Path(src) - dst = Path(dst) - # locking is needed until https://github.com/python/cpython/pull/14464 - with FileLock(f"{dst}.lock", timeout=10): - dst.unlink(missing_ok=True) - dst.symlink_to(src) - - -@cli.command( - help="Starts processes in foreground. See http://devenv.sh/processes", - short_help="Starts processes in foreground. See http://devenv.sh/processes", -) -@click.argument("process", required=False) -@click.option( - "--detach", "-d", is_flag=True, help="Starts processes in the background." -) -@click.pass_context -def up(ctx, process, detach): - with log_task("Building processes"): - ctx.invoke(assemble) - procfilescript = run_nix( - "build --no-link --print-out-paths '.#procfileScript'", use_cachix=True - ) - with open(procfilescript, "r") as file: - contents = file.read().strip() - if contents == "": - log( - "No 'processes' option defined: https://devenv.sh/processes/", level="error" - ) - exit(1) - else: - env, _ = get_dev_environment(ctx) - log("Starting processes ...", level="info") - add_gc("procfilescript", procfilescript) - processes_script = os.path.join(DEVENV_DIR, "processes") - with open(processes_script, "w") as f: - f.write( - f"""#!/usr/bin/env bash -{env} -exec {procfilescript} {process or ""} - """ - ) - os.chmod(processes_script, 0o755) - - if detach: - process = subprocess.Popen( - [processes_script], - stdout=open(PROCESSES_LOG, "w"), - stderr=subprocess.STDOUT, - ) - - with open(PROCESSES_PID, "w") as file: - file.write(str(process.pid)) - log(f" PID is {process.pid}.", level="info") - log(f" See logs: $ tail -f {PROCESSES_LOG}", level="info") - log(" Stop: $ devenv processes stop", level="info") - else: - os.execv(processes_script, [processes_script]) - - -processes.add_command(up) - - -@processes.command( - help="Stops processes started with 'devenv up'.", - short_help="Stops processes started with 'devenv up'.", -) -def stop(): - with log_task("Stopping processes", newline=False): - if not os.path.exists(PROCESSES_PID): - log("No processes running.", level="error") - exit(1) - - with open(PROCESSES_PID, "r") as file: - pid = int(file.read()) - - log(f"Stopping process with PID {pid} ...", level="info") - - try: - os.kill(pid, signal.SIGTERM) - except ProcessLookupError: - log(f"Process with PID {pid} not found.", level="error") - exit(1) - - os.remove(PROCESSES_PID) - - -@cli.command() -@click.argument("name") -@click.pass_context -def search(ctx, name): - """Search packages matching NAME in nixpkgs input.""" - ctx.invoke(assemble) - options = run_nix( - "build --no-link --print-out-paths '.#optionsJSON' ", use_cachix=True - ) - search = run_nix(f"search --json nixpkgs {name}") - - with open(Path(options) / "share" / "doc" / "nixos" / "options.json") as f: - options_results = [] - for key, value in json.load(f).items(): - if name in key: - options_results.append( - ( - key, - value["type"], - value.get("default", ""), - value["description"][:80], - ) - ) - results_options_count = len(options_results) - - search_results = [] - for key, value in json.loads(search).items(): - search_results.append( - ( - "pkgs." + (".".join(key.split(".")[2:])), - value["version"], - value["description"][:80], - ) - ) - search_results_count = len(search_results) - - if search_results: - click.echo( - terminaltables.AsciiTable( - [("Package", "Version", "Description")] + search_results - ).table - ) - - if options_results: - click.echo( - terminaltables.AsciiTable( - [("Option", "Type", "Default", "Description")] + options_results - ).table - ) - - log( - f"Found {search_results_count} packages and {results_options_count} options for '{name}'.", - level="info", - ) - - -@cli.command( - help="Build, copy and run a container. See http://devenv.sh/containers", - short_help="Build, copy and run a container. See http://devenv.sh/containers", -) -@click.option( - "--registry", - default=None, - help="Registry to copy the container to.", - metavar="REGISTRY", -) -@click.option("--copy", is_flag=True, help="Copy the container to the registry.") -@click.option( - "--copy-args", - default=None, - help="Arguments passed to `skopeo copy`.", - metavar="ARGS", -) -@click.option("--docker-run", is_flag=True, help="Execute `docker run`.") -@click.argument("container_name") -@click.pass_context -def container(ctx, registry, copy, copy_args, docker_run, container_name): - os.environ["DEVENV_CONTAINER"] = container_name - - with log_task(f"Building {container_name} container"): - ctx.invoke(assemble) - # NOTE: we need --impure here to read DEVENV_CONTAINER - spec = run_nix( - f'build --impure --print-out-paths --no-link .#devenv.containers."{container_name}".derivation', - use_cachix=True, - ) - click.echo(spec) - - # copy container - if copy or docker_run: - with log_task(f"Copying {container_name} container"): - # we need --impure here for DEVENV_CONTAINER - copy_script = run_nix( - f'build --print-out-paths --no-link \ - --impure .#devenv.containers."{container_name}".copyScript', - use_cachix=True, - ) - - if docker_run: - registry = "docker-daemon:" - - cp = f"{copy_script} {spec} {registry or 'false'} {copy_args or ''}" - - log(f"Running '{cp}'", level="info") - - subprocess.run( - cp, - shell=True, - check=True, - ) - - if docker_run: - log(f"Starting {container_name} container", level="info") - # we need --impure here for DEVENV_CONTAINER - docker_script = run_nix( - f'build --print-out-paths --no-link --impure \ - .#devenv.containers."{container_name}".dockerRun', - use_cachix=True, - ) - - subprocess.run(docker_script) - - -@cli.command( - help="Print information about this developer environment.", - short_help="Print information about this developer environment.", -) -@click.pass_context -def info(ctx): - ctx.invoke(assemble) - # TODO: use --json and reconstruct input metadata - metadata = run_nix("flake metadata") - matches = re.search(r"(Inputs:.+)$", metadata, re.DOTALL) - if matches: - inputs = matches.group(1) - else: - inputs = "" - info_ = run_nix("eval --raw '.#info'") - click.echo(f"{inputs}\n{info_}") - - -@cli.command() -@click.pass_context -def version(ctx): - """Display devenv version.""" - version = get_version() - click.echo(f"devenv {version} ({ctx.obj['system']})") - - -@cli.command( - help="Scaffold devenv.yaml, devenv.nix, and .envrc.", - short_help="Scaffold devenv.yaml, devenv.nix, and .envrc.", -) -@click.argument("target", default=".") -def init(target): - os.makedirs(target, exist_ok=True) - - required_files = ["devenv.nix", "devenv.yaml", ".envrc"] - for filename in required_files: - if os.path.exists(Path(target, filename)): - log(f"Aborting since {filename} already exist.", level="error") - exit(1) - return - - example = "simple" - examples_path = Path(MODULES_DIR / ".." / ".." / "examples").resolve() - - for filename in required_files: - full_filename = Path(target, filename) - if not os.path.exists(full_filename): - log(f"Creating {full_filename}", level="info") - shutil.copyfile( - os.path.join(examples_path, example, filename), full_filename - ) - - with open(".gitignore", "a+") as gitignore_file: - if "devenv" not in gitignore_file.read(): - log("Appending defaults to .gitignore", level="info") - gitignore_file.write("\n") - gitignore_file.write("# Devenv\n") - gitignore_file.write(".devenv*\n") - gitignore_file.write("devenv.local.nix\n") - gitignore_file.write("\n") - gitignore_file.write("# direnv\n") - gitignore_file.write(".direnv\n") - gitignore_file.write("\n") - gitignore_file.write("# pre-commit\n") - gitignore_file.write(".pre-commit-config.yaml\n") - gitignore_file.write("\n") - - log("Done.", level="info") - - # Check if direnv is installed - if shutil.which("direnv"): - log("direnv is installed. Running $ direnv allow .", level="info") - subprocess.run(["direnv", "allow"]) - - -@cli.command( - help="Update devenv.lock from devenv.yaml inputs. See http://devenv.sh/inputs/", - short_help="Update devenv.lock from devenv.yaml inputs. See http://devenv.sh/inputs/", -) -@click.argument("input_name", required=False) -@click.pass_context -def update(ctx, input_name): - ctx.invoke(assemble) - - if input_name: - run_nix(f"flake lock --update-input {input_name}") - else: - run_nix("flake update") - - -@cli.command() -@click.pass_context -def ci(ctx): - """Builds your developer environment and checks if everything builds.""" - ctx.invoke(assemble) - print("running ci") - print(run_command("cat ${FLAKE_FILE}")) - output_path = run_nix("build --no-link --print-out-paths .#ci", use_cachix=True) - add_gc("ci", output_path) - - -@cli.command(hidden=True) -@click.option("--json", is_flag=True) -@click.pass_context -def print_dev_env(ctx, json): - env, _ = get_dev_environment(ctx, json=json, logging=False) - click.echo(env) - - -def get_version(): - with open(Path(MODULES_DIR, "latest-version")) as f: - return f.read().strip() - - -@cli.group( - help="Manage inputs in devenv.yaml. See http://devenv.sh/inputs/", - short_help="Manage inputs in devenv.yaml. See http://devenv.sh/inputs/", -) -def inputs(): - pass - - -@inputs.command( - help="Add a new input to the developer environment.", - short_help="Add a new input to the developer environment.", -) -@click.argument("name") -@click.argument("url") -@click.option("--follows", "-f", multiple=True, help="Add a dependency to the input.") -@click.pass_context -def add(ctx, name, url, follows): - devenv = read_yaml() - attrs = {"url": url} - - inputs = {} - for follow in follows: - if follow not in devenv["inputs"]: - log( - f"Input {follow} does not exist so it can't be followed.", level="error" - ) - exit(1) - inputs[follow] = {"follows": follow} - - if inputs: - attrs["inputs"] = inputs - devenv["inputs"][name] = attrs - - write_yaml(devenv) - - -@cli.command( - help="Run tests. See http://devenv.sh/tests/", - short_help="Run tests. See http://devenv.sh/tests/", -) -@click.argument("names", nargs=-1) -@click.option("--debug", is_flag=True, help="Run tests in debug mode.") -@click.option("--keep-going", is_flag=True, help="Continue running tests if one fails.") -@click.option( - "--exclude", - multiple=True, - help="A test name to exclude, may be specified multiple times", -) -@click.pass_context -def test(ctx, debug, keep_going, exclude, names): - ctx.invoke(assemble) - with log_task("Gathering tests", newline=False): - tests = json.loads(run_nix("eval .#devenv.tests --json")) - - if not names: - names = ["local"] - - # group tests by tags - tags = {} - for name, test in tests.items(): - for tag in test["tags"]: - if tag not in tags: - tags[tag] = [] - tags[tag].append(name) - - selected_tests = [] - for name in names: - if name in tests: - selected_tests.append(name) - tag_tests = tags.get(name, {}) - for test in tag_tests: - if not test in exclude: - selected_tests.append(test) - - log(f"Found {len(tests)} test(s), running {len(selected_tests)}:", level="info") - - pwd = os.getcwd() - failed = [] - - for name in selected_tests: - with log_task(f" Testing {name}"): - with tempfile.TemporaryDirectory(prefix=name + "_") as tmpdir: - os.chdir(tmpdir) - test = tests[name] - - if test.get("src"): - shutil.copytree( - test["src"], ".", dirs_exist_ok=True, copy_function=shutil.copy - ) - run_command("find . -type d -exec chmod +wx {} \;") - else: - write_if_defined("devenv.nix", test.get("nix")) - write_if_defined("devenv.yaml", test.get("yaml")) - write_if_defined(".test.sh", test.get("test")) - if os.path.exists(".test.sh"): - os.chmod(".test.sh", 0o755) - - # predefined utilities - write_if_defined( - "devenv.local.nix", - """ -{ pkgs, ... }: { - packages = [ pkgs.coreutils-full ]; -} - """.strip() - + "\n", - ) - - # plug in devenv input if needed - if os.path.exists(os.path.join(pwd, "src/modules/latest-version")): - log( - " Detected devenv module. Using src/modules for tests.", - level="info", - ) - - if not os.path.exists("devenv.yaml"): - write_yaml( - strictyaml.as_document({"inputs": {}}, schema=schema) - ) - os.chmod("devenv.yaml", 0o644) - yaml = read_yaml() - inputs = yaml.get("inputs", {}) - inputs["devenv"] = {"url": f"path:{pwd}?dir=src/modules"} - yaml["inputs"] = inputs - write_yaml(yaml) - - devenv = sys.argv[0] - has_processes = False - try: - log(" Running $ devenv ci ...", level="info") - run_command(f"{devenv} ci") - - has_processes = os.path.exists( - ".devenv/gc/ci" - ) and "-devenv-up" in run_command("cat .devenv/gc/ci") - - if has_processes: - log(" Starting processes ...", level="info") - run_command(f"{devenv} up -d") - # stream logs - p = subprocess.Popen( - "tail -f .devenv/processes.log", - shell=True, - ) - else: - p = None - - try: - if os.path.exists(".test.sh"): - log(" Running .test.sh ...", level="info") - run_command(f"{devenv} shell bash ./.test.sh") - finally: - if has_processes and not debug: - run_command(f"{devenv} processes stop") - if p: - p.kill() - except KeyboardInterrupt: - raise - except BaseException as e: - log_error(f"Test {name} failed.") - if keep_going: - failed.append(name) - continue - if debug: - log( - "Entering shell because of the --debug flag:", - level="warning", - ) - log(f" - devenv: {devenv}", level="warning") - log(f" - cwd: {tmpdir}", level="warning") - if has_processes: - log(" - up logs: .devenv/processes.log:", level="warning") - os.execv("/bin/sh", ["/bin/sh"]) - else: - log_warning("Pass --debug flag to enter shell.") - raise e - if keep_going and failed: - log_error(f"Failed: {', '.join(failed)}") - sys.exit(2) - - -def write_if_defined(file, content): - if content: - with open(file, "w") as f: - f.write(content) - - -@functools.cache -def get_cachix_caches(logging=True): - """Get the full list of cachix caches we need and their public keys. - - This is cached because it's expensive to run. - """ - try: - caches_raw = run_nix( - "eval .#devenv.cachix --json", - dont_exit=True, - disable_stderr=True, - logging=False, - ) - except subprocess.CalledProcessError: - return {"pull": [], "push": None}, {} - - caches = json.loads(caches_raw) - - if CACHIX_KNOWN_PUBKEYS.exists(): - known_keys = json.loads(CACHIX_KNOWN_PUBKEYS.read_text()) - else: - known_keys = {} - new_known_keys = {} - for name in caches.get("pull", []): - if name not in known_keys: - resp = requests.get(f"https://cachix.org/api/v1/cache/{name}") - if resp.status_code in [401, 404]: - log_error( - f"Cache {name} does not exist or you don't have a CACHIX_AUTH_TOKEN configured." - ) - # TODO: instruct how to best configure netrc - # log_error("To configure a token, run `cachix authtoken `.") - log_error("To create a cache, go to https://app.cachix.org/.") - exit(1) - else: - resp.raise_for_status() - pubkey = resp.json()["publicSigningKeys"][0] - new_known_keys[name] = pubkey - - if caches.get("pull"): - if logging: - log_info(f"Using Cachix: {', '.join(caches.get('pull', []))} ") - if new_known_keys: - for name, pubkey in new_known_keys.items(): - if logging: - log_info( - f" Trusting {name}.cachix.org on first use with the public key {pubkey}" - ) - known_keys.update(new_known_keys) - CACHIX_KNOWN_PUBKEYS.write_text(json.dumps(known_keys)) - return caches, known_keys - - -@cli.command() -@click.argument("attrs", nargs=-1, required=True) -@click.pass_context -def build(ctx, attrs): - """Build attributes in your devenv.nix.""" - ctx.invoke(assemble) - attrs = " ".join(map(lambda attr: f".#devenv.{attr}", attrs)) - output = run_nix( - f"build --print-out-paths --print-build-logs --no-link {attrs}", use_cachix=True - ) - log("Built:", level="info") - for path in output.splitlines(): - log(path, level="info") diff --git a/src/devenv/log.py b/src/devenv/log.py deleted file mode 100644 index 0b56f3b69..000000000 --- a/src/devenv/log.py +++ /dev/null @@ -1,56 +0,0 @@ -from typing import Literal -import time - -import click - - -class log_task: - """Context manager for logging progress of a task.""" - - def __init__(self, message, newline=True): - self.message = message - self.newline = newline - - def __enter__(self): - prefix = click.style("•", fg="blue") - self.start = time.time() - click.echo(f"{prefix} {self.message} ...", nl=self.newline) - - def __exit__(self, exc, *args): - end = time.time() - if exc: - prefix = click.style("✖", fg="red") - else: - prefix = click.style("✔", fg="green") - click.echo(f"\r{prefix} {self.message} in {end - self.start:.1f}s.") - - -LogLevel = Literal["info", "warning", "error", "debug"] - - -def log(message, level: LogLevel): - match level: - case "info": - click.echo(click.style("• ", fg="green") + message) - case "warning": - click.echo(click.style("• ", fg="yellow") + message, err=True) - case "error": - click.echo(click.style("✖ ", fg="red") + message, err=True) - case "debug": - click.echo(click.style("• ", fg="magenta") + message, err=True) - - -def log_error(message): - log(message, "error") - - -def log_warning(message): - log(message, "warning") - - -def log_info(message): - log(message, "info") - - -def log_debug(message): - log(message, "debug") diff --git a/src/devenv/yaml.py b/src/devenv/yaml.py deleted file mode 100644 index 634a20e1d..000000000 --- a/src/devenv/yaml.py +++ /dev/null @@ -1,63 +0,0 @@ -import json -import sys -import os -from pathlib import Path - -from strictyaml import Map, MapPattern, Str, Seq -from strictyaml import load, Bool, Any, Optional, YAMLError, EmptyDict - - -inputsSchema = EmptyDict() | MapPattern( - Str(), - Map( - { - "url": Str(), - Optional("flake", default=None): Bool(), - Optional("inputs", default=None): Any(), - Optional("overlays", default=None): Seq(Str()), - } - ), -) - -schema = Map( - { - Optional("inputs", default=None): inputsSchema, - Optional("allowUnfree", default=False): Bool(), - Optional("allowBroken", default=False): Bool(), - Optional("imports", default=None): Seq(Str()), - Optional("permittedInsecurePackages", default=None): Seq(Str()), - } -) - -YAML_FILE = Path("devenv.yaml") - - -def read_yaml(): - try: - with open(YAML_FILE) as f: - return load(f.read(), schema, label="devenv.yaml") - except YAMLError as error: - print("Validation error in `devenv.yaml`", error) - sys.exit(1) - - -def write_yaml(yaml): - with open(YAML_FILE, "w") as f: - f.write(yaml.as_yaml()) - - -def validate_and_parse_yaml(dot_devenv_root): - devenv = read_yaml().data - - inputs = {} - for input, attrs in devenv.get("inputs", {}).items(): - inputs[input] = {k: attrs[k] for k in ("url", "inputs", "flake") if k in attrs} - - with open(os.path.join(dot_devenv_root, "flake.json"), "w") as f: - f.write(json.dumps(inputs)) - - with open(os.path.join(dot_devenv_root, "devenv.json"), "w") as f: - f.write(json.dumps(devenv)) - - with open(os.path.join(dot_devenv_root, "imports.txt"), "w") as f: - f.write("\n".join(devenv.get("imports", []))) diff --git a/src/modules/flake.tmpl.nix b/src/modules/flake.tmpl.nix deleted file mode 100644 index 61c9b0a75..000000000 --- a/src/modules/flake.tmpl.nix +++ /dev/null @@ -1,95 +0,0 @@ -{ - inputs = { - pre-commit-hooks.url = "github:cachix/pre-commit-hooks.nix"; - pre-commit-hooks.inputs.nixpkgs.follows = "nixpkgs"; - nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; - devenv.url = "github:cachix/devenv?dir=src/modules"; - } // (if builtins.pathExists ./.devenv/flake.json - then builtins.fromJSON (builtins.readFile ./.devenv/flake.json) - else { }); - - outputs = { nixpkgs, ... }@inputs: - let - __DEVENV_VARS__ - devenv = - if builtins.pathExists ./.devenv/devenv.json - then builtins.fromJSON (builtins.readFile ./.devenv/devenv.json) - else { }; - getOverlays = inputName: inputAttrs: - map - (overlay: - let - input = inputs.${inputName} or (throw "No such input `${inputName}` while trying to configure overlays."); - in - input.overlays.${overlay} or (throw "Input `${inputName}` has no overlay called `${overlay}`. Supported overlays: ${nixpkgs.lib.concatStringsSep ", " (builtins.attrNames input.overlays)}")) - inputAttrs.overlays or [ ]; - overlays = nixpkgs.lib.flatten (nixpkgs.lib.mapAttrsToList getOverlays (devenv.inputs or { })); - pkgs = import nixpkgs { - inherit system; - config = { - allowUnfree = devenv.allowUnfree or false; - allowBroken = devenv.allowBroken or false; - permittedInsecurePackages = devenv.permittedInsecurePackages or [ ]; - }; - inherit overlays; - }; - lib = pkgs.lib; - importModule = path: - if lib.hasPrefix "./" path - then if lib.hasSuffix ".nix" path - then ./. + (builtins.substring 1 255 path) - else ./. + (builtins.substring 1 255 path) + "/devenv.nix" - else if lib.hasPrefix "../" path - then throw "devenv: ../ is not supported for imports" - else - let - paths = lib.splitString "/" path; - name = builtins.head paths; - input = inputs.${name} or (throw "Unknown input ${name}"); - subpath = "/${lib.concatStringsSep "/" (builtins.tail paths)}"; - devenvpath = "${input}" + subpath + "/devenv.nix"; - in - if builtins.pathExists devenvpath - then devenvpath - else throw (devenvpath + " file does not exist for input ${name}."); - project = pkgs.lib.evalModules { - specialArgs = inputs // { inherit inputs pkgs; }; - modules = [ - (inputs.devenv.modules + /top-level.nix) - { - devenv.cliVersion = "${version}"; - devenv.root = devenv_root; - } - ] ++ (map importModule (devenv.imports or [ ])) ++ [ - ./devenv.nix - (devenv.devenv or { }) - (if builtins.pathExists ./devenv.local.nix then ./devenv.local.nix else { }) - ]; - }; - config = project.config; - - options = pkgs.nixosOptionsDoc { - options = builtins.removeAttrs project.options [ "_module" ]; - # Unpack Nix types, e.g. literalExpression, mDoc. - transformOptions = - let isDocType = v: builtins.elem v [ "literalDocBook" "literalExpression" "literalMD" "mdDoc" ]; - in lib.attrsets.mapAttrs (_: v: - if v ? _type && isDocType v._type then - v.text - else if v ? _type && v._type == "derivation" then - v.name - else - v - ); - }; - in - { - packages."${system}" = { - optionsJSON = options.optionsJSON; - inherit (config) info procfileScript procfileEnv procfile; - ci = config.ciDerivation; - }; - devenv = config; - devShell."${system}" = config.shell; - }; -} diff --git a/src/modules/integrations/devcontainer.nix b/src/modules/integrations/devcontainer.nix index 239bc2142..38e6ce1ac 100644 --- a/src/modules/integrations/devcontainer.nix +++ b/src/modules/integrations/devcontainer.nix @@ -31,7 +31,7 @@ in options.updateContentCommand = lib.mkOption { type = lib.types.anything; - default = "devenv ci"; + default = "devenv test"; description = lib.mdDoc '' Command to run after container creation. ''; diff --git a/src/modules/integrations/dotenv.nix b/src/modules/integrations/dotenv.nix index 7142e277a..c34b1369b 100644 --- a/src/modules/integrations/dotenv.nix +++ b/src/modules/integrations/dotenv.nix @@ -58,10 +58,12 @@ in config = lib.mkMerge [ (lib.mkIf cfg.enable { env = lib.mapAttrs (name: value: lib.mkDefault value) config.dotenv.resolved; - dotenv.resolved = mergeEnvFiles dotenvPaths; - }) - (lib.mkIf (cfg.enable) { enterShell = lib.concatStringsSep "\n" (map createMissingFileMessage dotenvPaths); + dotenv.resolved = mergeEnvFiles dotenvPaths; + assertions = [{ + assertion = lib.hasPrefix ".env" cfg.filename; + message = "The dotenv filename must start with '.env'."; + }]; }) (lib.mkIf (!cfg.enable && !cfg.disableHint) { enterShell = diff --git a/src/modules/integrations/pre-commit.nix b/src/modules/integrations/pre-commit.nix index 3dcbbae06..8b6f71e6a 100644 --- a/src/modules/integrations/pre-commit.nix +++ b/src/modules/integrations/pre-commit.nix @@ -20,6 +20,9 @@ config = lib.mkIf ((lib.filterAttrs (id: value: value.enable) config.pre-commit.hooks) != { }) { ci = [ config.pre-commit.run ]; + enterTest = '' + pre-commit run -a + ''; packages = [ config.pre-commit.package ]; enterShell = config.pre-commit.installationScript; }; diff --git a/src/modules/languages/python.nix b/src/modules/languages/python.nix index e391d195b..05ff0de76 100644 --- a/src/modules/languages/python.nix +++ b/src/modules/languages/python.nix @@ -46,7 +46,7 @@ let VENV_PATH="${config.env.DEVENV_STATE}/venv" profile_python="$(${readlink} ${package.interpreter})" - devenv_interpreter_path="$(${pkgs.coreutils}/bin/cat "$VENV_PATH/.devenv_interpreter" 2> /dev/null|| false )" + devenv_interpreter_path="$(${pkgs.coreutils}/bin/cat "$VENV_PATH/.devenv_interpreter" 2> /dev/null || echo false )" venv_python="$(${readlink} "$devenv_interpreter_path")" requirements="${lib.optionalString (cfg.venv.requirements != null) ''${requirements}''}" @@ -68,7 +68,7 @@ let # reinstall requirements if necessary if [ -n "$requirements" ] then - devenv_requirements_path="$(${pkgs.coreutils}/bin/cat "$VENV_PATH/.devenv_requirements" 2> /dev/null|| false )" + devenv_requirements_path="$(${pkgs.coreutils}/bin/cat "$VENV_PATH/.devenv_requirements" 2> /dev/null|| echo false )" devenv_requirements="$(${readlink} "$devenv_requirements_path")" if [ -z $devenv_requirements ] || [ $devenv_requirements != $requirements ] then diff --git a/src/modules/processes.nix b/src/modules/processes.nix index de7a25901..dcdbc9dea 100644 --- a/src/modules/processes.nix +++ b/src/modules/processes.nix @@ -53,7 +53,7 @@ in implementation = lib.mkOption { type = types.enum [ "honcho" "overmind" "process-compose" "hivemind" ]; description = "The implementation used when performing ``devenv up``."; - default = "honcho"; + default = "process-compose"; example = "overmind"; }; diff --git a/src/modules/tests.nix b/src/modules/tests.nix index 5eba38745..856fd1a62 100644 --- a/src/modules/tests.nix +++ b/src/modules/tests.nix @@ -1,60 +1,42 @@ -{ config, lib, ... }: +{ pkgs, config, lib, ... }: -let - testType = lib.types.submodule ({ config, ... }: { - options = { - tags = lib.mkOption { - type = lib.types.listOf lib.types.str; - default = [ "local" ]; - description = "Tags for this test."; - }; - - nix = lib.mkOption { - type = lib.types.nullOr lib.types.str; - default = null; - example = "{ pkgs, ... }: {}"; - description = "devenv.nix code."; - }; - - yaml = lib.mkOption { - type = lib.types.nullOr lib.types.str; - default = null; - example = '' - inputs: - nixpkgs: - url: github:NixOS/nixpkgs/nixpkgs-unstable - ''; - description = "devenv.yaml code."; - }; +{ + options = { + enterTest = lib.mkOption { + type = lib.types.lines; + description = "Bash code to execute to run the test."; + }; - test = lib.mkOption { - type = lib.types.nullOr lib.types.str; - description = "Bash to be executed."; - default = null; - }; + test = lib.mkOption { + type = lib.types.package; + internal = true; + default = pkgs.writeShellScript "devenv-test" '' + echo "• Setting up shell environment ..." + ${config.enterShell} - src = lib.mkOption { - type = lib.types.nullOr lib.types.path; - default = null; - description = "Source code with all the files."; - }; + set -euo pipefail + echo "• Testing ..." + ${config.enterTest} + ''; }; - }); -in -{ - options.tests = lib.mkOption { - type = lib.types.attrsOf testType; - default = { }; - description = "Tests for this module."; }; - config.assertions = - let - mk = name: cfg: - { - assertion = cfg.nix != null || cfg.src != null; - message = "Either tests.${name}.nix or tests.${name}.src needs to be defined."; - }; - in - lib.mapAttrsToList mk config.tests; + config = { + enterTest = '' + # Wait for the port to be open until the timeout is reached + wait_for_port() { + local port=$1 + local timeout=''${2:-15} + + timeout $timeout bash -c "until echo > /dev/tcp/localhost/$port; do sleep 0.5; done" + } + + export -f wait_for_port + + if [ -f ./.test.sh ]; then + echo "• Running .test.sh..." + ./.test.sh + fi + ''; + }; } diff --git a/src/modules/top-level.nix b/src/modules/top-level.nix index aa1ef0caa..839d44197 100644 --- a/src/modules/top-level.nix +++ b/src/modules/top-level.nix @@ -195,7 +195,6 @@ in } ]; # use builtins.toPath to normalize path if root is "/" (container) - devenv.dotfile = builtins.toPath (config.devenv.root + "/.devenv"); devenv.state = builtins.toPath (config.devenv.dotfile + "/state"); devenv.profile = profile; diff --git a/tests/clean/devenv.nix b/tests/clean/devenv.nix new file mode 100644 index 000000000..e3d2dda9e --- /dev/null +++ b/tests/clean/devenv.nix @@ -0,0 +1,14 @@ +{ + enterTest = '' + if [ -z "$DEVENV_NIX" ]; then + echo "DEVENV_NIX is not set" + exit 1 + fi + + set +u + if [ ! -z "$BROWSER" ]; then + echo "BROWSER is set" + exit 1 + fi + ''; +} diff --git a/tests/clean/devenv.yaml b/tests/clean/devenv.yaml new file mode 100644 index 000000000..1dc3c3e14 --- /dev/null +++ b/tests/clean/devenv.yaml @@ -0,0 +1,7 @@ +inputs: + devenv: + url: path:../../?dir=src/modules +clean: + enabled: true + keep: + - DEVENV_NIX diff --git a/tests/cli/.test.sh b/tests/cli/.test.sh index 769fea488..3c52a0920 100755 --- a/tests/cli/.test.sh +++ b/tests/cli/.test.sh @@ -1,4 +1,20 @@ -#!/usr/bin/env bash set -xe + +# TODO: provide devenv cli via inputs +export PATH=$(pwd)/../../result/bin:$PATH + devenv build languages.python.package -devenv shell ls -la \ No newline at end of file +devenv shell ls -- -la | grep ".test.sh" +devenv shell ls ../ | grep "cli" +devenv info | grep "python3-" +devenv show | grep "python3-" +devenv search ncdu | grep "Found 3 packages and 0 options for 'ncdu'" +# there should be no processes +devenv up && exit 1 +# containers +devenv container build shell && exit 1 +devenv inputs add mk-shell-bin github:rrbutani/nix-mk-shell-bin --follows nixpkgs +devenv inputs add nix2container github:nlewo/nix2container --follows nixpkgs +devenv container build shell | grep image-shell.json +# bw compat +devenv container shell | grep "image-shell.json" \ No newline at end of file diff --git a/tests/cli/devenv.nix b/tests/cli/devenv.nix index ecce39d5a..04d1d2c01 100644 --- a/tests/cli/devenv.nix +++ b/tests/cli/devenv.nix @@ -1,3 +1,3 @@ -{ ... }: { +{ pkgs, inputs, ... }: { languages.python.enable = true; } diff --git a/tests/cli/devenv.yaml b/tests/cli/devenv.yaml new file mode 100644 index 000000000..291d7fd61 --- /dev/null +++ b/tests/cli/devenv.yaml @@ -0,0 +1,11 @@ +inputs: + mk-shell-bin: + url: github:rrbutani/nix-mk-shell-bin + inputs: + nixpkgs: + follows: nixpkgs + nix2container: + url: github:nlewo/nix2container + inputs: + nixpkgs: + follows: nixpkgs diff --git a/tests/dotenv/.setup.sh b/tests/dotenv/.setup.sh new file mode 100755 index 000000000..39452af0f --- /dev/null +++ b/tests/dotenv/.setup.sh @@ -0,0 +1 @@ +echo "{ env.LOCAL = \"1\";}" > devenv.local.nix \ No newline at end of file diff --git a/examples/dotenv/.test.sh b/tests/dotenv/.test.sh similarity index 100% rename from examples/dotenv/.test.sh rename to tests/dotenv/.test.sh diff --git a/examples/dotenv/bar.env b/tests/dotenv/bar.env similarity index 100% rename from examples/dotenv/bar.env rename to tests/dotenv/bar.env diff --git a/examples/dotenv/devenv.nix b/tests/dotenv/devenv.nix similarity index 100% rename from examples/dotenv/devenv.nix rename to tests/dotenv/devenv.nix diff --git a/examples/dotenv/devenv.yaml b/tests/dotenv/devenv.yaml similarity index 100% rename from examples/dotenv/devenv.yaml rename to tests/dotenv/devenv.yaml diff --git a/tests/gitignore/.setup.sh b/tests/gitignore/.setup.sh new file mode 100644 index 000000000..d1bfa0b89 --- /dev/null +++ b/tests/gitignore/.setup.sh @@ -0,0 +1,2 @@ +echo "{ env.LOCAL = \"1\";}" > devenv.local.nix +echo "ENV=1" > .env diff --git a/tests/gitignore/.test.sh b/tests/gitignore/.test.sh new file mode 100755 index 000000000..a3d099347 --- /dev/null +++ b/tests/gitignore/.test.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +set -xe + +env | grep BAR=1 +env | grep ENV=1 +env | grep LOCAL=1 \ No newline at end of file diff --git a/tests/gitignore/devenv.nix b/tests/gitignore/devenv.nix new file mode 100644 index 000000000..4a3d67f13 --- /dev/null +++ b/tests/gitignore/devenv.nix @@ -0,0 +1,5 @@ +{ pkgs, lib, config, ... }: { + dotenv.enable = true; + + env.BAR = "1"; +} diff --git a/tests/gitignore/devenv.yaml b/tests/gitignore/devenv.yaml new file mode 100644 index 000000000..c7cb5ceda --- /dev/null +++ b/tests/gitignore/devenv.yaml @@ -0,0 +1,3 @@ +inputs: + nixpkgs: + url: github:NixOS/nixpkgs/nixpkgs-unstable diff --git a/tests/glibcLocales/devenv.lock b/tests/glibcLocales/devenv.lock new file mode 100644 index 000000000..c75382010 --- /dev/null +++ b/tests/glibcLocales/devenv.lock @@ -0,0 +1,156 @@ +{ + "nodes": { + "devenv": { + "locked": { + "dir": "src/modules", + "lastModified": 1709300857, + "owner": "cachix", + "repo": "devenv", + "rev": "f0319af4f966fb8bc25c6429f4f2e097e79116c2", + "treeHash": "a035e54b8fe8523068171e97568d4d891234ccb0", + "type": "github" + }, + "original": { + "dir": "src/modules", + "owner": "cachix", + "repo": "devenv", + "type": "github" + } + }, + "flake-compat": { + "flake": false, + "locked": { + "lastModified": 1696426674, + "owner": "edolstra", + "repo": "flake-compat", + "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", + "treeHash": "2addb7b71a20a25ea74feeaf5c2f6a6b30898ecb", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1709126324, + "owner": "numtide", + "repo": "flake-utils", + "rev": "d465f4819400de7c8d874d50b982301f28a84605", + "treeHash": "f52cf07f5dc7208c6379eb10b7505fda4c429b88", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "gitignore": { + "inputs": { + "nixpkgs": [ + "pre-commit-hooks", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1709087332, + "owner": "hercules-ci", + "repo": "gitignore.nix", + "rev": "637db329424fd7e46cf4185293b9cc8c88c95394", + "treeHash": "ca14199cabdfe1a06a7b1654c76ed49100a689f9", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "gitignore.nix", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1709386671, + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "fa9a51752f1b5de583ad5213eb621be071806663", + "treeHash": "2cf56c4a9c6d7667222890dd4fb45de7574483b2", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-stable": { + "locked": { + "lastModified": 1709309926, + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "79baff8812a0d68e24a836df0a364c678089e2c7", + "treeHash": "0a912c9b662a028d46d4bfad6193d4379eb28ceb", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-23.11", + "repo": "nixpkgs", + "type": "github" + } + }, + "pre-commit-hooks": { + "inputs": { + "flake-compat": "flake-compat", + "flake-utils": "flake-utils", + "gitignore": "gitignore", + "nixpkgs": [ + "nixpkgs" + ], + "nixpkgs-stable": "nixpkgs-stable" + }, + "locked": { + "lastModified": 1708018599, + "owner": "cachix", + "repo": "pre-commit-hooks.nix", + "rev": "5df5a70ad7575f6601d91f0efec95dd9bc619431", + "treeHash": "6b6519c2b58ad1e106d9633f0d1b490a70fc6980", + "type": "github" + }, + "original": { + "owner": "cachix", + "repo": "pre-commit-hooks.nix", + "type": "github" + } + }, + "root": { + "inputs": { + "devenv": "devenv", + "nixpkgs": "nixpkgs", + "pre-commit-hooks": "pre-commit-hooks" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "treeHash": "cce81f2a0f0743b2eb61bc2eb6c7adbe2f2c6beb", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/tests/glibcLocales/devenv.nix b/tests/glibcLocales/devenv.nix new file mode 100644 index 000000000..8e74deee9 --- /dev/null +++ b/tests/glibcLocales/devenv.nix @@ -0,0 +1,5 @@ +{ + enterTest = '' + locale | grep "LANG=en_US.UTF-8" + ''; +} diff --git a/tests/impure/devenv.nix b/tests/impure/devenv.nix new file mode 100644 index 000000000..9e9a2091a --- /dev/null +++ b/tests/impure/devenv.nix @@ -0,0 +1,5 @@ +{ + enterTest = '' + echo ${builtins.currentSystem}; + ''; +} diff --git a/tests/impure/devenv.yaml b/tests/impure/devenv.yaml new file mode 100644 index 000000000..eeb4d8d38 --- /dev/null +++ b/tests/impure/devenv.yaml @@ -0,0 +1 @@ +impure: true diff --git a/tests/permit-insecure/devenv.nix b/tests/permit-insecure/devenv.nix new file mode 100644 index 000000000..5505f0e00 --- /dev/null +++ b/tests/permit-insecure/devenv.nix @@ -0,0 +1,9 @@ +{ pkgs, ... }: + +{ + # https://devenv.sh/languages/ + languages.ruby = { + enable = true; + version = "2.6.5"; + }; +} diff --git a/tests/permit-insecure/devenv.yaml b/tests/permit-insecure/devenv.yaml new file mode 100644 index 000000000..50d421943 --- /dev/null +++ b/tests/permit-insecure/devenv.yaml @@ -0,0 +1,10 @@ +inputs: + nixpkgs: + url: github:NixOS/nixpkgs/nixpkgs-unstable + nixpkgs-ruby: + url: github:bobvanderlinden/nixpkgs-ruby + inputs: + nixpkgs: + follows: nixpkgs +permittedInsecurePackages: + - "openssl-1.1.1w" diff --git a/tests/python-native-libs/.test.sh b/tests/python-native-libs/.test.sh index 119fd2259..f8bcec0a7 100755 --- a/tests/python-native-libs/.test.sh +++ b/tests/python-native-libs/.test.sh @@ -1,9 +1,5 @@ -#!/usr/bin/env bash -set -ex - python -c "from PIL import Image" python -c "import grpc_tools.protoc" python -c "import transformers" -python -c "import torch" # TODO: invoke a subprocess with an old glibc and assert it doesn't crash \ No newline at end of file diff --git a/tests/python-native-libs/devenv.nix b/tests/python-native-libs/devenv.nix index 5d7bd5a29..f3fdb2f91 100644 --- a/tests/python-native-libs/devenv.nix +++ b/tests/python-native-libs/devenv.nix @@ -1,13 +1,6 @@ { pkgs, lib, ... }: { packages = [ pkgs.cairo ]; - # we must set LD_LIBRARY_PATH by hand without use of the env-venv - # version of nixpkgs, this can be removed when we switch to one - env.LD_LIBRARY_PATH = lib.makeLibraryPath [ - pkgs.pythonManylinuxPackages.manylinux2014Package - pkgs.zlib - ]; - languages.python = { enable = true; venv.enable = true; @@ -15,7 +8,6 @@ pillow grpcio-tools transformers - torch ''; }; } diff --git a/tests/python-native-libs/devenv.yaml b/tests/python-native-libs/devenv.yaml index 25b947129..777857cb4 100644 --- a/tests/python-native-libs/devenv.yaml +++ b/tests/python-native-libs/devenv.yaml @@ -1,5 +1,3 @@ inputs: - devenv: - url: path:./../../src/modules nixpkgs: - url: github:NixOS/nixpkgs/nixpkgs-unstable + url: github:cachix/nixpkgs/python-venv \ No newline at end of file diff --git a/tests/up-uses-shell/devenv.lock b/tests/up-uses-shell/devenv.lock new file mode 100644 index 000000000..c75382010 --- /dev/null +++ b/tests/up-uses-shell/devenv.lock @@ -0,0 +1,156 @@ +{ + "nodes": { + "devenv": { + "locked": { + "dir": "src/modules", + "lastModified": 1709300857, + "owner": "cachix", + "repo": "devenv", + "rev": "f0319af4f966fb8bc25c6429f4f2e097e79116c2", + "treeHash": "a035e54b8fe8523068171e97568d4d891234ccb0", + "type": "github" + }, + "original": { + "dir": "src/modules", + "owner": "cachix", + "repo": "devenv", + "type": "github" + } + }, + "flake-compat": { + "flake": false, + "locked": { + "lastModified": 1696426674, + "owner": "edolstra", + "repo": "flake-compat", + "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", + "treeHash": "2addb7b71a20a25ea74feeaf5c2f6a6b30898ecb", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1709126324, + "owner": "numtide", + "repo": "flake-utils", + "rev": "d465f4819400de7c8d874d50b982301f28a84605", + "treeHash": "f52cf07f5dc7208c6379eb10b7505fda4c429b88", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "gitignore": { + "inputs": { + "nixpkgs": [ + "pre-commit-hooks", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1709087332, + "owner": "hercules-ci", + "repo": "gitignore.nix", + "rev": "637db329424fd7e46cf4185293b9cc8c88c95394", + "treeHash": "ca14199cabdfe1a06a7b1654c76ed49100a689f9", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "gitignore.nix", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1709386671, + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "fa9a51752f1b5de583ad5213eb621be071806663", + "treeHash": "2cf56c4a9c6d7667222890dd4fb45de7574483b2", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-stable": { + "locked": { + "lastModified": 1709309926, + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "79baff8812a0d68e24a836df0a364c678089e2c7", + "treeHash": "0a912c9b662a028d46d4bfad6193d4379eb28ceb", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-23.11", + "repo": "nixpkgs", + "type": "github" + } + }, + "pre-commit-hooks": { + "inputs": { + "flake-compat": "flake-compat", + "flake-utils": "flake-utils", + "gitignore": "gitignore", + "nixpkgs": [ + "nixpkgs" + ], + "nixpkgs-stable": "nixpkgs-stable" + }, + "locked": { + "lastModified": 1708018599, + "owner": "cachix", + "repo": "pre-commit-hooks.nix", + "rev": "5df5a70ad7575f6601d91f0efec95dd9bc619431", + "treeHash": "6b6519c2b58ad1e106d9633f0d1b490a70fc6980", + "type": "github" + }, + "original": { + "owner": "cachix", + "repo": "pre-commit-hooks.nix", + "type": "github" + } + }, + "root": { + "inputs": { + "devenv": "devenv", + "nixpkgs": "nixpkgs", + "pre-commit-hooks": "pre-commit-hooks" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "treeHash": "cce81f2a0f0743b2eb61bc2eb6c7adbe2f2c6beb", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/tests/up-uses-shell/devenv.nix b/tests/up-uses-shell/devenv.nix new file mode 100644 index 000000000..6a9fe513c --- /dev/null +++ b/tests/up-uses-shell/devenv.nix @@ -0,0 +1,14 @@ +{ + enterShell = '' + export FOO=1 + ''; + + enterTest = '' + sleep 1 + if [ $(cat foo) -ne 1 ]; then + exit 1 + fi + ''; + + processes.test.exec = "while true; do echo $FOO > foo; sleep 1; done"; +} From 1f0bb1490638c0d7c3b7bef2d6583cc712bd642f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Tue, 12 Mar 2024 04:36:19 +0000 Subject: [PATCH 082/146] fix ci --- .github/workflows/buildtest.yml | 2 +- devenv.lock | 32 ++++++++++++++++---------------- devenv.nix | 2 +- devenv.yaml | 2 +- 4 files changed, 19 insertions(+), 19 deletions(-) diff --git a/.github/workflows/buildtest.yml b/.github/workflows/buildtest.yml index 4bc5343c6..1c4311dd5 100644 --- a/.github/workflows/buildtest.yml +++ b/.github/workflows/buildtest.yml @@ -37,7 +37,7 @@ jobs: uses: ./.github/workflows/pin.yml secrets: inherit generate-examples: - runs-on: ubuntu-latest + runs-on: [self-hosted, linux, X64] outputs: examples: ${{ steps.set-examples.outputs.examples }} steps: diff --git a/devenv.lock b/devenv.lock index fd6e746b8..dd368c611 100644 --- a/devenv.lock +++ b/devenv.lock @@ -50,11 +50,11 @@ "systems": "systems" }, "locked": { - "lastModified": 1709126324, + "lastModified": 1710146030, "owner": "numtide", "repo": "flake-utils", - "rev": "d465f4819400de7c8d874d50b982301f28a84605", - "treeHash": "f52cf07f5dc7208c6379eb10b7505fda4c429b88", + "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", + "treeHash": "bd263f021e345cb4a39d80c126ab650bebc3c10c", "type": "github" }, "original": { @@ -68,11 +68,11 @@ "systems": "systems_2" }, "locked": { - "lastModified": 1709126324, + "lastModified": 1710146030, "owner": "numtide", "repo": "flake-utils", - "rev": "d465f4819400de7c8d874d50b982301f28a84605", - "treeHash": "f52cf07f5dc7208c6379eb10b7505fda4c429b88", + "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", + "treeHash": "bd263f021e345cb4a39d80c126ab650bebc3c10c", "type": "github" }, "original": { @@ -111,11 +111,11 @@ "nixpkgs-regression": "nixpkgs-regression" }, "locked": { - "lastModified": 1709513008, + "lastModified": 1709963241, "owner": "domenkozar", "repo": "nix", - "rev": "d61bd1c0dda0ec7466079531547bbafdf538ed71", - "treeHash": "450086431140936247448766aecc37b90f4ff39e", + "rev": "e92c1fb8a57fe2e0bee725b1e7c68cfd8ffd55dc", + "treeHash": "86eda1beb323090366f08539b000539b461982fe", "type": "github" }, "original": { @@ -148,17 +148,17 @@ }, "nixpkgs": { "locked": { - "lastModified": 1709280738, + "lastModified": 1710219699, "owner": "domenkozar", "repo": "nixpkgs", - "rev": "0e172b739ff09c9dc652f2c9175ac0cf745cca81", - "treeHash": "ac7b46db5871ff29667646a328f426b945d3013c", + "rev": "b62ff9169f2aa2373995a690284a5681ed036f62", + "treeHash": "a45773f7fb8d252d7e7ca7e2b4aa067d25703fdd", "type": "github" }, "original": { "owner": "domenkozar", "repo": "nixpkgs", - "rev": "0e172b739ff09c9dc652f2c9175ac0cf745cca81", + "rev": "b62ff9169f2aa2373995a690284a5681ed036f62", "type": "github" } }, @@ -180,11 +180,11 @@ }, "nixpkgs-stable": { "locked": { - "lastModified": 1709128929, + "lastModified": 1710162809, "owner": "NixOS", "repo": "nixpkgs", - "rev": "c8e74c2f83fe12b4e5a8bd1abbc090575b0f7611", - "treeHash": "087dfee039daa2a8e336580010af1f20c03569d0", + "rev": "ddcd7598b2184008c97e6c9c6a21c5f37590b8d2", + "treeHash": "a89e05b79ecfce170082536583aa56246b24f6e4", "type": "github" }, "original": { diff --git a/devenv.nix b/devenv.nix index f7117e187..f86985e3a 100644 --- a/devenv.nix +++ b/devenv.nix @@ -122,7 +122,7 @@ pre-commit.hooks = { nixpkgs-fmt.enable = true; #shellcheck.enable = true; - clippy.enable = true; + #clippy.enable = true; rustfmt.enable = true; #markdownlint.enable = true; }; diff --git a/devenv.yaml b/devenv.yaml index 4ba91d45e..2447b77b7 100644 --- a/devenv.yaml +++ b/devenv.yaml @@ -12,7 +12,7 @@ inputs: nixpkgs: follows: nixpkgs nixpkgs: - url: github:domenkozar/nixpkgs/0e172b739ff09c9dc652f2c9175ac0cf745cca81 + url: github:domenkozar/nixpkgs/b62ff9169f2aa2373995a690284a5681ed036f62 pre-commit-hooks: url: github:cachix/pre-commit-hooks.nix inputs: From 7f39eef26a6fc0b3ac6f2054345efe57fc5abe64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Tue, 12 Mar 2024 10:43:08 +0000 Subject: [PATCH 083/146] Introduce devenv-nixpkgs Battle-tested nixpkgs using devenv's extensive testing infrastructure. --- .github/workflows/buildtest.yml | 5 +- devenv.lock | 69 +--------- devenv.yaml | 14 +- devenv/init/devenv.yaml | 13 +- devenv/src/flake.tmpl.nix | 2 +- docs/inputs.md | 4 +- docs/reference/yaml-options.md | 2 +- examples/aws-vault/devenv.yaml | 3 - examples/caddy-php/devenv.yaml | 3 - examples/clickhouse/devenv.yaml | 3 - examples/cockroachdb/devenv.yaml | 5 +- examples/couchdb/devenv.yaml | 3 - examples/dynamodb-local/devenv.yaml | 3 - examples/elasticmq/devenv.yaml | 3 - examples/hivemind/devenv.yaml | 3 - examples/influxdb/devenv.yaml | 3 - examples/javascript-bun/devenv.yaml | 3 - examples/javascript-directory/devenv.yaml | 3 - examples/javascript-pnpm/devenv.yaml | 3 - examples/javascript-yarn/devenv.yaml | 3 - examples/javascript/devenv.yaml | 3 - examples/jsonnet/devenv.yaml | 3 - examples/mailpit/devenv.yaml | 3 - examples/meilisearch/devenv.yaml | 3 - examples/minio/devenv.yaml | 3 - examples/mkcert/devenv.yaml | 3 - examples/modern-c/devenv.yaml | 3 - examples/mysql/devenv.yaml | 3 - examples/nur/devenv.yaml | 2 - examples/overlays/devenv.yaml | 2 - examples/overmind/devenv.yaml | 3 - examples/perl/devenv.yaml | 3 - examples/phoenix/devenv.yaml | 3 - examples/postgres-timescale/devenv.yaml | 3 - examples/postgres/devenv.yaml | 3 - examples/process-compose/devenv.yaml | 3 - examples/python-poetry/devenv.yaml | 3 - examples/python-venv/devenv.yaml | 3 - examples/python/devenv.yaml | 2 - examples/rabbitmq/devenv.yaml | 3 - examples/racket/devenv.yaml | 3 - examples/ruby/devenv.yaml | 2 - examples/rubyonrails/devenv.yaml | 2 - examples/scala/devenv.yaml | 3 - examples/scripts/devenv.yaml | 3 - examples/shell/devenv.yaml | 3 - examples/simple-remote/devenv.yaml | 2 - examples/simple/devenv.yaml | 3 - examples/starship/devenv.yaml | 3 - examples/supported-languages/devenv.yaml | 5 +- examples/temporal/devenv.yaml | 3 - examples/texlive/devenv.yaml | 3 - examples/vala/devenv.yaml | 3 - examples/varnish/devenv.yaml | 3 - examples/vault/devenv.yaml | 3 - examples/wiremock/devenv.yaml | 3 - flake.lock | 16 +-- flake.nix | 2 +- tests/dotenv/devenv.yaml | 3 - tests/gitignore/devenv.yaml | 3 - tests/glibcLocales/devenv.lock | 156 ---------------------- tests/permit-insecure/devenv.yaml | 4 +- tests/up-uses-shell/devenv.lock | 156 ---------------------- 63 files changed, 38 insertions(+), 556 deletions(-) delete mode 100644 examples/aws-vault/devenv.yaml delete mode 100644 examples/caddy-php/devenv.yaml delete mode 100644 examples/clickhouse/devenv.yaml delete mode 100644 examples/couchdb/devenv.yaml delete mode 100644 examples/elasticmq/devenv.yaml delete mode 100644 examples/hivemind/devenv.yaml delete mode 100644 examples/influxdb/devenv.yaml delete mode 100644 examples/javascript-bun/devenv.yaml delete mode 100644 examples/javascript-directory/devenv.yaml delete mode 100644 examples/javascript-pnpm/devenv.yaml delete mode 100644 examples/javascript-yarn/devenv.yaml delete mode 100644 examples/javascript/devenv.yaml delete mode 100644 examples/jsonnet/devenv.yaml delete mode 100644 examples/mailpit/devenv.yaml delete mode 100644 examples/meilisearch/devenv.yaml delete mode 100644 examples/minio/devenv.yaml delete mode 100644 examples/mkcert/devenv.yaml delete mode 100644 examples/modern-c/devenv.yaml delete mode 100644 examples/mysql/devenv.yaml delete mode 100644 examples/overmind/devenv.yaml delete mode 100644 examples/perl/devenv.yaml delete mode 100644 examples/phoenix/devenv.yaml delete mode 100644 examples/postgres-timescale/devenv.yaml delete mode 100644 examples/postgres/devenv.yaml delete mode 100644 examples/process-compose/devenv.yaml delete mode 100644 examples/python-poetry/devenv.yaml delete mode 100644 examples/python-venv/devenv.yaml delete mode 100644 examples/rabbitmq/devenv.yaml delete mode 100644 examples/racket/devenv.yaml delete mode 100644 examples/scala/devenv.yaml delete mode 100644 examples/scripts/devenv.yaml delete mode 100644 examples/shell/devenv.yaml delete mode 100644 examples/simple/devenv.yaml delete mode 100644 examples/starship/devenv.yaml delete mode 100644 examples/temporal/devenv.yaml delete mode 100644 examples/texlive/devenv.yaml delete mode 100644 examples/vala/devenv.yaml delete mode 100644 examples/varnish/devenv.yaml delete mode 100644 examples/wiremock/devenv.yaml delete mode 100644 tests/dotenv/devenv.yaml delete mode 100644 tests/gitignore/devenv.yaml delete mode 100644 tests/glibcLocales/devenv.lock delete mode 100644 tests/up-uses-shell/devenv.lock diff --git a/.github/workflows/buildtest.yml b/.github/workflows/buildtest.yml index 1c4311dd5..bedf12cb7 100644 --- a/.github/workflows/buildtest.yml +++ b/.github/workflows/buildtest.yml @@ -29,8 +29,7 @@ jobs: - name: Run tests run: | ./result/bin/devenv test - ./result/bin/devenv shell devenv-run-tests - ./result/bin/devenv search ncdu | grep "pkgs\.ncdu" + PATH=$PWD/result/bin:$PATH ./result/bin/devenv-run-tests tests pin: needs: build if: startsWith(github.ref, 'refs/tags/v') @@ -73,7 +72,7 @@ jobs: echo '{ allowAliases = false; }' > ~/.config/nixpkgs/config.nix - run: | nix build - ./result/bin/devenv test ${{ matrix.example }} + ./result/bin/devenv-run-tests --only ${{ matrix.example }} examples direnv: name: direnv (${{ join(matrix.os) }}) needs: build diff --git a/devenv.lock b/devenv.lock index dd368c611..0e55f63a0 100644 --- a/devenv.lock +++ b/devenv.lock @@ -63,24 +63,6 @@ "type": "github" } }, - "flake-utils_2": { - "inputs": { - "systems": "systems_2" - }, - "locked": { - "lastModified": 1710146030, - "owner": "numtide", - "repo": "flake-utils", - "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", - "treeHash": "bd263f021e345cb4a39d80c126ab650bebc3c10c", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "flake-utils", - "type": "github" - } - }, "gitignore": { "inputs": { "nixpkgs": [ @@ -125,40 +107,19 @@ "type": "github" } }, - "nix2container": { - "inputs": { - "flake-utils": "flake-utils", - "nixpkgs": [ - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1708764364, - "owner": "nlewo", - "repo": "nix2container", - "rev": "c891f90d2e3c48a6b33466c96e4851e0fc0cf455", - "treeHash": "747af167fd4350bd81b11ce824a756bb85b1757c", - "type": "github" - }, - "original": { - "owner": "nlewo", - "repo": "nix2container", - "type": "github" - } - }, "nixpkgs": { "locked": { - "lastModified": 1710219699, - "owner": "domenkozar", + "lastModified": 1710222005, + "owner": "NixOS", "repo": "nixpkgs", - "rev": "b62ff9169f2aa2373995a690284a5681ed036f62", - "treeHash": "a45773f7fb8d252d7e7ca7e2b4aa067d25703fdd", + "rev": "9a9a7552431c4f1a3b2eee9398641babf7c30d0e", + "treeHash": "f86a6354c1b9536fd6eec80186c371c5b09c0be8", "type": "github" }, "original": { - "owner": "domenkozar", + "owner": "NixOS", + "ref": "nixpkgs-unstable", "repo": "nixpkgs", - "rev": "b62ff9169f2aa2373995a690284a5681ed036f62", "type": "github" } }, @@ -197,7 +158,7 @@ "pre-commit-hooks": { "inputs": { "flake-compat": "flake-compat_2", - "flake-utils": "flake-utils_2", + "flake-utils": "flake-utils", "gitignore": "gitignore", "nixpkgs": [ "nixpkgs" @@ -222,7 +183,6 @@ "inputs": { "devenv": "devenv", "nix": "nix", - "nix2container": "nix2container", "nixpkgs": "nixpkgs", "pre-commit-hooks": "pre-commit-hooks" } @@ -241,21 +201,6 @@ "repo": "default", "type": "github" } - }, - "systems_2": { - "locked": { - "lastModified": 1681028828, - "owner": "nix-systems", - "repo": "default", - "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", - "treeHash": "cce81f2a0f0743b2eb61bc2eb6c7adbe2f2c6beb", - "type": "github" - }, - "original": { - "owner": "nix-systems", - "repo": "default", - "type": "github" - } } }, "root": "root", diff --git a/devenv.yaml b/devenv.yaml index 2447b77b7..e19cadd11 100644 --- a/devenv.yaml +++ b/devenv.yaml @@ -1,20 +1,8 @@ inputs: - nix2container: - url: github:nlewo/nix2container - inputs: - nixpkgs: - follows: nixpkgs devenv: url: path:.?dir=src/modules nix: url: github:domenkozar/nix/devenv-2.21 inputs: nixpkgs: - follows: nixpkgs - nixpkgs: - url: github:domenkozar/nixpkgs/b62ff9169f2aa2373995a690284a5681ed036f62 - pre-commit-hooks: - url: github:cachix/pre-commit-hooks.nix - inputs: - nixpkgs: - follows: nixpkgs + follows: nixpkgs \ No newline at end of file diff --git a/devenv/init/devenv.yaml b/devenv/init/devenv.yaml index c7cb5ceda..2457af5d1 100644 --- a/devenv/init/devenv.yaml +++ b/devenv/init/devenv.yaml @@ -1,3 +1,14 @@ inputs: nixpkgs: - url: github:NixOS/nixpkgs/nixpkgs-unstable + url: github:cachix/devenv-nixpkgs/rolling + +# If you're using non-OSS software, you can set allowUnfree to true. +# allowUnfree: true + +# If you're willing to use a package that's vulnerable +# permittedInsecurePackages: +# - "openssl-1.1.1w" + +# If you have more than one devenv you can merge them +#imports: +# - ./backend diff --git a/devenv/src/flake.tmpl.nix b/devenv/src/flake.tmpl.nix index 6d7d0ec30..ff27cb127 100644 --- a/devenv/src/flake.tmpl.nix +++ b/devenv/src/flake.tmpl.nix @@ -5,7 +5,7 @@ in { pre-commit-hooks.url = "github:cachix/pre-commit-hooks.nix"; pre-commit-hooks.inputs.nixpkgs.follows = "nixpkgs"; - nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; + nixpkgs.url = "github:cachix/devenv-nixpkgs/rolling"; devenv.url = "github:cachix/devenv?dir=src/modules"; } // (if builtins.pathExists (devenv_dotfile + "/flake.json") then builtins.fromJSON (builtins.readFile (devenv_dotfile + "/flake.json")) diff --git a/docs/inputs.md b/docs/inputs.md index 8275bb28f..4af007bdd 100644 --- a/docs/inputs.md +++ b/docs/inputs.md @@ -8,7 +8,7 @@ If you omit `devenv.yaml`, it defaults to: ```yaml title="devenv.yaml" inputs: nixpkgs: - url: github:NixOS/nixpkgs/nixpkgs-unstable + url: github:cachix/devenv-nixpkgs/rolling pre-commit-hooks: url: github:cachix/pre-commit-hooks.nix ``` @@ -20,7 +20,7 @@ For example, if you have a `devenv.yaml` file like: ```yaml title="devenv.yaml" inputs: nixpkgs-stable: - url: github:NixOS/nixpkgs/nixos-23.05 + url: github:NixOS/nixpkgs/nixos-23.11 ``` You can access the stable packages via the `inputs` field: diff --git a/docs/reference/yaml-options.md b/docs/reference/yaml-options.md index fbb5e1a72..38f79213a 100644 --- a/docs/reference/yaml-options.md +++ b/docs/reference/yaml-options.md @@ -41,7 +41,7 @@ allowUnfree: true inputs: nixpkgs: - url: github:NixOS/nixpkgs/nixpkgs-unstable + url: github:cachix/devenv-nixpkgs/rolling myproject: url: github:owner/myproject flake: false diff --git a/examples/aws-vault/devenv.yaml b/examples/aws-vault/devenv.yaml deleted file mode 100644 index 9860f4276..000000000 --- a/examples/aws-vault/devenv.yaml +++ /dev/null @@ -1,3 +0,0 @@ -inputs: - nixpkgs: - url: github:NixOS/nixpkgs/nixpkgs-unstable \ No newline at end of file diff --git a/examples/caddy-php/devenv.yaml b/examples/caddy-php/devenv.yaml deleted file mode 100644 index c7cb5ceda..000000000 --- a/examples/caddy-php/devenv.yaml +++ /dev/null @@ -1,3 +0,0 @@ -inputs: - nixpkgs: - url: github:NixOS/nixpkgs/nixpkgs-unstable diff --git a/examples/clickhouse/devenv.yaml b/examples/clickhouse/devenv.yaml deleted file mode 100644 index c7cb5ceda..000000000 --- a/examples/clickhouse/devenv.yaml +++ /dev/null @@ -1,3 +0,0 @@ -inputs: - nixpkgs: - url: github:NixOS/nixpkgs/nixpkgs-unstable diff --git a/examples/cockroachdb/devenv.yaml b/examples/cockroachdb/devenv.yaml index 41b52a524..4bb3b1c30 100644 --- a/examples/cockroachdb/devenv.yaml +++ b/examples/cockroachdb/devenv.yaml @@ -1,4 +1 @@ -inputs: - nixpkgs: - url: github:NixOS/nixpkgs/nixpkgs-unstable -allowUnfree: true +allowUnfree: true \ No newline at end of file diff --git a/examples/couchdb/devenv.yaml b/examples/couchdb/devenv.yaml deleted file mode 100644 index c7cb5ceda..000000000 --- a/examples/couchdb/devenv.yaml +++ /dev/null @@ -1,3 +0,0 @@ -inputs: - nixpkgs: - url: github:NixOS/nixpkgs/nixpkgs-unstable diff --git a/examples/dynamodb-local/devenv.yaml b/examples/dynamodb-local/devenv.yaml index 89a8475be..09bce897b 100644 --- a/examples/dynamodb-local/devenv.yaml +++ b/examples/dynamodb-local/devenv.yaml @@ -1,4 +1 @@ allowUnfree: true -inputs: - nixpkgs: - url: github:NixOS/nixpkgs/nixpkgs-unstable diff --git a/examples/elasticmq/devenv.yaml b/examples/elasticmq/devenv.yaml deleted file mode 100644 index c7cb5ceda..000000000 --- a/examples/elasticmq/devenv.yaml +++ /dev/null @@ -1,3 +0,0 @@ -inputs: - nixpkgs: - url: github:NixOS/nixpkgs/nixpkgs-unstable diff --git a/examples/hivemind/devenv.yaml b/examples/hivemind/devenv.yaml deleted file mode 100644 index c7cb5ceda..000000000 --- a/examples/hivemind/devenv.yaml +++ /dev/null @@ -1,3 +0,0 @@ -inputs: - nixpkgs: - url: github:NixOS/nixpkgs/nixpkgs-unstable diff --git a/examples/influxdb/devenv.yaml b/examples/influxdb/devenv.yaml deleted file mode 100644 index c7cb5ceda..000000000 --- a/examples/influxdb/devenv.yaml +++ /dev/null @@ -1,3 +0,0 @@ -inputs: - nixpkgs: - url: github:NixOS/nixpkgs/nixpkgs-unstable diff --git a/examples/javascript-bun/devenv.yaml b/examples/javascript-bun/devenv.yaml deleted file mode 100644 index c7cb5ceda..000000000 --- a/examples/javascript-bun/devenv.yaml +++ /dev/null @@ -1,3 +0,0 @@ -inputs: - nixpkgs: - url: github:NixOS/nixpkgs/nixpkgs-unstable diff --git a/examples/javascript-directory/devenv.yaml b/examples/javascript-directory/devenv.yaml deleted file mode 100644 index c7cb5ceda..000000000 --- a/examples/javascript-directory/devenv.yaml +++ /dev/null @@ -1,3 +0,0 @@ -inputs: - nixpkgs: - url: github:NixOS/nixpkgs/nixpkgs-unstable diff --git a/examples/javascript-pnpm/devenv.yaml b/examples/javascript-pnpm/devenv.yaml deleted file mode 100644 index c7cb5ceda..000000000 --- a/examples/javascript-pnpm/devenv.yaml +++ /dev/null @@ -1,3 +0,0 @@ -inputs: - nixpkgs: - url: github:NixOS/nixpkgs/nixpkgs-unstable diff --git a/examples/javascript-yarn/devenv.yaml b/examples/javascript-yarn/devenv.yaml deleted file mode 100644 index c7cb5ceda..000000000 --- a/examples/javascript-yarn/devenv.yaml +++ /dev/null @@ -1,3 +0,0 @@ -inputs: - nixpkgs: - url: github:NixOS/nixpkgs/nixpkgs-unstable diff --git a/examples/javascript/devenv.yaml b/examples/javascript/devenv.yaml deleted file mode 100644 index c7cb5ceda..000000000 --- a/examples/javascript/devenv.yaml +++ /dev/null @@ -1,3 +0,0 @@ -inputs: - nixpkgs: - url: github:NixOS/nixpkgs/nixpkgs-unstable diff --git a/examples/jsonnet/devenv.yaml b/examples/jsonnet/devenv.yaml deleted file mode 100644 index c7cb5ceda..000000000 --- a/examples/jsonnet/devenv.yaml +++ /dev/null @@ -1,3 +0,0 @@ -inputs: - nixpkgs: - url: github:NixOS/nixpkgs/nixpkgs-unstable diff --git a/examples/mailpit/devenv.yaml b/examples/mailpit/devenv.yaml deleted file mode 100644 index c7cb5ceda..000000000 --- a/examples/mailpit/devenv.yaml +++ /dev/null @@ -1,3 +0,0 @@ -inputs: - nixpkgs: - url: github:NixOS/nixpkgs/nixpkgs-unstable diff --git a/examples/meilisearch/devenv.yaml b/examples/meilisearch/devenv.yaml deleted file mode 100644 index c7cb5ceda..000000000 --- a/examples/meilisearch/devenv.yaml +++ /dev/null @@ -1,3 +0,0 @@ -inputs: - nixpkgs: - url: github:NixOS/nixpkgs/nixpkgs-unstable diff --git a/examples/minio/devenv.yaml b/examples/minio/devenv.yaml deleted file mode 100644 index c7cb5ceda..000000000 --- a/examples/minio/devenv.yaml +++ /dev/null @@ -1,3 +0,0 @@ -inputs: - nixpkgs: - url: github:NixOS/nixpkgs/nixpkgs-unstable diff --git a/examples/mkcert/devenv.yaml b/examples/mkcert/devenv.yaml deleted file mode 100644 index c7cb5ceda..000000000 --- a/examples/mkcert/devenv.yaml +++ /dev/null @@ -1,3 +0,0 @@ -inputs: - nixpkgs: - url: github:NixOS/nixpkgs/nixpkgs-unstable diff --git a/examples/modern-c/devenv.yaml b/examples/modern-c/devenv.yaml deleted file mode 100644 index c7cb5ceda..000000000 --- a/examples/modern-c/devenv.yaml +++ /dev/null @@ -1,3 +0,0 @@ -inputs: - nixpkgs: - url: github:NixOS/nixpkgs/nixpkgs-unstable diff --git a/examples/mysql/devenv.yaml b/examples/mysql/devenv.yaml deleted file mode 100644 index c7cb5ceda..000000000 --- a/examples/mysql/devenv.yaml +++ /dev/null @@ -1,3 +0,0 @@ -inputs: - nixpkgs: - url: github:NixOS/nixpkgs/nixpkgs-unstable diff --git a/examples/nur/devenv.yaml b/examples/nur/devenv.yaml index 284e6bab9..3094385fd 100644 --- a/examples/nur/devenv.yaml +++ b/examples/nur/devenv.yaml @@ -1,5 +1,3 @@ inputs: - nixpkgs: - url: github:NixOS/nixpkgs/nixpkgs-unstable nur: url: github:nix-community/NUR diff --git a/examples/overlays/devenv.yaml b/examples/overlays/devenv.yaml index 044462b43..708667382 100644 --- a/examples/overlays/devenv.yaml +++ b/examples/overlays/devenv.yaml @@ -1,7 +1,5 @@ allowUnfree: true inputs: - nixpkgs: - url: github:NixOS/nixpkgs/nixpkgs-unstable subflake: url: path:./subflake overlays: diff --git a/examples/overmind/devenv.yaml b/examples/overmind/devenv.yaml deleted file mode 100644 index c7cb5ceda..000000000 --- a/examples/overmind/devenv.yaml +++ /dev/null @@ -1,3 +0,0 @@ -inputs: - nixpkgs: - url: github:NixOS/nixpkgs/nixpkgs-unstable diff --git a/examples/perl/devenv.yaml b/examples/perl/devenv.yaml deleted file mode 100644 index c7cb5ceda..000000000 --- a/examples/perl/devenv.yaml +++ /dev/null @@ -1,3 +0,0 @@ -inputs: - nixpkgs: - url: github:NixOS/nixpkgs/nixpkgs-unstable diff --git a/examples/phoenix/devenv.yaml b/examples/phoenix/devenv.yaml deleted file mode 100644 index c7cb5ceda..000000000 --- a/examples/phoenix/devenv.yaml +++ /dev/null @@ -1,3 +0,0 @@ -inputs: - nixpkgs: - url: github:NixOS/nixpkgs/nixpkgs-unstable diff --git a/examples/postgres-timescale/devenv.yaml b/examples/postgres-timescale/devenv.yaml deleted file mode 100644 index c7cb5ceda..000000000 --- a/examples/postgres-timescale/devenv.yaml +++ /dev/null @@ -1,3 +0,0 @@ -inputs: - nixpkgs: - url: github:NixOS/nixpkgs/nixpkgs-unstable diff --git a/examples/postgres/devenv.yaml b/examples/postgres/devenv.yaml deleted file mode 100644 index c7cb5ceda..000000000 --- a/examples/postgres/devenv.yaml +++ /dev/null @@ -1,3 +0,0 @@ -inputs: - nixpkgs: - url: github:NixOS/nixpkgs/nixpkgs-unstable diff --git a/examples/process-compose/devenv.yaml b/examples/process-compose/devenv.yaml deleted file mode 100644 index c7cb5ceda..000000000 --- a/examples/process-compose/devenv.yaml +++ /dev/null @@ -1,3 +0,0 @@ -inputs: - nixpkgs: - url: github:NixOS/nixpkgs/nixpkgs-unstable diff --git a/examples/python-poetry/devenv.yaml b/examples/python-poetry/devenv.yaml deleted file mode 100644 index c7cb5ceda..000000000 --- a/examples/python-poetry/devenv.yaml +++ /dev/null @@ -1,3 +0,0 @@ -inputs: - nixpkgs: - url: github:NixOS/nixpkgs/nixpkgs-unstable diff --git a/examples/python-venv/devenv.yaml b/examples/python-venv/devenv.yaml deleted file mode 100644 index c7cb5ceda..000000000 --- a/examples/python-venv/devenv.yaml +++ /dev/null @@ -1,3 +0,0 @@ -inputs: - nixpkgs: - url: github:NixOS/nixpkgs/nixpkgs-unstable diff --git a/examples/python/devenv.yaml b/examples/python/devenv.yaml index 21272489a..c9bef614a 100644 --- a/examples/python/devenv.yaml +++ b/examples/python/devenv.yaml @@ -1,5 +1,3 @@ inputs: - nixpkgs: - url: github:NixOS/nixpkgs/nixpkgs-unstable nixpkgs-python: url: github:cachix/nixpkgs-python \ No newline at end of file diff --git a/examples/rabbitmq/devenv.yaml b/examples/rabbitmq/devenv.yaml deleted file mode 100644 index c7cb5ceda..000000000 --- a/examples/rabbitmq/devenv.yaml +++ /dev/null @@ -1,3 +0,0 @@ -inputs: - nixpkgs: - url: github:NixOS/nixpkgs/nixpkgs-unstable diff --git a/examples/racket/devenv.yaml b/examples/racket/devenv.yaml deleted file mode 100644 index c7cb5ceda..000000000 --- a/examples/racket/devenv.yaml +++ /dev/null @@ -1,3 +0,0 @@ -inputs: - nixpkgs: - url: github:NixOS/nixpkgs/nixpkgs-unstable diff --git a/examples/ruby/devenv.yaml b/examples/ruby/devenv.yaml index d6309408a..fa52210ad 100644 --- a/examples/ruby/devenv.yaml +++ b/examples/ruby/devenv.yaml @@ -1,6 +1,4 @@ inputs: - nixpkgs: - url: github:NixOS/nixpkgs/nixpkgs-unstable nixpkgs-ruby: url: github:bobvanderlinden/nixpkgs-ruby inputs: diff --git a/examples/rubyonrails/devenv.yaml b/examples/rubyonrails/devenv.yaml index d6309408a..fa52210ad 100644 --- a/examples/rubyonrails/devenv.yaml +++ b/examples/rubyonrails/devenv.yaml @@ -1,6 +1,4 @@ inputs: - nixpkgs: - url: github:NixOS/nixpkgs/nixpkgs-unstable nixpkgs-ruby: url: github:bobvanderlinden/nixpkgs-ruby inputs: diff --git a/examples/scala/devenv.yaml b/examples/scala/devenv.yaml deleted file mode 100644 index c7cb5ceda..000000000 --- a/examples/scala/devenv.yaml +++ /dev/null @@ -1,3 +0,0 @@ -inputs: - nixpkgs: - url: github:NixOS/nixpkgs/nixpkgs-unstable diff --git a/examples/scripts/devenv.yaml b/examples/scripts/devenv.yaml deleted file mode 100644 index c7cb5ceda..000000000 --- a/examples/scripts/devenv.yaml +++ /dev/null @@ -1,3 +0,0 @@ -inputs: - nixpkgs: - url: github:NixOS/nixpkgs/nixpkgs-unstable diff --git a/examples/shell/devenv.yaml b/examples/shell/devenv.yaml deleted file mode 100644 index c7cb5ceda..000000000 --- a/examples/shell/devenv.yaml +++ /dev/null @@ -1,3 +0,0 @@ -inputs: - nixpkgs: - url: github:NixOS/nixpkgs/nixpkgs-unstable diff --git a/examples/simple-remote/devenv.yaml b/examples/simple-remote/devenv.yaml index 995a9d996..44c953e6f 100644 --- a/examples/simple-remote/devenv.yaml +++ b/examples/simple-remote/devenv.yaml @@ -1,6 +1,4 @@ inputs: - nixpkgs: - url: github:NixOS/nixpkgs/nixpkgs-unstable getting-started: url: github:nix-dot-dev/getting-started-nix-template flake: false diff --git a/examples/simple/devenv.yaml b/examples/simple/devenv.yaml deleted file mode 100644 index c7cb5ceda..000000000 --- a/examples/simple/devenv.yaml +++ /dev/null @@ -1,3 +0,0 @@ -inputs: - nixpkgs: - url: github:NixOS/nixpkgs/nixpkgs-unstable diff --git a/examples/starship/devenv.yaml b/examples/starship/devenv.yaml deleted file mode 100644 index c7cb5ceda..000000000 --- a/examples/starship/devenv.yaml +++ /dev/null @@ -1,3 +0,0 @@ -inputs: - nixpkgs: - url: github:NixOS/nixpkgs/nixpkgs-unstable diff --git a/examples/supported-languages/devenv.yaml b/examples/supported-languages/devenv.yaml index 41b52a524..4bb3b1c30 100644 --- a/examples/supported-languages/devenv.yaml +++ b/examples/supported-languages/devenv.yaml @@ -1,4 +1 @@ -inputs: - nixpkgs: - url: github:NixOS/nixpkgs/nixpkgs-unstable -allowUnfree: true +allowUnfree: true \ No newline at end of file diff --git a/examples/temporal/devenv.yaml b/examples/temporal/devenv.yaml deleted file mode 100644 index c7cb5ceda..000000000 --- a/examples/temporal/devenv.yaml +++ /dev/null @@ -1,3 +0,0 @@ -inputs: - nixpkgs: - url: github:NixOS/nixpkgs/nixpkgs-unstable diff --git a/examples/texlive/devenv.yaml b/examples/texlive/devenv.yaml deleted file mode 100644 index c7cb5ceda..000000000 --- a/examples/texlive/devenv.yaml +++ /dev/null @@ -1,3 +0,0 @@ -inputs: - nixpkgs: - url: github:NixOS/nixpkgs/nixpkgs-unstable diff --git a/examples/vala/devenv.yaml b/examples/vala/devenv.yaml deleted file mode 100644 index c7cb5ceda..000000000 --- a/examples/vala/devenv.yaml +++ /dev/null @@ -1,3 +0,0 @@ -inputs: - nixpkgs: - url: github:NixOS/nixpkgs/nixpkgs-unstable diff --git a/examples/varnish/devenv.yaml b/examples/varnish/devenv.yaml deleted file mode 100644 index c7cb5ceda..000000000 --- a/examples/varnish/devenv.yaml +++ /dev/null @@ -1,3 +0,0 @@ -inputs: - nixpkgs: - url: github:NixOS/nixpkgs/nixpkgs-unstable diff --git a/examples/vault/devenv.yaml b/examples/vault/devenv.yaml index 41b52a524..09bce897b 100644 --- a/examples/vault/devenv.yaml +++ b/examples/vault/devenv.yaml @@ -1,4 +1 @@ -inputs: - nixpkgs: - url: github:NixOS/nixpkgs/nixpkgs-unstable allowUnfree: true diff --git a/examples/wiremock/devenv.yaml b/examples/wiremock/devenv.yaml deleted file mode 100644 index c6d28940e..000000000 --- a/examples/wiremock/devenv.yaml +++ /dev/null @@ -1,3 +0,0 @@ -inputs: - nixpkgs: - url: github:NixOS/nixpkgs/nixos-unstable diff --git a/flake.lock b/flake.lock index 97cfaca12..8c3c92bf5 100644 --- a/flake.lock +++ b/flake.lock @@ -96,17 +96,17 @@ }, "nixpkgs": { "locked": { - "lastModified": 1709069307, - "narHash": "sha256-ER6N232jucnqu4+AK80RdmgBDuk61FAqmp36EMqkQns=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "9c1ea5e3a2a2578792438cba233f2763593e19c5", + "lastModified": 1710236354, + "narHash": "sha256-vWrciFdq49vve43g4pbi7NjmL4cwG1ifXnQx+dU3T5E=", + "owner": "cachix", + "repo": "devenv-nixpkgs", + "rev": "829e73affeadfb4198a7105cbe3a03153d13edc9", "type": "github" }, "original": { - "owner": "NixOS", - "ref": "nixpkgs-unstable", - "repo": "nixpkgs", + "owner": "cachix", + "ref": "rolling", + "repo": "devenv-nixpkgs", "type": "github" } }, diff --git a/flake.nix b/flake.nix index 82eb06a3b..83ae7aaf0 100644 --- a/flake.nix +++ b/flake.nix @@ -6,7 +6,7 @@ extra-substituters = "https://devenv.cachix.org"; }; - inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; + inputs.nixpkgs.url = "github:cachix/devenv-nixpkgs/rolling"; inputs.pre-commit-hooks = { url = "github:cachix/pre-commit-hooks.nix"; inputs = { diff --git a/tests/dotenv/devenv.yaml b/tests/dotenv/devenv.yaml deleted file mode 100644 index 9860f4276..000000000 --- a/tests/dotenv/devenv.yaml +++ /dev/null @@ -1,3 +0,0 @@ -inputs: - nixpkgs: - url: github:NixOS/nixpkgs/nixpkgs-unstable \ No newline at end of file diff --git a/tests/gitignore/devenv.yaml b/tests/gitignore/devenv.yaml deleted file mode 100644 index c7cb5ceda..000000000 --- a/tests/gitignore/devenv.yaml +++ /dev/null @@ -1,3 +0,0 @@ -inputs: - nixpkgs: - url: github:NixOS/nixpkgs/nixpkgs-unstable diff --git a/tests/glibcLocales/devenv.lock b/tests/glibcLocales/devenv.lock deleted file mode 100644 index c75382010..000000000 --- a/tests/glibcLocales/devenv.lock +++ /dev/null @@ -1,156 +0,0 @@ -{ - "nodes": { - "devenv": { - "locked": { - "dir": "src/modules", - "lastModified": 1709300857, - "owner": "cachix", - "repo": "devenv", - "rev": "f0319af4f966fb8bc25c6429f4f2e097e79116c2", - "treeHash": "a035e54b8fe8523068171e97568d4d891234ccb0", - "type": "github" - }, - "original": { - "dir": "src/modules", - "owner": "cachix", - "repo": "devenv", - "type": "github" - } - }, - "flake-compat": { - "flake": false, - "locked": { - "lastModified": 1696426674, - "owner": "edolstra", - "repo": "flake-compat", - "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", - "treeHash": "2addb7b71a20a25ea74feeaf5c2f6a6b30898ecb", - "type": "github" - }, - "original": { - "owner": "edolstra", - "repo": "flake-compat", - "type": "github" - } - }, - "flake-utils": { - "inputs": { - "systems": "systems" - }, - "locked": { - "lastModified": 1709126324, - "owner": "numtide", - "repo": "flake-utils", - "rev": "d465f4819400de7c8d874d50b982301f28a84605", - "treeHash": "f52cf07f5dc7208c6379eb10b7505fda4c429b88", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "flake-utils", - "type": "github" - } - }, - "gitignore": { - "inputs": { - "nixpkgs": [ - "pre-commit-hooks", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1709087332, - "owner": "hercules-ci", - "repo": "gitignore.nix", - "rev": "637db329424fd7e46cf4185293b9cc8c88c95394", - "treeHash": "ca14199cabdfe1a06a7b1654c76ed49100a689f9", - "type": "github" - }, - "original": { - "owner": "hercules-ci", - "repo": "gitignore.nix", - "type": "github" - } - }, - "nixpkgs": { - "locked": { - "lastModified": 1709386671, - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "fa9a51752f1b5de583ad5213eb621be071806663", - "treeHash": "2cf56c4a9c6d7667222890dd4fb45de7574483b2", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixpkgs-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs-stable": { - "locked": { - "lastModified": 1709309926, - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "79baff8812a0d68e24a836df0a364c678089e2c7", - "treeHash": "0a912c9b662a028d46d4bfad6193d4379eb28ceb", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixos-23.11", - "repo": "nixpkgs", - "type": "github" - } - }, - "pre-commit-hooks": { - "inputs": { - "flake-compat": "flake-compat", - "flake-utils": "flake-utils", - "gitignore": "gitignore", - "nixpkgs": [ - "nixpkgs" - ], - "nixpkgs-stable": "nixpkgs-stable" - }, - "locked": { - "lastModified": 1708018599, - "owner": "cachix", - "repo": "pre-commit-hooks.nix", - "rev": "5df5a70ad7575f6601d91f0efec95dd9bc619431", - "treeHash": "6b6519c2b58ad1e106d9633f0d1b490a70fc6980", - "type": "github" - }, - "original": { - "owner": "cachix", - "repo": "pre-commit-hooks.nix", - "type": "github" - } - }, - "root": { - "inputs": { - "devenv": "devenv", - "nixpkgs": "nixpkgs", - "pre-commit-hooks": "pre-commit-hooks" - } - }, - "systems": { - "locked": { - "lastModified": 1681028828, - "owner": "nix-systems", - "repo": "default", - "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", - "treeHash": "cce81f2a0f0743b2eb61bc2eb6c7adbe2f2c6beb", - "type": "github" - }, - "original": { - "owner": "nix-systems", - "repo": "default", - "type": "github" - } - } - }, - "root": "root", - "version": 7 -} diff --git a/tests/permit-insecure/devenv.yaml b/tests/permit-insecure/devenv.yaml index 50d421943..9e2de855a 100644 --- a/tests/permit-insecure/devenv.yaml +++ b/tests/permit-insecure/devenv.yaml @@ -1,10 +1,8 @@ inputs: - nixpkgs: - url: github:NixOS/nixpkgs/nixpkgs-unstable nixpkgs-ruby: url: github:bobvanderlinden/nixpkgs-ruby inputs: nixpkgs: follows: nixpkgs permittedInsecurePackages: - - "openssl-1.1.1w" + - "openssl-1.1.1w" \ No newline at end of file diff --git a/tests/up-uses-shell/devenv.lock b/tests/up-uses-shell/devenv.lock deleted file mode 100644 index c75382010..000000000 --- a/tests/up-uses-shell/devenv.lock +++ /dev/null @@ -1,156 +0,0 @@ -{ - "nodes": { - "devenv": { - "locked": { - "dir": "src/modules", - "lastModified": 1709300857, - "owner": "cachix", - "repo": "devenv", - "rev": "f0319af4f966fb8bc25c6429f4f2e097e79116c2", - "treeHash": "a035e54b8fe8523068171e97568d4d891234ccb0", - "type": "github" - }, - "original": { - "dir": "src/modules", - "owner": "cachix", - "repo": "devenv", - "type": "github" - } - }, - "flake-compat": { - "flake": false, - "locked": { - "lastModified": 1696426674, - "owner": "edolstra", - "repo": "flake-compat", - "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", - "treeHash": "2addb7b71a20a25ea74feeaf5c2f6a6b30898ecb", - "type": "github" - }, - "original": { - "owner": "edolstra", - "repo": "flake-compat", - "type": "github" - } - }, - "flake-utils": { - "inputs": { - "systems": "systems" - }, - "locked": { - "lastModified": 1709126324, - "owner": "numtide", - "repo": "flake-utils", - "rev": "d465f4819400de7c8d874d50b982301f28a84605", - "treeHash": "f52cf07f5dc7208c6379eb10b7505fda4c429b88", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "flake-utils", - "type": "github" - } - }, - "gitignore": { - "inputs": { - "nixpkgs": [ - "pre-commit-hooks", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1709087332, - "owner": "hercules-ci", - "repo": "gitignore.nix", - "rev": "637db329424fd7e46cf4185293b9cc8c88c95394", - "treeHash": "ca14199cabdfe1a06a7b1654c76ed49100a689f9", - "type": "github" - }, - "original": { - "owner": "hercules-ci", - "repo": "gitignore.nix", - "type": "github" - } - }, - "nixpkgs": { - "locked": { - "lastModified": 1709386671, - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "fa9a51752f1b5de583ad5213eb621be071806663", - "treeHash": "2cf56c4a9c6d7667222890dd4fb45de7574483b2", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixpkgs-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs-stable": { - "locked": { - "lastModified": 1709309926, - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "79baff8812a0d68e24a836df0a364c678089e2c7", - "treeHash": "0a912c9b662a028d46d4bfad6193d4379eb28ceb", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixos-23.11", - "repo": "nixpkgs", - "type": "github" - } - }, - "pre-commit-hooks": { - "inputs": { - "flake-compat": "flake-compat", - "flake-utils": "flake-utils", - "gitignore": "gitignore", - "nixpkgs": [ - "nixpkgs" - ], - "nixpkgs-stable": "nixpkgs-stable" - }, - "locked": { - "lastModified": 1708018599, - "owner": "cachix", - "repo": "pre-commit-hooks.nix", - "rev": "5df5a70ad7575f6601d91f0efec95dd9bc619431", - "treeHash": "6b6519c2b58ad1e106d9633f0d1b490a70fc6980", - "type": "github" - }, - "original": { - "owner": "cachix", - "repo": "pre-commit-hooks.nix", - "type": "github" - } - }, - "root": { - "inputs": { - "devenv": "devenv", - "nixpkgs": "nixpkgs", - "pre-commit-hooks": "pre-commit-hooks" - } - }, - "systems": { - "locked": { - "lastModified": 1681028828, - "owner": "nix-systems", - "repo": "default", - "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", - "treeHash": "cce81f2a0f0743b2eb61bc2eb6c7adbe2f2c6beb", - "type": "github" - }, - "original": { - "owner": "nix-systems", - "repo": "default", - "type": "github" - } - } - }, - "root": "root", - "version": 7 -} From 0565784cef416a145e7c8312471f16c22acd2809 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Tue, 12 Mar 2024 12:13:59 +0000 Subject: [PATCH 084/146] display process logs during testing --- devenv-run-tests/src/main.rs | 7 ++++++- devenv/src/main.rs | 36 +++++++++++++++++++++++------------- 2 files changed, 29 insertions(+), 14 deletions(-) diff --git a/devenv-run-tests/src/main.rs b/devenv-run-tests/src/main.rs index a53b3fba9..64e554f1b 100644 --- a/devenv-run-tests/src/main.rs +++ b/devenv-run-tests/src/main.rs @@ -106,5 +106,10 @@ fn main() -> Result<(), Box> { println!(); println!("Ran {} tests, {} failed.", num_tests, num_failed_tests); - Ok(()) + + if num_failed_tests > 0 { + Err("Some tests failed".into()) + } else { + Ok(()) + } } diff --git a/devenv/src/main.rs b/devenv/src/main.rs index d671b3295..5144e5ab2 100644 --- a/devenv/src/main.rs +++ b/devenv/src/main.rs @@ -333,9 +333,11 @@ fn main() -> Result<()> { Commands::Info {} => app.info(), Commands::Build { attributes } => app.build(&attributes), Commands::Update { name } => app.update(&name), - Commands::Up { process, detach } => app.up(process.as_deref(), &detach), + Commands::Up { process, detach } => app.up(process.as_deref(), &detach, &detach), Commands::Processes { command } => match command { - ProcessesCommand::Up { process, detach } => app.up(process.as_deref(), &detach), + ProcessesCommand::Up { process, detach } => { + app.up(process.as_deref(), &detach, &detach) + } ProcessesCommand::Down {} => app.down(), }, Commands::Inputs { command } => match command { @@ -818,7 +820,7 @@ impl App { } if self.has_processes()? { - self.up(None, &true)?; + self.up(None, &true, &false); } let result = { @@ -911,7 +913,7 @@ impl App { Ok(()) } - fn up(&mut self, process: Option<&str>, detach: &bool) -> Result<()> { + fn up(&mut self, process: Option<&str>, detach: &bool, log_to_file: &bool) -> Result<()> { self.assemble()?; if !self.has_processes()? { self.logger @@ -973,19 +975,27 @@ impl App { if *detach { let log_file = std::fs::File::create(self.processes_log()) .expect("Failed to create PROCESSES_LOG"); - let process = cmd - .stdout(log_file.try_clone().expect("Failed to clone Stdio")) - .stderr(log_file) - .spawn() - .expect("Failed to spawn process"); + let process = if !*log_to_file { + cmd.stdout(std::process::Stdio::inherit()) + .stderr(std::process::Stdio::inherit()) + .spawn() + .expect("Failed to spawn process") + } else { + cmd.stdout(log_file.try_clone().expect("Failed to clone Stdio")) + .stderr(log_file) + .spawn() + .expect("Failed to spawn process") + }; std::fs::write(self.processes_pid(), process.id().to_string()) .expect("Failed to write PROCESSES_PID"); self.logger.info(&format!("PID is {}", process.id())); - self.logger.info(&format!( - "See logs: $ tail -f {}", - self.processes_log().display() - )); + if *log_to_file { + self.logger.info(&format!( + "See logs: $ tail -f {}", + self.processes_log().display() + )); + } self.logger.info("Stop: $ devenv processes stop"); } else { cmd.exec(); From bbbe0a333baa360bfddc0468d86a5993aa8a2b50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Tue, 12 Mar 2024 12:28:38 +0000 Subject: [PATCH 085/146] fix cli test --- examples/.gitignore | 1 + tests/.gitignore | 2 ++ tests/cli/.gitignore | 1 + tests/cli/devenv.yaml | 11 ----------- 4 files changed, 4 insertions(+), 11 deletions(-) create mode 100644 examples/.gitignore create mode 100644 tests/.gitignore create mode 100644 tests/cli/.gitignore delete mode 100644 tests/cli/devenv.yaml diff --git a/examples/.gitignore b/examples/.gitignore new file mode 100644 index 000000000..2cc0d1968 --- /dev/null +++ b/examples/.gitignore @@ -0,0 +1 @@ +devenv.lock diff --git a/tests/.gitignore b/tests/.gitignore new file mode 100644 index 000000000..c10f0eb9e --- /dev/null +++ b/tests/.gitignore @@ -0,0 +1,2 @@ +devenv.lock +devenv.local.nix diff --git a/tests/cli/.gitignore b/tests/cli/.gitignore new file mode 100644 index 000000000..d031aec0a --- /dev/null +++ b/tests/cli/.gitignore @@ -0,0 +1 @@ +devenv.yaml diff --git a/tests/cli/devenv.yaml b/tests/cli/devenv.yaml deleted file mode 100644 index 291d7fd61..000000000 --- a/tests/cli/devenv.yaml +++ /dev/null @@ -1,11 +0,0 @@ -inputs: - mk-shell-bin: - url: github:rrbutani/nix-mk-shell-bin - inputs: - nixpkgs: - follows: nixpkgs - nix2container: - url: github:nlewo/nix2container - inputs: - nixpkgs: - follows: nixpkgs From 02c48f660668be83bc3c0bac14692a2a5f4fc793 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Wed, 13 Mar 2024 10:54:12 +0000 Subject: [PATCH 086/146] --cores defaults to 2, --max-jobs defaults to num_cpu/2 --- devenv.lock | 16 ++++++++-------- devenv/src/command.rs | 3 +++ devenv/src/main.rs | 27 +++++++++++++++++++++++---- tests/cli/.test.sh | 4 +--- 4 files changed, 35 insertions(+), 15 deletions(-) diff --git a/devenv.lock b/devenv.lock index 0e55f63a0..b5dc8416e 100644 --- a/devenv.lock +++ b/devenv.lock @@ -109,17 +109,17 @@ }, "nixpkgs": { "locked": { - "lastModified": 1710222005, - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "9a9a7552431c4f1a3b2eee9398641babf7c30d0e", - "treeHash": "f86a6354c1b9536fd6eec80186c371c5b09c0be8", + "lastModified": 1710236354, + "owner": "cachix", + "repo": "devenv-nixpkgs", + "rev": "829e73affeadfb4198a7105cbe3a03153d13edc9", + "treeHash": "c92d1301b904a3d47027cca315d4de397f711280", "type": "github" }, "original": { - "owner": "NixOS", - "ref": "nixpkgs-unstable", - "repo": "nixpkgs", + "owner": "cachix", + "ref": "rolling", + "repo": "devenv-nixpkgs", "type": "github" } }, diff --git a/devenv/src/command.rs b/devenv/src/command.rs index 99f47d9af..e583b2e34 100644 --- a/devenv/src/command.rs +++ b/devenv/src/command.rs @@ -109,6 +109,9 @@ impl App { ) -> Result { let cmd = if command.starts_with("nix") { let mut flags = NIX_FLAGS.to_vec(); + flags.push("--max-jobs"); + let max_jobs = self.cli.max_jobs.to_string(); + flags.push(&max_jobs); // handle --nix-option key value for chunk in self.cli.nix_option.chunks_exact(2) { diff --git a/devenv/src/main.rs b/devenv/src/main.rs index 5144e5ab2..66e0079e5 100644 --- a/devenv/src/main.rs +++ b/devenv/src/main.rs @@ -34,6 +34,17 @@ struct Cli { #[arg(short, long, help = "Enable debug log level.")] verbose: bool, + #[arg(short = 'j', long, help = "Maximum number of Nix builds at any time.", default_value_t = max_jobs())] + max_jobs: u8, + + #[arg( + short = 'j', + long, + help = "Maximum number CPU cores being used by a single build..", + default_value = "2" + )] + cores: u8, + #[arg(short, long, default_value_t = default_system())] system: String, @@ -376,7 +387,7 @@ impl App { for filename in REQUIRED_FILES { let file_path = target.join(filename); if file_path.exists() { - panic!("File already exists {}", file_path.display()); + bail!("File already exists {}", file_path.display()); } } @@ -404,10 +415,10 @@ impl App { if !status.success() { match status.code() { Some(code) => { - panic!("direnv allow failed with code: {code}!"); + bail!("direnv allow failed with code: {code}!"); } None => { - panic!("direnv allow failed!"); + bail!("direnv allow failed!"); } } } @@ -1034,7 +1045,7 @@ impl App { fn assemble(&mut self) -> Result<()> { if !PathBuf::from("devenv.nix").exists() { - panic!(indoc::indoc! {" + bail!(indoc::indoc! {" File devenv.nix does not exist. To get started, run: $ devenv init @@ -1233,3 +1244,11 @@ fn cleanup_symlinks(root: &Path) -> (Vec, Vec) { (to_gc, removed_symlinks) } + +fn max_jobs() -> u8 { + let num_cpus = std::thread::available_parallelism().unwrap_or_else(|e| { + eprintln!("Failed to get number of logical CPUs: {}", e); + std::num::NonZeroUsize::new(1).unwrap() + }); + (num_cpus.get() / 2).try_into().unwrap() +} diff --git a/tests/cli/.test.sh b/tests/cli/.test.sh index 3c52a0920..bd6e5d0da 100755 --- a/tests/cli/.test.sh +++ b/tests/cli/.test.sh @@ -1,8 +1,6 @@ set -xe -# TODO: provide devenv cli via inputs -export PATH=$(pwd)/../../result/bin:$PATH - +rm devenv.yaml || true devenv build languages.python.package devenv shell ls -- -la | grep ".test.sh" devenv shell ls ../ | grep "cli" From 6f91d5ada1b8c26953c9d25765d077a456788c26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Wed, 13 Mar 2024 18:25:06 +0000 Subject: [PATCH 087/146] fix dotenv test --- src/modules/integrations/dotenv.nix | 19 +++++++++++-------- tests/dotenv/.setup.sh | 4 +++- tests/dotenv/bar.env | 1 - tests/dotenv/devenv.nix | 2 +- 4 files changed, 15 insertions(+), 11 deletions(-) delete mode 100644 tests/dotenv/bar.env diff --git a/src/modules/integrations/dotenv.nix b/src/modules/integrations/dotenv.nix index c34b1369b..61cf84d6b 100644 --- a/src/modules/integrations/dotenv.nix +++ b/src/modules/integrations/dotenv.nix @@ -1,11 +1,11 @@ -{ pkgs, config, lib, ... }: +{ pkgs, config, lib, self, ... }: let cfg = config.dotenv; normalizeFilenames = filenames: if lib.isList filenames then filenames else [ filenames ]; dotenvFiles = normalizeFilenames cfg.filename; - dotenvPaths = map (filename: config.devenv.root + "/" + filename) dotenvFiles; + dotenvPaths = map (filename: (self + ("/" + filename))) dotenvFiles; parseLine = line: let @@ -22,16 +22,19 @@ let createMissingFileMessage = file: let - exampleExists = builtins.pathExists (file + ".example"); + exampleExists = lib.pathExists (file + ".example"); + filename = builtins.baseNameOf (toString file); in lib.optionalString (!lib.pathExists file) '' - echo "💡 The dotenv file '${file}' was not found." + echo "💡 The dotenv file '${filename}' was not found." ${lib.optionalString exampleExists '' + echo echo " To create this file, you can copy the example file:" - echo " $ cp ${file}.example ${file}" + echo + echo " $ cp ${filename}.example ${filename}" + echo ''} ''; - in { options.dotenv = { @@ -61,14 +64,14 @@ in enterShell = lib.concatStringsSep "\n" (map createMissingFileMessage dotenvPaths); dotenv.resolved = mergeEnvFiles dotenvPaths; assertions = [{ - assertion = lib.hasPrefix ".env" cfg.filename; + assertion = builtins.all (lib.hasPrefix ".env") dotenvFiles; message = "The dotenv filename must start with '.env'."; }]; }) (lib.mkIf (!cfg.enable && !cfg.disableHint) { enterShell = let - dotenvFound = lib.any (file: lib.pathExists file) dotenvPaths; + dotenvFound = lib.any lib.pathExists dotenvPaths; in lib.optionalString dotenvFound '' echo "💡 A dotenv file was found, while dotenv integration is currently not enabled." diff --git a/tests/dotenv/.setup.sh b/tests/dotenv/.setup.sh index 39452af0f..d498074ee 100755 --- a/tests/dotenv/.setup.sh +++ b/tests/dotenv/.setup.sh @@ -1 +1,3 @@ -echo "{ env.LOCAL = \"1\";}" > devenv.local.nix \ No newline at end of file +echo "{ env.LOCAL = \"1\";}" > devenv.local.nix +echo "FOO=1\nBAR=2\nBAZ=3" > .env +echo "BAZ=5" > .env.bar \ No newline at end of file diff --git a/tests/dotenv/bar.env b/tests/dotenv/bar.env deleted file mode 100644 index 7dec7853a..000000000 --- a/tests/dotenv/bar.env +++ /dev/null @@ -1 +0,0 @@ -BAZ=5 diff --git a/tests/dotenv/devenv.nix b/tests/dotenv/devenv.nix index 29a801e9d..05cc64e38 100644 --- a/tests/dotenv/devenv.nix +++ b/tests/dotenv/devenv.nix @@ -1,6 +1,6 @@ { pkgs, ... }: { dotenv.enable = true; - dotenv.filename = [ ".env" "bar.env" ]; + dotenv.filename = [ ".env" ".env.bar" ]; env.BAR = "1"; } From e91d7a4ff22a91f6e18000675ea1d11e9947e831 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Thu, 14 Mar 2024 06:25:31 +0000 Subject: [PATCH 088/146] fix glibcLocales test on darwin --- tests/glibcLocales/devenv.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/glibcLocales/devenv.nix b/tests/glibcLocales/devenv.nix index 8e74deee9..0a16d9baa 100644 --- a/tests/glibcLocales/devenv.nix +++ b/tests/glibcLocales/devenv.nix @@ -1,5 +1,5 @@ { enterTest = '' - locale | grep "LANG=en_US.UTF-8" + locale -a | grep "en_US.UTF-8" ''; } From d2f7f88c18c16e19f8c08f16cf4f800e2073cfa9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Thu, 14 Mar 2024 07:49:30 +0000 Subject: [PATCH 089/146] bump nix --- flake.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/flake.lock b/flake.lock index 8c3c92bf5..2f9f8dbb8 100644 --- a/flake.lock +++ b/flake.lock @@ -80,11 +80,11 @@ "nixpkgs-regression": "nixpkgs-regression" }, "locked": { - "lastModified": 1709963241, - "narHash": "sha256-8RGoqq9ApGLGh6lNJfBRzqHy/S3u53HL8mDtmI7y9Hc=", + "lastModified": 1710402466, + "narHash": "sha256-d7EDvejHLnAI2KDdKo/1eAgdQn/FtIpyXhPhr8114Kg=", "owner": "domenkozar", "repo": "nix", - "rev": "e92c1fb8a57fe2e0bee725b1e7c68cfd8ffd55dc", + "rev": "10d5a3af9694a0d54d75e4450f95c8f6eb3f5e95", "type": "github" }, "original": { From b9e31f3132c54f55330f18bac50aee8da5476960 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Thu, 14 Mar 2024 08:29:00 +0000 Subject: [PATCH 090/146] fix flakes eval --- src/modules/top-level.nix | 1 + 1 file changed, 1 insertion(+) diff --git a/src/modules/top-level.nix b/src/modules/top-level.nix index 839d44197..71433d5b5 100644 --- a/src/modules/top-level.nix +++ b/src/modules/top-level.nix @@ -196,6 +196,7 @@ in ]; # use builtins.toPath to normalize path if root is "/" (container) devenv.state = builtins.toPath (config.devenv.dotfile + "/state"); + devenv.dotfile = lib.mkDefault (builtins.toPath (config.devenv.root + "/.devenv")); devenv.profile = profile; env.DEVENV_PROFILE = config.devenv.profile; From 2006015f10e8443f4664ae810a2bfd3b81e0cb3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Thu, 14 Mar 2024 09:14:56 +0000 Subject: [PATCH 091/146] skip tests for now --- .github/workflows/buildtest.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/buildtest.yml b/.github/workflows/buildtest.yml index bedf12cb7..a4acb7f3f 100644 --- a/.github/workflows/buildtest.yml +++ b/.github/workflows/buildtest.yml @@ -29,7 +29,7 @@ jobs: - name: Run tests run: | ./result/bin/devenv test - PATH=$PWD/result/bin:$PATH ./result/bin/devenv-run-tests tests + #PATH=$PWD/result/bin:$PATH ./result/bin/devenv-run-tests tests pin: needs: build if: startsWith(github.ref, 'refs/tags/v') From 051c6c49509f4f2f0350b12812d4e703b24cef86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Fri, 15 Mar 2024 04:42:06 +0000 Subject: [PATCH 092/146] fix direnv test --- .github/workflows/buildtest.yml | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/.github/workflows/buildtest.yml b/.github/workflows/buildtest.yml index a4acb7f3f..4f9978b86 100644 --- a/.github/workflows/buildtest.yml +++ b/.github/workflows/buildtest.yml @@ -70,9 +70,7 @@ jobs: run: | mkdir -p ~/.config/nixpkgs echo '{ allowAliases = false; }' > ~/.config/nixpkgs/config.nix - - run: | - nix build - ./result/bin/devenv-run-tests --only ${{ matrix.example }} examples + - run: PATH=$PWD/result/bin:$PATH ./result/bin/devenv-run-tests --only ${{ matrix.example }} examples direnv: name: direnv (${{ join(matrix.os) }}) needs: build @@ -91,23 +89,21 @@ jobs: name: devenv authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}' - run: | - mv ./examples/simple/devenv.yaml ./examples/simple/devenv.yaml.orig - nix run nixpkgs#gawk -- ' - { print } - /^inputs:$/ { - print " devenv:"; - print " url: path:../../?dir=src/modules"; - } - ' ./examples/simple/devenv.yaml.orig > ./examples/simple/devenv.yaml - nix profile remove '.*' - nix profile install . 'nixpkgs#direnv' mkdir -p ~/.config/direnv/ cat > ~/.config/direnv/direnv.toml << 'EOF' [global] strict_env = true EOF - direnv allow ./examples/simple - direnv exec ./examples/simple true + + nix build + devenv_dir=$PWD + export PATH=$PWD/result/bin:$PATH + + pushd examples/simple + devenv inputs add devenv path:$devenv_dir?dir=src/modules + nix shell nixpkgs#direnv -c direnv allow . + nix shell nixpkgs#direnv -c direnv exec . true + popd fish-zsh: name: zsh/fish (${{ join(matrix.os) }}) needs: build From 688973c234ad13ce48c2f9f1e740e312890016dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Fri, 15 Mar 2024 07:16:53 +0000 Subject: [PATCH 093/146] fix example generation --- .github/workflows/buildtest.yml | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/.github/workflows/buildtest.yml b/.github/workflows/buildtest.yml index 4f9978b86..9df2935a5 100644 --- a/.github/workflows/buildtest.yml +++ b/.github/workflows/buildtest.yml @@ -44,7 +44,7 @@ jobs: uses: actions/checkout@v4 - id: set-examples run: | - json=$(tree -J -L 1 examples | jq -c '[.[0].contents[] | .name]') + json=$(nix shell nixpkgs#tree -c tree -J -L 1 examples | nix shell nixpkgs#jq -c jq -c '[.[0].contents[] | .name]') echo "examples=$json" >> $GITHUB_OUTPUT examples: name: ${{ matrix.example }} (${{ join(matrix.os) }}) @@ -66,10 +66,7 @@ jobs: with: name: devenv authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}' - - name: Disable package aliases - run: | - mkdir -p ~/.config/nixpkgs - echo '{ allowAliases = false; }' > ~/.config/nixpkgs/config.nix + - run: nix build - run: PATH=$PWD/result/bin:$PATH ./result/bin/devenv-run-tests --only ${{ matrix.example }} examples direnv: name: direnv (${{ join(matrix.os) }}) From 928228da39b3855d4a439624b33f566174a91bbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Fri, 15 Mar 2024 08:13:52 +0000 Subject: [PATCH 094/146] ci: avoid building all over again --- .github/workflows/buildtest.yml | 45 +++++++++++++++++++++++++-------- 1 file changed, 34 insertions(+), 11 deletions(-) diff --git a/.github/workflows/buildtest.yml b/.github/workflows/buildtest.yml index 9df2935a5..1899fc539 100644 --- a/.github/workflows/buildtest.yml +++ b/.github/workflows/buildtest.yml @@ -15,6 +15,8 @@ jobs: matrix: os: [[self-hosted, linux, X64], [macos-latest], [self-hosted, macOS], [self-hosted, linux, ARM64]] runs-on: ${{ matrix.os }} + outputs: + bin: ${{ steps.build.outputs.bin }} steps: - uses: actions/checkout@v4 - uses: cachix/install-nix-action@v26 @@ -25,11 +27,31 @@ jobs: with: name: devenv authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}' - - run: nix build - - name: Run tests + - id: build run: | - ./result/bin/devenv test - #PATH=$PWD/result/bin:$PATH ./result/bin/devenv-run-tests tests + bin=$(nix build --print-out-paths) + echo "bin=$bin" >> $GITHUB_OUTPUT + - name: Run tests + run: ./result/bin/devenv test + tests: + strategy: + fail-fast: false + matrix: + os: [[self-hosted, linux, X64], [macos-latest], [self-hosted, macOS], [self-hosted, linux, ARM64]] + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v4 + - uses: cachix/install-nix-action@v26 + with: + extra_nix_config: | + access-tokens = github.com=${{ secrets.GITHUB_TOKEN }} + - uses: cachix/cachix-action@v14 + with: + name: devenv + authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}' + - run: | + nix-store -r ${{ needs.build.outputs.bin }} + PATH=${{ needs.build.outputs.bin }}/bin:$PATH ${{ needs.build.outputs.bin }}/bin/devenv-run-tests tests pin: needs: build if: startsWith(github.ref, 'refs/tags/v') @@ -66,8 +88,9 @@ jobs: with: name: devenv authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}' - - run: nix build - - run: PATH=$PWD/result/bin:$PATH ./result/bin/devenv-run-tests --only ${{ matrix.example }} examples + - run: | + nix-store -r ${{ needs.build.outputs.bin }} + PATH=${{ needs.build.outputs.bin }}/bin:$PATH ${{ needs.build.outputs.bin }}/bin/devenv-run-tests --only ${{ matrix.example }} examples direnv: name: direnv (${{ join(matrix.os) }}) needs: build @@ -92,9 +115,9 @@ jobs: strict_env = true EOF - nix build devenv_dir=$PWD - export PATH=$PWD/result/bin:$PATH + export PATH=${{ needs.build.outputs.bin }}/bin:$PATH + nix-store -r ${{ needs.build.outputs.bin }} pushd examples/simple devenv inputs add devenv path:$devenv_dir?dir=src/modules @@ -118,7 +141,7 @@ jobs: with: name: devenv authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}' - - run: nix build + - run: nix-store -r ${{ needs.build.outputs.bin }} - run: | - nix shell nixpkgs#zsh -c zsh -c "./result/bin/devenv version" - nix shell nixpkgs#fish -c fish -c "./result/bin/devenv version" + nix shell nixpkgs#zsh -c zsh -c "${{ needs.build.outputs.bin }}/bin/devenv version" + nix shell nixpkgs#fish -c fish -c "${{ needs.build.outputs.bin }}/bin/devenv version" From 2cd189bf07cd625f0bc18920ffdc9453a3150710 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Fri, 15 Mar 2024 11:43:14 +0000 Subject: [PATCH 095/146] remove dummy removal of tmpdir --- devenv/src/main.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/devenv/src/main.rs b/devenv/src/main.rs index 66e0079e5..ea8d48653 100644 --- a/devenv/src/main.rs +++ b/devenv/src/main.rs @@ -856,10 +856,6 @@ impl App { self.down()?; } - tmpdir - .close() - .expect("Failed to remove temporary directory"); - if !result.status.success() { self.logger.error("Tests failed :("); bail!("Tests failed"); From 4c986e8e3bd947f074ea9599157bca3e4a92ff93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Fri, 15 Mar 2024 11:43:29 +0000 Subject: [PATCH 096/146] docs: more devenv.yaml examples --- docs/composing-using-imports.md | 2 +- docs/reference/yaml-options.md | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/docs/composing-using-imports.md b/docs/composing-using-imports.md index b2ca8d45c..83fd5ae1e 100644 --- a/docs/composing-using-imports.md +++ b/docs/composing-using-imports.md @@ -8,7 +8,7 @@ that live in separate folders. ```yaml title="devenv.yaml" inputs: nixpkgs: - url: github:NixOS/nixpkgs/nixpkgs-unstable + url: github:cachix/devenv-nixpkgs/rolling devenv: url: github:cachix/devenv imports: diff --git a/docs/reference/yaml-options.md b/docs/reference/yaml-options.md index 38f79213a..9385cdd24 100644 --- a/docs/reference/yaml-options.md +++ b/docs/reference/yaml-options.md @@ -39,6 +39,11 @@ ```yaml allowUnfree: true +allowBroken: true +clean: + enabled: true + keep: + - EDITOR inputs: nixpkgs: url: github:cachix/devenv-nixpkgs/rolling From 796c609c10590e83a0d3eaa1640f71f8f1e9729b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Fri, 15 Mar 2024 11:43:51 +0000 Subject: [PATCH 097/146] examples/cockroachdb: supports only linux --- examples/cockroachdb/devenv.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/cockroachdb/devenv.nix b/examples/cockroachdb/devenv.nix index 65a2e365e..cee00f43e 100644 --- a/examples/cockroachdb/devenv.nix +++ b/examples/cockroachdb/devenv.nix @@ -1,7 +1,7 @@ -{ ... }: +{ pkgs, ... }: { services.cockroachdb = { - enable = true; + enable = pkgs.stdenv.isLinux; }; } From 49a97ab953da4101ae069fc9a6e2411a93686dc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Fri, 15 Mar 2024 11:44:08 +0000 Subject: [PATCH 098/146] examples/python-venv: correctly use state dir --- examples/python-venv/.test.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/python-venv/.test.sh b/examples/python-venv/.test.sh index 2cd787cbe..a2c9b3e38 100755 --- a/examples/python-venv/.test.sh +++ b/examples/python-venv/.test.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash set -ex -[ "$(command -v python)" = "$PWD/.devenv/state/venv/bin/python" ] -[ "$VIRTUAL_ENV" = "$PWD/.devenv/state/venv" ] -python --version +[ "$(command -v python)" = "$DEVENV_STATE/venv/bin/python" ] +[ "$VIRTUAL_ENV" = "$$DEVENV_STATE/venv" ] +python --version \ No newline at end of file From 2e043c03bd93d38b6e3e996617cf61380fb0f3b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Fri, 15 Mar 2024 11:44:34 +0000 Subject: [PATCH 099/146] examples/simple-remote: use simple example as a base --- examples/simple-remote/devenv.nix | 4 ++-- examples/simple-remote/devenv.yaml | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/simple-remote/devenv.nix b/examples/simple-remote/devenv.nix index a036865b3..f61a360c8 100644 --- a/examples/simple-remote/devenv.nix +++ b/examples/simple-remote/devenv.nix @@ -1,5 +1,5 @@ -{ lib, ... }: +{ pkgs, ... }: { - pre-commit.hooks.statix.enable = lib.mkForce false; + env.GREET2 = "Hello from Nix!"; } diff --git a/examples/simple-remote/devenv.yaml b/examples/simple-remote/devenv.yaml index 44c953e6f..788f7f845 100644 --- a/examples/simple-remote/devenv.yaml +++ b/examples/simple-remote/devenv.yaml @@ -1,6 +1,6 @@ inputs: - getting-started: - url: github:nix-dot-dev/getting-started-nix-template + simple: + url: github:cachix/devenv flake: false imports: - - getting-started + - simple/examples/simple \ No newline at end of file From d8a8c122679e98abc53d1c68f3344af5183cf24b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Fri, 15 Mar 2024 11:44:44 +0000 Subject: [PATCH 100/146] bump nix --- flake.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/flake.lock b/flake.lock index 2f9f8dbb8..ab02c9473 100644 --- a/flake.lock +++ b/flake.lock @@ -80,11 +80,11 @@ "nixpkgs-regression": "nixpkgs-regression" }, "locked": { - "lastModified": 1710402466, - "narHash": "sha256-d7EDvejHLnAI2KDdKo/1eAgdQn/FtIpyXhPhr8114Kg=", + "lastModified": 1710500156, + "narHash": "sha256-zvCqeUO2GLOm7jnU23G4EzTZR7eylcJN+HJ5svjmubI=", "owner": "domenkozar", "repo": "nix", - "rev": "10d5a3af9694a0d54d75e4450f95c8f6eb3f5e95", + "rev": "c5bbf14ecbd692eeabf4184cc8d50f79c2446549", "type": "github" }, "original": { From 794116e327e3dfe7e1edeaf6995e05c9babc8c26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Fri, 15 Mar 2024 11:44:56 +0000 Subject: [PATCH 101/146] fix flake/flake-parts templates --- examples/simple-remote/.test.sh | 2 ++ examples/simple/devenv.yaml | 3 +++ templates/flake-parts/flake.nix | 5 ++++- templates/simple/flake.nix | 2 +- 4 files changed, 10 insertions(+), 2 deletions(-) create mode 100644 examples/simple-remote/.test.sh create mode 100644 examples/simple/devenv.yaml diff --git a/examples/simple-remote/.test.sh b/examples/simple-remote/.test.sh new file mode 100644 index 000000000..7a2ced314 --- /dev/null +++ b/examples/simple-remote/.test.sh @@ -0,0 +1,2 @@ +env | grep GREET +env | grep GREET2 \ No newline at end of file diff --git a/examples/simple/devenv.yaml b/examples/simple/devenv.yaml new file mode 100644 index 000000000..c7cb5ceda --- /dev/null +++ b/examples/simple/devenv.yaml @@ -0,0 +1,3 @@ +inputs: + nixpkgs: + url: github:NixOS/nixpkgs/nixpkgs-unstable diff --git a/templates/flake-parts/flake.nix b/templates/flake-parts/flake.nix index f9d1e7a46..1aea74d5c 100644 --- a/templates/flake-parts/flake.nix +++ b/templates/flake-parts/flake.nix @@ -2,7 +2,7 @@ description = "Description for the project"; inputs = { - nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + nixpkgs.url = "github:github:cachix/devenv-nixpkgs/rolling"; devenv.url = "github:cachix/devenv"; nix2container.url = "github:nlewo/nix2container"; nix2container.inputs.nixpkgs.follows = "nixpkgs"; @@ -26,6 +26,9 @@ # module parameters provide easy access to attributes of the same # system. + # needed for devenv up + packages.devenv-up = self'.devShells.default.config.procfileScript; + # Equivalent to inputs'.nixpkgs.legacyPackages.hello; packages.default = pkgs.hello; diff --git a/templates/simple/flake.nix b/templates/simple/flake.nix index a440343d2..b049d27f1 100644 --- a/templates/simple/flake.nix +++ b/templates/simple/flake.nix @@ -1,6 +1,6 @@ { inputs = { - nixpkgs.url = "github:NixOS/nixpkgs/nixos-23.05"; + nixpkgs.url = "github:github:cachix/devenv-nixpkgs/rolling"; systems.url = "github:nix-systems/default"; devenv.url = "github:cachix/devenv"; }; From dffe8c917d7061ff8258371ab1d6ce5c63cf881c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Fri, 15 Mar 2024 11:55:18 +0000 Subject: [PATCH 102/146] fix github actions for tests --- .github/workflows/buildtest.yml | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/.github/workflows/buildtest.yml b/.github/workflows/buildtest.yml index 1899fc539..f09c5cecf 100644 --- a/.github/workflows/buildtest.yml +++ b/.github/workflows/buildtest.yml @@ -15,8 +15,6 @@ jobs: matrix: os: [[self-hosted, linux, X64], [macos-latest], [self-hosted, macOS], [self-hosted, linux, ARM64]] runs-on: ${{ matrix.os }} - outputs: - bin: ${{ steps.build.outputs.bin }} steps: - uses: actions/checkout@v4 - uses: cachix/install-nix-action@v26 @@ -34,6 +32,7 @@ jobs: - name: Run tests run: ./result/bin/devenv test tests: + needs: build strategy: fail-fast: false matrix: @@ -50,8 +49,8 @@ jobs: name: devenv authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}' - run: | - nix-store -r ${{ needs.build.outputs.bin }} - PATH=${{ needs.build.outputs.bin }}/bin:$PATH ${{ needs.build.outputs.bin }}/bin/devenv-run-tests tests + nix build + PATH=$PWD/result/bin:$PATH devenv-run-tests tests pin: needs: build if: startsWith(github.ref, 'refs/tags/v') @@ -89,8 +88,8 @@ jobs: name: devenv authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}' - run: | - nix-store -r ${{ needs.build.outputs.bin }} - PATH=${{ needs.build.outputs.bin }}/bin:$PATH ${{ needs.build.outputs.bin }}/bin/devenv-run-tests --only ${{ matrix.example }} examples + nix build + PATH=$PWD/result/bin:$PATH devenv-run-tests --only ${{ matrix.example }} examples direnv: name: direnv (${{ join(matrix.os) }}) needs: build @@ -116,8 +115,8 @@ jobs: EOF devenv_dir=$PWD - export PATH=${{ needs.build.outputs.bin }}/bin:$PATH - nix-store -r ${{ needs.build.outputs.bin }} + export PATH=$PWD/result/bin:$PATH + nix build pushd examples/simple devenv inputs add devenv path:$devenv_dir?dir=src/modules @@ -141,7 +140,7 @@ jobs: with: name: devenv authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}' - - run: nix-store -r ${{ needs.build.outputs.bin }} + - run: nix build - run: | - nix shell nixpkgs#zsh -c zsh -c "${{ needs.build.outputs.bin }}/bin/devenv version" - nix shell nixpkgs#fish -c fish -c "${{ needs.build.outputs.bin }}/bin/devenv version" + nix shell nixpkgs#zsh -c zsh -c ./result/bin/devenv version + nix shell nixpkgs#fish -c fish -c ./result/bin/devenv version From 3baecf32a721a8f9b509b3ca6465fbbf29ab05ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Sat, 16 Mar 2024 07:31:40 +0000 Subject: [PATCH 103/146] try fix more examples --- .github/workflows/buildtest.yml | 2 +- examples/python-venv/.test.sh | 2 +- examples/simple-remote/.test.sh | 0 3 files changed, 2 insertions(+), 2 deletions(-) mode change 100644 => 100755 examples/simple-remote/.test.sh diff --git a/.github/workflows/buildtest.yml b/.github/workflows/buildtest.yml index f09c5cecf..9e68089f2 100644 --- a/.github/workflows/buildtest.yml +++ b/.github/workflows/buildtest.yml @@ -73,7 +73,7 @@ jobs: strategy: fail-fast: false matrix: - os: [[ubuntu-latest], [macos-latest], [self-hosted, macOS], [self-hosted, linux, ARM64]] + os: [[self-hosted, linux, X64], [macos-latest], [self-hosted, macOS], [self-hosted, linux, ARM64]] example: ${{ fromJSON(needs.generate-examples.outputs.examples) }} runs-on: ${{ matrix.os }} steps: diff --git a/examples/python-venv/.test.sh b/examples/python-venv/.test.sh index a2c9b3e38..311e50f77 100755 --- a/examples/python-venv/.test.sh +++ b/examples/python-venv/.test.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash set -ex [ "$(command -v python)" = "$DEVENV_STATE/venv/bin/python" ] -[ "$VIRTUAL_ENV" = "$$DEVENV_STATE/venv" ] +[ "$VIRTUAL_ENV" = "$DEVENV_STATE/venv" ] python --version \ No newline at end of file diff --git a/examples/simple-remote/.test.sh b/examples/simple-remote/.test.sh old mode 100644 new mode 100755 From fb7d97762a7f09a7721ca11a37901ff88a62673b Mon Sep 17 00:00:00 2001 From: Bob van der Linden Date: Sat, 16 Mar 2024 10:42:32 +0100 Subject: [PATCH 104/146] examples: rubyonrails: use port 3000 instead of 5100 Rails listens on port 3000 by default. --- examples/rubyonrails/.test.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/rubyonrails/.test.sh b/examples/rubyonrails/.test.sh index a055c6b04..1c701bfa9 100755 --- a/examples/rubyonrails/.test.sh +++ b/examples/rubyonrails/.test.sh @@ -2,9 +2,9 @@ set -ex pushd blog - wait_for_port 5100 + wait_for_port 3000 rails db:create - curl -s http://localhost:5100/ | grep "version" + curl -s http://localhost:3000/ | grep "version" popd # make sure puma was compiled with ssl From 055bc43d02e301fb8b10e41bb2e7711de859e862 Mon Sep 17 00:00:00 2001 From: Bob van der Linden Date: Sat, 16 Mar 2024 10:43:58 +0100 Subject: [PATCH 105/146] examples: rubyonrails: force overwriting any files The test outputted errors regarding upon running `rails new` that `.gitignore` already exists. For the test it doesn't really matter to overwrite these files, so I added `--force`. --- examples/rubyonrails/devenv.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/rubyonrails/devenv.nix b/examples/rubyonrails/devenv.nix index 1273110ca..4586b3f9d 100644 --- a/examples/rubyonrails/devenv.nix +++ b/examples/rubyonrails/devenv.nix @@ -16,7 +16,7 @@ enterShell = '' if [ ! -d "blog" ]; then gem install rails - rails new blog -d=postgresql + rails new blog --database=postgresql --force fi export PATH="$DEVENV_ROOT/blog/bin:$PATH" pushd blog From 6ab8ee4545c8dc9bc48324c4724840f03344682e Mon Sep 17 00:00:00 2001 From: Bob van der Linden Date: Sat, 16 Mar 2024 10:47:20 +0100 Subject: [PATCH 106/146] postgres: support non-alphanumeric usernames Currently postgres fails to create a database because my username contains a `.`. Wrapping the database name in `"` will resolve the problem. I've rewritten the line to use HEREDOC so that we do not have to mess with escaping (from Nix) within escaping (from Bash) within escaping (from psql). Now it only escapes using Nix and psql. --- src/modules/services/postgres.nix | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/modules/services/postgres.nix b/src/modules/services/postgres.nix index 4dfef8c68..847380764 100644 --- a/src/modules/services/postgres.nix +++ b/src/modules/services/postgres.nix @@ -56,7 +56,10 @@ let cfg.initialDatabases) else lib.optionalString cfg.createDatabase '' - echo "CREATE DATABASE ''${USER:-$(id -nu)};" | psql --dbname postgres''; + psql --dbname postgres << EOF + CREATE DATABASE "''${USER:-$(id -nu)}"; + EOF + ''; runInitialScript = if cfg.initialScript != null then From 74364ee1d08295a327a4aa3ad9082d00c0fbdb31 Mon Sep 17 00:00:00 2001 From: Bob van der Linden Date: Sat, 16 Mar 2024 11:38:41 +0100 Subject: [PATCH 107/146] devenv: avoid rebuild when unrelated sources change Currently whenever the examples are changed, devenv will need to be rebuild. This isn't needed, because the package isn't relying on the examples explicity. Using `builtins.path` was just too much of a hassle (paths are absolute, directory path needs to be match along with sub-files/directories). Regex seemed easier. Regex in Nix uses extended Posix, which is again a bit funky, but maybe less so than doing matching by hand. --- package.nix | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/package.nix b/package.nix index 6a6cf019d..54651a6c5 100644 --- a/package.nix +++ b/package.nix @@ -4,11 +4,12 @@ pkgs.rustPlatform.buildRustPackage { pname = "devenv"; version = "1.0.0"; - src = builtins.path { - path = ./.; - filter = path: type: - path != "Cargo.lock" || path != "Cargo.toml" || path != "src/devenv"; - }; + src = pkgs.lib.sourceByRegex ./. [ + "Cargo.toml" + "Cargo.lock" + "devenv(/\.*)?" + "devenv-run-tests(/\.*)?" + ]; cargoLock = { lockFile = ./Cargo.lock; From c574ac17457e435b05275d63093c0cd6779c3813 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Sun, 17 Mar 2024 06:39:05 +0000 Subject: [PATCH 108/146] fix a few more tests --- .github/workflows/buildtest.yml | 4 ++-- examples/vala/devenv.nix | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/buildtest.yml b/.github/workflows/buildtest.yml index 9e68089f2..5fa56ec7c 100644 --- a/.github/workflows/buildtest.yml +++ b/.github/workflows/buildtest.yml @@ -142,5 +142,5 @@ jobs: authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}' - run: nix build - run: | - nix shell nixpkgs#zsh -c zsh -c ./result/bin/devenv version - nix shell nixpkgs#fish -c fish -c ./result/bin/devenv version + nix shell nixpkgs#zsh -c zsh -c "./result/bin/devenv version" + nix shell nixpkgs#fish -c fish -c "./result/bin/devenv version" diff --git a/examples/vala/devenv.nix b/examples/vala/devenv.nix index 7cf0870f9..4525b58f4 100644 --- a/examples/vala/devenv.nix +++ b/examples/vala/devenv.nix @@ -8,7 +8,7 @@ languages = { vala = { - enable = true; + enable = pkgs.stdenv.isLinux; # This is the default package for Vala for the configured channel (see nixpkgs input in devenv.yaml) # It can be configured to use a specific version # Take a look [here](https://search.nixos.org/packages?channel=unstable&from=0&size=50&sort=relevance&type=packages&query=vala) to find out which versions are available From 7ebf8ce4229c32cc6a84a5a2c49b0ec1d5a38ad4 Mon Sep 17 00:00:00 2001 From: midchildan Date: Sat, 16 Mar 2024 08:12:32 +0900 Subject: [PATCH 109/146] feat: add DEVENV_RUNTIME --- src/modules/top-level.nix | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/modules/top-level.nix b/src/modules/top-level.nix index 71433d5b5..3ba6bf5e9 100644 --- a/src/modules/top-level.nix +++ b/src/modules/top-level.nix @@ -33,6 +33,8 @@ let ${lib.concatStringsSep "\n" (builtins.map formatAssertionMessage failedAssertions)} '' else lib.trivial.showWarnings config.warnings; + + q = lib.escapeShellArg; in { options = { @@ -158,6 +160,11 @@ in internal = true; }; + runtime = lib.mkOption { + type = types.str; + internal = true; + }; + profile = lib.mkOption { type = types.package; internal = true; @@ -199,8 +206,23 @@ in devenv.dotfile = lib.mkDefault (builtins.toPath (config.devenv.root + "/.devenv")); devenv.profile = profile; + # The path has to be + # - unique to each DEVENV_ROOT to let multiple devenv environments coexist + # - deterministic so that it won't change constantly + # - short so that unix domain sockets won't hit the path length limit + # - free to create as an unprivileged user across OSes + devenv.runtime = + let + hashedRoot = builtins.hashString "sha256" config.devenv.root; + + # same length as git's abbreviated commit hashes + shortHash = builtins.substring 0 7 hashedRoot; + in + "/tmp/devenv-${shortHash}"; + env.DEVENV_PROFILE = config.devenv.profile; env.DEVENV_STATE = config.devenv.state; + env.DEVENV_RUNTIME = config.devenv.runtime; env.DEVENV_DOTFILE = config.devenv.dotfile; env.DEVENV_ROOT = config.devenv.root; @@ -236,6 +258,9 @@ in ln -nsf ${profile} .devenv/profile fi unset ${lib.concatStringsSep " " config.unsetEnvVars} + + mkdir -p ${q config.devenv.runtime} + ln -fs ${q config.devenv.runtime} ${q config.devenv.dotfile}/run ''; shell = performAssertions ( From 547d33a9b3308a38df2dd9eef165bf611d88e1e6 Mon Sep 17 00:00:00 2001 From: midchildan Date: Sat, 16 Mar 2024 08:15:50 +0900 Subject: [PATCH 110/146] fix(postgres): don't crash with long working directory --- src/modules/services/postgres.nix | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/src/modules/services/postgres.nix b/src/modules/services/postgres.nix index 847380764..edca33ed3 100644 --- a/src/modules/services/postgres.nix +++ b/src/modules/services/postgres.nix @@ -4,6 +4,10 @@ let cfg = config.services.postgres; types = lib.types; + q = lib.escapeShellArg; + + runtimeDir = "${config.env.DEVENV_RUNTIME}/postgres"; + postgresPkg = if cfg.extensions != null then if builtins.hasAttr "withPackages" cfg.package @@ -64,7 +68,7 @@ let runInitialScript = if cfg.initialScript != null then '' - echo ${lib.escapeShellArg cfg.initialScript} | psql --dbname postgres + echo ${q cfg.initialScript} | psql --dbname postgres '' else ""; @@ -102,21 +106,13 @@ let echo "PostgreSQL is setting up the initial database." echo OLDPGHOST="$PGHOST" - PGHOST=$(mktemp -d "$DEVENV_STATE/pg-init-XXXXXX") - - function remove_tmp_pg_init_sock_dir() { - if [[ -d "$1" ]]; then - rm -rf "$1" - fi - } - trap "remove_tmp_pg_init_sock_dir '$PGHOST'" EXIT + PGHOST=${q runtimeDir} - pg_ctl -D "$PGDATA" -w start -o "-c unix_socket_directories=$PGHOST -c listen_addresses= -p ${toString cfg.port}" + pg_ctl -D "$PGDATA" -w start -o "-c unix_socket_directories=${runtimeDir} -c listen_addresses= -p ${toString cfg.port}" ${setupInitialDatabases} ${runInitialScript} pg_ctl -D "$PGDATA" -m fast -w stop - remove_tmp_pg_init_sock_dir "$PGHOST" PGHOST="$OLDPGHOST" unset OLDPGHOST else @@ -128,6 +124,7 @@ let ''; startScript = pkgs.writeShellScriptBin "start-postgres" '' set -euo pipefail + mkdir -p ${q runtimeDir} ${setupScript}/bin/setup-postgres exec ${postgresPkg}/bin/postgres ''; @@ -285,14 +282,13 @@ in packages = [ postgresPkg startScript ]; env.PGDATA = config.env.DEVENV_STATE + "/postgres"; - env.PGHOST = config.env.PGDATA; + env.PGHOST = runtimeDir; env.PGPORT = cfg.port; services.postgres.settings = { listen_addresses = cfg.listen_addresses; port = cfg.port; - # relative to PGDATA - unix_socket_directories = lib.mkDefault "."; + unix_socket_directories = lib.mkDefault runtimeDir; }; processes.postgres = { From e1c2d72e62ad04ebdd7b675df5441274f3436d6c Mon Sep 17 00:00:00 2001 From: midchildan Date: Sat, 16 Mar 2024 11:11:03 +0900 Subject: [PATCH 111/146] doc: explain DEVENV_RUNTIME --- docs/files-and-variables.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/files-and-variables.md b/docs/files-and-variables.md index 454dc6fe0..29a8a8e6d 100644 --- a/docs/files-and-variables.md +++ b/docs/files-and-variables.md @@ -41,6 +41,11 @@ Points to `$DEVENV_ROOT/.devenv`. Points to `$DEVENV_DOTFILE/state`. +### $DEVENV_RUNTIME + +Points to a temporary directory with a path that's unique to each `$DEVENV_ROOT`. +It's similar in purpose to `/run`. + ### $DEVENV_PROFILE Points to the Nix store path that has final profile of packages/scripts provided by devenv. From d9d8928baa4a24077fd719286220d3b7c57e358a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Sun, 17 Mar 2024 11:15:04 +0000 Subject: [PATCH 112/146] more test fixes --- examples/phoenix/.test.sh | 12 ------------ examples/phoenix/README.md | 12 ------------ examples/phoenix/devenv.nix | 13 ------------- examples/supported-languages/.setup.sh | 2 ++ examples/vala/devenv.nix | 2 +- tests/glibcLocales/devenv.nix | 2 +- 6 files changed, 4 insertions(+), 39 deletions(-) delete mode 100755 examples/phoenix/.test.sh delete mode 100644 examples/phoenix/README.md delete mode 100644 examples/phoenix/devenv.nix create mode 100755 examples/supported-languages/.setup.sh diff --git a/examples/phoenix/.test.sh b/examples/phoenix/.test.sh deleted file mode 100755 index 95a374e03..000000000 --- a/examples/phoenix/.test.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env bash -set -ex - -mix local.hex --force -mix local.rebar --force -echo Y | mix archive.install hex phx_new -echo Y | mix phx.new hello -sed -i.bak -e "s/username: \"postgres\",/socket_dir: System.get_env(\"PGDATA\"),/" \ - ./hello/config/dev.exs && rm ./hello/config/dev.exs.bak - -wait_for_port 4000 -curl -s http://localhost:4000/ | grep "Phoenix Framework" diff --git a/examples/phoenix/README.md b/examples/phoenix/README.md deleted file mode 100644 index 893474d7c..000000000 --- a/examples/phoenix/README.md +++ /dev/null @@ -1,12 +0,0 @@ -Based on [the official tutorial](https://hexdocs.pm/phoenix/installation.html). - -```shell-session -$ devenv shell -$ mix local.hex --force -$ mix local.rebar --force -$ mix archive.install hex phx_new -$ mix phx.new hello -$ sed -i.bak -e "s/username: \"postgres\",/socket_dir: System.get_env(\"PGDATA\"),/" \ - ./hello/config/dev.exs && rm ./hello/config/dev.exs.bak -$ devenv up -``` diff --git a/examples/phoenix/devenv.nix b/examples/phoenix/devenv.nix deleted file mode 100644 index a5ce5f7b3..000000000 --- a/examples/phoenix/devenv.nix +++ /dev/null @@ -1,13 +0,0 @@ -{ pkgs, lib, ... }: - -{ - # this example is currently broken - - packages = lib.optionals pkgs.stdenv.isLinux [ pkgs.inotify-tools ]; - - languages.elixir.enable = true; - - services.postgres.enable = true; - - processes.phoenix.exec = "mix ecto.create && mix phx.server"; -} diff --git a/examples/supported-languages/.setup.sh b/examples/supported-languages/.setup.sh new file mode 100755 index 000000000..6514f82aa --- /dev/null +++ b/examples/supported-languages/.setup.sh @@ -0,0 +1,2 @@ +# arm is not supported yet +echo "{ pkgs, lib, ... }: { languages.unison.enable = lib.mkForce (!(pkgs.stdenv.isLinux && pkgs.stdenv.isAarch64)); }" > devenv.local.nix \ No newline at end of file diff --git a/examples/vala/devenv.nix b/examples/vala/devenv.nix index 4525b58f4..3d5ba50cb 100644 --- a/examples/vala/devenv.nix +++ b/examples/vala/devenv.nix @@ -3,7 +3,7 @@ { packages = with pkgs; [ # Check Vala code files for code-style errors - vala-lint + # vala-lint ]; languages = { diff --git a/tests/glibcLocales/devenv.nix b/tests/glibcLocales/devenv.nix index 0a16d9baa..e3f5c8a2d 100644 --- a/tests/glibcLocales/devenv.nix +++ b/tests/glibcLocales/devenv.nix @@ -1,5 +1,5 @@ { enterTest = '' - locale -a | grep "en_US.UTF-8" + locale -a | grep -E '(en_US.UTF-8|en_US.utf8)' ''; } From 92fa4a70d77d517c2127db260f854dee43debbb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Mon, 18 Mar 2024 03:44:32 +0000 Subject: [PATCH 113/146] fix impure test --- devenv/src/command.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/devenv/src/command.rs b/devenv/src/command.rs index e583b2e34..990d5cd45 100644 --- a/devenv/src/command.rs +++ b/devenv/src/command.rs @@ -137,8 +137,9 @@ impl App { if self.cli.impure || self.config.impure { flags.push("--impure"); + // set a dummy value to overcome https://github.com/NixOS/nix/issues/10247 + cmd.env("NIX_PATH", ":"); } - cmd.args(flags); cmd } else { From 1b788115bc274ca943b79c317bfad02a25970202 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Mon, 18 Mar 2024 03:55:30 +0000 Subject: [PATCH 114/146] make /tmp configurable --- src/modules/top-level.nix | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/modules/top-level.nix b/src/modules/top-level.nix index 3ba6bf5e9..60281194b 100644 --- a/src/modules/top-level.nix +++ b/src/modules/top-level.nix @@ -165,6 +165,12 @@ in internal = true; }; + tmpdir = lib.mkOption { + type = types.str; + internal = true; + default = "/tmp"; + }; + profile = lib.mkOption { type = types.package; internal = true; @@ -207,18 +213,18 @@ in devenv.profile = profile; # The path has to be - # - unique to each DEVENV_ROOT to let multiple devenv environments coexist + # - unique to each DEVENV_STATE to let multiple devenv environments coexist # - deterministic so that it won't change constantly # - short so that unix domain sockets won't hit the path length limit # - free to create as an unprivileged user across OSes devenv.runtime = let - hashedRoot = builtins.hashString "sha256" config.devenv.root; + hashedRoot = builtins.hashString "sha256" config.devenv.state; # same length as git's abbreviated commit hashes shortHash = builtins.substring 0 7 hashedRoot; in - "/tmp/devenv-${shortHash}"; + "${config.devenv.tmpdir}/devenv-${shortHash}"; env.DEVENV_PROFILE = config.devenv.profile; env.DEVENV_STATE = config.devenv.state; From cb94234d7188ac043828ac8a299f3c026588ac22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Mon, 18 Mar 2024 03:56:40 +0000 Subject: [PATCH 115/146] ruby: try with clean --- examples/ruby/devenv.yaml | 2 ++ examples/rubyonrails/devenv.yaml | 2 ++ 2 files changed, 4 insertions(+) diff --git a/examples/ruby/devenv.yaml b/examples/ruby/devenv.yaml index fa52210ad..351d48fed 100644 --- a/examples/ruby/devenv.yaml +++ b/examples/ruby/devenv.yaml @@ -4,3 +4,5 @@ inputs: inputs: nixpkgs: follows: nixpkgs +clean: + enabled: true \ No newline at end of file diff --git a/examples/rubyonrails/devenv.yaml b/examples/rubyonrails/devenv.yaml index fa52210ad..351d48fed 100644 --- a/examples/rubyonrails/devenv.yaml +++ b/examples/rubyonrails/devenv.yaml @@ -4,3 +4,5 @@ inputs: inputs: nixpkgs: follows: nixpkgs +clean: + enabled: true \ No newline at end of file From f0cfaf648175c7d1aa8308c7a5e806dbd5b0bdca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Mon, 18 Mar 2024 06:56:48 +0000 Subject: [PATCH 116/146] Remove permit-insecure test for now --- tests/permit-insecure/devenv.nix | 9 --------- tests/permit-insecure/devenv.yaml | 8 -------- 2 files changed, 17 deletions(-) delete mode 100644 tests/permit-insecure/devenv.nix delete mode 100644 tests/permit-insecure/devenv.yaml diff --git a/tests/permit-insecure/devenv.nix b/tests/permit-insecure/devenv.nix deleted file mode 100644 index 5505f0e00..000000000 --- a/tests/permit-insecure/devenv.nix +++ /dev/null @@ -1,9 +0,0 @@ -{ pkgs, ... }: - -{ - # https://devenv.sh/languages/ - languages.ruby = { - enable = true; - version = "2.6.5"; - }; -} diff --git a/tests/permit-insecure/devenv.yaml b/tests/permit-insecure/devenv.yaml deleted file mode 100644 index 9e2de855a..000000000 --- a/tests/permit-insecure/devenv.yaml +++ /dev/null @@ -1,8 +0,0 @@ -inputs: - nixpkgs-ruby: - url: github:bobvanderlinden/nixpkgs-ruby - inputs: - nixpkgs: - follows: nixpkgs -permittedInsecurePackages: - - "openssl-1.1.1w" \ No newline at end of file From 23404861b84299b2f532eb02e16d23b4bf5e74c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Mon, 18 Mar 2024 07:05:38 +0000 Subject: [PATCH 117/146] disable standardml on aarch64 --- examples/supported-languages/.setup.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/examples/supported-languages/.setup.sh b/examples/supported-languages/.setup.sh index 6514f82aa..8f91361d9 100755 --- a/examples/supported-languages/.setup.sh +++ b/examples/supported-languages/.setup.sh @@ -1,2 +1,5 @@ # arm is not supported yet -echo "{ pkgs, lib, ... }: { languages.unison.enable = lib.mkForce (!(pkgs.stdenv.isLinux && pkgs.stdenv.isAarch64)); }" > devenv.local.nix \ No newline at end of file +echo "{ pkgs, lib, ... }: {" > devenv.local.nix +echo "languages.unison.enable = lib.mkForce (!(pkgs.stdenv.isLinux && pkgs.stdenv.isAarch64)); }" > devenv.local.nix +echo "languages.standardml.enable = lib.mkForce (!pkgs.stdenv.isAarch64); }" > devenv.local.nix +echo "}" >> devenv.local.nix From 9e459eb788727da2e7c422ca4f242416d68536d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Mon, 18 Mar 2024 12:07:36 +0000 Subject: [PATCH 118/146] add 1.0 blog post --- .../blog/posts/devenv-v1.0-rewrite-in-rust.md | 237 ++++++++++++++++++ 1 file changed, 237 insertions(+) create mode 100644 docs/blog/posts/devenv-v1.0-rewrite-in-rust.md diff --git a/docs/blog/posts/devenv-v1.0-rewrite-in-rust.md b/docs/blog/posts/devenv-v1.0-rewrite-in-rust.md new file mode 100644 index 000000000..8d39a5442 --- /dev/null +++ b/docs/blog/posts/devenv-v1.0-rewrite-in-rust.md @@ -0,0 +1,237 @@ +--- +draft: false +date: 2023-03-19 +authors: + - domenkozar +--- + +# devenv 1.0: Rewrite in Rust + +We've just [released devenv 1.0](https://devenv.sh/)! 🎉 + +This is a rewrite of the CLI to ~~[Python](https://github.com/cachix/devenv/pull/745)~~ [Rust](https://github.com/cachix/devenv/pull/1005), +which brings a lot of new features and improvements. + +I'd like to thank [mightyiam](https://app.reclaim.ai/m/mightyiam/flexible) for a week long +pair Rust programming session at [Thaiger Sprint](https://thaigersprint.org). + +Note to read the migration guide at the end of this post, as 1.0 is not entirely backwards compatible. + +## Why rewrite twice? + +When I started to write this blog post for the Python rewrite, +I came up with only excuses why it's not fast and realized that we're breaking our promise. + +The seconds reason is that in the Nix community there was a lot of controversy around flakes (that's for another blog post) +and [tvix](https://tvix.dev/) people decided to do something about it and rewrite Nix in Rust. + +This leaves us the opportunity to use the same libraries and tools as tvix in the future. + +## What's new? + +There are many contributions in this release spanning over a year, but here are some of the highlights: + +### process-compose is now the default process manager + +`devenv up` is now using [process-compose](https://github.com/F1bonacc1/process-compose), +as it handles dependencies between processes and provides a nice ncurses interface to see all processes +and their logs. + +### Testing infrastructure + +Testing has been a major focus of this release, and we've added a number of features to make it easier to write and run tests. + +There's a new `enterTest` attribute in `devenv.nix` that allows you to define testing logic: + +```nix +{ pkgs, ... }: { + packages = [ pkgs.ncdu ]; + + enterTest = '' + ncdu --version | grep "ncdu 2.2" + ''; +} +``` + +When you run `devenv test`, it will run the `enterTest` command and report the results. + +If you have any [processes](/processes) defined, they will be started and stopped. + +Read more about this in the [testing documentation](/tests). + + +### devenv-nixpkgs + +We run about 300 tests across different languages and processes to make sure to catch any regressions. + +Since [nixpkgs-unstable](https://status.nixos.org/) has fairly few tests, +we've created [devenv-nixpkgs](https://github.com/cachix/devenv-nixpkgs) to run tests on top of nixpkgs-unstable +and apply any patches we're upstreaming to address any issues. + +### non-root containers + +Generated containers now run as a plain user, +which is a security improvement and as well unlocks running software that forbids root. + +### DEVENV_RUNTIME + +Due to [socket path limits](https://github.com/cachix/devenv/issues/540), we've introduced `DEVENV_RUNTIME` environment variable that points to `$XDG_RUNTIME_DIR` and falls back to `/tmp`. + +### Python has first-class support for native libraries + +This one was the hardest nut to crack. + +Nix is known to have poor experience using tools like pip. + +We've put in a lot of effort to make it finally be possible to use native libraries in Python without any extra effort. + +```nix +{ pkgs, lib, ... }: { + languages.python = { + enable = true; + venv.enable = true; + venv.requirements = '' + pillow + ''; + libraries = [ pkgs.cairo ]; + }; +} +``` + +### CLI improvements + +If you need to add an input to `devenv.yaml`, you can now do: + +`devenv inputs add ` + +To update only one input: + +`devenv update ` + +To build any attribute in your `devenv.nix`: + +`devenv build languages.rust.package` + +To run the environment with as clean as possible environment but keeping some variables: + +`devenv shell --clean EDITOR,PAGER` + +We've also tweaked default number of cores to 2 and max-jobs to number of cpus divided by two. +It's impossible to find an ideal default, but we've found that too much parallelism hurts performance and +running out of memory is a common issue. + +... and a number of other additions: + +``` +https://devenv.sh 1.0.0: Fast, Declarative, Reproducible, and Composable Developer Environments + +Usage: devenv [OPTIONS] + +Commands: + init Scaffold devenv.yaml, devenv.nix, .gitignore and .envrc. + shell Activate the developer environment. https://devenv.sh/basics/ + update Update devenv.lock from devenv.yaml inputs. http://devenv.sh/inputs/ + search Search for packages and options in nixpkgs. https://devenv.sh/packages/#searching-for-a-file + info Print information about this developer environment. + up Start processes in the foreground. https://devenv.sh/processes/ + processes Start or stop processes. + test Run tests. http://devenv.sh/tests/ + container Build, copy, or run a container. https://devenv.sh/containers/ + inputs Add an input to devenv.yaml. https://devenv.sh/inputs/ + gc Deletes previous shell generations. See http://devenv.sh/garbage-collection + build Build any attribute in devenv.nix. + version Print the version of devenv. + help Print this message or the help of the given subcommand(s) + +Options: + -v, --verbose + Enable debug log level. + -j, --max-jobs + Maximum number of Nix builds at any time. [default: 8] + -j, --cores + Maximum number CPU cores being used by a single build.. [default: 2] + -s, --system + [default: x86_64-linux] + -i, --impure + Relax the hermeticity of the environment. + -c, --clean [...] + Ignore existing environment variables when entering the shell. Pass a list of comma-separated environment variables to let through. + -d, --nix-debugger + Enter Nix debugger on failure. + -n, --nix-option + Pass additional options to nix commands, see `man nix.conf` for full list. + -o, --override-input + Override inputs in devenv.yaml. + -h, --help + Print help +``` + +## Migration guide + +### Deprecations: + +* `devenv container --copy ` has been renamed to `devenv container copy `. +* `devenv container --docker-run ` has been renamed to `devenv container run `. +* `devenv ci` has been renamed to `devenv test` with a broader scope. + +### Breaking changes + +* `.env` files must start with `.env` prefix +* We've finally removed the need for `--impure` flag, which means that devenv is now fully hermetic by default. + + Things like `builtins.currentSystem` won't work anymore, you'll have to use `pkgs.stdenv.system`. + + If you need to relax the hermeticity of the environment, you can use `devenv shell --impure`. +* Since `devenv.lock` changed format, once you generate it you can not use it with older versions of devenv. + +## Looking ahead + +There are a number of features we're looking to add in the future, please vote on the issues: + +### Running devenv in a container + +While devenv is designed to be run on your local machine, we're looking to add support for [running devenv inside a container](https://github.com/cachix/devenv/issues/1010). + +Something like: + +``` +devenv shell --in-container +devenv test --in-container +``` + +This is convenient when the environment is too complex to set up on your local machine (for example, running two databases) or when you want to run tests in a clean environment. + +### Generating containers with full environment + +Currently `enterShell` is executed once the container start, +if we want to execute it as part of the container generation, we have +to [execute it inside a container to generate a layer](https://github.com/cachix/devenv/issues/997). + +### macOS support for generating containers + +Currently it's only possible to build containers on macOS, +but [it should be possible](https://github.com/cachix/devenv/issues/997). + +### Native mapping of dependencies + +Would it be cool if devenv could map language specific dependencies to your local system? + +```nix +{ pkgs, lib, ... }: { + languages.python = { + enable = true; + venv.enable = true; + venv.requirements = '' + pillow + ''; + }; +} +``` + +Should know that `pillow` requires `pkgs.cario`. + +### Voilà + +If you give devenv a try, hop on [our discord](https://discord.com/invite/naMgvexb6q) and let us know how it goes! + +Domen \ No newline at end of file From b5681ea985f503ee352440dbd04af5b0b6af80b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Mon, 18 Mar 2024 12:11:01 +0000 Subject: [PATCH 119/146] fix supported-languages example --- examples/supported-languages/.setup.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/supported-languages/.setup.sh b/examples/supported-languages/.setup.sh index 8f91361d9..0cfeaee6b 100755 --- a/examples/supported-languages/.setup.sh +++ b/examples/supported-languages/.setup.sh @@ -1,5 +1,5 @@ # arm is not supported yet echo "{ pkgs, lib, ... }: {" > devenv.local.nix -echo "languages.unison.enable = lib.mkForce (!(pkgs.stdenv.isLinux && pkgs.stdenv.isAarch64)); }" > devenv.local.nix -echo "languages.standardml.enable = lib.mkForce (!pkgs.stdenv.isAarch64); }" > devenv.local.nix +echo " languages.unison.enable = lib.mkForce (!(pkgs.stdenv.isLinux && pkgs.stdenv.isAarch64));" >> devenv.local.nix +echo " languages.standardml.enable = lib.mkForce (!pkgs.stdenv.isAarch64);" >> devenv.local.nix echo "}" >> devenv.local.nix From fe19d7f0ceab6b5d878745ae3e0521ace17ab20a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Mon, 18 Mar 2024 12:38:13 +0000 Subject: [PATCH 120/146] process-compose: set is_strict --- src/modules/process-managers/process-compose.nix | 1 + 1 file changed, 1 insertion(+) diff --git a/src/modules/process-managers/process-compose.nix b/src/modules/process-managers/process-compose.nix index 58df8fcc9..d8acb4a9f 100644 --- a/src/modules/process-managers/process-compose.nix +++ b/src/modules/process-managers/process-compose.nix @@ -50,6 +50,7 @@ in configFile = settingsFormat.generate "process-compose.yaml" cfg.settings; settings = { version = "0.5"; + is_strict = true; port = lib.mkDefault 9999; tui = lib.mkDefault true; environment = lib.mapAttrsToList From 27f89238a3c2a7cc716b0323f19686446df700c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Mon, 18 Mar 2024 21:30:33 +0000 Subject: [PATCH 121/146] disable purescript on aarch64-linux --- examples/supported-languages/.setup.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/examples/supported-languages/.setup.sh b/examples/supported-languages/.setup.sh index 0cfeaee6b..ca0db0fa0 100755 --- a/examples/supported-languages/.setup.sh +++ b/examples/supported-languages/.setup.sh @@ -2,4 +2,6 @@ echo "{ pkgs, lib, ... }: {" > devenv.local.nix echo " languages.unison.enable = lib.mkForce (!(pkgs.stdenv.isLinux && pkgs.stdenv.isAarch64));" >> devenv.local.nix echo " languages.standardml.enable = lib.mkForce (!pkgs.stdenv.isAarch64);" >> devenv.local.nix +# https://github.com/NixOS/nixpkgs/issues/297019 +echo " languages.purescript.enable = lib.mkForce (!pkgs.stdenv.isAarch64);" >> devenv.local.nix echo "}" >> devenv.local.nix From cc76f0b89f240eb729741d8b3b03ee315e77b48d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Mon, 18 Mar 2024 21:30:05 +0000 Subject: [PATCH 122/146] always keep going --- devenv/src/command.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/devenv/src/command.rs b/devenv/src/command.rs index 990d5cd45..38022e2ce 100644 --- a/devenv/src/command.rs +++ b/devenv/src/command.rs @@ -3,7 +3,7 @@ use miette::{bail, Result}; use std::env; use std::os::unix::process::CommandExt; -const NIX_FLAGS: [&str; 11] = [ +const NIX_FLAGS: [&str; 12] = [ "--show-trace", "--extra-experimental-features", "nix-command", @@ -17,6 +17,8 @@ const NIX_FLAGS: [&str; 11] = [ "--option", "eval-cache", "false", + // always build all dependencies and report errors at the end + "--keep-going", ]; pub struct Options { From 2e9debcceac77dbc50ca9c71433e1cf05e358732 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Tue, 19 Mar 2024 03:55:22 +0000 Subject: [PATCH 123/146] docs: sync with pre-commit hooks --- docs/pre-commit-hooks.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/docs/pre-commit-hooks.md b/docs/pre-commit-hooks.md index a2dd0299a..84d7e5160 100644 --- a/docs/pre-commit-hooks.md +++ b/docs/pre-commit-hooks.md @@ -17,6 +17,17 @@ We recommend a two-step approach for integrating your linters and formatters. mdsh.enable = true; # format Python code black.enable = true; + + # override a package with a different version + ormolu.enable = true; + ormolu.package = pkgs.haskellPackages.ormolu; + + # some hooks have more than one package, like clippy: + clippy.enable = true; + clippy.packageOverrides.cargo = pkgs.cargo; + clippy.packageOverrides.clippy = tools.clippy; + # some hooks provide settings + clippy.settings.allFeatures = true; }; } ``` From a5bb0bda38e2be61223bf863127bf88703377a9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Tue, 19 Mar 2024 04:38:11 +0000 Subject: [PATCH 124/146] docs: render strikethrough --- mkdocs.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/mkdocs.yml b/mkdocs.yml index f9689b979..c84d367e3 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -111,3 +111,4 @@ markdown_extensions: - pymdownx.tabbed: alternate_style: true - pymdownx.tasklist + - pymdownx.tilde From dea8689069f25dc58b3f9de621609bfb6444b100 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Tue, 19 Mar 2024 07:04:35 +0000 Subject: [PATCH 125/146] texlive: use str instead of string --- src/modules/languages/texlive.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/languages/texlive.nix b/src/modules/languages/texlive.nix index 7300dfde9..a2bcdfc3b 100644 --- a/src/modules/languages/texlive.nix +++ b/src/modules/languages/texlive.nix @@ -15,7 +15,7 @@ in description = "TeX Live package set to use"; }; packages = lib.mkOption { - type = lib.types.nonEmptyListOf lib.types.string; + type = lib.types.nonEmptyListOf lib.types.str; default = [ "collection-basic" ]; description = "Packages available to TeX Live"; }; From ccbd3062eea01d580f6c90c1c8dbf4d771acac42 Mon Sep 17 00:00:00 2001 From: Nicholas Sidwell Date: Tue, 19 Mar 2024 00:47:37 -0700 Subject: [PATCH 126/146] Make edit pass on 1.0 release post --- .../blog/posts/devenv-v1.0-rewrite-in-rust.md | 91 +++++++++---------- 1 file changed, 42 insertions(+), 49 deletions(-) diff --git a/docs/blog/posts/devenv-v1.0-rewrite-in-rust.md b/docs/blog/posts/devenv-v1.0-rewrite-in-rust.md index 8d39a5442..8022cc4f4 100644 --- a/docs/blog/posts/devenv-v1.0-rewrite-in-rust.md +++ b/docs/blog/posts/devenv-v1.0-rewrite-in-rust.md @@ -1,5 +1,5 @@ --- -draft: false +draft: false date: 2023-03-19 authors: - domenkozar @@ -10,31 +10,29 @@ authors: We've just [released devenv 1.0](https://devenv.sh/)! 🎉 This is a rewrite of the CLI to ~~[Python](https://github.com/cachix/devenv/pull/745)~~ [Rust](https://github.com/cachix/devenv/pull/1005), -which brings a lot of new features and improvements. +which brings with it many new features and improvements. I'd like to thank [mightyiam](https://app.reclaim.ai/m/mightyiam/flexible) for a week long pair Rust programming session at [Thaiger Sprint](https://thaigersprint.org). -Note to read the migration guide at the end of this post, as 1.0 is not entirely backwards compatible. +Note: Read the migration guide at the end of this post, as 1.0 is not entirely backwards compatible. ## Why rewrite twice? -When I started to write this blog post for the Python rewrite, -I came up with only excuses why it's not fast and realized that we're breaking our promise. +When I started to write this blog post for the Python rewrite, I came up with only excuses as to why it's not fast and realized that we're breaking our promise to you. -The seconds reason is that in the Nix community there was a lot of controversy around flakes (that's for another blog post) -and [tvix](https://tvix.dev/) people decided to do something about it and rewrite Nix in Rust. +The second reason is that in the Nix community there was a lot of controversy around flakes (that's for another blog post); the [tvix](https://tvix.dev/) people decided to do something about it and rewrite Nix in Rust. -This leaves us the opportunity to use the same libraries and tools as tvix in the future. +This leaves us with the opportunity to use the same libraries and tools as tvix in the future. ## What's new? -There are many contributions in this release spanning over a year, but here are some of the highlights: +There are many contributions in this release, spanning over a year, but here are some of the highlights: ### process-compose is now the default process manager `devenv up` is now using [process-compose](https://github.com/F1bonacc1/process-compose), -as it handles dependencies between processes and provides a nice ncurses interface to see all processes +as it handles dependencies between processes and provides a nice ncurses interface to view the processes and their logs. ### Testing infrastructure @@ -59,31 +57,28 @@ If you have any [processes](/processes) defined, they will be started and stoppe Read more about this in the [testing documentation](/tests). - ### devenv-nixpkgs -We run about 300 tests across different languages and processes to make sure to catch any regressions. - Since [nixpkgs-unstable](https://status.nixos.org/) has fairly few tests, -we've created [devenv-nixpkgs](https://github.com/cachix/devenv-nixpkgs) to run tests on top of nixpkgs-unstable -and apply any patches we're upstreaming to address any issues. +we've created [devenv-nixpkgs](https://github.com/cachix/devenv-nixpkgs) to run tests on top of `nixpkgs-unstable`—applying patches we're upstreaming to address any issues. + +We run around 300 tests across different languages and processes to ensure all regressions are caught. ### non-root containers -Generated containers now run as a plain user, -which is a security improvement and as well unlocks running software that forbids root. +Generated containers now run as a plain user—improving security and unlocking the ability to run software that forbids root. ### DEVENV_RUNTIME -Due to [socket path limits](https://github.com/cachix/devenv/issues/540), we've introduced `DEVENV_RUNTIME` environment variable that points to `$XDG_RUNTIME_DIR` and falls back to `/tmp`. +Due to [socket path limits](https://github.com/cachix/devenv/issues/540), we've introduced the `DEVENV_RUNTIME` environment variable: pointing to `$XDG_RUNTIME_DIR` and falling back to `/tmp`. -### Python has first-class support for native libraries +### first-class support for Python native libraries This one was the hardest nut to crack. -Nix is known to have poor experience using tools like pip. +Nix is known to provide a poor experience when using tools like pip. -We've put in a lot of effort to make it finally be possible to use native libraries in Python without any extra effort. +We've put in a lot of work here, finally making it possible to use native libraries in Python without any extra effort: ```nix { pkgs, lib, ... }: { @@ -104,23 +99,22 @@ If you need to add an input to `devenv.yaml`, you can now do: `devenv inputs add ` -To update only one input: +To update a single input: `devenv update ` -To build any attribute in your `devenv.nix`: +To build any attribute in `devenv.nix`: `devenv build languages.rust.package` -To run the environment with as clean as possible environment but keeping some variables: +To run the environment as cleanly as possible while keeping variables: `devenv shell --clean EDITOR,PAGER` -We've also tweaked default number of cores to 2 and max-jobs to number of cpus divided by two. -It's impossible to find an ideal default, but we've found that too much parallelism hurts performance and -running out of memory is a common issue. +We've also tweaked the default number of cores to 2, and max-jobs to half of the number of cpus. +It is impossible to find an ideal default, but we've found that too much parallelism hurts performance—running out of memory is a common issue. -... and a number of other additions: +... plus a number of other additions: ``` https://devenv.sh 1.0.0: Fast, Declarative, Reproducible, and Composable Developer Environments @@ -170,27 +164,28 @@ Options: ### Deprecations: -* `devenv container --copy ` has been renamed to `devenv container copy `. -* `devenv container --docker-run ` has been renamed to `devenv container run `. -* `devenv ci` has been renamed to `devenv test` with a broader scope. +- `devenv container --copy ` has been renamed to `devenv container copy `. +- `devenv container --docker-run ` has been renamed to `devenv container run `. +- `devenv ci` has been renamed to `devenv test` with a broader scope. ### Breaking changes -* `.env` files must start with `.env` prefix -* We've finally removed the need for `--impure` flag, which means that devenv is now fully hermetic by default. +- `.env` files must start with the `.env` prefix +- We've finally removed the need for the `--impure` flag, meaning that devenv is now fully hermetic by default. - Things like `builtins.currentSystem` won't work anymore, you'll have to use `pkgs.stdenv.system`. - - If you need to relax the hermeticity of the environment, you can use `devenv shell --impure`. -* Since `devenv.lock` changed format, once you generate it you can not use it with older versions of devenv. + Things like `builtins.currentSystem` no longer work—you'll have to use `pkgs.stdenv.system`. + + If you need to relax the hermeticity of the environment you can use `devenv shell --impure`. + +- Since the format of `devenv.lock` has changed, newly-generated lockfiles cannot be used with older versions of devenv. ## Looking ahead -There are a number of features we're looking to add in the future, please vote on the issues: +There are a number of features we're looking to add in the future—please vote on the issues: ### Running devenv in a container -While devenv is designed to be run on your local machine, we're looking to add support for [running devenv inside a container](https://github.com/cachix/devenv/issues/1010). +While devenv is designed to be run on your local machine, we are looking to add support for [running devenv inside a container](https://github.com/cachix/devenv/issues/1010). Something like: @@ -199,22 +194,22 @@ devenv shell --in-container devenv test --in-container ``` -This is convenient when the environment is too complex to set up on your local machine (for example, running two databases) or when you want to run tests in a clean environment. +This would be convenient when the environment is too complex to set up on your local machine; for example, when running two databases or when you want to run tests in a clean environment. ### Generating containers with full environment -Currently `enterShell` is executed once the container start, -if we want to execute it as part of the container generation, we have +Currently, `enterShell` is executed only once the container has started. +If we want to execute it as part of the container generation, we have to [execute it inside a container to generate a layer](https://github.com/cachix/devenv/issues/997). ### macOS support for generating containers -Currently it's only possible to build containers on macOS, -but [it should be possible](https://github.com/cachix/devenv/issues/997). +Building containers on macOS is not currently supported, +but it [should be possible](https://github.com/cachix/devenv/issues/997). ### Native mapping of dependencies -Would it be cool if devenv could map language specific dependencies to your local system? +Would it be cool if devenv could map language specific dependencies to your local system? In this example, devenv should know that `pillow` requires `pkgs.cairo`: ```nix { pkgs, lib, ... }: { @@ -228,10 +223,8 @@ Would it be cool if devenv could map language specific dependencies to your loca } ``` -Should know that `pillow` requires `pkgs.cario`. - ### Voilà -If you give devenv a try, hop on [our discord](https://discord.com/invite/naMgvexb6q) and let us know how it goes! +Give devenv a try, and hop on to [our discord](https://discord.com/invite/naMgvexb6q) to let us know how it goes! -Domen \ No newline at end of file +Domen From b80b15995046d97adda446da13e44bcfadcf1dc7 Mon Sep 17 00:00:00 2001 From: Arvin Sevilla Date: Tue, 19 Mar 2024 15:49:10 +0800 Subject: [PATCH 127/146] docs(phoenix): add example for elixir phoenix patterned using example/rubyonrails --- examples/phoenix/.test.sh | 8 ++++++++ examples/phoenix/README.md | 11 +++++++++++ examples/phoenix/devenv.nix | 25 +++++++++++++++++++++++++ 3 files changed, 44 insertions(+) create mode 100755 examples/phoenix/.test.sh create mode 100644 examples/phoenix/README.md create mode 100644 examples/phoenix/devenv.nix diff --git a/examples/phoenix/.test.sh b/examples/phoenix/.test.sh new file mode 100755 index 000000000..b3405d8a4 --- /dev/null +++ b/examples/phoenix/.test.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash +set -ex + +pushd hello + wait_for_port 4000 + mix ecto.create + curl -s http://localhost:4000/ | grep "Phoenix Framework" +popd diff --git a/examples/phoenix/README.md b/examples/phoenix/README.md new file mode 100644 index 000000000..5ee416ee6 --- /dev/null +++ b/examples/phoenix/README.md @@ -0,0 +1,11 @@ +Based on [the official tutorial](https://hexdocs.pm/phoenix/installation.html). + +```shell-session +$ devenv shell +$ mix local.hex --force +$ mix local.rebar --force +$ mix archive.install hex phx_new +$ mix phx.new hello +$ devenv up +$ cd hello && mix ecto.create +``` diff --git a/examples/phoenix/devenv.nix b/examples/phoenix/devenv.nix new file mode 100644 index 000000000..6141beda2 --- /dev/null +++ b/examples/phoenix/devenv.nix @@ -0,0 +1,25 @@ +{ pkgs, lib, ... }: + +{ + packages = lib.optionals pkgs.stdenv.isLinux [ pkgs.inotify-tools ]; + + languages.elixir.enable = true; + + services.postgres = { + enable = true; + initialScript = '' + CREATE ROLE postgres WITH LOGIN PASSWORD 'postgres' SUPERUSER; + ''; + }; + + processes.phoenix.exec = "cd hello && mix phx.server"; + + enterShell = '' + if [ ! -d "hello" ]; then + mix local.hex --force + mix local.rebar --force + mix archive.install hex phx_new + mix phx.new hello + fi + ''; +} From fef4366e50ffb477c198d28c3582e621f5bf95bc Mon Sep 17 00:00:00 2001 From: Nicholas Sidwell Date: Tue, 19 Mar 2024 01:05:33 -0700 Subject: [PATCH 128/146] Make more release-post tweaks --- docs/blog/posts/devenv-v1.0-rewrite-in-rust.md | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/docs/blog/posts/devenv-v1.0-rewrite-in-rust.md b/docs/blog/posts/devenv-v1.0-rewrite-in-rust.md index 8022cc4f4..ca3420f17 100644 --- a/docs/blog/posts/devenv-v1.0-rewrite-in-rust.md +++ b/docs/blog/posts/devenv-v1.0-rewrite-in-rust.md @@ -12,18 +12,15 @@ We've just [released devenv 1.0](https://devenv.sh/)! 🎉 This is a rewrite of the CLI to ~~[Python](https://github.com/cachix/devenv/pull/745)~~ [Rust](https://github.com/cachix/devenv/pull/1005), which brings with it many new features and improvements. -I'd like to thank [mightyiam](https://app.reclaim.ai/m/mightyiam/flexible) for a week long -pair Rust programming session at [Thaiger Sprint](https://thaigersprint.org). +I'd like to thank [mightyiam](https://app.reclaim.ai/m/mightyiam/flexible) for a week-long, Rust pair-programming session at [Thaiger Sprint](https://thaigersprint.org). Note: Read the migration guide at the end of this post, as 1.0 is not entirely backwards compatible. ## Why rewrite twice? -When I started to write this blog post for the Python rewrite, I came up with only excuses as to why it's not fast and realized that we're breaking our promise to you. +When I started to write this blog post for the Python rewrite, I came up with only excuses as to why it's not fast and realized that we were simply breaking our promise to you. -The second reason is that in the Nix community there was a lot of controversy around flakes (that's for another blog post); the [tvix](https://tvix.dev/) people decided to do something about it and rewrite Nix in Rust. - -This leaves us with the opportunity to use the same libraries and tools as tvix in the future. +The second reason is that in the Nix community there has been a lot of controversy surrounding flakes (that's for another blog post); the [tvix](https://tvix.dev/) people decided to do something about it and rewrite Nix in Rust. This leaves us with the opportunity to use the same libraries and tools as tvix in the future. ## What's new? @@ -70,7 +67,7 @@ Generated containers now run as a plain user—improving security and unlocking ### DEVENV_RUNTIME -Due to [socket path limits](https://github.com/cachix/devenv/issues/540), we've introduced the `DEVENV_RUNTIME` environment variable: pointing to `$XDG_RUNTIME_DIR` and falling back to `/tmp`. +Due to [socket path limits](https://github.com/cachix/devenv/issues/540), we've introduced the `DEVENV_RUNTIME` environment variable: pointing to `$XDG_RUNTIME_DIR` by default and falling back to `/tmp`. ### first-class support for Python native libraries @@ -107,11 +104,11 @@ To build any attribute in `devenv.nix`: `devenv build languages.rust.package` -To run the environment as cleanly as possible while keeping variables: +To run the environment as cleanly as possible while keeping specific variables: `devenv shell --clean EDITOR,PAGER` -We've also tweaked the default number of cores to 2, and max-jobs to half of the number of cpus. +We've also tweaked the default number of cores to 2, and max-jobs to half of the number of CPUs. It is impossible to find an ideal default, but we've found that too much parallelism hurts performance—running out of memory is a common issue. ... plus a number of other additions: @@ -170,7 +167,7 @@ Options: ### Breaking changes -- `.env` files must start with the `.env` prefix +- `.env` files must start with the `.env` prefix. - We've finally removed the need for the `--impure` flag, meaning that devenv is now fully hermetic by default. Things like `builtins.currentSystem` no longer work—you'll have to use `pkgs.stdenv.system`. From 68d3840c0dee9d4806fdaaf935eeb4dbf3c0b3fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Tue, 19 Mar 2024 10:22:07 +0000 Subject: [PATCH 129/146] blog: edits --- docs/blog/posts/devenv-v1.0-rewrite-in-rust.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/blog/posts/devenv-v1.0-rewrite-in-rust.md b/docs/blog/posts/devenv-v1.0-rewrite-in-rust.md index ca3420f17..3fe0e8d65 100644 --- a/docs/blog/posts/devenv-v1.0-rewrite-in-rust.md +++ b/docs/blog/posts/devenv-v1.0-rewrite-in-rust.md @@ -20,7 +20,7 @@ Note: Read the migration guide at the end of this post, as 1.0 is not entirely b When I started to write this blog post for the Python rewrite, I came up with only excuses as to why it's not fast and realized that we were simply breaking our promise to you. -The second reason is that in the Nix community there has been a lot of controversy surrounding flakes (that's for another blog post); the [tvix](https://tvix.dev/) people decided to do something about it and rewrite Nix in Rust. This leaves us with the opportunity to use the same libraries and tools as tvix in the future. +The second reason is that in the Nix community there has been a lot of controversy surrounding flakes (that's for another blog post); the [tvix](https://tvix.dev/) developers decided to do something about it and rewrite Nix in Rust. This leaves us with the opportunity to use the same libraries and tools as tvix in the future. ## What's new? @@ -222,6 +222,6 @@ Would it be cool if devenv could map language specific dependencies to your loca ### Voilà -Give devenv a try, and hop on to [our discord](https://discord.com/invite/naMgvexb6q) to let us know how it goes! +Give [devenv a try](https://devenv.sh/getting-started/), and hop on to [our discord](https://discord.com/invite/naMgvexb6q) to let us know how it goes! Domen From ecaa6b2c6f0fad4f2834595d8fa6d4ffe3d2f2b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Tue, 19 Mar 2024 10:39:37 +0000 Subject: [PATCH 130/146] recommend experimental Nix installer --- docs/getting-started.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/getting-started.md b/docs/getting-started.md index 493f0412d..9b9ecbd33 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -27,6 +27,14 @@ docker run -it nixos/nix ``` +!!! note + + We recommended to use experimental installer on macOS to avoid issues with Apple Scilicon chips: + + ``` + curl -L https://raw.githubusercontent.com/NixOS/experimental-nix-installer/main/nix-installer.sh | sh -s install + ``` + ### 2. Install [Cachix](https://cachix.org) Recommended, speeds up the installation by providing binaries. From 24775a72d2f1c188d43dd98617e514b311a17141 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Tue, 19 Mar 2024 11:03:49 +0000 Subject: [PATCH 131/146] fix a bug in devenv init --- .github/workflows/buildtest.yml | 7 +++---- devenv/src/main.rs | 34 ++++++++++++--------------------- docs/getting-started.md | 9 ++++----- 3 files changed, 19 insertions(+), 31 deletions(-) diff --git a/.github/workflows/buildtest.yml b/.github/workflows/buildtest.yml index 5fa56ec7c..a12a0e380 100644 --- a/.github/workflows/buildtest.yml +++ b/.github/workflows/buildtest.yml @@ -118,10 +118,9 @@ jobs: export PATH=$PWD/result/bin:$PATH nix build - pushd examples/simple - devenv inputs add devenv path:$devenv_dir?dir=src/modules - nix shell nixpkgs#direnv -c direnv allow . - nix shell nixpkgs#direnv -c direnv exec . true + tmp="$(mktemp -d)" + pushd "$tmp" + nix shell nixpkgs#direnv -c devenv --override-input devenv path:$devenv_dir?dir=src/modules init popd fish-zsh: name: zsh/fish (${{ join(matrix.os) }}) diff --git a/devenv/src/main.rs b/devenv/src/main.rs index ea8d48653..717dcf336 100644 --- a/devenv/src/main.rs +++ b/devenv/src/main.rs @@ -392,6 +392,8 @@ impl App { } for filename in REQUIRED_FILES { + self.logger.info(&format!("Creating {}", filename)); + let path = PROJECT_DIR .get_file(filename) .unwrap_or_else(|| panic!("missing {} in the executable", filename)); @@ -399,30 +401,18 @@ impl App { // write path.contents to target/filename let target_path = target.join(filename); std::fs::write(target_path, path.contents()).expect("Failed to write file"); + } - // check if direnv executable is available - let Ok(direnv) = which::which("direnv") else { - return Ok(()); - }; + // check if direnv executable is available + let Ok(direnv) = which::which("direnv") else { + return Ok(()); + }; - // run direnv allow - let status = std::process::Command::new(direnv) - .arg("allow") - .current_dir(&target) - .status() - .expect("Failed to run direnv allow"); - - if !status.success() { - match status.code() { - Some(code) => { - bail!("direnv allow failed with code: {code}!"); - } - None => { - bail!("direnv allow failed!"); - } - } - } - } + // run direnv allow + let status = std::process::Command::new(direnv) + .arg("allow") + .current_dir(&target) + .exec(); Ok(()) } diff --git a/docs/getting-started.md b/docs/getting-started.md index 9b9ecbd33..fbea327d5 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -90,11 +90,10 @@ Given a Git repository, create the initial structure: ```shell-session $ devenv init -Creating .envrc -Creating devenv.nix -Creating devenv.yaml -Appending .devenv* to .gitignore -Done. +• Creating .envrc +• reating devenv.nix +• Creating devenv.yaml +• Creating .gitignore ``` ## Commands From ba710af8d590902635d3909b1319559cb16457c9 Mon Sep 17 00:00:00 2001 From: Arvin Sevilla Date: Tue, 19 Mar 2024 21:46:43 +0800 Subject: [PATCH 132/146] docs(phoenix): remove interactive prompt from devenv shell init script --- examples/phoenix/devenv.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/phoenix/devenv.nix b/examples/phoenix/devenv.nix index 6141beda2..c92067006 100644 --- a/examples/phoenix/devenv.nix +++ b/examples/phoenix/devenv.nix @@ -18,8 +18,8 @@ if [ ! -d "hello" ]; then mix local.hex --force mix local.rebar --force - mix archive.install hex phx_new - mix phx.new hello + mix archive.install --force hex phx_new + mix phx.new --install hello fi ''; } From 08d8a3456e762f952e127ea3bd7cae1b7085d240 Mon Sep 17 00:00:00 2001 From: Nicholas Sidwell Date: Tue, 19 Mar 2024 10:19:46 -0700 Subject: [PATCH 133/146] Make further tweaks to 1.0-release-post copy --- .../blog/posts/devenv-v1.0-rewrite-in-rust.md | 38 +++++++++---------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/docs/blog/posts/devenv-v1.0-rewrite-in-rust.md b/docs/blog/posts/devenv-v1.0-rewrite-in-rust.md index 3fe0e8d65..8aa22a7dc 100644 --- a/docs/blog/posts/devenv-v1.0-rewrite-in-rust.md +++ b/docs/blog/posts/devenv-v1.0-rewrite-in-rust.md @@ -7,20 +7,20 @@ authors: # devenv 1.0: Rewrite in Rust -We've just [released devenv 1.0](https://devenv.sh/)! 🎉 +We have just released [devenv 1.0](https://devenv.sh/)! 🎉 This is a rewrite of the CLI to ~~[Python](https://github.com/cachix/devenv/pull/745)~~ [Rust](https://github.com/cachix/devenv/pull/1005), which brings with it many new features and improvements. -I'd like to thank [mightyiam](https://app.reclaim.ai/m/mightyiam/flexible) for a week-long, Rust pair-programming session at [Thaiger Sprint](https://thaigersprint.org). +I would like to thank [mightyiam](https://app.reclaim.ai/m/mightyiam/flexible) for a week-long, Rust pair-programming session at [Thaiger Sprint](https://thaigersprint.org). Note: Read the migration guide at the end of this post, as 1.0 is not entirely backwards compatible. ## Why rewrite twice? -When I started to write this blog post for the Python rewrite, I came up with only excuses as to why it's not fast and realized that we were simply breaking our promise to you. +When I started to write this blog post for the Python rewrite, I came up with only excuses as to why it is not fast and realized that we were simply breaking our promise to you. -The second reason is that in the Nix community there has been a lot of controversy surrounding flakes (that's for another blog post); the [tvix](https://tvix.dev/) developers decided to do something about it and rewrite Nix in Rust. This leaves us with the opportunity to use the same libraries and tools as tvix in the future. +The second reason is that in the Nix community there has been a lot of controversy surrounding flakes (that's for another blog post); the [tvix](https://tvix.dev/) developers decided to do something about it and rewrite Nix in Rust. This leaves us with the opportunity in the future to use the same libraries and tools as tvix. ## What's new? @@ -34,9 +34,9 @@ and their logs. ### Testing infrastructure -Testing has been a major focus of this release, and we've added a number of features to make it easier to write and run tests. +Testing has been a major focus of this release, and a number of features have been added to make it easier to write and run tests. -There's a new `enterTest` attribute in `devenv.nix` that allows you to define testing logic: +The new `enterTest` attribute in `devenv.nix` allows you to define testing logic: ```nix { pkgs, ... }: { @@ -57,25 +57,25 @@ Read more about this in the [testing documentation](/tests). ### devenv-nixpkgs Since [nixpkgs-unstable](https://status.nixos.org/) has fairly few tests, -we've created [devenv-nixpkgs](https://github.com/cachix/devenv-nixpkgs) to run tests on top of `nixpkgs-unstable`—applying patches we're upstreaming to address any issues. +we have created [devenv-nixpkgs](https://github.com/cachix/devenv-nixpkgs) to run tests on top of `nixpkgs-unstable`—applying patches we are upstreaming to address any issues. We run around 300 tests across different languages and processes to ensure all regressions are caught. -### non-root containers +### Non-root containers Generated containers now run as a plain user—improving security and unlocking the ability to run software that forbids root. ### DEVENV_RUNTIME -Due to [socket path limits](https://github.com/cachix/devenv/issues/540), we've introduced the `DEVENV_RUNTIME` environment variable: pointing to `$XDG_RUNTIME_DIR` by default and falling back to `/tmp`. +Due to [socket path limits](https://github.com/cachix/devenv/issues/540), the `DEVENV_RUNTIME` environment variable has been introduced: pointing to `$XDG_RUNTIME_DIR` by default and falling back to `/tmp`. -### first-class support for Python native libraries +### First-class support for Python native libraries This one was the hardest nut to crack. Nix is known to provide a poor experience when using tools like pip. -We've put in a lot of work here, finally making it possible to use native libraries in Python without any extra effort: +A lot of work has been put in here, finally making it possible to use native libraries in Python without any extra effort: ```nix { pkgs, lib, ... }: { @@ -108,8 +108,8 @@ To run the environment as cleanly as possible while keeping specific variables: `devenv shell --clean EDITOR,PAGER` -We've also tweaked the default number of cores to 2, and max-jobs to half of the number of CPUs. -It is impossible to find an ideal default, but we've found that too much parallelism hurts performance—running out of memory is a common issue. +The default number of cores has been tweaked to 2, and `max-jobs` to half of the number of CPUs. +It is impossible to find an ideal default, but we have found that too much parallelism hurts performance—running out of memory is a common issue. ... plus a number of other additions: @@ -159,7 +159,7 @@ Options: ## Migration guide -### Deprecations: +### Deprecations - `devenv container --copy ` has been renamed to `devenv container copy `. - `devenv container --docker-run ` has been renamed to `devenv container run `. @@ -168,9 +168,9 @@ Options: ### Breaking changes - `.env` files must start with the `.env` prefix. -- We've finally removed the need for the `--impure` flag, meaning that devenv is now fully hermetic by default. +- The need for the `--impure` flag has finally been removed, meaning that devenv is now fully hermetic by default. - Things like `builtins.currentSystem` no longer work—you'll have to use `pkgs.stdenv.system`. + Things like `builtins.currentSystem` no longer work—you will have to use `pkgs.stdenv.system`. If you need to relax the hermeticity of the environment you can use `devenv shell --impure`. @@ -178,7 +178,7 @@ Options: ## Looking ahead -There are a number of features we're looking to add in the future—please vote on the issues: +There are a number of features that we are looking to add in the future—please vote on the issues: ### Running devenv in a container @@ -206,7 +206,7 @@ but it [should be possible](https://github.com/cachix/devenv/issues/997). ### Native mapping of dependencies -Would it be cool if devenv could map language specific dependencies to your local system? In this example, devenv should know that `pillow` requires `pkgs.cairo`: +Wouldn't it be cool if devenv could map language-specific dependencies to your local system? In this example, devenv should be able to determine that `pillow` requires `pkgs.cairo`: ```nix { pkgs, lib, ... }: { @@ -222,6 +222,6 @@ Would it be cool if devenv could map language specific dependencies to your loca ### Voilà -Give [devenv a try](https://devenv.sh/getting-started/), and hop on to [our discord](https://discord.com/invite/naMgvexb6q) to let us know how it goes! +[Give devenv a try](https://devenv.sh/getting-started/), and [hop on to our discord](https://discord.com/invite/naMgvexb6q) to let us know how it goes! Domen From 910e2b8778d65fc8729383151fcf1f655a66060c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Tue, 19 Mar 2024 11:30:38 +0000 Subject: [PATCH 134/146] DEVENV_RUNTIME: use XDG_RUNTIME_DIR or TMPDIR or /tmp --- devenv/src/flake.tmpl.nix | 1 + devenv/src/main.rs | 9 ++++++--- docs/files-and-variables.md | 3 ++- src/modules/top-level.nix | 7 ++++++- 4 files changed, 15 insertions(+), 5 deletions(-) diff --git a/devenv/src/flake.tmpl.nix b/devenv/src/flake.tmpl.nix index ff27cb127..b283b351b 100644 --- a/devenv/src/flake.tmpl.nix +++ b/devenv/src/flake.tmpl.nix @@ -63,6 +63,7 @@ devenv.cliVersion = version; devenv.root = devenv_root; devenv.dotfile = pkgs.lib.mkForce (devenv_root + "/" + devenv_dotfile_string); + devenv.tmpdir = tmpdir; } (if container_name != null then { container.isBuilding = pkgs.lib.mkForce true; diff --git a/devenv/src/main.rs b/devenv/src/main.rs index 717dcf336..b50389adb 100644 --- a/devenv/src/main.rs +++ b/devenv/src/main.rs @@ -18,7 +18,7 @@ use std::{ }; // templates -const FLAKE_TMP: &str = include_str!("flake.tmpl.nix"); +const FLAKE_TMPL: &str = include_str!("flake.tmpl.nix"); const REQUIRED_FILES: [&str; 4] = ["devenv.nix", "devenv.yaml", ".envrc", ".gitignore"]; const PROJECT_DIR: Dir = include_dir!("$CARGO_MANIFEST_DIR/init"); // project vars @@ -1068,6 +1068,7 @@ impl App { devenv_dotfile = ./{}; devenv_dotfile_string = \"{}\"; container_name = {}; + tmpdir = \"{}\"; ", crate_version!(), self.cli.system, @@ -1077,9 +1078,11 @@ impl App { self.container_name .as_deref() .map(|s| format!("\"{}\"", s)) - .unwrap_or_else(|| "null".to_string()) + .unwrap_or_else(|| "null".to_string()), + std::env::var("XDG_RUNTIME_DIR") + .unwrap_or_else(|_| std::env::var("TMPDIR").unwrap_or_else(|_| "/tmp".to_string())), ); - let flake = FLAKE_TMP.replace("__DEVENV_VARS__", &vars); + let flake = FLAKE_TMPL.replace("__DEVENV_VARS__", &vars); std::fs::write(DEVENV_FLAKE, flake).expect("Failed to write flake.nix"); Ok(()) } diff --git a/docs/files-and-variables.md b/docs/files-and-variables.md index 29a8a8e6d..30f13b779 100644 --- a/docs/files-and-variables.md +++ b/docs/files-and-variables.md @@ -44,7 +44,8 @@ Points to `$DEVENV_DOTFILE/state`. ### $DEVENV_RUNTIME Points to a temporary directory with a path that's unique to each `$DEVENV_ROOT`. -It's similar in purpose to `/run`. +It's used for storing sockets and other runtime files. +Defaults to `$XDG_RUNTIME_DIR` and falls back to `$TMPDIR` and finally `/tmp`. ### $DEVENV_PROFILE diff --git a/src/modules/top-level.nix b/src/modules/top-level.nix index 60281194b..6df69f2c2 100644 --- a/src/modules/top-level.nix +++ b/src/modules/top-level.nix @@ -168,7 +168,12 @@ in tmpdir = lib.mkOption { type = types.str; internal = true; - default = "/tmp"; + default = + let + xdg = builtins.getEnv "XDG_RUNTIME_DIR"; + tmp = builtins.getEnv "TMPDIR"; + in + if xdg != "" then xdg else if tmp != "" then tmp else "/tmp"; }; profile = lib.mkOption { From d0c7023f6b548f02f8b5c65fbf543ab643994c3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Wed, 20 Mar 2024 08:07:00 +0000 Subject: [PATCH 135/146] fix #694 --- docs/pre-commit-hooks.md | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/docs/pre-commit-hooks.md b/docs/pre-commit-hooks.md index 84d7e5160..c2b32ac2e 100644 --- a/docs/pre-commit-hooks.md +++ b/docs/pre-commit-hooks.md @@ -55,3 +55,43 @@ See [the list of all available hooks](reference/options.md#pre-commithooks). The `.pre-commit-config.yaml` file is a symlink to an autogenerated file in your `devenv` Nix store. It is not necessary to commit this file to your repository and it can safely be ignored. This file name will be added to your `.gitignore` file by default when you run `devenv init`. + + +## Adding custom hooks + +If you'd like to define your own hook you can do: + +```nix title="devenv.nix" +{ + pre-commit.hooks.unit-tests = { + enable = true; + + # The name of the hook (appears on the report table): + name = "Unit tests"; + + # The command to execute (mandatory): + entry = "make check"; + + # The pattern of files to run on (default: "" (all)) + # see also https://pre-commit.com/#hooks-files + files = "\\.(c|h)$"; + + # List of file types to run on (default: [ "file" ] (all files)) + # see also https://pre-commit.com/#filtering-files-with-types + # You probably only need to specify one of `files` or `types`: + types = [ "text" "c" ]; + + # Exclude files that were matched by these patterns (default: [ ] (none)): + excludes = [ "irrelevant\\.c" ]; + + # The language of the hook - tells pre-commit + # how to install the hook (default: "system") + # see also https://pre-commit.com/#supported-languages + language = "system"; + + # Set this to false to not pass the changed files + # to the command (default: true): + pass_filenames = false; + }; +} +``` \ No newline at end of file From 23e9cf0a9fc47469089c89a0553a6f3ef30f45f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Wed, 20 Mar 2024 08:08:52 +0000 Subject: [PATCH 136/146] pre-commit: provide all packages that are used for the hooks --- src/modules/integrations/pre-commit.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/integrations/pre-commit.nix b/src/modules/integrations/pre-commit.nix index 8b6f71e6a..b57f12ab7 100644 --- a/src/modules/integrations/pre-commit.nix +++ b/src/modules/integrations/pre-commit.nix @@ -23,7 +23,7 @@ enterTest = '' pre-commit run -a ''; - packages = [ config.pre-commit.package ]; + packages = [ config.pre-commit.package ] ++ config.pre-commit.enabledPackages; enterShell = config.pre-commit.installationScript; }; } From 129434aeb89f918a1155df0ae22f3746b5fcfc60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Wed, 20 Mar 2024 09:19:21 +0000 Subject: [PATCH 137/146] blog clarify things --- docs/blog/posts/devenv-v1.0-rewrite-in-rust.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/blog/posts/devenv-v1.0-rewrite-in-rust.md b/docs/blog/posts/devenv-v1.0-rewrite-in-rust.md index 8aa22a7dc..4ff11949a 100644 --- a/docs/blog/posts/devenv-v1.0-rewrite-in-rust.md +++ b/docs/blog/posts/devenv-v1.0-rewrite-in-rust.md @@ -1,6 +1,6 @@ --- draft: false -date: 2023-03-19 +date: 2023-03-20 authors: - domenkozar --- @@ -20,7 +20,7 @@ Note: Read the migration guide at the end of this post, as 1.0 is not entirely b When I started to write this blog post for the Python rewrite, I came up with only excuses as to why it is not fast and realized that we were simply breaking our promise to you. -The second reason is that in the Nix community there has been a lot of controversy surrounding flakes (that's for another blog post); the [tvix](https://tvix.dev/) developers decided to do something about it and rewrite Nix in Rust. This leaves us with the opportunity in the future to use the same libraries and tools as tvix. +The second reason is that in the Nix community there has been a lot of controversy surrounding flakes (that's for another blog post); the [tvix](https://tvix.dev/) developers decided to do something about it two years ago and started a rewrite Nix in Rust. This leaves us with the opportunity in the future to use the same libraries and tools in Rust. ## What's new? @@ -54,6 +54,9 @@ If you have any [processes](/processes) defined, they will be started and stoppe Read more about this in the [testing documentation](/tests). +This allows you to run tests with all your tooling and processes running, +extremely convenient for integration and functional tests. + ### devenv-nixpkgs Since [nixpkgs-unstable](https://status.nixos.org/) has fairly few tests, From 3adfb7f8633e4d53b6e02c3f7c8fadd1625048b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Wed, 20 Mar 2024 10:10:40 +0000 Subject: [PATCH 138/146] run flake tests --- .github/workflows/buildtest.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/buildtest.yml b/.github/workflows/buildtest.yml index a12a0e380..1a9aa3267 100644 --- a/.github/workflows/buildtest.yml +++ b/.github/workflows/buildtest.yml @@ -50,7 +50,9 @@ jobs: authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}' - run: | nix build - PATH=$PWD/result/bin:$PATH devenv-run-tests tests + export PATH=$PWD/result/bin:$PATH + devenv shell devenv-test-cli + devenv-run-tests tests pin: needs: build if: startsWith(github.ref, 'refs/tags/v') From f840b83c1cd865ae9bb868e4a77492c5465ce28c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Wed, 20 Mar 2024 10:12:05 +0000 Subject: [PATCH 139/146] integrate cachix --- Cargo.lock | 205 ++++++++++++++++++++--- devenv.lock | 24 +-- devenv.nix | 1 + devenv/Cargo.toml | 2 + devenv/src/command.rs | 228 ++++++++++++++++++++++--- devenv/src/log.rs | 3 +- devenv/src/main.rs | 51 ++---- flake.lock | 368 +++++++++++++++++++++++++++++++++++++++-- flake.nix | 5 + package.nix | 6 +- src/modules/cachix.nix | 8 +- 11 files changed, 794 insertions(+), 107 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 80784216c..9a1e5b3ff 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -89,7 +89,7 @@ version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ - "hermit-abi 0.1.19", + "hermit-abi", "libc", "winapi", ] @@ -397,6 +397,7 @@ dependencies = [ "miette", "nix", "regex", + "reqwest", "schematic", "serde", "serde_json", @@ -404,6 +405,7 @@ dependencies = [ "tempdir", "tracing", "which", + "whoami", "xdg", ] @@ -493,6 +495,21 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + [[package]] name = "form_urlencoded" version = "1.2.1" @@ -654,12 +671,6 @@ dependencies = [ "libc", ] -[[package]] -name = "hermit-abi" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "379dada1584ad501b383485dd706b8afb7a70fcbc7f4da7d780638a5a6124a60" - [[package]] name = "home" version = "0.5.9" @@ -727,6 +738,19 @@ dependencies = [ "want", ] +[[package]] +name = "hyper-tls" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" +dependencies = [ + "bytes", + "hyper", + "native-tls", + "tokio", + "tokio-native-tls", +] + [[package]] name = "ident_case" version = "1.0.1" @@ -816,6 +840,12 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + [[package]] name = "libc" version = "0.2.153" @@ -917,24 +947,32 @@ dependencies = [ ] [[package]] -name = "nix" -version = "0.28.0" +name = "native-tls" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab2156c4fce2f8df6c499cc1c763e4394b7482525bf2a9701c9d79d215f519e4" +checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" dependencies = [ - "bitflags 2.4.2", - "cfg-if", - "cfg_aliases", + "lazy_static", "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", ] [[package]] -name = "num_cpus" -version = "1.16.0" +name = "nix" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +checksum = "ab2156c4fce2f8df6c499cc1c763e4394b7482525bf2a9701c9d79d215f519e4" dependencies = [ - "hermit-abi 0.3.8", + "bitflags 2.4.2", + "cfg-if", + "cfg_aliases", "libc", ] @@ -953,6 +991,50 @@ version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +[[package]] +name = "openssl" +version = "0.10.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f" +dependencies = [ + "bitflags 2.4.2", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.51", +] + +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "openssl-sys" +version = "0.9.101" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dda2b0f344e78efc2facf7d195d098df0dd72151b26ab98da807afc26c198dff" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + [[package]] name = "option-ext" version = "0.2.0" @@ -989,6 +1071,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "pkg-config" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" + [[package]] name = "proc-macro-error" version = "1.0.4" @@ -1128,9 +1216,9 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.11.24" +version = "0.11.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6920094eb85afde5e4a138be3f2de8bbdf28000f0029e72c45025a56b042251" +checksum = "78bf93c4af7a8bb7d879d51cebe797356ff10ae8516ace542b5182d9dcac10b2" dependencies = [ "base64", "bytes", @@ -1141,19 +1229,23 @@ dependencies = [ "http", "http-body", "hyper", + "hyper-tls", "ipnet", "js-sys", "log", "mime", + "native-tls", "once_cell", "percent-encoding", "pin-project-lite", + "rustls-pemfile", "serde", "serde_json", "serde_urlencoded", "sync_wrapper", "system-configuration", "tokio", + "tokio-native-tls", "tower-service", "url", "wasm-bindgen", @@ -1181,6 +1273,15 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "rustls-pemfile" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" +dependencies = [ + "base64", +] + [[package]] name = "rustversion" version = "1.0.14" @@ -1193,6 +1294,15 @@ version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" +[[package]] +name = "schannel" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" +dependencies = [ + "windows-sys 0.52.0", +] + [[package]] name = "schemars" version = "0.8.16" @@ -1246,6 +1356,29 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f3adfbe1c90a6a9643433e490ef1605c6a99f93be37e4c83fe5149fca9698c6" +[[package]] +name = "security-framework" +version = "2.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "serde" version = "1.0.197" @@ -1540,12 +1673,21 @@ dependencies = [ "bytes", "libc", "mio", - "num_cpus", "pin-project-lite", "socket2", "windows-sys 0.48.0", ] +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", +] + [[package]] name = "tokio-util" version = "0.7.10" @@ -1671,6 +1813,12 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + [[package]] name = "version_check" version = "0.9.4" @@ -1692,6 +1840,12 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "wasite" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" + [[package]] name = "wasm-bindgen" version = "0.2.91" @@ -1781,6 +1935,17 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "whoami" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a44ab49fad634e88f55bf8f9bb3abd2f27d7204172a112c7c9987e01c1c94ea9" +dependencies = [ + "redox_syscall", + "wasite", + "web-sys", +] + [[package]] name = "winapi" version = "0.3.9" diff --git a/devenv.lock b/devenv.lock index b5dc8416e..751b45863 100644 --- a/devenv.lock +++ b/devenv.lock @@ -93,11 +93,11 @@ "nixpkgs-regression": "nixpkgs-regression" }, "locked": { - "lastModified": 1709963241, + "lastModified": 1710500156, "owner": "domenkozar", "repo": "nix", - "rev": "e92c1fb8a57fe2e0bee725b1e7c68cfd8ffd55dc", - "treeHash": "86eda1beb323090366f08539b000539b461982fe", + "rev": "c5bbf14ecbd692eeabf4184cc8d50f79c2446549", + "treeHash": "e03f107b6573d452d1b64399580c7011d0e4c83e", "type": "github" }, "original": { @@ -109,11 +109,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1710236354, + "lastModified": 1710796454, "owner": "cachix", "repo": "devenv-nixpkgs", - "rev": "829e73affeadfb4198a7105cbe3a03153d13edc9", - "treeHash": "c92d1301b904a3d47027cca315d4de397f711280", + "rev": "06fb0f1c643aee3ae6838dda3b37ef0abc3c763b", + "treeHash": "9bb13f7f39e825a5d91bbe4139fbc129243b907d", "type": "github" }, "original": { @@ -141,11 +141,11 @@ }, "nixpkgs-stable": { "locked": { - "lastModified": 1710162809, + "lastModified": 1710838473, "owner": "NixOS", "repo": "nixpkgs", - "rev": "ddcd7598b2184008c97e6c9c6a21c5f37590b8d2", - "treeHash": "a89e05b79ecfce170082536583aa56246b24f6e4", + "rev": "fa9f817df522ac294016af3d40ccff82f5fd3a63", + "treeHash": "30ab1e864f3804dc0a9df0e539ae7f922d355b34", "type": "github" }, "original": { @@ -166,11 +166,11 @@ "nixpkgs-stable": "nixpkgs-stable" }, "locked": { - "lastModified": 1708018599, + "lastModified": 1710921752, "owner": "cachix", "repo": "pre-commit-hooks.nix", - "rev": "5df5a70ad7575f6601d91f0efec95dd9bc619431", - "treeHash": "6b6519c2b58ad1e106d9633f0d1b490a70fc6980", + "rev": "543d006fef3a86e0887d2f2a213bffa7afbf19d1", + "treeHash": "26995e90a5cd8f44d2b0e37c2ef37dbfa299e329", "type": "github" }, "original": { diff --git a/devenv.nix b/devenv.nix index f86985e3a..84339cc96 100644 --- a/devenv.nix +++ b/devenv.nix @@ -8,6 +8,7 @@ pkgs.xorg.libxcb pkgs.yaml2json pkgs.tesh + pkgs.openssl ] ++ lib.optionals pkgs.stdenv.isDarwin (with pkgs.darwin.apple_sdk; [ frameworks.SystemConfiguration ]); diff --git a/devenv/Cargo.toml b/devenv/Cargo.toml index e6dfcda3e..aba416736 100644 --- a/devenv/Cargo.toml +++ b/devenv/Cargo.toml @@ -15,6 +15,7 @@ indoc = "2.0.4" miette = { version = "7.1.0", features = ["fancy"] } nix = { version = "0.28.0", features = ["signal"] } regex = "1.10.3" +reqwest = "0.11.26" schematic = { version = "0.14.3", features = ["schema", "yaml", "renderer_template", "renderer_json_schema"] } serde = "1.0.197" serde_json = "1.0.114" @@ -22,4 +23,5 @@ serde_yaml = "0.9.32" tempdir = "0.3.7" tracing = "0.1.40" which = "6.0.0" +whoami = "1.5.1" xdg = "2.5.2" diff --git a/devenv/src/command.rs b/devenv/src/command.rs index 38022e2ce..40141f878 100644 --- a/devenv/src/command.rs +++ b/devenv/src/command.rs @@ -1,5 +1,7 @@ use crate::App; use miette::{bail, Result}; +use serde::Deserialize; +use std::collections::HashMap; use std::env; use std::os::unix::process::CommandExt; @@ -23,18 +25,14 @@ const NIX_FLAGS: [&str; 12] = [ pub struct Options { pub replace_shell: bool, - pub use_cachix: bool, pub logging: bool, - pub dont_exit: bool, } impl Default for Options { fn default() -> Self { Options { replace_shell: false, - use_cachix: false, logging: true, - dont_exit: false, } } } @@ -46,6 +44,11 @@ impl App { args: &[&str], options: &Options, ) -> Result { + let prev_logging = self.logger.clone(); + if !options.logging { + self.logger = crate::log::Logger::new(crate::log::Level::Error); + } + let mut cmd = self.prepare_command(command, args)?; if options.replace_shell { @@ -72,19 +75,14 @@ impl App { cmd.output().expect("Failed to run command") }; if !result.status.success() { + let code = match result.status.code() { + Some(code) => format!("with exit code {}", code), + None => "without exit code".to_string(), + }; if options.logging { println!(); - let code = match result.status.code() { - Some(code) => format!("with exit code {}", code), - None => "without exit code".to_string(), - }; self.logger.error(&format!( - "Command `{} {}` failed {code} and produced the following output:\n{}\n{}", - cmd.get_program().to_string_lossy(), - cmd.get_args() - .map(|arg| arg.to_str().unwrap()) - .collect::>() - .join(" "), + "Command produced the following output:\n{}\n{}", String::from_utf8_lossy(&result.stdout), String::from_utf8_lossy(&result.stderr), )); @@ -93,12 +91,16 @@ impl App { self.logger.info("Starting Nix debugger ..."); cmd.arg("--debugger").exec(); } - if !options.dont_exit { - bail!("Command failed") - } else { - Ok(result) - } + bail!(format!( + "Command `{} {}` failed with {code}", + cmd.get_program().to_string_lossy(), + cmd.get_args() + .map(|arg| arg.to_str().unwrap()) + .collect::>() + .join(" ") + )) } else { + self.logger = prev_logging; Ok(result) } } @@ -143,6 +145,64 @@ impl App { cmd.env("NIX_PATH", ":"); } cmd.args(flags); + + if args + .first() + .map(|arg| arg == &"build" || arg == &"print-dev-env") + .unwrap_or(false) + { + let cachix_caches = self.get_cachix_caches()?; + + // handle cachix.pull + let pull_caches = cachix_caches + .caches + .pull + .iter() + .map(|cache| format!("https://{}.cachix.org", cache)) + .collect::>() + .join(" "); + cmd.arg("--option"); + cmd.arg("extra-substituters"); + cmd.arg(pull_caches); + cmd.arg("--option"); + cmd.arg("extra-trusted-public-keys"); + cmd.arg( + cachix_caches + .known_keys + .values() + .cloned() + .collect::>() + .join(" "), + ); + + // handle cachix.push + if let Some(push_cache) = &cachix_caches.caches.push { + if let Ok(_) = env::var("CACHIX_AUTH_TOKEN") { + let args = cmd + .get_args() + .map(|arg| arg.to_str().unwrap()) + .collect::>(); + let envs = cmd.get_envs().collect::>(); + let command_name = cmd.get_program().to_string_lossy(); + let mut newcmd = std::process::Command::new(format!( + "cachix watch-exec {} {}", + push_cache, command_name + )); + newcmd.args(args); + for (key, value) in envs { + if let Some(value) = value { + newcmd.env(key, value); + } + } + cmd = newcmd; + } else { + self.logger.warn(&format!( + "CACHIX_AUTH_TOKEN is not set, but required to push to {}.", + push_cache + )); + } + } + } cmd } else { let mut cmd = std::process::Command::new(command); @@ -163,4 +223,134 @@ impl App { Ok(cmd) } + + fn get_cachix_caches(&mut self) -> Result { + match &self.cachix_caches { + Some(caches) => Ok(caches.clone()), + None => { + let no_logging = Options { + logging: false, + ..Default::default() + }; + let store = self.run_nix("nix", &["store", "ping", "--json"], &no_logging)?; + + let caches_raw = + self.run_nix("nix", &["eval", ".#devenv.cachix", "--json"], &no_logging)?; + + let cachix = + serde_json::from_slice(&caches_raw.stdout).expect("Failed to parse JSON"); + + let known_keys = + if let Ok(known_keys) = std::fs::read_to_string(&self.cachix_trusted_keys) { + serde_json::from_str(&known_keys).expect("Failed to parse JSON") + } else { + HashMap::new() + }; + + let mut caches = CachixCaches { + caches: cachix, + known_keys, + }; + + let mut new_known_keys: HashMap = HashMap::new(); + for name in caches.caches.pull.iter() { + if !caches.known_keys.contains_key(name) { + let resp = reqwest::blocking::get(&format!( + "https://cachix.org/api/v1/cache/{}", + name + )) + .expect("Failed to get cache"); + if resp.status().is_client_error() { + self.logger.error(&format!( + "Cache {} does not exist or you don't have a CACHIX_AUTH_TOKEN configured.", + name + )); + self.logger + .error("To create a cache, go to https://app.cachix.org/."); + bail!("Cache does not exist or you don't have a CACHIX_AUTH_TOKEN configured.") + } else { + let resp_json = + serde_json::from_slice::(&resp.bytes().unwrap()) + .expect("Failed to parse JSON"); + new_known_keys + .insert(name.clone(), resp_json.publicSigningKeys[0].clone()); + } + } + } + + if !caches.caches.pull.is_empty() { + // parse trusted from store and assert it's 1 + if serde_json::from_slice::(&store.stdout) + .expect("Failed to parse JSON") + .trusted + != 1 + { + bail!(indoc::formatdoc!( + "You're not a trusted user of the Nix store. You have the following options: + + 1. Add yourself to the trusted-users list in /etc/nix/nix.conf for devenv to manage caches for you. + + trusted-users = root {} + + 2. Add binary caches to /etc/nix/nix.conf yourself: + + extra-substituters = {} + extra-trusted-public-keys = {} + + 3. Disable Cachix in `devenv.nix`: + + {{ + cachix.enable = false; + }} + ", whoami::username() + , caches.caches.pull.iter().map(|cache| format!("https://{}.cachix.org", cache)).collect::>().join(" ") + , caches.known_keys.values().cloned().collect::>().join(" ") + )); + } + + self.logger + .info(&format!("Using Cachix: {}", caches.caches.pull.join(", "))); + if !new_known_keys.is_empty() { + for (name, pubkey) in new_known_keys.iter() { + self.logger.info(&format!( + "Trusting {}.cachix.org on first use with the public key {}", + name, pubkey + )); + } + caches.known_keys.extend(new_known_keys); + } + std::fs::write( + &self.cachix_trusted_keys, + serde_json::to_string(&caches.known_keys).unwrap(), + ) + .expect("Failed to write cachix caches to file") + } + + self.cachix_caches = Some(caches.clone()); + Ok(caches) + } + } + } +} + +#[derive(Deserialize, Clone)] +pub struct Cachix { + pull: Vec, + push: Option, +} + +#[derive(Deserialize, Clone)] +pub struct CachixCaches { + caches: Cachix, + known_keys: HashMap, +} + +#[derive(Deserialize, Clone)] +struct CachixResponse { + publicSigningKeys: Vec, +} + +#[derive(Deserialize, Clone)] +struct StorePing { + trusted: u8, } diff --git a/devenv/src/log.rs b/devenv/src/log.rs index 2a028729e..b2dd0bee4 100644 --- a/devenv/src/log.rs +++ b/devenv/src/log.rs @@ -41,7 +41,7 @@ impl Drop for LogProgress { } } -#[derive(PartialEq, Eq, PartialOrd, Ord)] +#[derive(PartialEq, Eq, PartialOrd, Ord, Clone)] pub enum Level { Error, Warn, @@ -49,6 +49,7 @@ pub enum Level { Debug, } +#[derive(Clone)] pub struct Logger { level: Level, } diff --git a/devenv/src/main.rs b/devenv/src/main.rs index b50389adb..bdea6d5fb 100644 --- a/devenv/src/main.rs +++ b/devenv/src/main.rs @@ -241,6 +241,8 @@ struct App { devenv_dotfile: PathBuf, devenv_dot_gc: PathBuf, devenv_home_gc: PathBuf, + cachix_trusted_keys: PathBuf, + cachix_caches: Option, } fn main() -> Result<()> { @@ -263,12 +265,12 @@ fn main() -> Result<()> { let devenv_dot_gc = devenv_root.join(".devenv").join("gc"); std::fs::create_dir_all(&devenv_dot_gc).expect("Failed to create .devenv/gc directory"); let devenv_dotfile = devenv_root.join(".devenv"); + let cachix_trusted_keys = devenv_home.join("cachix_trusted_keys.json"); let logger = log::Logger::new(level); let mut config = config::Config::load()?; for input in cli.override_input.chunks_exact(2) { config.add_input(&input[0].clone(), &input[1].clone(), &[]); } - let mut app = App { cli, config, @@ -279,6 +281,8 @@ fn main() -> Result<()> { devenv_dotfile, devenv_dot_gc, devenv_home_gc, + cachix_trusted_keys, + cachix_caches: None, }; match app.cli.command.clone() { @@ -409,7 +413,7 @@ impl App { }; // run direnv allow - let status = std::process::Command::new(direnv) + std::process::Command::new(direnv) .arg("allow") .current_dir(&target) .exec(); @@ -520,11 +524,6 @@ impl App { } fn container_build(&mut self, name: &str) -> Result { - let options = command::Options { - use_cachix: true, - ..command::Options::default() - }; - let _logprogress = log::LogProgress::new(&format!("Building {name} container"), true); self.assemble()?; @@ -537,7 +536,7 @@ impl App { "--no-link", &format!(".#devenv.containers.{name}.derivation"), ], - &options, + &command::Options::default(), )?; let container_store_path_string = String::from_utf8_lossy(&container_store_path.stdout) @@ -556,11 +555,6 @@ impl App { ) -> Result<()> { let spec = self.container_build(name)?; - let options = command::Options { - use_cachix: true, - ..command::Options::default() - }; - let _logprogress = log::LogProgress::new(&format!("Copying {name} container"), false); let copy_script = self.run_nix( @@ -571,7 +565,7 @@ impl App { "--no-link", &format!(".#devenv.containers.{name}.copyScript"), ], - &options, + &command::Options::default(), )?; let copy_script = String::from_utf8_lossy(©_script.stdout) @@ -612,11 +606,6 @@ impl App { }; self.container_copy(name, copy_args, Some("docker-daemon:"))?; - let options = command::Options { - use_cachix: true, - ..command::Options::default() - }; - let _logprogress = log::LogProgress::new(&format!("Running {name} container"), false); let run_script = self.run_nix( @@ -627,7 +616,7 @@ impl App { "--no-link", &format!(".#devenv.containers.{name}.dockerRun"), ], - &options, + &command::Options::default(), )?; let run_script = String::from_utf8_lossy(&run_script.stdout) @@ -708,10 +697,7 @@ impl App { "--print-out-paths", ".#optionsJSON", ], - &command::Options { - use_cachix: true, - ..command::Options::default() - }, + &command::Options::default(), )?; let options_str = std::str::from_utf8(&options.stdout).unwrap().trim(); @@ -821,7 +807,7 @@ impl App { } if self.has_processes()? { - self.up(None, &true, &false); + self.up(None, &true, &false)?; } let result = { @@ -922,10 +908,6 @@ impl App { { let _logprogress = log::LogProgress::new("Building processes", true); - let options = command::Options { - use_cachix: true, - ..command::Options::default() - }; let proc_script = self.run_nix( "nix", &[ @@ -934,7 +916,7 @@ impl App { "--print-out-paths", ".#procfileScript", ], - &options, + &command::Options::default(), )?; proc_script_string = String::from_utf8_lossy(&proc_script.stdout) @@ -1090,7 +1072,7 @@ impl App { fn get_dev_environment(&mut self, json: bool, logging: bool) -> Result<(Vec, PathBuf)> { self.assemble()?; let _logprogress = if logging { - Some(log::LogProgress::new("Building shell", false)) + Some(log::LogProgress::new("Building shell", true)) } else { None }; @@ -1102,12 +1084,13 @@ impl App { args.push("--json"); } - let env_ = self.run_nix("nix", &args, &command::Options::default())?; - let options = command::Options { logging: false, ..command::Options::default() }; + + let env = self.run_nix("nix", &args, &options)?; + let args: Vec<&str> = vec!["-p", gc_root_str, "--delete-generations", "old"]; self.run_nix("nix-env", &args, &options)?; let now_ns = get_now_with_nanoseconds(); @@ -1118,7 +1101,7 @@ impl App { &self.devenv_home_gc.join(target), ); - Ok((env_.stdout, gc_root)) + Ok((env.stdout, gc_root)) } } diff --git a/flake.lock b/flake.lock index ab02c9473..9528ac05a 100644 --- a/flake.lock +++ b/flake.lock @@ -1,6 +1,74 @@ { "nodes": { + "cachix": { + "inputs": { + "devenv": "devenv", + "flake-compat": "flake-compat_2", + "nixpkgs": [ + "nixpkgs" + ], + "pre-commit-hooks": "pre-commit-hooks" + }, + "locked": { + "lastModified": 1710475558, + "narHash": "sha256-egKrPCKjy/cE+NqCj4hg2fNX/NwLCf0bRDInraYXDgs=", + "owner": "cachix", + "repo": "cachix", + "rev": "661bbb7f8b55722a0406456b15267b5426a3bda6", + "type": "github" + }, + "original": { + "owner": "cachix", + "repo": "cachix", + "type": "github" + } + }, + "devenv": { + "inputs": { + "flake-compat": [ + "cachix", + "flake-compat" + ], + "nix": "nix", + "nixpkgs": "nixpkgs", + "poetry2nix": "poetry2nix", + "pre-commit-hooks": [ + "cachix", + "pre-commit-hooks" + ] + }, + "locked": { + "lastModified": 1708704632, + "narHash": "sha256-w+dOIW60FKMaHI1q5714CSibk99JfYxm0CzTinYWr+Q=", + "owner": "cachix", + "repo": "devenv", + "rev": "2ee4450b0f4b95a1b90f2eb5ffea98b90e48c196", + "type": "github" + }, + "original": { + "owner": "cachix", + "ref": "python-rewrite", + "repo": "devenv", + "type": "github" + } + }, "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" + } + }, + "flake-compat_2": { "flake": false, "locked": { "lastModified": 1696426674, @@ -16,7 +84,39 @@ "type": "github" } }, - "flake-compat_2": { + "flake-compat_3": { + "flake": false, + "locked": { + "lastModified": 1696426674, + "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, + "flake-compat_4": { + "flake": false, + "locked": { + "lastModified": 1696426674, + "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, + "flake-compat_5": { "flake": false, "locked": { "lastModified": 1673956053, @@ -36,6 +136,42 @@ "inputs": { "systems": "systems" }, + "locked": { + "lastModified": 1689068808, + "narHash": "sha256-6ixXo3wt24N/melDWjq70UuHQLxGV8jZvooRanIHXw0=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "919d646de7be200f3bf08cb76ae1f09402b6f9b4", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_2": { + "inputs": { + "systems": "systems_2" + }, + "locked": { + "lastModified": 1701680307, + "narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "4022d587cbbfd70fe950c1e2083a02621806a725", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_3": { + "inputs": { + "systems": "systems_3" + }, "locked": { "lastModified": 1701680307, "narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=", @@ -51,6 +187,28 @@ } }, "gitignore": { + "inputs": { + "nixpkgs": [ + "cachix", + "pre-commit-hooks", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1703887061, + "narHash": "sha256-gGPa9qWNc6eCXT/+Z5/zMkyYOuRZqeFZBDbopNZQkuY=", + "owner": "hercules-ci", + "repo": "gitignore.nix", + "rev": "43e1aa1308018f37118e34d3a9cb4f5e75dc11d5", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "gitignore.nix", + "type": "github" + } + }, + "gitignore_2": { "inputs": { "nixpkgs": [ "pre-commit-hooks", @@ -73,12 +231,60 @@ }, "nix": { "inputs": { - "flake-compat": "flake-compat_2", + "flake-compat": "flake-compat", "nixpkgs": [ + "cachix", + "devenv", "nixpkgs" ], "nixpkgs-regression": "nixpkgs-regression" }, + "locked": { + "lastModified": 1708577783, + "narHash": "sha256-92xq7eXlxIT5zFNccLpjiP7sdQqQI30Gyui2p/PfKZM=", + "owner": "domenkozar", + "repo": "nix", + "rev": "ecd0af0c1f56de32cbad14daa1d82a132bf298f8", + "type": "github" + }, + "original": { + "owner": "domenkozar", + "ref": "devenv-2.21", + "repo": "nix", + "type": "github" + } + }, + "nix-github-actions": { + "inputs": { + "nixpkgs": [ + "cachix", + "devenv", + "poetry2nix", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1688870561, + "narHash": "sha256-4UYkifnPEw1nAzqqPOTL2MvWtm3sNGw1UTYTalkTcGY=", + "owner": "nix-community", + "repo": "nix-github-actions", + "rev": "165b1650b753316aa7f1787f3005a8d2da0f5301", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "nix-github-actions", + "type": "github" + } + }, + "nix_2": { + "inputs": { + "flake-compat": "flake-compat_5", + "nixpkgs": [ + "nixpkgs" + ], + "nixpkgs-regression": "nixpkgs-regression_2" + }, "locked": { "lastModified": 1710500156, "narHash": "sha256-zvCqeUO2GLOm7jnU23G4EzTZR7eylcJN+HJ5svjmubI=", @@ -96,17 +302,17 @@ }, "nixpkgs": { "locked": { - "lastModified": 1710236354, - "narHash": "sha256-vWrciFdq49vve43g4pbi7NjmL4cwG1ifXnQx+dU3T5E=", - "owner": "cachix", - "repo": "devenv-nixpkgs", - "rev": "829e73affeadfb4198a7105cbe3a03153d13edc9", + "lastModified": 1692808169, + "narHash": "sha256-x9Opq06rIiwdwGeK2Ykj69dNc2IvUH1fY55Wm7atwrE=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "9201b5ff357e781bf014d0330d18555695df7ba8", "type": "github" }, "original": { - "owner": "cachix", - "ref": "rolling", - "repo": "devenv-nixpkgs", + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", "type": "github" } }, @@ -126,6 +332,22 @@ "type": "github" } }, + "nixpkgs-regression_2": { + "locked": { + "lastModified": 1643052045, + "narHash": "sha256-uGJ0VXIhWKGXxkeNnq4TvV3CIOkUJ3PAoLZ3HMzNVMw=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2", + "type": "github" + }, + "original": { + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2", + "type": "github" + } + }, "nixpkgs-stable": { "locked": { "lastModified": 1704874635, @@ -142,17 +364,98 @@ "type": "github" } }, + "nixpkgs-stable_2": { + "locked": { + "lastModified": 1704874635, + "narHash": "sha256-YWuCrtsty5vVZvu+7BchAxmcYzTMfolSPP5io8+WYCg=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "3dc440faeee9e889fe2d1b4d25ad0f430d449356", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-23.11", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_2": { + "locked": { + "lastModified": 1710236354, + "narHash": "sha256-vWrciFdq49vve43g4pbi7NjmL4cwG1ifXnQx+dU3T5E=", + "owner": "cachix", + "repo": "devenv-nixpkgs", + "rev": "829e73affeadfb4198a7105cbe3a03153d13edc9", + "type": "github" + }, + "original": { + "owner": "cachix", + "ref": "rolling", + "repo": "devenv-nixpkgs", + "type": "github" + } + }, + "poetry2nix": { + "inputs": { + "flake-utils": "flake-utils", + "nix-github-actions": "nix-github-actions", + "nixpkgs": [ + "cachix", + "devenv", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1692876271, + "narHash": "sha256-IXfZEkI0Mal5y1jr6IRWMqK8GW2/f28xJenZIPQqkY0=", + "owner": "nix-community", + "repo": "poetry2nix", + "rev": "d5006be9c2c2417dafb2e2e5034d83fabd207ee3", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "poetry2nix", + "type": "github" + } + }, "pre-commit-hooks": { + "inputs": { + "flake-compat": "flake-compat_3", + "flake-utils": "flake-utils_2", + "gitignore": "gitignore", + "nixpkgs": [ + "cachix", + "nixpkgs" + ], + "nixpkgs-stable": "nixpkgs-stable" + }, + "locked": { + "lastModified": 1708018599, + "narHash": "sha256-M+Ng6+SePmA8g06CmUZWi1AjG2tFBX9WCXElBHEKnyM=", + "owner": "cachix", + "repo": "pre-commit-hooks.nix", + "rev": "5df5a70ad7575f6601d91f0efec95dd9bc619431", + "type": "github" + }, + "original": { + "owner": "cachix", + "repo": "pre-commit-hooks.nix", + "type": "github" + } + }, + "pre-commit-hooks_2": { "inputs": { "flake-compat": [ "flake-compat" ], - "flake-utils": "flake-utils", - "gitignore": "gitignore", + "flake-utils": "flake-utils_3", + "gitignore": "gitignore_2", "nixpkgs": [ "nixpkgs" ], - "nixpkgs-stable": "nixpkgs-stable" + "nixpkgs-stable": "nixpkgs-stable_2" }, "locked": { "lastModified": 1708018599, @@ -170,10 +473,11 @@ }, "root": { "inputs": { - "flake-compat": "flake-compat", - "nix": "nix", - "nixpkgs": "nixpkgs", - "pre-commit-hooks": "pre-commit-hooks" + "cachix": "cachix", + "flake-compat": "flake-compat_4", + "nix": "nix_2", + "nixpkgs": "nixpkgs_2", + "pre-commit-hooks": "pre-commit-hooks_2" } }, "systems": { @@ -190,6 +494,36 @@ "repo": "default", "type": "github" } + }, + "systems_2": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_3": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } } }, "root": "root", diff --git a/flake.nix b/flake.nix index 83ae7aaf0..c35ed8d85 100644 --- a/flake.nix +++ b/flake.nix @@ -22,6 +22,11 @@ url = "github:domenkozar/nix/devenv-2.21"; inputs.nixpkgs.follows = "nixpkgs"; }; + inputs.cachix = { + url = "github:cachix/cachix"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + outputs = { self, nixpkgs, pre-commit-hooks, nix, ... }@inputs: let diff --git a/package.nix b/package.nix index 54651a6c5..1d11644c6 100644 --- a/package.nix +++ b/package.nix @@ -15,13 +15,13 @@ pkgs.rustPlatform.buildRustPackage { lockFile = ./Cargo.lock; }; - nativeBuildInputs = [ pkgs.makeWrapper ]; + nativeBuildInputs = [ pkgs.makeWrapper pkgs.pkg-config ]; - buildInputs = pkgs.lib.optionals pkgs.stdenv.isDarwin [ + buildInputs = [ pkgs.openssl ] ++ pkgs.lib.optionals pkgs.stdenv.isDarwin [ pkgs.darwin.apple_sdk.frameworks.SystemConfiguration ]; postInstall = '' - wrapProgram $out/bin/devenv --set DEVENV_NIX ${inputs.nix.packages.${pkgs.stdenv.system}.nix} + wrapProgram $out/bin/devenv --set DEVENV_NIX ${inputs.nix.packages.${pkgs.stdenv.system}.nix} --prefix PATH ":" "$out/bin:${inputs.cachix.packages.${pkgs.stdenv.system}.cachix}/bin" ''; } diff --git a/src/modules/cachix.nix b/src/modules/cachix.nix index e5413f450..78c8fdf3f 100644 --- a/src/modules/cachix.nix +++ b/src/modules/cachix.nix @@ -4,6 +4,12 @@ let in { options.cachix = { + enable = lib.mkOption { + type = lib.types.bool; + description = "Whether to enable Cachix integration."; + default = true; + }; + pull = lib.mkOption { type = lib.types.listOf lib.types.str; description = "What caches to pull from."; @@ -16,7 +22,7 @@ in }; }; - config = { + config = lib.mkIf cfg.enable { cachix.pull = [ "devenv" ] ++ (lib.optionals (cfg.push != null) [ config.cachix.push ]); From 883b0e4894541546b5d3988f79cb160e515de1ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Wed, 20 Mar 2024 10:12:12 +0000 Subject: [PATCH 140/146] fix flake template --- templates/simple/flake.nix | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/templates/simple/flake.nix b/templates/simple/flake.nix index b049d27f1..303f4afec 100644 --- a/templates/simple/flake.nix +++ b/templates/simple/flake.nix @@ -1,8 +1,9 @@ { inputs = { - nixpkgs.url = "github:github:cachix/devenv-nixpkgs/rolling"; + nixpkgs.url = "github:cachix/devenv-nixpkgs/rolling"; systems.url = "github:nix-systems/default"; devenv.url = "github:cachix/devenv"; + devenv.inputs.nixpkgs.follows = "nixpkgs"; }; nixConfig = { From c7f36c76fc84ccd6807f60ee39996dbd50e0dcdf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Wed, 20 Mar 2024 10:49:20 +0000 Subject: [PATCH 141/146] don't fail on older devenv modules --- devenv/src/command.rs | 100 +++++++++++++++++++++++------------------- 1 file changed, 54 insertions(+), 46 deletions(-) diff --git a/devenv/src/command.rs b/devenv/src/command.rs index 40141f878..2dd88752f 100644 --- a/devenv/src/command.rs +++ b/devenv/src/command.rs @@ -151,55 +151,63 @@ impl App { .map(|arg| arg == &"build" || arg == &"print-dev-env") .unwrap_or(false) { - let cachix_caches = self.get_cachix_caches()?; - - // handle cachix.pull - let pull_caches = cachix_caches - .caches - .pull - .iter() - .map(|cache| format!("https://{}.cachix.org", cache)) - .collect::>() - .join(" "); - cmd.arg("--option"); - cmd.arg("extra-substituters"); - cmd.arg(pull_caches); - cmd.arg("--option"); - cmd.arg("extra-trusted-public-keys"); - cmd.arg( - cachix_caches - .known_keys - .values() - .cloned() - .collect::>() - .join(" "), - ); + let cachix_caches = self.get_cachix_caches(); - // handle cachix.push - if let Some(push_cache) = &cachix_caches.caches.push { - if let Ok(_) = env::var("CACHIX_AUTH_TOKEN") { - let args = cmd - .get_args() - .map(|arg| arg.to_str().unwrap()) - .collect::>(); - let envs = cmd.get_envs().collect::>(); - let command_name = cmd.get_program().to_string_lossy(); - let mut newcmd = std::process::Command::new(format!( - "cachix watch-exec {} {}", - push_cache, command_name - )); - newcmd.args(args); - for (key, value) in envs { - if let Some(value) = value { - newcmd.env(key, value); + match cachix_caches { + Err(e) => { + self.logger + .warn("Failed to get cachix caches due to evaluation error"); + } + Ok(cachix_caches) => { + // handle cachix.pull + let pull_caches = cachix_caches + .caches + .pull + .iter() + .map(|cache| format!("https://{}.cachix.org", cache)) + .collect::>() + .join(" "); + cmd.arg("--option"); + cmd.arg("extra-substituters"); + cmd.arg(pull_caches); + cmd.arg("--option"); + cmd.arg("extra-trusted-public-keys"); + cmd.arg( + cachix_caches + .known_keys + .values() + .cloned() + .collect::>() + .join(" "), + ); + + // handle cachix.push + if let Some(push_cache) = &cachix_caches.caches.push { + if let Ok(_) = env::var("CACHIX_AUTH_TOKEN") { + let args = cmd + .get_args() + .map(|arg| arg.to_str().unwrap()) + .collect::>(); + let envs = cmd.get_envs().collect::>(); + let command_name = cmd.get_program().to_string_lossy(); + let mut newcmd = std::process::Command::new(format!( + "cachix watch-exec {} {}", + push_cache, command_name + )); + newcmd.args(args); + for (key, value) in envs { + if let Some(value) = value { + newcmd.env(key, value); + } + } + cmd = newcmd; + } else { + self.logger.warn(&format!( + "CACHIX_AUTH_TOKEN is not set, but required to push to {}.", + push_cache + )); } } - cmd = newcmd; - } else { - self.logger.warn(&format!( - "CACHIX_AUTH_TOKEN is not set, but required to push to {}.", - push_cache - )); } } } From 60cb6f70fb782023b0ddecbd6946a707b809e74e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Wed, 20 Mar 2024 10:49:43 +0000 Subject: [PATCH 142/146] fix postgresql localhost healthcheck --- docs/blog/posts/devenv-v1.0-rewrite-in-rust.md | 9 ++++++++- docs/tests.md | 6 +++++- src/modules/services/postgres.nix | 7 +++++-- tests/postgresql-localhost/.test.sh | 2 ++ tests/postgresql-localhost/devenv.nix | 10 ++++++++++ 5 files changed, 30 insertions(+), 4 deletions(-) create mode 100755 tests/postgresql-localhost/.test.sh create mode 100644 tests/postgresql-localhost/devenv.nix diff --git a/docs/blog/posts/devenv-v1.0-rewrite-in-rust.md b/docs/blog/posts/devenv-v1.0-rewrite-in-rust.md index 4ff11949a..e871feff7 100644 --- a/docs/blog/posts/devenv-v1.0-rewrite-in-rust.md +++ b/docs/blog/posts/devenv-v1.0-rewrite-in-rust.md @@ -42,8 +42,15 @@ The new `enterTest` attribute in `devenv.nix` allows you to define testing logic { pkgs, ... }: { packages = [ pkgs.ncdu ]; + services.postgres = { + enable = true; + listen_addresses = "127.0.0.1"; + initialDatabases = [{ name = "mydb"; }]; + }; + enterTest = '' - ncdu --version | grep "ncdu 2.2" + wait_for_port 5432 + ncdu --version | grep "ncdu 2.2" ''; } ``` diff --git a/docs/tests.md b/docs/tests.md index 2b765034d..a32f37110 100644 --- a/docs/tests.md +++ b/docs/tests.md @@ -74,4 +74,8 @@ ncdu 2.2 ✔ Running tests in 4.7s. • Stopping process with PID 113105 ✔ Tests passed. in 0.0s. -``` \ No newline at end of file +``` + +## Provided functions for enterTest + +- `wait_for_port `: waits for a port to be open \ No newline at end of file diff --git a/src/modules/services/postgres.nix b/src/modules/services/postgres.nix index edca33ed3..7e8584cd1 100644 --- a/src/modules/services/postgres.nix +++ b/src/modules/services/postgres.nix @@ -282,7 +282,10 @@ in packages = [ postgresPkg startScript ]; env.PGDATA = config.env.DEVENV_STATE + "/postgres"; - env.PGHOST = runtimeDir; + env.PGHOST = + if cfg.listen_addresses == "" + then runtimeDir + else cfg.listen_addresses; env.PGPORT = cfg.port; services.postgres.settings = { @@ -299,7 +302,7 @@ in shutdown.signal = 2; readiness_probe = { - exec.command = "${postgresPkg}/bin/pg_isready -h $PGDATA -d template1"; + exec.command = "${postgresPkg}/bin/pg_isready -d template1"; initial_delay_seconds = 2; period_seconds = 10; timeout_seconds = 4; diff --git a/tests/postgresql-localhost/.test.sh b/tests/postgresql-localhost/.test.sh new file mode 100755 index 000000000..18df58bf8 --- /dev/null +++ b/tests/postgresql-localhost/.test.sh @@ -0,0 +1,2 @@ +wait_for_port 2345 +pg_isready -d template1 \ No newline at end of file diff --git a/tests/postgresql-localhost/devenv.nix b/tests/postgresql-localhost/devenv.nix new file mode 100644 index 000000000..0b03a291b --- /dev/null +++ b/tests/postgresql-localhost/devenv.nix @@ -0,0 +1,10 @@ +{ + services.postgres = { + enable = true; + listen_addresses = "localhost"; + port = 2345; + initialScript = '' + CREATE USER postgres SUPERUSER; + ''; + }; +} From 1bf66bfbad3f459a5fc626e66bfc50e36331fecd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Wed, 20 Mar 2024 10:55:30 +0000 Subject: [PATCH 143/146] garden --- devenv/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/devenv/src/main.rs b/devenv/src/main.rs index bdea6d5fb..fdf38583e 100644 --- a/devenv/src/main.rs +++ b/devenv/src/main.rs @@ -786,7 +786,7 @@ impl App { // collect tests let test_script = { - let _logprogress = log::LogProgress::new("Building tests", false); + let _logprogress = log::LogProgress::new("Building tests", true); self.run_nix( "nix", &["build", ".#devenv.test", "--no-link", "--print-out-paths"], From 3ccd354eb75428b424c1333a25eb25ec208bd72b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Wed, 20 Mar 2024 12:21:30 +0000 Subject: [PATCH 144/146] fix tests --- devenv-run-tests/src/main.rs | 2 +- devenv.nix | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/devenv-run-tests/src/main.rs b/devenv-run-tests/src/main.rs index 64e554f1b..bb56a731e 100644 --- a/devenv-run-tests/src/main.rs +++ b/devenv-run-tests/src/main.rs @@ -72,8 +72,8 @@ fn run_tests_in_directory(args: &Args) -> Result, Box Date: Wed, 20 Mar 2024 12:21:41 +0000 Subject: [PATCH 145/146] log to stderr --- devenv/src/command.rs | 2 +- devenv/src/log.rs | 16 ++++++++-------- devenv/src/main.rs | 6 +++--- examples/dynamodb-local/.test.sh | 12 +----------- 4 files changed, 13 insertions(+), 23 deletions(-) diff --git a/devenv/src/command.rs b/devenv/src/command.rs index 2dd88752f..0096b2aec 100644 --- a/devenv/src/command.rs +++ b/devenv/src/command.rs @@ -80,7 +80,7 @@ impl App { None => "without exit code".to_string(), }; if options.logging { - println!(); + eprintln!(); self.logger.error(&format!( "Command produced the following output:\n{}\n{}", String::from_utf8_lossy(&result.stdout), diff --git a/devenv/src/log.rs b/devenv/src/log.rs index b2dd0bee4..ce69c2fbe 100644 --- a/devenv/src/log.rs +++ b/devenv/src/log.rs @@ -11,11 +11,11 @@ pub struct LogProgress { impl LogProgress { pub fn new(message: &str, newline: bool) -> LogProgress { let prefix = Blue.paint("•"); - print!("{} {} ...", prefix, message); + eprint!("{} {} ...", prefix, message); if newline { - println!(); + eprintln!(); } - std::io::stdout().flush().unwrap(); + std::io::stderr().flush().unwrap(); LogProgress { message: message.to_string(), start: Some(Instant::now()), @@ -32,7 +32,7 @@ impl Drop for LogProgress { } else { Green.paint("✔") }; - println!( + eprintln!( "\r{} {} in {:.1}s.", prefix, self.message, @@ -82,19 +82,19 @@ impl Logger { match level { Level::Info => { let prefix = Blue.paint("•"); - println!("{} {}", prefix, message); + eprintln!("{} {}", prefix, message); } Level::Error => { let prefix = Red.paint("✖"); - println!("{} {}", prefix, message); + eprintln!("{} {}", prefix, message); } Level::Warn => { let prefix = Yellow.paint("•"); - println!("{} {}", prefix, message); + eprintln!("{} {}", prefix, message); } Level::Debug => { let prefix = DarkGray.paint("•"); - println!("{} {}", prefix, message); + eprintln!("{} {}", prefix, message); } } } diff --git a/devenv/src/main.rs b/devenv/src/main.rs index fdf38583e..8d9e50b23 100644 --- a/devenv/src/main.rs +++ b/devenv/src/main.rs @@ -676,7 +676,7 @@ impl App { let (after_gc, _) = cleanup_symlinks(&self.devenv_home_gc); let end = std::time::Instant::now(); - println!(); + eprintln!(); self.logger.info(&format!( "Done. Successfully removed {} symlinks in {}s.", to_gc.len() - after_gc.len(), @@ -1084,13 +1084,13 @@ impl App { args.push("--json"); } + let env = self.run_nix("nix", &args, &command::Options::default())?; + let options = command::Options { logging: false, ..command::Options::default() }; - let env = self.run_nix("nix", &args, &options)?; - let args: Vec<&str> = vec!["-p", gc_root_str, "--delete-generations", "old"]; self.run_nix("nix-env", &args, &options)?; let now_ns = get_now_with_nanoseconds(); diff --git a/examples/dynamodb-local/.test.sh b/examples/dynamodb-local/.test.sh index 0809a62ae..e31380d52 100755 --- a/examples/dynamodb-local/.test.sh +++ b/examples/dynamodb-local/.test.sh @@ -1,20 +1,10 @@ #!/usr/bin/env bash set -ex -devenv up & -DEVENV_PID=$! -export DEVENV_PID - -function stop() { - pkill -P "$DEVENV_PID" -} - -trap stop EXIT - export AWS_DEFAULT_REGION=fakeRegion export AWS_ACCESS_KEY_ID=fakeMyKeyId export AWS_SECRET_ACCESS_KEY=fakeSecretAccessKey -timeout 60 bash -c 'until echo > /dev/tcp/localhost/8000; do sleep 0.5; done' +wait_for_port 8000 aws dynamodb list-tables --endpoint-url http://localhost:8000 From 2edb077b05483f2a9f6ce5c15bcdb81e455e7933 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Wed, 20 Mar 2024 12:40:03 +0000 Subject: [PATCH 146/146] Fix flake-parts template --- templates/flake-parts/flake.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/flake-parts/flake.nix b/templates/flake-parts/flake.nix index 1aea74d5c..115c28de4 100644 --- a/templates/flake-parts/flake.nix +++ b/templates/flake-parts/flake.nix @@ -2,7 +2,7 @@ description = "Description for the project"; inputs = { - nixpkgs.url = "github:github:cachix/devenv-nixpkgs/rolling"; + nixpkgs.url = "github:cachix/devenv-nixpkgs/rolling"; devenv.url = "github:cachix/devenv"; nix2container.url = "github:nlewo/nix2container"; nix2container.inputs.nixpkgs.follows = "nixpkgs";