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 e1a99be..8cb5769 100644 --- a/.copier-answers.yml +++ b/.copier-answers.yml @@ -1,12 +1,12 @@ # 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: noreply@quantco.com author_name: QuantCo, Inc. github_url: https://github.com/quantco/multiregex github_user: pavelzw -minimal_python_version: py39 +minimal_python_version: py310 project_short_description: Quickly match many regexes against a string. Provides 2-10x speedups over naïve regex matching. project_slug: multiregex diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 49b9ad3..3af1f39 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -10,3 +10,5 @@ updates: gh-actions: patterns: - "*" + cooldown: + default-days: 7 diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 2897906..743a5cd 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -18,14 +18,29 @@ 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 +<<<<<<< before updating uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 +||||||| last update + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 +======= + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 +>>>>>>> after updating with: name: artifact path: dist/* @@ -39,7 +54,13 @@ jobs: id-token: write environment: pypi steps: +<<<<<<< before updating - uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.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 4c6dfef..07ed671 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,7 +14,8 @@ permissions: contents: read jobs: - pre-commit: + lint: + name: Lint timeout-minutes: 30 runs-on: ubuntu-latest steps: @@ -22,10 +23,10 @@ jobs: uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Set up pixi 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 + - name: Run linting + run: pixi run lint + env: + CLICOLOR_FORCE: 1 pytest: timeout-minutes: 30 @@ -34,11 +35,11 @@ jobs: fail-fast: false matrix: environment: - - py39 - py310 - py311 - py312 - py313 + - py314 os: - ubuntu-latest - macos-latest @@ -52,7 +53,5 @@ jobs: uses: prefix-dev/setup-pixi@a0af7a228712d6121d37aba47adf55c1332c9c2e # v0.9.4 with: environments: ${{ matrix.environment }} - - name: Install repository - run: pixi run -e ${{ matrix.environment }} postinstall - name: Run pytest run: pixi run -e ${{ matrix.environment }} test-coverage --color=yes diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index a84ba91..a962fea 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -65,7 +65,13 @@ jobs: # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF # format to the repository Actions tab. - name: "Upload artifact" +<<<<<<< before updating uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 +||||||| last update + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 +======= + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 +>>>>>>> after updating with: name: SARIF file path: results.sarif @@ -74,6 +80,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@b20883b0cd1f46c72ae0ba6d1090936928f9fa30 # v4.32.0 +||||||| 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 e8c3e32..0000000 --- a/.pre-commit-config.yaml +++ /dev/null @@ -1,69 +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 - # 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 9d3af01..6a5f4aa 100644 --- a/pixi.toml +++ b/pixi.toml @@ -1,22 +1,30 @@ -[project] +[workspace] name = "multiregex" channels = ["conda-forge"] platforms = ["osx-arm64", "osx-64", "linux-64", "win-64"] +preview = ["pixi-build"] -[tasks] -postinstall = "pip install --no-build-isolation --no-deps --disable-pip-version-check -e ." +[package] +name = "multiregex" +[package.build.backend] +name = "pixi-build-python" +version = "*" +[package.host-dependencies] +python = ">=3.10" +hatchling = "*" [dependencies] -python = ">=3.9" +multiregex = { path = "." } pyahocorasick = "*" -[host-dependencies] -pip = "*" -setuptools = ">=61" -setuptools-scm = "*" - [feature.test.dependencies] +<<<<<<< before updating pytest = ">=6,<8" +||||||| last update +pytest = ">=6" +======= +pytest = "*" +>>>>>>> after updating pytest-cov = "*" mypy = "*" [feature.test.tasks] @@ -24,28 +32,26 @@ test = "pytest" test-coverage = "pytest --cov=multiregex --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] -pre-commit = "*" -insert-license-header = "*" -docformatter = "*" +lefthook = "*" ruff = "*" prettier = "*" taplo = "*" pre-commit-hooks = "*" 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.py39.dependencies] -python = "3.9.*" [feature.py310.dependencies] python = "3.10.*" [feature.py311.dependencies] @@ -54,13 +60,13 @@ python = "3.11.*" python = "3.12.*" [feature.py313.dependencies] python = "3.13.*" +[feature.py314.dependencies] +python = "3.14.*" [environments] -default = ["test"] -py39 = ["py39", "test"] +default = ["test", "build", "lint"] py310 = ["py310", "test"] py311 = ["py311", "test"] py312 = ["py312", "test"] py313 = ["py313", "test"] -build = ["build"] -lint = { features = ["lint"], no-default-feature = true } +py314 = ["py314", "test"] diff --git a/pyproject.toml b/pyproject.toml index 4e957fc..ff4956d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,8 +1,6 @@ [build-system] -requires = ["setuptools", "setuptools-scm", "wheel"] - -[tool.setuptools_scm] -version_scheme = "post-release" +requires = ["hatchling"] +build-backend = "hatchling.build" [project] name = "multiregex" @@ -11,17 +9,18 @@ authors = [ { name = "QuantCo, Inc.", email = "noreply@quantco.com" }, { name = "Jonas Haag", email = "jonas@lophus.org" }, ] -dynamic = ["version"] +# replaced in CI +version = "0.0.0" maintainers = [{ name = "Bela Stoyan", email = "bela.stoyan@quantco.com" }] classifiers = [ "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14", ] -requires-python = ">=3.9" +requires-python = ">=3.10" readme = "README.md" dependencies = ["pyahocorasick"] @@ -61,7 +60,7 @@ quote-style = "double" indent-style = "space" [tool.mypy] -python_version = '3.9' +python_version = '3.10' no_implicit_optional = true check_untyped_defs = true allow_redefinition = true