From 08c74d89cfccf0525a45d9cde9188a2b776e767b Mon Sep 17 00:00:00 2001 From: Johann Bahl Date: Fri, 21 Jul 2023 15:10:55 +0200 Subject: [PATCH] nix flakes --- .github/workflows/python-app.yml | 23 ++++-- .gitignore | 1 + README.txt | 4 +- .../20230825_181711_jb_feature_nix_flake.rst | 1 + default.nix | 24 +++---- flake.lock | 44 ++++++++++++ flake.nix | 70 +++++++++++++++++++ shell.nix | 27 +++---- smoketest.sh | 9 ++- src/backy/conftest.py | 7 +- src/backy/tests/test_backy.py | 5 +- 11 files changed, 170 insertions(+), 45 deletions(-) create mode 100644 changelog.d/20230825_181711_jb_feature_nix_flake.rst create mode 100644 flake.lock create mode 100644 flake.nix diff --git a/.github/workflows/python-app.yml b/.github/workflows/python-app.yml index b86b781b..e767c389 100644 --- a/.github/workflows/python-app.yml +++ b/.github/workflows/python-app.yml @@ -10,10 +10,8 @@ on: branches: [ main ] jobs: - build: - + check-poetry: runs-on: ubuntu-latest - steps: - uses: actions/checkout@v3 - name: Install poetry @@ -26,8 +24,25 @@ jobs: - name: Install dependencies run: | sudo apt-get update - sudo apt-get install liblzo2-dev libsystemd-dev + sudo apt-get install liblzo2-dev poetry install - name: Test with pytest run: | poetry run pytest + + check-nix: + runs-on: ubuntu-latest + steps: + - name: git checkout + uses: actions/checkout@v3 + - name: Install Nix + uses: DeterminateSystems/nix-installer-action@main + - uses: DeterminateSystems/magic-nix-cache-action@main + - name: Check Nixpkgs inputs + uses: DeterminateSystems/flake-checker-action@main + with: + fail-mode: true + + - name: check flake + run: | + nix flake check -L diff --git a/.gitignore b/.gitignore index 9b78b798..5800bd9c 100644 --- a/.gitignore +++ b/.gitignore @@ -29,3 +29,4 @@ tags vagrant/.vagrant .pytest_cache share/ +/venv diff --git a/README.txt b/README.txt index 6330aa82..5dc849e1 100644 --- a/README.txt +++ b/README.txt @@ -173,10 +173,10 @@ Backy has switched to using `poetry` to manage its dependencies. This means that you can use `poetry install` to install dependencies from PyPI. If you don't have `backy` in your PATH when developing, enter the poetry -virtualenv with `poetry shell` or if you're using nix with `nix-shell`. +virtualenv with `poetry shell` or if you're using nix with `nix develop`. You can build backy with `poetry build` making a wheel and a tar archive -in the `dist` directory, or by running `nix-build`. +in the `dist` directory, or by running `nix build`. Authors ======= diff --git a/changelog.d/20230825_181711_jb_feature_nix_flake.rst b/changelog.d/20230825_181711_jb_feature_nix_flake.rst new file mode 100644 index 00000000..9393a46f --- /dev/null +++ b/changelog.d/20230825_181711_jb_feature_nix_flake.rst @@ -0,0 +1 @@ +- Add nix flake support diff --git a/default.nix b/default.nix index ff4bb098..2cccff28 100644 --- a/default.nix +++ b/default.nix @@ -1,14 +1,10 @@ -{ - pkgs ? import {}, - poetry2nix ? pkgs.poetry2nix, - lzo ? pkgs.lzo, - ... -}: -poetry2nix.mkPoetryApplication { - projectDir = ./.; - overrides = poetry2nix.overrides.withDefaults (self: super: { - python-lzo = super.python-lzo.overrideAttrs (old: { - buildInputs = [ lzo ]; - }); - }); -} +(import + ( + let lock = builtins.fromJSON (builtins.readFile ./flake.lock); in + fetchTarball { + url = "https://github.com/edolstra/flake-compat/archive/${lock.nodes.flake-compat.locked.rev}.tar.gz"; + sha256 = lock.nodes.flake-compat.locked.narHash; + } + ) + { src = ./.; } +).defaultNix diff --git a/flake.lock b/flake.lock new file mode 100644 index 00000000..f7b8a7b5 --- /dev/null +++ b/flake.lock @@ -0,0 +1,44 @@ +{ + "nodes": { + "flake-compat": { + "flake": false, + "locked": { + "lastModified": 1673956053, + "narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1693060755, + "narHash": "sha256-KNsbfqewEziFJEpPR0qvVz4rx0x6QXxw1CcunRhlFdk=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "c66ccfa00c643751da2fd9290e096ceaa30493fc", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-compat": "flake-compat", + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 00000000..ad0122b1 --- /dev/null +++ b/flake.nix @@ -0,0 +1,70 @@ +{ + inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; + inputs.flake-compat = { + url = "github:edolstra/flake-compat"; + flake = false; + }; + + outputs = { self, nixpkgs, ... }: + let + supportedSystems = [ "x86_64-linux" "x86_64-darwin" "aarch64-linux" "aarch64-darwin" ]; + forAllSystems = nixpkgs.lib.genAttrs supportedSystems; + pkgs = forAllSystems (system: nixpkgs.legacyPackages.${system}); + poetryOverrides = pkgs: [ + # https://github.com/nix-community/poetry2nix/pull/899#issuecomment-1620306977 + pkgs.poetry2nix.defaultPoetryOverrides + (self: super: { + python-lzo = super.python-lzo.overrideAttrs (old: { + buildInputs = (old.buildInputs or []) ++ [ pkgs.lzo ]; + }); + scriv = super.scriv.overrideAttrs (old: { + buildInputs = (old.buildInputs or []) ++ [ super.setuptools ]; + }); + consulate-fc-nix-test = super.consulate-fc-nix-test.overrideAttrs (old: { + buildInputs = (old.buildInputs or []) ++ [ super.setuptools super.setuptools-scm ]; + }); + }) + ]; + poetryEnv = pkgs: pkgs.poetry2nix.mkPoetryEnv { + projectDir = self; + python = pkgs.python310; + overrides = poetryOverrides pkgs; + editablePackageSources = { + backy = ./src; + }; + }; + in + { + packages = forAllSystems (system: { + default = pkgs.${system}.poetry2nix.mkPoetryApplication { + projectDir = self; + doCheck = true; + python = pkgs.${system}.python310; + overrides = poetryOverrides pkgs.${system}; + }; + + venv = poetryEnv pkgs.${system}; + }); + + devShells = forAllSystems (system: { + default = pkgs.${system}.mkShellNoCC { + BACKY_CMD = "backy"; + packages = with pkgs.${system}; [ + (poetryEnv pkgs.${system}) + poetry + ]; + }; + }); + + checks = forAllSystems (system: { + pytest = pkgs.${system}.runCommand "pytest" { + nativeBuildInputs = [ (poetryEnv pkgs.${system}) ]; + } '' + export BACKY_CMD=backy + cd ${self} + pytest -vv -p no:cacheprovider --no-cov + touch $out + ''; + }); + }; +} diff --git a/shell.nix b/shell.nix index 48ec7a25..6234bb4d 100644 --- a/shell.nix +++ b/shell.nix @@ -1,17 +1,10 @@ -{ - pkgs ? import {}, - ... -}: -pkgs.mkShell { - buildInputs = [ pkgs.lzo ]; - packages = [ pkgs.poetry ]; - shellHook = '' - # check if `poetry env info --path`/bin/activate exists - POETRY_ENV_PATH=$(poetry env info --path)/bin/activate - if [ -f $POETRY_ENV_PATH ]; then - source $POETRY_ENV_PATH - else - echo "Run \`poetry install\` to install dependencies first" - fi - ''; -} +(import + ( + let lock = builtins.fromJSON (builtins.readFile ./flake.lock); in + fetchTarball { + url = "https://github.com/edolstra/flake-compat/archive/${lock.nodes.flake-compat.locked.rev}.tar.gz"; + sha256 = lock.nodes.flake-compat.locked.narHash; + } + ) + { src = ./.; } +).shellNix diff --git a/smoketest.sh b/smoketest.sh index 5394cbe5..9d9e528b 100755 --- a/smoketest.sh +++ b/smoketest.sh @@ -3,10 +3,13 @@ set -e umask 022 -source `poetry env info --path`/bin/activate +if [[ -z "$BACKY_CMD" ]]; then + echo "error: BACKY_CMD is not set. Set it manually or call via pytest" + exit 2 +fi BACKUP=$(mktemp -d -t backy.test.XXXXX) -BACKY="backy -l ${BACKUP}/backy.log" +BACKY="$BACKY_CMD -l ${BACKUP}/backy.log" export TZ=Europe/Berlin mkdir ${BACKUP}/backup @@ -40,7 +43,7 @@ $BACKY backup manual:test echo "Done." echo -n "Backing up img_state1.img with unknown tag. " -! $BACKY backup unknown +$BACKY backup unknown && exit 1 echo "Done." echo -n "Restoring img_state1.img from level 0. " diff --git a/src/backy/conftest.py b/src/backy/conftest.py index 200ee9df..0cb8c8b1 100644 --- a/src/backy/conftest.py +++ b/src/backy/conftest.py @@ -18,9 +18,10 @@ @pytest.fixture(autouse=True, scope="session") def fix_pytest_coverage_465(): - os.environ["COV_CORE_SOURCE"] = os.path.abspath( - os.environ["COV_CORE_SOURCE"] - ) + if "COV_CORE_SOURCE" in os.environ: + os.environ["COV_CORE_SOURCE"] = os.path.abspath( + os.environ["COV_CORE_SOURCE"] + ) @pytest.fixture diff --git a/src/backy/tests/test_backy.py b/src/backy/tests/test_backy.py index df8e19c4..7ee3eb10 100644 --- a/src/backy/tests/test_backy.py +++ b/src/backy/tests/test_backy.py @@ -4,7 +4,7 @@ import pytest import backy.backup -from backy.ext_deps import BASH +from backy.ext_deps import BACKY_CMD, BASH from backy.tests import Ellipsis @@ -107,7 +107,8 @@ def test_smoketest_internal(tmpdir, log): @pytest.mark.slow def test_smoketest_external(): output = subprocess.check_output( - [BASH, os.path.dirname(__file__) + "/../../../smoketest.sh"] + [BASH, os.path.dirname(__file__) + "/../../../smoketest.sh"], + env=os.environ | {"BACKY_CMD": BACKY_CMD}, ) output = output.decode("utf-8") assert (