diff --git a/.claude/CLAUDE.md b/.claude/CLAUDE.md new file mode 120000 index 0000000..be77ac8 --- /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 421d62f..7892b74 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 3891848..549c9f0 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -8,3 +8,5 @@ updates: gh-actions: patterns: - "*" + cooldown: + default-days: 7 diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 8088e3f..11bbcfd 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -17,12 +17,21 @@ jobs: fetch-depth: 0 - name: Set up pixi uses: prefix-dev/setup-pixi@a0af7a228712d6121d37aba47adf55c1332c9c2e # v0.9.4 - with: - environments: build + - 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 }} - name: Build project - run: pixi run -e build build-wheel + run: pixi run build-wheel - 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: @@ -38,7 +47,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: name: artifact path: dist diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 99d2eb3..5d8c7f1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,18 +13,33 @@ permissions: contents: read jobs: - pre-commit: + lint: + name: Lint timeout-minutes: 30 runs-on: ubuntu-latest steps: - name: Checkout branch uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Set up pixi +<<<<<<< before updating uses: prefix-dev/setup-pixi@a0af7a228712d6121d37aba47adf55c1332c9c2e # v0.9.4 with: environments: default lint - 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 pytest: timeout-minutes: 30 @@ -40,6 +55,7 @@ jobs: strategy: fail-fast: false matrix: +<<<<<<< before updating environment: [py311, py312, py313] database: [sqlite, mssql, duckdb] include: @@ -49,6 +65,26 @@ jobs: connection-string: mssql+pyodbc://sa:Passw0rd@localhost:1433/master?driver=ODBC+Driver+18+for+SQL+Server&Encrypt=no - database: duckdb connection-string: duckdb:///test.duckdb +||||||| last update + environment: + - py311 + - py312 + - py313 + os: + - ubuntu-latest + - macos-latest + - windows-latest +======= + environment: + - py311 + - py312 + - py313 + - py314 + os: + - ubuntu-latest + - macos-latest + - windows-latest +>>>>>>> after updating steps: - name: Checkout branch uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -61,9 +97,15 @@ jobs: uses: prefix-dev/setup-pixi@a0af7a228712d6121d37aba47adf55c1332c9c2e # v0.9.4 with: environments: ${{ matrix.environment }} +<<<<<<< before updating activate-environment: true - name: Install repository run: pixi run postinstall +||||||| last update + - name: Install repository + run: pixi run -e ${{ matrix.environment }} postinstall +======= +>>>>>>> after updating - name: Run pytest run: pixi run test-coverage --color=yes env: diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index ca9a186..efe8496 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 0000000..68ca3c3 --- /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 06b9034..0000000 --- a/.pre-commit-config.yaml +++ /dev/null @@ -1,80 +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 - language: system - always_run: true - require_serial: true - pass_filenames: false - - id: insert-license - name: insert-license - entry: pixi run -e lint insert-license - types: [python] - language: system - args: - - --license-base64 - - Q29weXJpZ2h0IChjKSBRdWFudENvIDIwMjQtMjAyNApTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQlNELTMtQ2xhdXNl - - --dynamic-years - - --comment-style - - "#" - # 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 - # 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] - # 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 0000000..5b31c3c --- /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 cac2d08..43e9e80 100644 --- a/pixi.toml +++ b/pixi.toml @@ -1,13 +1,31 @@ +<<<<<<< before updating [project] +||||||| last update +[project] +name = "sqlcompyre" +======= +[workspace] +name = "sqlcompyre" +>>>>>>> after updating channels = ["conda-forge"] +<<<<<<< before updating name = "sqlcompyre" platforms = ["linux-64", "osx-64", "osx-arm64"] +||||||| last update +platforms = ["osx-arm64", "osx-64", "linux-64", "win-64"] +======= +platforms = ["osx-arm64", "osx-64", "linux-64", "win-64"] +preview = ["pixi-build"] +>>>>>>> after updating -[tasks] -postinstall = "pip install --no-build-isolation --no-deps --disable-pip-version-check -e ." - -[dependencies] +[package] +name = "sqlcompyre" +[package.build.backend] +name = "pixi-build-python" +version = "*" +[package.host-dependencies] python = ">=3.11" +<<<<<<< before updating # Dependencies click = "*" pydantic = ">=2.0" @@ -22,7 +40,12 @@ unixodbc = "*" # Database Dependencies: DuckDB duckdb-engine = "*" python-duckdb = "*" +||||||| last update +======= +hatchling = "*" +>>>>>>> after updating +<<<<<<< before updating [host-dependencies] pip = "*" setuptools = ">=61" @@ -38,8 +61,25 @@ sphinxcontrib-apidoc = "*" [feature.docs.tasks] docs = "cd docs && make html" readthedocs = "rm -rf $READTHEDOCS_OUTPUT/html && cp -r docs/_build/html $READTHEDOCS_OUTPUT/html" +||||||| last update +[host-dependencies] +pip = "*" +setuptools = ">=61" +setuptools-scm = "*" +======= +[dependencies] +sqlcompyre = { path = "." } +>>>>>>> after updating [feature.test.dependencies] +<<<<<<< before updating +||||||| last update +pytest = ">=6" +pytest-cov = "*" +======= +pytest = "*" +pytest-cov = "*" +>>>>>>> after updating mypy = "*" pandas = "*" polars = "*" @@ -55,25 +95,37 @@ test = "python -m pytest" test-coverage = "python -m pytest --cov=sqlcompyre --cov-report=xml --cov-report=term-missing" [feature.build.dependencies] +python = "*" +hatchling = "*" python-build = "*" -twine = "*" -wheel = "*" +twine = ">=6" [feature.build.tasks] build-wheel = "python -m build --no-isolation ." check-wheel = "twine check dist/*" [feature.lint.dependencies] +<<<<<<< before updating docformatter = "*" insert-license-header = "*" pre-commit = "*" pre-commit-hooks = "*" +||||||| last update +pre-commit = "*" +insert-license-header = "*" +docformatter = "*" +ruff = "*" +======= +lefthook = "*" +ruff = "*" +>>>>>>> after updating 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.py311.dependencies] python = "3.11.*" @@ -81,12 +133,27 @@ python = "3.11.*" python = "3.12.*" [feature.py313.dependencies] python = "3.13.*" +[feature.py314.dependencies] +python = "3.14.*" [environments] +<<<<<<< before updating build = ["build"] default = ["test"] docs = ["docs"] lint = { features = ["lint"], no-default-feature = true } +||||||| last update +default = ["test"] +======= +default = ["test", "build", "lint"] +>>>>>>> after updating py311 = ["py311", "test"] py312 = ["py312", "test"] py313 = ["py313", "test"] +<<<<<<< before updating +||||||| last update +build = ["build"] +lint = { features = ["lint"], no-default-feature = true } +======= +py314 = ["py314", "test"] +>>>>>>> after updating diff --git a/pyproject.toml b/pyproject.toml index 44aef42..c20053d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,16 +1,22 @@ [build-system] -requires = ["setuptools", "setuptools-scm", "wheel"] - -[tool.setuptools_scm] -version_scheme = "post-release" +requires = ["hatchling"] +build-backend = "hatchling.build" [project] authors = [{ name = "Oliver Borchert", email = "oliver.borchert@quantco.com" }] +<<<<<<< before updating +||||||| last update +dynamic = ["version"] +======= +# replaced in CI +version = "0.0.0" +>>>>>>> after updating classifiers = [ "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14", ] dependencies = [ "click",