Skip to content

Commit 1be45da

Browse files
committed
fix(ci): add ruff.toml, format check, coverage, merge tests.yml, fix bare excepts (#454)
1 parent 5d46e60 commit 1be45da

30 files changed

Lines changed: 2571 additions & 1796 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.py

Lines changed: 35 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,33 @@
1-
import time
1+
import time # noqa: F401
22
import logging
33
import os
44
import atexit
5-
from ast import literal_eval
5+
from ast import literal_eval # noqa: F401
66
import sys
7-
import re
8-
import zmq
9-
import numpy as np
7+
import re # noqa: F401
8+
import zmq # noqa: F401
9+
import numpy as np # noqa: F401
1010
import signal
1111

1212
import concore_base
1313

14-
logger = logging.getLogger('concore')
14+
logger = logging.getLogger("concore")
1515
logger.addHandler(logging.NullHandler())
1616

17-
#these lines mute the noisy library
18-
logging.getLogger('matplotlib').setLevel(logging.WARNING)
19-
logging.getLogger('PIL').setLevel(logging.WARNING)
20-
logging.getLogger('urllib3').setLevel(logging.WARNING)
21-
logging.getLogger('requests').setLevel(logging.WARNING)
17+
# these lines mute the noisy library
18+
logging.getLogger("matplotlib").setLevel(logging.WARNING)
19+
logging.getLogger("PIL").setLevel(logging.WARNING)
20+
logging.getLogger("urllib3").setLevel(logging.WARNING)
21+
logging.getLogger("requests").setLevel(logging.WARNING)
2222

2323

24-
# if windows, create script to kill this process
24+
# if windows, create script to kill this process
2525
# because batch files don't provide easy way to know pid of last command
2626
# ignored for posix != windows, because "concorepid" is handled by script
2727
# ignored for docker (linux != windows), because handled by docker stop
28-
if hasattr(sys, 'getwindowsversion'):
29-
with open("concorekill.bat","w") as fpid:
30-
fpid.write("taskkill /F /PID "+str(os.getpid())+"\n")
28+
if hasattr(sys, "getwindowsversion"):
29+
with open("concorekill.bat", "w") as fpid:
30+
fpid.write("taskkill /F /PID " + str(os.getpid()) + "\n")
3131

3232
ZeroMQPort = concore_base.ZeroMQPort
3333
convert_numpy_to_python = concore_base.convert_numpy_to_python
@@ -38,17 +38,19 @@
3838
zmq_ports = {}
3939
_cleanup_in_progress = False
4040

41-
s = ''
42-
olds = ''
41+
s = ""
42+
olds = ""
4343
delay = 1
4444
retrycount = 0
45-
inpath = "./in" #must be rel path for local
45+
inpath = "./in" # must be rel path for local
4646
outpath = "./out"
4747
simtime = 0
4848

49+
4950
def _port_path(base, port_num):
5051
return base + str(port_num)
5152

53+
5254
concore_params_file = os.path.join(_port_path(inpath, 1), "concore.params")
5355
concore_maxtime_file = os.path.join(_port_path(inpath, 1), "concore.maxtime")
5456

@@ -58,16 +60,19 @@ def _port_path(base, port_num):
5860

5961
_mod = sys.modules[__name__]
6062

63+
6164
# ===================================================================
6265
# ZeroMQ Communication Wrapper
6366
# ===================================================================
6467
def init_zmq_port(port_name, port_type, address, socket_type_str):
6568
concore_base.init_zmq_port(_mod, port_name, port_type, address, socket_type_str)
6669

70+
6771
def terminate_zmq():
6872
"""Clean up all ZMQ sockets and contexts before exit."""
6973
concore_base.terminate_zmq(_mod)
7074

75+
7176
def signal_handler(sig, frame):
7277
"""Handle interrupt signals gracefully."""
7378
print(f"\nReceived signal {sig}, shutting down gracefully...")
@@ -78,20 +83,23 @@ def signal_handler(sig, frame):
7883
concore_base.terminate_zmq(_mod)
7984
sys.exit(0)
8085

86+
8187
# Register cleanup handlers
8288
atexit.register(terminate_zmq)
83-
signal.signal(signal.SIGINT, signal_handler) # Handle Ctrl+C
84-
if not hasattr(sys, 'getwindowsversion'):
89+
signal.signal(signal.SIGINT, signal_handler) # Handle Ctrl+C
90+
if not hasattr(sys, "getwindowsversion"):
8591
signal.signal(signal.SIGTERM, signal_handler) # Handle termination (Unix only)
8692

8793
params = concore_base.load_params(concore_params_file)
8894

89-
#9/30/22
95+
96+
# 9/30/22
9097
def tryparam(n, i):
9198
"""Return parameter `n` from params dict, else default `i`."""
9299
return params.get(n, i)
93100

94-
#9/12/21
101+
102+
# 9/12/21
95103
# ===================================================================
96104
# Simulation Time Handling
97105
# ===================================================================
@@ -100,12 +108,15 @@ def default_maxtime(default):
100108
global maxtime
101109
maxtime = safe_literal_eval(concore_maxtime_file, default)
102110

111+
103112
default_maxtime(100)
104113

114+
105115
def unchanged():
106116
"""Check if global string `s` is unchanged since last call."""
107117
return concore_base.unchanged(_mod)
108118

119+
109120
# ===================================================================
110121
# I/O Handling (File + ZMQ)
111122
# ===================================================================
@@ -116,5 +127,6 @@ def read(port_identifier, name, initstr_val):
116127
def write(port_identifier, name, val, delta=0):
117128
concore_base.write(_mod, port_identifier, name, val, delta)
118129

119-
def initval(simtime_val_str):
130+
131+
def initval(simtime_val_str):
120132
return concore_base.initval(_mod, simtime_val_str)

0 commit comments

Comments
 (0)