Skip to content

Commit 2a8a795

Browse files
authored
Merge pull request #461 from avinxshKD/fix/ci-ruff-coverage-454
fix(ci): add ruff.toml, format check, coverage, merge tests.yml
2 parents c3b6f84 + 72f3653 commit 2a8a795

24 files changed

Lines changed: 1080 additions & 870 deletions

.github/workflows/ci.yml

Lines changed: 31 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -7,67 +7,58 @@ on:
77
branches: [main, dev]
88

99
jobs:
10-
lint-and-test:
10+
lint:
1111
runs-on: ubuntu-latest
12-
1312
steps:
14-
- name: Checkout repository
15-
uses: actions/checkout@v4
13+
- uses: actions/checkout@v4
1614

17-
- name: Set up Python
18-
uses: actions/setup-python@v5
15+
- uses: actions/setup-python@v5
1916
with:
2017
python-version: '3.11'
2118
cache: 'pip'
2219

20+
- name: Install ruff
21+
run: pip install ruff
22+
23+
- name: Check formatting
24+
run: ruff format --check .
25+
26+
- name: Lint
27+
run: ruff check . --output-format=github
28+
29+
test:
30+
runs-on: ubuntu-latest
31+
strategy:
32+
matrix:
33+
python-version: ['3.9', '3.10', '3.11', '3.12']
34+
35+
steps:
36+
- uses: actions/checkout@v4
37+
38+
- uses: actions/setup-python@v5
39+
with:
40+
python-version: ${{ matrix.python-version }}
41+
cache: 'pip'
42+
2343
- name: Install dependencies
2444
run: |
2545
python -m pip install --upgrade pip
2646
pip install -r requirements-ci.txt
27-
# Uses minimal CI requirements (no tensorflow/heavy packages)
2847
29-
- name: Run linter (ruff)
48+
- name: Run tests
3049
run: |
31-
ruff check . --select=E9,F63,F7,F82 --output-format=github \
32-
--exclude="Dockerfile.*" \
33-
--exclude="linktest/" \
34-
--exclude="measurements/" \
35-
--exclude="0mq/" \
36-
--exclude="ratc/"
37-
# E9: Runtime errors (syntax errors, etc.)
38-
# F63: Invalid print syntax
39-
# F7: Syntax errors in type comments
40-
# F82: Undefined names in __all__
41-
# Excludes: Dockerfiles (not Python), linktest (symlinks),
42-
# measurements/0mq/ratc (config-dependent experimental scripts)
43-
44-
- name: Run tests (pytest)
45-
run: |
46-
set +e
4750
pytest --tb=short -q \
51+
--cov=concore_cli --cov=concore_base \
52+
--cov-report=term-missing \
4853
--ignore=measurements/ \
4954
--ignore=0mq/ \
5055
--ignore=ratc/ \
5156
--ignore=linktest/
52-
status=$?
53-
set -e
54-
# Allow success if no tests are collected (pytest exit code 5)
55-
if [ "$status" -ne 0 ] && [ "$status" -ne 5 ]; then
56-
exit "$status"
57-
fi
58-
# Fails on real test failures, passes on no tests collected
5957
6058
docker-build:
6159
runs-on: ubuntu-latest
62-
# Only run when Dockerfile.py or related files change
63-
if: |
64-
github.event_name == 'push' ||
65-
(github.event_name == 'pull_request' &&
66-
contains(github.event.pull_request.changed_files, 'Dockerfile'))
67-
6860
steps:
69-
- name: Checkout repository
70-
uses: actions/checkout@v4
61+
- uses: actions/checkout@v4
7162

7263
- name: Check if Dockerfile.py changed
7364
uses: dorny/paths-filter@v3
@@ -80,7 +71,4 @@ jobs:
8071
8172
- name: Validate Dockerfile build
8273
if: steps.filter.outputs.dockerfile == 'true'
83-
run: |
84-
docker build -f Dockerfile.py -t concore-py-test .
85-
# Validates that Dockerfile.py can be built successfully
86-
# Does not push the image
74+
run: docker build -f Dockerfile.py -t concore-py-test .

.github/workflows/tests.yml

Lines changed: 0 additions & 33 deletions
This file was deleted.

.pre-commit-config.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
repos:
2+
- repo: https://github.com/astral-sh/ruff-pre-commit
3+
rev: v0.11.12
4+
hooks:
5+
- id: ruff
6+
args: [--output-format=full]
7+
- id: ruff-format

concore_cli/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22

33
from .cli import cli
44

5-
__all__ = ['cli']
5+
__all__ = ["cli"]

concore_cli/cli.py

Lines changed: 36 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,18 @@
1313
from . import __version__
1414

1515
console = Console()
16-
DEFAULT_EXEC_TYPE = 'windows' if os.name == 'nt' else 'posix'
16+
DEFAULT_EXEC_TYPE = "windows" if os.name == "nt" else "posix"
17+
1718

1819
@click.group()
19-
@click.version_option(version=__version__, prog_name='concore')
20+
@click.version_option(version=__version__, prog_name="concore")
2021
def cli():
2122
pass
2223

24+
2325
@cli.command()
24-
@click.argument('name', required=True)
25-
@click.option('--template', default='basic', help='Template type to use')
26+
@click.argument("name", required=True)
27+
@click.option("--template", default="basic", help="Template type to use")
2628
def init(name, template):
2729
"""Create a new concore project"""
2830
try:
@@ -31,12 +33,21 @@ def init(name, template):
3133
console.print(f"[red]Error:[/red] {str(e)}")
3234
sys.exit(1)
3335

36+
3437
@cli.command()
35-
@click.argument('workflow_file', type=click.Path(exists=True))
36-
@click.option('--source', '-s', default='src', help='Source directory')
37-
@click.option('--output', '-o', default='out', help='Output directory')
38-
@click.option('--type', '-t', default=DEFAULT_EXEC_TYPE, type=click.Choice(['windows', 'posix', 'docker']), help='Execution type')
39-
@click.option('--auto-build', is_flag=True, help='Automatically run build after generation')
38+
@click.argument("workflow_file", type=click.Path(exists=True))
39+
@click.option("--source", "-s", default="src", help="Source directory")
40+
@click.option("--output", "-o", default="out", help="Output directory")
41+
@click.option(
42+
"--type",
43+
"-t",
44+
default=DEFAULT_EXEC_TYPE,
45+
type=click.Choice(["windows", "posix", "docker"]),
46+
help="Execution type",
47+
)
48+
@click.option(
49+
"--auto-build", is_flag=True, help="Automatically run build after generation"
50+
)
4051
def run(workflow_file, source, output, type, auto_build):
4152
"""Run a concore workflow"""
4253
try:
@@ -45,9 +56,10 @@ def run(workflow_file, source, output, type, auto_build):
4556
console.print(f"[red]Error:[/red] {str(e)}")
4657
sys.exit(1)
4758

59+
4860
@cli.command()
49-
@click.argument('workflow_file', type=click.Path(exists=True))
50-
@click.option('--source', '-s', default='src', help='Source directory')
61+
@click.argument("workflow_file", type=click.Path(exists=True))
62+
@click.option("--source", "-s", default="src", help="Source directory")
5163
def validate(workflow_file, source):
5264
"""Validate a workflow file"""
5365
try:
@@ -58,10 +70,11 @@ def validate(workflow_file, source):
5870
console.print(f"[red]Error:[/red] {str(e)}")
5971
sys.exit(1)
6072

73+
6174
@cli.command()
62-
@click.argument('workflow_file', type=click.Path(exists=True))
63-
@click.option('--source', '-s', default='src', help='Source directory')
64-
@click.option('--json', 'output_json', is_flag=True, help='Output in JSON format')
75+
@click.argument("workflow_file", type=click.Path(exists=True))
76+
@click.option("--source", "-s", default="src", help="Source directory")
77+
@click.option("--json", "output_json", is_flag=True, help="Output in JSON format")
6578
def inspect(workflow_file, source, output_json):
6679
"""Inspect a workflow file and show its structure"""
6780
try:
@@ -70,6 +83,7 @@ def inspect(workflow_file, source, output_json):
7083
console.print(f"[red]Error:[/red] {str(e)}")
7184
sys.exit(1)
7285

86+
7387
@cli.command()
7488
def status():
7589
"""Show running concore processes"""
@@ -79,8 +93,9 @@ def status():
7993
console.print(f"[red]Error:[/red] {str(e)}")
8094
sys.exit(1)
8195

96+
8297
@cli.command()
83-
@click.confirmation_option(prompt='Stop all running concore processes?')
98+
@click.confirmation_option(prompt="Stop all running concore processes?")
8499
def stop():
85100
"""Stop all running concore processes"""
86101
try:
@@ -89,10 +104,11 @@ def stop():
89104
console.print(f"[red]Error:[/red] {str(e)}")
90105
sys.exit(1)
91106

107+
92108
@cli.command()
93-
@click.argument('study_dir', type=click.Path(exists=True))
94-
@click.option('--interval', '-n', default=2.0, help='Refresh interval in seconds')
95-
@click.option('--once', is_flag=True, help='Print a single snapshot and exit')
109+
@click.argument("study_dir", type=click.Path(exists=True))
110+
@click.option("--interval", "-n", default=2.0, help="Refresh interval in seconds")
111+
@click.option("--once", is_flag=True, help="Print a single snapshot and exit")
96112
def watch(study_dir, interval, once):
97113
"""Watch a running simulation study for live monitoring"""
98114
try:
@@ -101,5 +117,6 @@ def watch(study_dir, interval, once):
101117
console.print(f"[red]Error:[/red] {str(e)}")
102118
sys.exit(1)
103119

104-
if __name__ == '__main__':
120+
121+
if __name__ == "__main__":
105122
cli()

concore_cli/commands/__init__.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,11 @@
55
from .stop import stop_all
66
from .watch import watch_study
77

8-
__all__ = ['init_project', 'run_workflow', 'validate_workflow', 'show_status', 'stop_all', 'watch_study']
8+
__all__ = [
9+
"init_project",
10+
"run_workflow",
11+
"validate_workflow",
12+
"show_status",
13+
"stop_all",
14+
"watch_study",
15+
]

concore_cli/commands/init.py

Lines changed: 32 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
1-
import os
2-
import shutil
31
from pathlib import Path
42
from rich.panel import Panel
53

6-
SAMPLE_GRAPHML = '''<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
4+
SAMPLE_GRAPHML = """<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
75
<graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://www.yworks.com/xml/schema/graphml/1.1/ygraphml.xsd" xmlns:y="http://www.yworks.com/xml/graphml">
86
<key for="node" id="d6" yfiles.type="nodegraphics"/>
97
<key for="edge" id="d10" yfiles.type="edgegraphics"/>
@@ -21,9 +19,9 @@
2119
</node>
2220
</graph>
2321
</graphml>
24-
'''
22+
"""
2523

26-
SAMPLE_PYTHON = '''import concore
24+
SAMPLE_PYTHON = """import concore
2725
2826
concore.default_maxtime(100)
2927
concore.delay = 0.02
@@ -36,9 +34,9 @@
3634
val = concore.read(1,"data",init_simtime_val)
3735
result = [v * 2 for v in val]
3836
concore.write(1,"result",result,delta=0)
39-
'''
37+
"""
4038

41-
README_TEMPLATE = '''# {project_name}
39+
README_TEMPLATE = """# {project_name}
4240
4341
A concore workflow project.
4442
@@ -63,38 +61,41 @@
6361
- Add Python/C++/MATLAB scripts to `src/`
6462
- Use `concore validate workflow.graphml` to check your workflow
6563
- Use `concore status` to monitor running processes
66-
'''
64+
"""
65+
6766

6867
def init_project(name, template, console):
6968
project_path = Path(name)
70-
69+
7170
if project_path.exists():
7271
raise FileExistsError(f"Directory '{name}' already exists")
73-
72+
7473
console.print(f"[cyan]Creating project:[/cyan] {name}")
75-
74+
7675
project_path.mkdir()
77-
(project_path / 'src').mkdir()
78-
79-
workflow_file = project_path / 'workflow.graphml'
80-
with open(workflow_file, 'w') as f:
76+
(project_path / "src").mkdir()
77+
78+
workflow_file = project_path / "workflow.graphml"
79+
with open(workflow_file, "w") as f:
8180
f.write(SAMPLE_GRAPHML)
82-
83-
sample_script = project_path / 'src' / 'script.py'
84-
with open(sample_script, 'w') as f:
81+
82+
sample_script = project_path / "src" / "script.py"
83+
with open(sample_script, "w") as f:
8584
f.write(SAMPLE_PYTHON)
86-
87-
readme_file = project_path / 'README.md'
88-
with open(readme_file, 'w') as f:
85+
86+
readme_file = project_path / "README.md"
87+
with open(readme_file, "w") as f:
8988
f.write(README_TEMPLATE.format(project_name=name))
90-
89+
9190
console.print()
92-
console.print(Panel.fit(
93-
f"[green]✓[/green] Project created successfully!\n\n"
94-
f"Next steps:\n"
95-
f" cd {name}\n"
96-
f" concore validate workflow.graphml\n"
97-
f" concore run workflow.graphml",
98-
title="Success",
99-
border_style="green"
100-
))
91+
console.print(
92+
Panel.fit(
93+
f"[green]✓[/green] Project created successfully!\n\n"
94+
f"Next steps:\n"
95+
f" cd {name}\n"
96+
f" concore validate workflow.graphml\n"
97+
f" concore run workflow.graphml",
98+
title="Success",
99+
border_style="green",
100+
)
101+
)

0 commit comments

Comments
 (0)