Skip to content

Commit 986aa38

Browse files
authored
Merge pull request #418 from Metaswitch/md/ruff
Add `ruff` for linting instead of flake8 and isort
2 parents 64c6cab + 271f752 commit 986aa38

File tree

13 files changed

+925
-993
lines changed

13 files changed

+925
-993
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ version number is tracked in the file `pyproject.toml`.
1111
### Breaking Changes
1212

1313
### Added
14+
- Add `ruff` for linting instead of flake8 and isort
15+
- Fix up associated errors
1416

1517
### Fixed
1618

CONTRIBUTING.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,8 @@ Ready to contribute? Here's how to set up `announcer` for local development.
7979

8080
Now you can make your changes locally.
8181

82-
5. When you're done making changes, check that your changes pass flake8 and the
83-
tests using tox.
82+
5. When you're done making changes, check that your changes pass Ruff and the
83+
tests using tox.
8484
8585
```shell
8686
$ tox
@@ -104,7 +104,7 @@ Before you submit a pull request, check that it meets these guidelines:
104104
2. If the pull request adds functionality, the docs should be updated. Put
105105
your new functionality into a function with a docstring, and add the
106106
feature to the list in README.md.
107-
3. The pull request should work for Python >=3.7.
107+
3. The pull request should work for Python >=3.10.
108108
109109
## Tips
110110

pyproject.toml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,19 +21,15 @@ announce = "announcer.__init__:main"
2121

2222
[dependency-groups]
2323
dev = [
24-
"pylint==4.0.5",
2524
"wheel==0.46.3",
2625
"mypy==1.19.1",
27-
"yamllint==1.38.0",
28-
"bandit==1.9.4",
2926
"pytest==8.4.2",
30-
"flake8==7.3.0",
3127
"werkzeug==3.1.7",
3228
"pytest-httpserver==1.1.5",
3329
"tox==4.51.0",
3430
"pytest-cov==7.1.0",
3531
"types-requests>=2.32.0,<3",
36-
"isort==7.0.0",
32+
"ruff>=0.15.8,<0.16.0",
3733
]
3834

3935
[build-system]
@@ -43,3 +39,7 @@ build-backend = "uv_build"
4339
[[tool.uv.index]]
4440
name = "pypi"
4541
url = "https://pypi.org/simple"
42+
43+
[tool.mypy]
44+
python_version = "3.10"
45+
files = ["src/announcer", "tests"]

ruff.toml

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# Copyright (c) Alianza, Inc. All rights reserved.
2+
exclude = [
3+
".venv",
4+
"__pycache__",
5+
".mypy_cache",
6+
".git",
7+
]
8+
9+
# Match black
10+
line-length = 88
11+
indent-width = 4
12+
13+
# Assume Python 3.10
14+
target-version = "py310"
15+
16+
[lint]
17+
extend-select = [
18+
"E",
19+
"I", # isort
20+
"D", # pydocstyle
21+
"S", # security
22+
"ARG", # flake8-unused-arguments
23+
"ANN", # flake8-annotations
24+
]
25+
26+
ignore = [
27+
"D203", # ignore incompatible rules
28+
"D213", # ignore incompatible rules
29+
"D400",
30+
"D401",
31+
"D415",
32+
# Allow long lines if needed
33+
"E501",
34+
# Subprocess module imported. Warning to be careful only.
35+
"S404",
36+
# Yaml loader
37+
"S506",
38+
# Subprocess used without shell=True. Warning to be careful only.
39+
"S603",
40+
# Starting a process with a partial executable path
41+
"S607",
42+
]
43+
44+
[lint.extend-per-file-ignores]
45+
"tests/*" = ["S"]
46+
47+
[format]
48+
# Like Black, use double quotes for strings.
49+
quote-style = "double"
50+
51+
# Like Black, indent with spaces, rather than tabs.
52+
indent-style = "space"
53+
54+
# Like Black, respect magic trailing commas.
55+
skip-magic-trailing-comma = false
56+
57+
# Like Black, automatically detect the appropriate line ending.
58+
line-ending = "auto"

setup.cfg

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

src/announcer/__init__.py

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,26 @@
11
#!/usr/bin/env python3
22
# -*- coding: utf-8 -*-
33
# Copyright (c) Alianza, Inc. All rights reserved.
4-
"""A tool for announcing keepachangelog format logs to Slack and Microsoft
5-
Teams channels"""
4+
"""A tool for announcing keepachangelog format logs to Slack and Microsoft Teams channels"""
65

76
import argparse
87
import json
98
import logging
109
import re
1110
import sys
1211
from enum import Enum
13-
from typing import Any, Dict, List, Optional, Tuple
12+
from typing import Any, Dict, List, Optional, Tuple, Union
1413

15-
import mistletoe
1614
import requests
17-
from mistletoe.base_renderer import BaseRenderer
15+
from mistletoe.block_token import Document
1816

1917
from .changelogrenderer import ChangeLogRenderer
2018
from .teamschangelogrenderer import TeamsChangeLogRenderer
2119

2220
log = logging.getLogger(__name__)
2321

22+
ValidRenderers = Union[ChangeLogRenderer, TeamsChangeLogRenderer]
23+
2424

2525
DIFF_URL_RE = re.compile("^(.*)/compare/[^/]+[.][.][.]([^/]+)$")
2626
TREE_URL_RE = re.compile("^(.*)/tree/([^/]+)$")
@@ -29,6 +29,7 @@
2929
def derive_urls(
3030
diff_url: Optional[str],
3131
) -> Tuple[Optional[str], Optional[str]]:
32+
"""Derive base and reference URLs from a GitHub compare or tree URL."""
3233
base_url = None
3334
reference = None
3435
if diff_url:
@@ -44,10 +45,13 @@ def derive_urls(
4445

4546

4647
class TargetTypes(Enum):
48+
"""Supported announcement targets."""
49+
4750
SLACK = "slack"
4851
TEAMS = "teams"
4952

50-
def __str__(self):
53+
def __str__(self) -> str:
54+
"""Return the enum value for argparse and logging display."""
5155
return self.value
5256

5357

@@ -85,7 +89,7 @@ def announce_slack(
8589
username: Optional[str] = None,
8690
icon_url: Optional[str] = None,
8791
icon_emoji: Optional[str] = None,
88-
):
92+
) -> None:
8993
"""Announce changelog changes to Slack"""
9094
# Get the changelog
9195
log.info("Querying changelog %s", changelogfile)
@@ -166,7 +170,7 @@ def announce_teams(
166170
changelogfile: str,
167171
projectname: str,
168172
compatibility_teams_sections: bool,
169-
):
173+
) -> None:
170174
"""Announce changelog changes to Teams"""
171175
# Get the changelog
172176
log.info("Querying changelog %s", changelogfile)
@@ -251,15 +255,19 @@ def announce_teams(
251255

252256

253257
class Changelog(object):
254-
def __init__(self, filename: str, renderer_class: type[BaseRenderer]) -> None:
258+
"""Helper for loading and rendering changelog sections."""
259+
260+
def __init__(self, filename: str, renderer_class: type[ValidRenderers]) -> None:
261+
"""Create a changelog reader bound to a renderer implementation."""
255262
self.filename = filename
256263
self.renderer_class = renderer_class
257264

258265
def get_version_details(
259266
self, version: str
260267
) -> Tuple[str, Optional[str], List[Dict[str, str]]]:
268+
"""Render and return details for a specific changelog version."""
261269
with open(self.filename, "r") as f:
262-
document = mistletoe.Document(f)
270+
document = Document(f)
263271

264272
with self.renderer_class(version) as renderer:
265273
rendered = renderer.render(document)
@@ -270,9 +278,8 @@ def get_version_details(
270278
return rendered, diff_url, sections
271279

272280

273-
def main():
281+
def main() -> None:
274282
"""Main handling function."""
275-
276283
# Run main script.
277284
parser = argparse.ArgumentParser(
278285
description="Announce CHANGELOG changes on Slack and Microsoft Teams"

0 commit comments

Comments
 (0)