Skip to content

Commit 79966be

Browse files
committed
RF: improve cli management and introduce typer
1 parent 7826577 commit 79966be

36 files changed

Lines changed: 3307 additions & 1876 deletions

.github/workflows/codeformat.yml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
name: Code Format
2+
3+
on:
4+
push:
5+
branches: [master]
6+
pull_request:
7+
branches: [master]
8+
9+
permissions:
10+
contents: read
11+
12+
jobs:
13+
pre-commit:
14+
name: Pre-commit checks
15+
runs-on: ubuntu-latest
16+
17+
steps:
18+
- name: Check out repository
19+
uses: actions/checkout@v4
20+
21+
- name: Set up Python
22+
uses: actions/setup-python@v5
23+
with:
24+
python-version: "3.12"
25+
26+
- name: Install and run pre-commit hooks
27+
uses: pre-commit/action@v3.0.1

.github/workflows/coverage.yml

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
name: Coverage
2+
3+
on:
4+
push:
5+
branches: [master]
6+
pull_request:
7+
branches: [master]
8+
9+
permissions:
10+
contents: read
11+
12+
jobs:
13+
coverage:
14+
name: Code Coverage
15+
runs-on: ubuntu-latest
16+
17+
steps:
18+
- name: Check out repository
19+
uses: actions/checkout@v4
20+
with:
21+
fetch-depth: 0
22+
23+
- name: Set up Python
24+
uses: actions/setup-python@v5
25+
with:
26+
python-version: "3.12"
27+
cache: pip
28+
cache-dependency-path: pyproject.toml
29+
30+
- name: Install dependencies
31+
run: |
32+
python -m pip install --upgrade pip
33+
python -m pip install -e .[test]
34+
35+
- name: Run tests with coverage
36+
run: |
37+
pytest trx/tests --cov=trx --cov-report=xml --cov-report=term-missing
38+
39+
- name: Upload coverage to Codecov
40+
uses: codecov/codecov-action@v4
41+
with:
42+
files: ./coverage.xml
43+
flags: unittests
44+
name: codecov-trx
45+
fail_ci_if_error: false
46+
verbose: true
47+
env:
48+
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}

.github/workflows/publish-to-test-pypi.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,10 @@ jobs:
1616
- uses: actions/checkout@v4
1717
with:
1818
fetch-depth: 0 # Fetch all history and tags for setuptools_scm
19-
- name: Set up Python 3.9
19+
- name: Set up Python 3.11
2020
uses: actions/setup-python@v5
2121
with:
22-
python-version: 3.9
22+
python-version: "3.11"
2323
- name: Install pypa/build
2424
run: python -m pip install build --user
2525
- name: Build a binary wheel and a source tarball

.github/workflows/test.yml

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ jobs:
1616
strategy:
1717
fail-fast: false
1818
matrix:
19-
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
19+
python-version: ["3.11", "3.12", "3.13"]
2020
os: [ubuntu-latest, windows-latest, macos-latest]
2121
steps:
2222
- uses: actions/checkout@v4
@@ -35,8 +35,5 @@ jobs:
3535
python -m pip install --upgrade pip
3636
python -m pip install -e .[dev,test]
3737
38-
- name: Lint
39-
run: spin lint
40-
4138
- name: Test
4239
run: spin test

.pre-commit-config.yaml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
default_language_version:
2+
python: python3
3+
4+
repos:
5+
- repo: https://github.com/astral-sh/ruff-pre-commit
6+
rev: v0.8.6
7+
hooks:
8+
# Run the linter
9+
- id: ruff
10+
args: [ --fix ]
11+
# Run the formatter
12+
- id: ruff-format
13+
- repo: https://github.com/codespell-project/codespell
14+
rev: v2.3.0
15+
hooks:
16+
- id: codespell
17+
args: [--skip, "pyproject.toml,docs/_build/*,*.egg-info"]
18+
additional_dependencies:
19+
- tomli

.spin/cmds.py

Lines changed: 59 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,21 @@
11
"""Custom spin commands for trx-python development."""
2+
3+
import glob
24
import os
5+
import shutil
36
import subprocess
47
import sys
58
import tempfile
6-
import glob
7-
import shutil
89

910
import click
1011

11-
1212
UPSTREAM_URL = "https://github.com/tee-ar-ex/trx-python.git"
1313
UPSTREAM_NAME = "upstream"
1414

1515

1616
def run(cmd, check=True, capture=True):
1717
"""Run a shell command."""
18-
result = subprocess.run(
19-
cmd,
20-
capture_output=capture,
21-
text=True,
22-
check=False
23-
)
18+
result = subprocess.run(cmd, capture_output=capture, text=True, check=False)
2419
if check and result.returncode != 0:
2520
if capture:
2621
click.echo(f"Error: {result.stderr}", err=True)
@@ -81,14 +76,15 @@ def setup():
8176
click.echo("\nVerifying version detection...")
8277
try:
8378
from setuptools_scm import get_version
79+
8480
version = get_version()
8581
click.echo(f"Detected version: {version}")
8682

8783
# Check for suspicious version patterns
8884
if version.startswith("0.0"):
8985
click.echo(
9086
"\nWarning: Version starts with 0.0 - tags may not be fetched.",
91-
err=True
87+
err=True,
9288
)
9389
sys.exit(1)
9490
except ImportError:
@@ -101,13 +97,13 @@ def setup():
10197

10298
@click.command()
10399
@click.option(
104-
"-m", "--match", "pattern", default=None,
105-
help="Only run tests matching this pattern (passed to pytest -k)"
106-
)
107-
@click.option(
108-
"-v", "--verbose", is_flag=True, default=False,
109-
help="Verbose output"
100+
"-m",
101+
"--match",
102+
"pattern",
103+
default=None,
104+
help="Only run tests matching this pattern (passed to pytest -k)",
110105
)
106+
@click.option("-v", "--verbose", is_flag=True, default=False, help="Verbose output")
111107
@click.argument("pytest_args", nargs=-1)
112108
def test(pattern, verbose, pytest_args):
113109
"""Run tests using pytest.
@@ -120,7 +116,7 @@ def test(pattern, verbose, pytest_args):
120116
spin test -v # Verbose output
121117
spin test -- -x --tb=short # Pass args to pytest
122118
"""
123-
cmd = ["pytest", "trx/tests", "scripts/tests"]
119+
cmd = ["pytest", "trx/tests"]
124120

125121
if pattern:
126122
cmd.extend(["-k", pattern])
@@ -137,46 +133,60 @@ def test(pattern, verbose, pytest_args):
137133

138134
@click.command()
139135
@click.option(
140-
"--fix", is_flag=True, default=False,
141-
help="Currently unused (for future auto-fix support)"
136+
"--fix", is_flag=True, default=False, help="Automatically fix issues where possible"
142137
)
143138
def lint(fix):
144-
"""Run linting checks using flake8.
139+
"""Run linting checks using ruff and codespell.
145140
146141
Examples:
147-
spin lint # Run flake8 checks
142+
spin lint # Run ruff and codespell checks
143+
spin lint --fix # Run ruff and auto-fix issues
148144
"""
149-
# Strict check for syntax errors
150-
click.echo("Checking for syntax errors...")
151-
cmd_strict = [
152-
"flake8", ".", "--count",
153-
"--select=E9,F63,F7,F82",
154-
"--show-source", "--statistics"
155-
]
156-
result = run(cmd_strict, capture=False, check=False)
145+
click.echo("Running ruff linter...")
146+
cmd = ["ruff", "check", "."]
147+
148+
if fix:
149+
cmd.append("--fix")
150+
151+
result = run(cmd, capture=False, check=False)
152+
if result != 0:
153+
click.echo("\nLinting issues found!", err=True)
154+
sys.exit(1)
155+
156+
click.echo("\nRunning ruff formatter check...")
157+
cmd_format = ["ruff", "format", "--check", "."]
158+
result = run(cmd_format, capture=False, check=False)
157159
if result != 0:
158-
click.echo("Syntax errors found!", err=True)
160+
click.echo("\nFormatting issues found!", err=True)
159161
sys.exit(1)
160162

161-
# Full lint check
162-
click.echo("\nRunning full lint check...")
163-
cmd_full = [
164-
"flake8", ".", "--count",
165-
"--max-line-length=88",
166-
"--max-complexity=10",
167-
"--statistics"
163+
click.echo("\nRunning codespell...")
164+
cmd_spell = [
165+
"codespell",
166+
"--skip",
167+
"*.pyc,.git,pyproject.toml,./docs/_build/*,*.egg-info,./build/*,./dist/*,./tmp/*",
168+
"trx",
169+
"docs/source",
170+
".spin",
168171
]
169-
sys.exit(run(cmd_full, capture=False, check=False))
172+
result = run(cmd_spell, capture=False, check=False)
173+
if result != 0:
174+
click.echo("\nSpelling issues found!", err=True)
175+
sys.exit(1)
176+
177+
click.echo("\nAll checks passed!")
170178

171179

172180
@click.command()
173181
@click.option(
174-
"--clean", is_flag=True, default=False,
175-
help="Clean build directory before building"
182+
"--clean", is_flag=True, default=False, help="Clean build directory before building"
176183
)
177184
@click.option(
178-
"--open", "open_browser", is_flag=True, default=False,
179-
help="Open documentation in browser after building"
185+
"--open",
186+
"open_browser",
187+
is_flag=True,
188+
default=False,
189+
help="Open documentation in browser after building",
180190
)
181191
def docs(clean, open_browser):
182192
"""Build documentation using Sphinx.
@@ -187,13 +197,15 @@ def docs(clean, open_browser):
187197
spin docs --open # Build and open in browser
188198
"""
189199
import os
200+
190201
docs_dir = "docs"
191202

192203
if clean:
193204
click.echo("Cleaning build directory...")
194205
build_dir = os.path.join(docs_dir, "_build")
195206
if os.path.exists(build_dir):
196207
import shutil
208+
197209
shutil.rmtree(build_dir)
198210

199211
click.echo("Building documentation...")
@@ -209,6 +221,7 @@ def docs(clean, open_browser):
209221

210222
if open_browser:
211223
import webbrowser
224+
212225
webbrowser.open(f"file://{index_path}")
213226

214227
sys.exit(result)
@@ -220,16 +233,16 @@ def clean(): # noqa: C901
220233
click.echo("Cleaning up temporary files...")
221234

222235
# Clean TRX temp directory
223-
trx_tmp_dir = os.getenv('TRX_TMPDIR', tempfile.gettempdir())
236+
trx_tmp_dir = os.getenv("TRX_TMPDIR", tempfile.gettempdir())
224237
if os.path.exists(trx_tmp_dir):
225-
temp_files = glob.glob(os.path.join(trx_tmp_dir, 'trx_*'))
238+
temp_files = glob.glob(os.path.join(trx_tmp_dir, "trx_*"))
226239
for temp_dir in temp_files:
227240
if os.path.isdir(temp_dir):
228241
click.echo(f"Removing temporary directory: {temp_dir}")
229242
shutil.rmtree(temp_dir)
230243

231244
# Clean build artifacts
232-
for build_pattern in ['build', 'dist', '*.egg-info']:
245+
for build_pattern in ["build", "dist", "*.egg-info"]:
233246
for path in glob.glob(build_pattern):
234247
if os.path.isdir(path):
235248
click.echo(f"Removing build directory: {path}")
@@ -239,7 +252,7 @@ def clean(): # noqa: C901
239252
os.remove(path)
240253

241254
# Clean Python cache
242-
for cache_dir in ['**/__pycache__', '**/.pytest_cache']:
255+
for cache_dir in ["**/__pycache__", "**/.pytest_cache"]:
243256
for path in glob.glob(cache_dir, recursive=True):
244257
if os.path.isdir(path):
245258
click.echo(f"Removing cache directory: {path}")

0 commit comments

Comments
 (0)