From 24b503706010fe87cd0f0156c18661168939392b Mon Sep 17 00:00:00 2001 From: "quant-ranger[bot]" <132915763+quant-ranger[bot]@users.noreply.github.com> Date: Mon, 16 Mar 2026 00:14:00 +0000 Subject: [PATCH] chore: Update copier template to v0.5.1 --- .claude/CLAUDE.md | 1 + .copier-answers.yml | 2 +- .github/dependabot.yml | 2 + .github/workflows/build.yml | 37 ++++++++++- .github/workflows/ci.yml | 66 +++++++++++++++++++ .github/workflows/scorecard.yml | 6 ++ .lefthook.yaml | 49 ++++++++++++++ .pre-commit-config.yaml | 110 -------------------------------- AGENTS.md | 5 ++ pixi.toml | 34 +++++++--- pyproject.toml | 20 +++++- 11 files changed, 211 insertions(+), 121 deletions(-) create mode 120000 .claude/CLAUDE.md create mode 100644 .lefthook.yaml delete mode 100644 .pre-commit-config.yaml create mode 100644 AGENTS.md diff --git a/.claude/CLAUDE.md b/.claude/CLAUDE.md new file mode 120000 index 00000000..be77ac83 --- /dev/null +++ b/.claude/CLAUDE.md @@ -0,0 +1 @@ +../AGENTS.md \ No newline at end of file diff --git a/.copier-answers.yml b/.copier-answers.yml index db27a863..8001b08c 100644 --- a/.copier-answers.yml +++ b/.copier-answers.yml @@ -1,5 +1,5 @@ # This file is managed by Copier; DO NOT EDIT OR REMOVE. -_commit: v0.4.1 +_commit: v0.5.1 _src_path: https://github.com/quantco/copier-template-python-open-source add_autobump_workflow: false author_email: oliver.borchert@quantco.com diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 63fc30c1..32553f89 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -10,3 +10,5 @@ updates: - "*" commit-message: prefix: ci + cooldown: + default-days: 7 diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 407a6866..6558219e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -17,13 +17,42 @@ jobs: with: fetch-depth: 0 - name: Set up pixi +<<<<<<< before updating uses: prefix-dev/setup-pixi@a0af7a228712d6121d37aba47adf55c1332c9c2e # v0.9.4 with: environments: build - name: Set version run: pixi run -e build set-version +||||||| last update + uses: prefix-dev/setup-pixi@19eac09b398e3d0c747adc7921926a6d802df4da # v0.8.8 + with: + environments: build +======= + uses: prefix-dev/setup-pixi@a0af7a228712d6121d37aba47adf55c1332c9c2e # v0.9.4 + - name: Derive version + id: version + if: startsWith(github.ref, 'refs/tags/') + shell: bash + run: echo "version=$(git describe --tags --abbrev=0 | sed 's/^v//')" >> $GITHUB_OUTPUT + - name: Replace version + if: startsWith(github.ref, 'refs/tags/') + run: | + sed -i -e "s/0.0.0/${STEPS_VERSION_OUTPUTS_VERSION}/g" pyproject.toml + env: + STEPS_VERSION_OUTPUTS_VERSION: ${{ steps.version.outputs.version }} +>>>>>>> after updating - name: Build project +<<<<<<< before updating run: pixi run -e build build-sdist +||||||| last update + run: pixi run -e build build-wheel + - name: Check package + run: pixi run check-wheel +======= + run: pixi run build-wheel + - name: Check package + run: pixi run check-wheel +>>>>>>> after updating - name: Upload package uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: @@ -68,7 +97,7 @@ jobs: manylinux: auto sccache: true - name: Check package - run: pixi run -e build check-wheel + run: pixi run check-wheel - name: Upload package uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: @@ -84,7 +113,13 @@ jobs: id-token: write environment: pypi steps: +<<<<<<< before updating - uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8.0.0 +||||||| last update + - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0 +======= + - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 +>>>>>>> after updating with: path: dist merge-multiple: true diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4badb746..cc1ba84d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,17 +13,31 @@ permissions: contents: read jobs: +<<<<<<< before updating pre-commit-checks: name: Pre-commit Checks +||||||| last update + pre-commit: +======= + lint: + name: Lint +>>>>>>> after updating timeout-minutes: 30 runs-on: ubuntu-latest steps: - name: Checkout branch +<<<<<<< before updating uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: # needed for 'pre-commit-mirrors-insert-license' fetch-depth: 0 +||||||| last update + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 +======= + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 +>>>>>>> after updating - name: Set up pixi +<<<<<<< before updating uses: prefix-dev/setup-pixi@a0af7a228712d6121d37aba47adf55c1332c9c2e # v0.9.4 with: environments: default lint polars-minimal @@ -33,6 +47,19 @@ jobs: uses: Swatinem/rust-cache@779680da715d629ac1d338a641029a2f4372abb5 # v2.8.2 - name: pre-commit run: pixi run pre-commit-run --color=always --show-diff-on-failure +||||||| last update + uses: prefix-dev/setup-pixi@19eac09b398e3d0c747adc7921926a6d802df4da # v0.8.8 + with: + environments: default lint + - name: pre-commit + run: pixi run pre-commit-run --color=always --show-diff-on-failure +======= + uses: prefix-dev/setup-pixi@a0af7a228712d6121d37aba47adf55c1332c9c2e # v0.9.4 + - name: Run linting + run: pixi run lint + env: + CLICOLOR_FORCE: 1 +>>>>>>> after updating unit-tests: name: Unit Tests (${{ contains(matrix.os, 'ubuntu') && 'Linux' || (contains(matrix.os, 'windows') && 'Windows' || 'macOS') }}) - ${{ matrix.environment }} @@ -41,6 +68,7 @@ jobs: strategy: fail-fast: true matrix: +<<<<<<< before updating os: [ubuntu-latest, windows-latest, macos-latest] environment: [py310, py311, py312, py313, py314] with_optionals: [false] @@ -59,13 +87,46 @@ jobs: - os: ubuntu-latest environment: polars-minimal with_optionals: false +||||||| last update + environment: + - py310 + - py311 + - py312 + - py313 + os: + - ubuntu-latest + - macos-latest + - windows-latest +======= + environment: + - py310 + - py311 + - py312 + - py313 + - py314 + os: + - ubuntu-latest + - macos-latest + - windows-latest +>>>>>>> after updating steps: - name: Checkout branch +<<<<<<< before updating + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 +||||||| last update + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + fetch-depth: 0 +======= uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + fetch-depth: 0 +>>>>>>> after updating - name: Set up pixi uses: prefix-dev/setup-pixi@a0af7a228712d6121d37aba47adf55c1332c9c2e # v0.9.4 with: environments: ${{ matrix.environment }} +<<<<<<< before updating # FIXME: Remove when `s3_server` fixture does not start a process anymore post-cleanup: ${{ matrix.os != 'windows-latest' }} - name: Install Rust @@ -74,6 +135,11 @@ jobs: uses: Swatinem/rust-cache@779680da715d629ac1d338a641029a2f4372abb5 # v2.8.2 - name: Install repository run: pixi run -e ${{ matrix.environment }} postinstall +||||||| last update + - name: Install repository + run: pixi run -e ${{ matrix.environment }} postinstall +======= +>>>>>>> after updating - name: Run pytest run: pixi run -e ${{ matrix.environment }} test-coverage --color=yes ${{ matrix.with_optionals && '-m with_optionals' || '-m "not with_optionals"'}} --cov=dataframely --cov-report=xml - name: Upload codecov diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 097b5b08..218231bb 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -74,6 +74,12 @@ jobs: # Upload the results to GitHub's code scanning dashboard (optional). # Commenting out will disable upload of results to your repo's Code Scanning dashboard - name: "Upload to code-scanning" +<<<<<<< before updating uses: github/codeql-action/upload-sarif@89a39a4e59826350b863aa6b6252a07ad50cf83e # v3.29.5 +||||||| last update + uses: github/codeql-action/upload-sarif@ff0a06e83cb2de871e5a09832bc6a81e7276941f # v3.28.18 +======= + uses: github/codeql-action/upload-sarif@0d579ffd059c29b07949a3cce3983f0780820c98 # v4.32.6 +>>>>>>> after updating with: sarif_file: results.sarif diff --git a/.lefthook.yaml b/.lefthook.yaml new file mode 100644 index 00000000..68ca3c37 --- /dev/null +++ b/.lefthook.yaml @@ -0,0 +1,49 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/evilmartians/lefthook/refs/heads/master/schema.json +output: [summary] +templates: + run: run --quiet --no-progress +no_auto_install: true +pre-commit: + fail_on_changes: always + exclude: + - assets/**/* + jobs: + - name: pixi-install + run: pixi install + - group: + parallel: true + jobs: + - name: ruff-check + glob: "*.{py,pyi}" + run: pixi {run} ruff check --fix --exit-non-zero-on-fix --force-exclude + - name: ruff-format + glob: "*.{py,pyi}" + run: pixi {run} ruff format --force-exclude + - name: mypy + glob: "*.py" + run: pixi {run} mypy {staged_files} + - name: prettier + glob: "*.{md,yml,yaml}" + run: pixi {run} prettier --write --no-error-on-unmatched-pattern --list-different --ignore-unknown {staged_files} + - name: taplo + glob: "*.toml" + run: pixi {run} taplo format {staged_files} + - name: trailing-whitespace-fixer + glob: "*" + file_types: text + run: pixi {run} trailing-whitespace-fixer {staged_files} + - name: end-of-file-fixer + glob: "*" + file_types: text + run: pixi {run} end-of-file-fixer {staged_files} + - name: check-merge-conflict + glob: "*" + file_types: text + run: pixi {run} check-merge-conflict --assume-in-merge {staged_files} + - name: typos + glob: "*" + file_types: text + run: pixi {run} typos --force-exclude {staged_files} + - name: zizmor + glob: "*.{yml,yaml}" + run: pixi {run} zizmor --no-progress --min-severity high --fix . diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml deleted file mode 100644 index 2fb87a65..00000000 --- a/.pre-commit-config.yaml +++ /dev/null @@ -1,110 +0,0 @@ -exclude: ^(\.copier-answers\.yml)|.pixi$ -repos: - - repo: local - hooks: - # ensure pixi environments are up to date - # workaround for https://github.com/prefix-dev/pixi/issues/1482 - - id: pixi-install - name: pixi-install - entry: pixi install -e default -e lint -e polars-minimal - language: system - always_run: true - require_serial: true - pass_filenames: false - # insert-license - - id: insert-license - name: insert-license - entry: >- - pixi run -e lint - insert-license - --license-base64 Q29weXJpZ2h0IChjKSBRdWFudENvIDIwMjUtMjAyNQpTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQlNELTMtQ2xhdXNl - --dynamic-years - --comment-style "#" - language: system - types: [python] - # docformatter - - id: docformatter - name: docformatter - entry: pixi run -e lint docformatter -i - language: system - types: [python] - # ruff - - id: ruff - name: ruff - entry: pixi run -e lint ruff check --fix --exit-non-zero-on-fix --force-exclude - language: system - types_or: [python, pyi] - require_serial: true - - id: ruff-format - name: ruff-format - entry: pixi run -e lint ruff format --force-exclude - language: system - types_or: [python, pyi] - require_serial: true - # mypy - - id: mypy - name: mypy - entry: pixi run -e default mypy - language: system - types: [python] - require_serial: true - # mypy with oldest supported polars version - - id: mypy - name: mypy-polars-minimal - entry: pixi run -e default-polars-minimal mypy --cache-dir .mypy_cache_polars_minimal - language: system - types: [python] - require_serial: true - # cargo-fmt - - id: cargo-fmt - name: cargo-fmt - entry: cargo fmt - language: system - types: [rust] - require_serial: true - pass_filenames: false - # cargo-clippy - - id: cargo-clippy - name: cargo-clippy - entry: cargo clippy --all-targets - language: system - types: [rust] - require_serial: true - pass_filenames: false - # prettier - - id: prettier - name: prettier - entry: pixi run -e lint prettier --write --list-different --ignore-unknown - language: system - types: [text] - files: \.(md|yml|yaml)$ - # taplo - - id: taplo - name: taplo - entry: pixi run -e lint taplo format - language: system - types: [toml] - # pre-commit-hooks - - id: trailing-whitespace-fixer - name: trailing-whitespace-fixer - entry: pixi run -e lint trailing-whitespace-fixer - language: system - types: [text] - - id: end-of-file-fixer - name: end-of-file-fixer - entry: pixi run -e lint end-of-file-fixer - language: system - types: [text] - - id: check-merge-conflict - name: check-merge-conflict - entry: pixi run -e lint check-merge-conflict --assume-in-merge - language: system - types: [text] - exclude: \.rst$ - # typos - - id: typos - name: typos - entry: pixi run -e lint typos --force-exclude - language: system - types: [text] - require_serial: true diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 00000000..5b31c3c8 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,5 @@ +Lockfiles must be consistent with package metadata. After any change to `pixi.toml`, run `pixi lock`. + +Everything runs in a pixi environment. Any command (like `pytest`) must be prefixed with `pixi run` (e.g. `pixi run pytest`). + +Code formatting must align with our standards. Run `pixi run lint` before `git commit`s to ensure this. diff --git a/pixi.toml b/pixi.toml index 855b3bc3..be0e64bf 100644 --- a/pixi.toml +++ b/pixi.toml @@ -10,6 +10,7 @@ postinstall-release = "pip install --no-build-isolation --no-deps --disable-pip- [dependencies] python = ">=3.10" +hatchling = "*" fsspec = ">=2025.9" numpy = "*" @@ -36,6 +37,7 @@ sphinx = ">=8.2" sphinx-copybutton = "*" sphinx-design = "*" sphinx-toolbox = "*" + [feature.docs.tasks] docs = { cmd = "rm -rf _build && find . -name _gen -type d -exec rm -rf \"{}\" + && sphinx-build -M html . _build --fail-on-warning", cwd = "docs", depends-on = "postinstall" } readthedocs = { cmd = "rm -rf $READTHEDOCS_OUTPUT/html && cp -r docs/_build/html $READTHEDOCS_OUTPUT/html", depends-on = "docs" } @@ -47,7 +49,7 @@ mypy = ">=1.13" pandas = "*" pandas-stubs = "*" pyodbc = "*" -pytest = ">=6" +pytest = "*" pytest-benchmark = "*" pytest-cov = "*" pytest-md = "*" @@ -69,10 +71,12 @@ pydantic-core = ">=2.33.2,<3" sqlalchemy = ">=2" [feature.build.dependencies] +python = "*" +hatchling = "*" python-build = "*" -setuptools-scm = "*" -twine = "*" -wheel = "*" +version = "*" +twine = ">=6" + [feature.build.target.unix.dependencies] sed = "*" @@ -83,7 +87,7 @@ check-wheel = "twine check dist/*" set-version = "sed -i \"s/0.0.0/$(python -m setuptools_scm)/\" pyproject.toml" [feature.lint.dependencies] -docformatter = "*" +lefthook = "*" insert-license-header = "*" pre-commit = "*" pre-commit-hooks = "*" @@ -91,9 +95,11 @@ prettier = "*" ruff = "*" taplo = "*" typos = "*" +zizmor = "*" + [feature.lint.tasks] -pre-commit-install = "pre-commit install" -pre-commit-run = "pre-commit run -a" +pre-commit-install = "lefthook install" +lint = "lefthook run pre-commit --all-files" [feature.py310.dependencies] python = "3.10.*" @@ -111,6 +117,9 @@ python = "3.13.*" [feature.py314.dependencies] python = "3.14.*" +[feature.py314.dependencies] +python = "3.14.*" + [feature.polars-minimal.dependencies] # NOTE: Update docs/faq.md when updating this. polars = "1.35.*" @@ -123,7 +132,14 @@ polars = "1.38.*" install-polars-nightly = "pip install --pre --no-deps --upgrade --only-binary :all: polars polars-runtime-32" [environments] +<<<<<<< before updating build = ["build"] +py314 = ["polars-latest", "py314", "test"] +||||||| last update +build = ["build"] +======= +py314 = ["py314", "test"] +>>>>>>> after updating default = ["dev", "lint", "optionals", "polars-latest", "py314", "test"] docs = ["docs"] lint = { features = ["lint"], no-default-feature = true } @@ -134,7 +150,6 @@ py310 = ["polars-latest", "py310", "test"] py311 = ["polars-latest", "py311", "test"] py312 = ["polars-latest", "py312", "test"] py313 = ["polars-latest", "py313", "test"] -py314 = ["polars-latest", "py314", "test"] # Test with optional dependencies py314-optionals = ["optionals", "polars-latest", "py314", "test"] @@ -149,3 +164,6 @@ default-polars-minimal = [ "test", ] polars-minimal = ["polars-minimal", "py314", "test"] + +[dependencies] +dataframely = { path = "." } diff --git a/pyproject.toml b/pyproject.toml index a13adb65..b7218fd2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,13 +1,31 @@ [build-system] +<<<<<<< before updating build-backend = "maturin" -requires = ["maturin>=1.7,<2.0"] +||||||| last update +======= +build-backend = "hatchling.build" +>>>>>>> after updating +requires = ["maturin>=1.7,<2.0", "hatchling"] [project] +<<<<<<< before updating authors = [ { name = "Andreas Albert", email = "andreas.albert@quantco.com" }, { name = "Daniel Elsner", email = "daniel.elsner@quantco.com" }, { name = "Oliver Borchert", email = "oliver.borchert@quantco.com" }, ] +||||||| last update +name = "dataframely" +description = "A declarative, polars-native data frame validation library" +authors = [{ name = "Oliver Borchert", email = "oliver.borchert@quantco.com" }] +dynamic = ["version"] +======= +name = "dataframely" +description = "A declarative, polars-native data frame validation library" +authors = [{ name = "Oliver Borchert", email = "oliver.borchert@quantco.com" }] +# replaced in CI +version = "0.0.0" +>>>>>>> after updating classifiers = [ "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.10",