Skip to content

Commit ed7a981

Browse files
authored
update workflows and unit tests (#84)
now uses the following reusable workflows: - pre-commit.yml - py-coverage.yml ## Adjusting Unit tests - codecov-action v4 now requires a CODECOV token (which I added to repo secrets) - `test_download_file` was passing unexpectedly (should have expectedly failed for `"latest"` release_tag). - `test_path_warning` wouldn't pass when run in a venv (which is how I run tests locally). - `test_get_sha` was using outdated sha512sum for Windows. - CI now runs unit tests on all 3 OS and the reusable workflow will combine coverage data for the coverage reports. * update pre-commit hooks; switch to ruff for linting and formatting in a pre-commit hook * improve test runtime and coverage - now includes test code in coverage - does not download every supported version just to trigger lines in coverage data; only 1 version will suffice. - only download clang-format when testing `install_tool()` because it gets same coverage and downloads faster on all supported platforms.
1 parent fdb016d commit ed7a981

15 files changed

+110
-77
lines changed

.github/workflows/bump-version.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
import requests
22
import sys
3-
sys.path.append('../../')
4-
from clang_tools import release_tag
3+
4+
sys.path.append("../../")
5+
from clang_tools import release_tag # noqa E402
56

67

78
def get_latest_tag() -> str:
8-
response = requests.get("https://github.com/api/repos/cpp-linter/clang-tools-static-binaries/releases/latest")
9-
return response.json()['tag_name']
9+
response = requests.get(
10+
"https://github.com/api/repos/cpp-linter/clang-tools-static-binaries/releases/latest"
11+
)
12+
return response.json()["tag_name"]
1013

1114

1215
def update_tag(current_tag, latest_tag) -> None:
@@ -16,7 +19,7 @@ def update_tag(current_tag, latest_tag) -> None:
1619

1720
updated_content = file_content.replace(current_tag, latest_tag)
1821

19-
with open(file_path, 'w') as file:
22+
with open(file_path, "w") as file:
2023
file.write(updated_content)
2124

2225

.github/workflows/python-publish.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ name: Upload Python Package
1010

1111
on:
1212
release:
13-
branches: [main]
1413
types: [published]
1514
workflow_dispatch:
1615

.github/workflows/python-test.yml

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,12 @@ on:
1717

1818

1919
jobs:
20-
build:
21-
runs-on: ubuntu-latest
20+
test:
21+
strategy:
22+
matrix:
23+
os: [ ubuntu-latest, macos-latest, windows-latest ]
24+
fail-fast: false
25+
runs-on: ${{ matrix.os }}
2226
steps:
2327
- uses: actions/checkout@v4
2428

@@ -32,20 +36,29 @@ jobs:
3236
python3 -m pip install --upgrade pip
3337
python3 -m pip install . -r requirements-dev.txt
3438
35-
- name: Run pre-commit
36-
run: pre-commit run --all-files
39+
- name: Collect Coverage
40+
run: coverage run -m pytest -vv
3741

38-
- name: Collect coverage
39-
run: |
40-
coverage run -m pytest -vv
41-
coverage report -m
42-
coverage xml
42+
- name: Upload coverage data
43+
uses: actions/upload-artifact@v4
44+
with:
45+
name: coverage-data-${{ runner.os }}
46+
path: .coverage*
4347

44-
- name: Upload coverage reports to Codecov
45-
uses: codecov/codecov-action@v4
48+
coverage-report:
49+
needs: [test]
50+
uses: cpp-linter/.github/.github/workflows/py-coverage.yml@main
51+
secrets: inherit
52+
53+
build:
54+
runs-on: ubuntu-latest
55+
steps:
56+
- uses: actions/checkout@v4
57+
58+
- name: Set up Python 3.10
59+
uses: actions/setup-python@v5
4660
with:
47-
files: ./coverage.xml
48-
verbose: true # optional (default = false)
61+
python-version: "3.10"
4962

5063
- name: Build wheel
5164
run: python -m pip wheel -w dist .

.github/workflows/run-pre-commit.yml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
name: Run pre-commit
2+
3+
on:
4+
push:
5+
pull_request:
6+
types: opened
7+
8+
jobs:
9+
pre-commit:
10+
uses: cpp-linter/.github/.github/workflows/pre-commit.yml@main

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ clang_tools.egg-info
44
clang_tools/__pycache__
55
dist
66
clang_tools/llvm-project*
7-
.coverage
7+
.coverage*
88
coverage.xml
99
htmlcov/
1010
.vscode/

.pre-commit-config.yaml

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,14 @@ repos:
1212
- id: debug-statements
1313
- id: requirements-txt-fixer
1414
- repo: https://github.com/asottile/pyupgrade
15-
rev: v3.15.0
15+
rev: v3.15.1
1616
hooks:
1717
- id: pyupgrade
18-
- repo: https://github.com/pycqa/flake8
19-
rev: '7.0.0'
18+
- repo: https://github.com/astral-sh/ruff-pre-commit
19+
rev: v0.2.2
2020
hooks:
21-
- id: flake8
22-
args: [--max-line-length=120]
23-
exclude: ^(.github/workflows/bump-version.py)
21+
- id: ruff
22+
- id: ruff-format
2423
# - repo: local
2524
# hooks:
2625
# - id: pytest

clang_tools/install.py

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -39,33 +39,32 @@ def is_installed(tool_name: str, version: str) -> Optional[Path]:
3939
)
4040
try:
4141
result = subprocess.run(
42-
[exe_name, "--version"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, check=True
42+
[exe_name, "--version"],
43+
stdout=subprocess.PIPE,
44+
stderr=subprocess.PIPE,
45+
check=True,
4346
)
4447
except (FileNotFoundError, subprocess.CalledProcessError):
4548
return None # tool is not installed
4649
ver_num = RE_PARSE_VERSION.search(result.stdout)
4750
print(
4851
f"Found a installed version of {tool_name}:",
4952
ver_num.groups(0)[0].decode(encoding="utf-8"),
50-
end=" "
53+
end=" ",
5154
)
5255
path = shutil.which(exe_name) # find the installed binary
5356
if path is None:
5457
print() # print end-of-line
5558
return None # failed to locate the binary
5659
path = Path(path).resolve()
5760
print("at", str(path))
58-
ver_num = ver_num.groups(0)[0].decode(encoding="utf-8").split(".") # pragma: no cover
59-
if (
60-
ver_num is None or ver_num[0] != ver_major
61-
):
61+
ver_num = ver_num.groups(0)[0].decode(encoding="utf-8").split(".")
62+
if ver_num is None or ver_num[0] != ver_major:
6263
return None # version is unknown or not the desired major release
6364
return path
6465

6566

66-
def clang_tools_binary_url(
67-
tool: str, version: str, tag: str = release_tag
68-
) -> str:
67+
def clang_tools_binary_url(tool: str, version: str, tag: str = release_tag) -> str:
6968
"""Assemble the URL to the binary.
7069
7170
:param tool: The name of the tool to download.

clang_tools/main.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ def get_parser() -> argparse.ArgumentParser:
2323
parser.add_argument(
2424
"-t",
2525
"--tool",
26-
nargs='+',
27-
default=['clang-format', 'clang-tidy'],
26+
nargs="+",
27+
default=["clang-format", "clang-tidy"],
2828
metavar="TOOL",
2929
help="Specify which tool(s) to install.",
3030
)
@@ -67,12 +67,16 @@ def main():
6767
uninstall_clang_tools(args.uninstall, args.directory)
6868
if args.install:
6969
install_clang_tools(
70-
args.install, args.tool, args.directory, args.overwrite, args.no_progress_bar
70+
args.install,
71+
args.tool,
72+
args.directory,
73+
args.overwrite,
74+
args.no_progress_bar,
7175
)
7276
else:
7377
print(
7478
f"{YELLOW}Nothing to do because `--install` and `--uninstall`",
75-
f"was not specified.{RESET_COLOR}"
79+
f"was not specified.{RESET_COLOR}",
7680
)
7781
parser.print_help()
7882

clang_tools/util.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ def download_file(url: str, file_name: str, no_progress_bar: bool) -> Optional[s
4848
return None
4949
assert response.length is not None
5050
length = response.length
51-
buffer = b''
51+
buffer = b""
5252
progress_bar = "=" if check_install_os() == "windows" else "█"
5353
while len(buffer) < length:
5454
block_size = int(length / 20)

docs/conf.py

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
"sphinx.ext.intersphinx",
3838
]
3939

40-
intersphinx_mapping = {'python': ('https://docs.python.org/3', None)}
40+
intersphinx_mapping = {"python": ("https://docs.python.org/3", None)}
4141

4242
# Add any paths that contain templates here, relative to this directory.
4343
templates_path = ["_templates"]
@@ -78,7 +78,7 @@
7878
"toggle": {
7979
"icon": "material/lightbulb-outline",
8080
"name": "Switch to dark mode",
81-
}
81+
},
8282
},
8383
{
8484
"media": "(prefers-color-scheme: dark)",
@@ -88,7 +88,7 @@
8888
"toggle": {
8989
"icon": "material/lightbulb",
9090
"name": "Switch to light mode",
91-
}
91+
},
9292
},
9393
],
9494
"features": [
@@ -98,7 +98,7 @@
9898
"toc.sticky",
9999
"toc.follow",
100100
"search.share",
101-
]
101+
],
102102
}
103103

104104
object_description_options = [
@@ -122,9 +122,7 @@ def setup(app: Sphinx):
122122
if arg.default != "==SUPPRESS==":
123123
doc += f" :Default: ``{repr(arg.default)}``\n\n"
124124
description = (
125-
""
126-
if arg.help is None
127-
else " %s\n" % (arg.help.replace('\n', '\n '))
125+
"" if arg.help is None else " %s\n" % (arg.help.replace("\n", "\n "))
128126
)
129127
doc += description
130128
cli_doc = Path(app.srcdir, "cli_args.rst")

0 commit comments

Comments
 (0)