diff --git a/.forgejo/workflows/pull-request.yml b/.forgejo/workflows/pull-request.yml new file mode 100644 index 0000000..0ebf982 --- /dev/null +++ b/.forgejo/workflows/pull-request.yml @@ -0,0 +1,38 @@ +on: + pull_request: + workflow_dispatch: + +jobs: + static-analysis: + runs-on: runner-latest + steps: + - uses: actions/checkout@v4 + - name: Linting + run: pipx run pre-commit run ruff -a + - name: Format + run: pipx run pre-commit run ruff-format -a + - name: Validate Yaml + run: pipx run pre-commit run check-yaml -a + - name: Validate shell scripts + run: pipx run pre-commit run shellcheck -a + tests: + runs-on: runner-latest + steps: + - uses: actions/checkout@v4 + - uses: https://github.com/astral-sh/setup-uv@v3 + - name: Tests + run: | + uv venv + uv pip install . + pipx run pre-commit run pytest -a + export-trace: + runs-on: runner-latest + needs: [static-analysis] + steps: + - uses: https://forge.karnov.club/marc/opentelemetry-trace-export-forgejo-action@main + with: + otlp-endpoint: "http://otel.home.karnov.club:4318" + forgejo-token: ${{ secrets.GITHUB_TOKEN }} + forgejo-base-url: ${{ env.GITHUB_SERVER_URL }} + run-id: ${{ env.GITHUB_RUN_NUMBER }} + repo-name: ${{ env.GITHUB_REPOSITORY }} diff --git a/.forgejo/workflows/push.yml b/.forgejo/workflows/push.yml new file mode 100644 index 0000000..cf0992f --- /dev/null +++ b/.forgejo/workflows/push.yml @@ -0,0 +1,39 @@ +on: + workflow_dispatch: + push: + branches: [main] + +jobs: + static-analysis: + runs-on: runner-latest + steps: + - uses: actions/checkout@v4 + - name: Linting + run: pipx run pre-commit run ruff -a + - name: Format + run: pipx run pre-commit run ruff-format -a + - name: Validate Yaml + run: pipx run pre-commit run check-yaml -a + - name: Validate shell scripts + run: pipx run pre-commit run shellcheck -a + tests: + runs-on: runner-latest + steps: + - uses: actions/checkout@v4 + - uses: https://github.com/astral-sh/setup-uv@v3 + - name: Tests + run: | + uv venv + uv pip install . + pipx run pre-commit run pytest -a + export-trace: + runs-on: runner-latest + needs: [static-analysis] + steps: + - uses: https://forge.karnov.club/marc/opentelemetry-trace-export-forgejo-action@main + with: + otlp-endpoint: "http://otel.home.karnov.club:4318" + forgejo-token: ${{ secrets.GITHUB_TOKEN }} + forgejo-base-url: ${{ env.GITHUB_SERVER_URL }} + run-id: ${{ env.GITHUB_RUN_NUMBER }} + repo-name: ${{ env.GITHUB_REPOSITORY }} diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..5df8d5b --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,29 @@ +--- +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.6.0 + hooks: + - id: check-yaml + - repo: https://github.com/shellcheck-py/shellcheck-py + rev: v0.10.0.1 + hooks: + - id: shellcheck + - repo: https://github.com/pycqa/isort + rev: 5.13.2 + hooks: + - id: isort + - repo: local + hooks: + - id: pytest + name: pytest + description: 'Run tests with pytest' + entry: uv run pytest + language: python + types: [python] + require_serial: true + pass_filenames: false + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.7.0 + hooks: + - id: ruff + - id: ruff-format diff --git a/bootstrap.sh b/bootstrap.sh new file mode 100755 index 0000000..9b5446a --- /dev/null +++ b/bootstrap.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +uv pip install -e . + +uv run pre-commit install diff --git a/frg/cli.py b/frg/cli.py index 27dad69..32a229b 100644 --- a/frg/cli.py +++ b/frg/cli.py @@ -1,11 +1,11 @@ +import logging + import click import pydantic import frg.forgejo.browser as forgejo_browser -from frg.context import get_git_context, GitContext -from frg.configuration import get_configuration, Config - -import logging +from frg.configuration import Config, get_configuration +from frg.context import GitContext, get_git_context logger = logging.getLogger(__name__) diff --git a/frg/configuration.py b/frg/configuration.py index cf12e28..c6d42bd 100644 --- a/frg/configuration.py +++ b/frg/configuration.py @@ -4,11 +4,11 @@ Configuration file handling Takes care of parsing the configuration file if it exists. """ +import pathlib + import pydantic import yaml -import pathlib - class Config(pydantic.BaseModel): domain_aliases: dict[str, str] = pydantic.Field(default=dict()) diff --git a/frg/context.py b/frg/context.py index 27aaf9a..530463f 100644 --- a/frg/context.py +++ b/frg/context.py @@ -5,11 +5,11 @@ This module takes care of anything that needs to be pulled from the invocation environment (i.e. git context, ...) to make things work. """ -import pydantic - import logging import subprocess +import pydantic + logger = logging.getLogger(__name__) diff --git a/pyproject.toml b/pyproject.toml index 8664c9f..39b6512 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -27,6 +27,7 @@ packages = ["frg"] [tool.uv] dev-dependencies = [ + "pre-commit>=4.0.1", "pytest>=8.3.3", "ruff>=0.7.2", ] diff --git a/tests/test_configuration.py b/tests/test_configuration.py index a0ba2f6..6d5de1e 100644 --- a/tests/test_configuration.py +++ b/tests/test_configuration.py @@ -1,7 +1,7 @@ import pytest import yaml -from frg.configuration import get_configuration, Config +from frg.configuration import Config, get_configuration @pytest.fixture(autouse=True) diff --git a/tests/test_context.py b/tests/test_context.py index 9134eb5..c94afd3 100644 --- a/tests/test_context.py +++ b/tests/test_context.py @@ -1,7 +1,6 @@ -import pytest - import unittest.mock -import subprocess + +import pytest from frg.context import GitContext, get_git_context, parse_remote_url diff --git a/uv.lock b/uv.lock index 9021aab..77b3d77 100644 --- a/uv.lock +++ b/uv.lock @@ -36,6 +36,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/12/90/3c9ff0512038035f59d279fddeb79f5f1eccd8859f06d6163c58798b9487/certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8", size = 167321 }, ] +[[package]] +name = "cfgv" +version = "3.4.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/11/74/539e56497d9bd1d484fd863dd69cbbfa653cd2aa27abfe35653494d85e94/cfgv-3.4.0.tar.gz", hash = "sha256:e52591d4c5f5dead8e0f673fb16db7949d2cfb3f7da4582893288f0ded8fe560", size = 7114 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c5/55/51844dd50c4fc7a33b653bfaba4c2456f06955289ca770a5dbd5fd267374/cfgv-3.4.0-py2.py3-none-any.whl", hash = "sha256:b7265b1f29fd3316bfcd2b330d63d024f2bfd8bcb8b0272f8e19a504856c48f9", size = 7249 }, +] + [[package]] name = "click" version = "8.1.7" @@ -57,6 +66,24 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335 }, ] +[[package]] +name = "distlib" +version = "0.3.9" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/0d/dd/1bec4c5ddb504ca60fc29472f3d27e8d4da1257a854e1d96742f15c1d02d/distlib-0.3.9.tar.gz", hash = "sha256:a60f20dea646b8a33f3e7772f74dc0b2d0772d2837ee1342a00645c81edf9403", size = 613923 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/91/a1/cf2472db20f7ce4a6be1253a81cfdf85ad9c7885ffbed7047fb72c24cf87/distlib-0.3.9-py2.py3-none-any.whl", hash = "sha256:47f8c22fd27c27e25a65601af709b38e4f0a45ea4fc2e710f65755fa8caaaf87", size = 468973 }, +] + +[[package]] +name = "filelock" +version = "3.16.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/9d/db/3ef5bb276dae18d6ec2124224403d1d67bccdbefc17af4cc8f553e341ab1/filelock-3.16.1.tar.gz", hash = "sha256:c249fbfcd5db47e5e2d6d62198e565475ee65e4831e2561c8e313fa7eb961435", size = 18037 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b9/f8/feced7779d755758a52d1f6635d990b8d98dc0a29fa568bbe0625f18fdf3/filelock-3.16.1-py3-none-any.whl", hash = "sha256:2082e5703d51fbf98ea75855d9d5527e33d8ff23099bec374a134febee6946b0", size = 16163 }, +] + [[package]] name = "forge-tools" version = "0.0.0" @@ -70,6 +97,7 @@ dependencies = [ [package.dev-dependencies] dev = [ + { name = "pre-commit" }, { name = "pytest" }, { name = "ruff" }, ] @@ -84,6 +112,7 @@ requires-dist = [ [package.metadata.requires-dev] dev = [ + { name = "pre-commit", specifier = ">=4.0.1" }, { name = "pytest", specifier = ">=8.3.3" }, { name = "ruff", specifier = ">=0.7.2" }, ] @@ -126,6 +155,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/56/95/9377bcb415797e44274b51d46e3249eba641711cf3348050f76ee7b15ffc/httpx-0.27.2-py3-none-any.whl", hash = "sha256:7bb2708e112d8fdd7829cd4243970f0c223274051cb35ee80c03301ee29a3df0", size = 76395 }, ] +[[package]] +name = "identify" +version = "2.6.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/29/bb/25024dbcc93516c492b75919e76f389bac754a3e4248682fba32b250c880/identify-2.6.1.tar.gz", hash = "sha256:91478c5fb7c3aac5ff7bf9b4344f803843dc586832d5f110d672b19aa1984c98", size = 99097 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7d/0c/4ef72754c050979fdcc06c744715ae70ea37e734816bb6514f79df77a42f/identify-2.6.1-py2.py3-none-any.whl", hash = "sha256:53863bcac7caf8d2ed85bd20312ea5dcfc22226800f6d6881f232d861db5a8f0", size = 98972 }, +] + [[package]] name = "idna" version = "3.10" @@ -144,6 +182,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ef/a6/62565a6e1cf69e10f5727360368e451d4b7f58beeac6173dc9db836a5b46/iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374", size = 5892 }, ] +[[package]] +name = "nodeenv" +version = "1.9.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/43/16/fc88b08840de0e0a72a2f9d8c6bae36be573e475a6326ae854bcc549fc45/nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f", size = 47437 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d2/1d/1b658dbd2b9fa9c4c9f32accbfc0205d532c8c6194dc0f2a4c0428e7128a/nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9", size = 22314 }, +] + [[package]] name = "packaging" version = "24.1" @@ -153,6 +200,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/08/aa/cc0199a5f0ad350994d660967a8efb233fe0416e4639146c089643407ce6/packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124", size = 53985 }, ] +[[package]] +name = "platformdirs" +version = "4.3.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/13/fc/128cc9cb8f03208bdbf93d3aa862e16d376844a14f9a0ce5cf4507372de4/platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907", size = 21302 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3c/a6/bc1012356d8ece4d66dd75c4b9fc6c1f6650ddd5991e421177d9f8f671be/platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb", size = 18439 }, +] + [[package]] name = "pluggy" version = "1.5.0" @@ -162,6 +218,22 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/88/5f/e351af9a41f866ac3f1fac4ca0613908d9a41741cfcf2228f4ad853b697d/pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669", size = 20556 }, ] +[[package]] +name = "pre-commit" +version = "4.0.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cfgv" }, + { name = "identify" }, + { name = "nodeenv" }, + { name = "pyyaml" }, + { name = "virtualenv" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/2e/c8/e22c292035f1bac8b9f5237a2622305bc0304e776080b246f3df57c4ff9f/pre_commit-4.0.1.tar.gz", hash = "sha256:80905ac375958c0444c65e9cebebd948b3cdb518f335a091a670a89d652139d2", size = 191678 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/16/8f/496e10d51edd6671ebe0432e33ff800aa86775d2d147ce7d43389324a525/pre_commit-4.0.1-py2.py3-none-any.whl", hash = "sha256:efde913840816312445dc98787724647c65473daefe420785f885e8ed9a06878", size = 218713 }, +] + [[package]] name = "pydantic" version = "2.9.2" @@ -294,3 +366,17 @@ sdist = { url = "https://files.pythonhosted.org/packages/df/db/f35a00659bc03fec3 wheels = [ { url = "https://files.pythonhosted.org/packages/26/9f/ad63fc0248c5379346306f8668cda6e2e2e9c95e01216d2b8ffd9ff037d0/typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d", size = 37438 }, ] + +[[package]] +name = "virtualenv" +version = "20.27.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "distlib" }, + { name = "filelock" }, + { name = "platformdirs" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/8c/b3/7b6a79c5c8cf6d90ea681310e169cf2db2884f4d583d16c6e1d5a75a4e04/virtualenv-20.27.1.tar.gz", hash = "sha256:142c6be10212543b32c6c45d3d3893dff89112cc588b7d0879ae5a1ec03a47ba", size = 6491145 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ae/92/78324ff89391e00c8f4cf6b8526c41c6ef36b4ea2d2c132250b1a6fc2b8d/virtualenv-20.27.1-py3-none-any.whl", hash = "sha256:f11f1b8a29525562925f745563bfd48b189450f61fb34c4f9cc79dd5aa32a1f4", size = 3117838 }, +]