Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ version number is tracked in the file `pyproject.toml`.
### Breaking Changes

### Added
- Add `ruff` for linting instead of flake8 and isort
- Fix up associated errors

### Fixed

Expand Down
6 changes: 3 additions & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,8 @@ Ready to contribute? Here's how to set up `announcer` for local development.

Now you can make your changes locally.

5. When you're done making changes, check that your changes pass flake8 and the
tests using tox.
5. When you're done making changes, check that your changes pass Ruff and the
tests using tox.

```shell
$ tox
Expand All @@ -104,7 +104,7 @@ Before you submit a pull request, check that it meets these guidelines:
2. If the pull request adds functionality, the docs should be updated. Put
your new functionality into a function with a docstring, and add the
feature to the list in README.md.
3. The pull request should work for Python >=3.7.
3. The pull request should work for Python >=3.10.

## Tips

Expand Down
10 changes: 5 additions & 5 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,15 @@ announce = "announcer.__init__:main"

[dependency-groups]
dev = [
"pylint==4.0.5",
"wheel==0.46.3",
"mypy==1.19.1",
"yamllint==1.38.0",
"bandit==1.9.4",
"pytest==8.4.2",
"flake8==7.3.0",
"werkzeug==3.1.7",
"pytest-httpserver==1.1.5",
"tox==4.51.0",
"pytest-cov==7.1.0",
"types-requests>=2.32.0,<3",
"isort==7.0.0",
"ruff>=0.15.8,<0.16.0",
]

[build-system]
Expand All @@ -43,3 +39,7 @@ build-backend = "uv_build"
[[tool.uv.index]]
name = "pypi"
url = "https://pypi.org/simple"

[tool.mypy]
python_version = "3.10"
files = ["src/announcer", "tests"]
58 changes: 58 additions & 0 deletions ruff.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# Copyright (c) Alianza, Inc. All rights reserved.
exclude = [
".venv",
"__pycache__",
".mypy_cache",
".git",
]

# Match black
line-length = 88
indent-width = 4

# Assume Python 3.10
target-version = "py310"

[lint]
extend-select = [
"E",
"I", # isort
"D", # pydocstyle
"S", # security
"ARG", # flake8-unused-arguments
"ANN", # flake8-annotations
]

ignore = [
"D203", # ignore incompatible rules
"D213", # ignore incompatible rules
"D400",
"D401",
"D415",
# Allow long lines if needed
"E501",
# Subprocess module imported. Warning to be careful only.
"S404",
# Yaml loader
"S506",
# Subprocess used without shell=True. Warning to be careful only.
"S603",
# Starting a process with a partial executable path
"S607",
]

[lint.extend-per-file-ignores]
"tests/*" = ["S"]

[format]
# Like Black, use double quotes for strings.
quote-style = "double"

# Like Black, indent with spaces, rather than tabs.
indent-style = "space"

# Like Black, respect magic trailing commas.
skip-magic-trailing-comma = false

# Like Black, automatically detect the appropriate line ending.
line-ending = "auto"
2 changes: 0 additions & 2 deletions setup.cfg

This file was deleted.

31 changes: 19 additions & 12 deletions src/announcer/__init__.py
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Copyright (c) Alianza, Inc. All rights reserved.
"""A tool for announcing keepachangelog format logs to Slack and Microsoft
Teams channels"""
"""A tool for announcing keepachangelog format logs to Slack and Microsoft Teams channels"""

import argparse
import json
import logging
import re
import sys
from enum import Enum
from typing import Any, Dict, List, Optional, Tuple
from typing import Any, Dict, List, Optional, Tuple, Union

import mistletoe
import requests
from mistletoe.base_renderer import BaseRenderer
from mistletoe.block_token import Document

from .changelogrenderer import ChangeLogRenderer
from .teamschangelogrenderer import TeamsChangeLogRenderer

log = logging.getLogger(__name__)

ValidRenderers = Union[ChangeLogRenderer, TeamsChangeLogRenderer]


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


class TargetTypes(Enum):
"""Supported announcement targets."""

SLACK = "slack"
TEAMS = "teams"

def __str__(self):
def __str__(self) -> str:
"""Return the enum value for argparse and logging display."""
return self.value


Expand Down Expand Up @@ -85,7 +89,7 @@ def announce_slack(
username: Optional[str] = None,
icon_url: Optional[str] = None,
icon_emoji: Optional[str] = None,
):
) -> None:
"""Announce changelog changes to Slack"""
# Get the changelog
log.info("Querying changelog %s", changelogfile)
Expand Down Expand Up @@ -166,7 +170,7 @@ def announce_teams(
changelogfile: str,
projectname: str,
compatibility_teams_sections: bool,
):
) -> None:
"""Announce changelog changes to Teams"""
# Get the changelog
log.info("Querying changelog %s", changelogfile)
Expand Down Expand Up @@ -251,15 +255,19 @@ def announce_teams(


class Changelog(object):
def __init__(self, filename: str, renderer_class: type[BaseRenderer]) -> None:
"""Helper for loading and rendering changelog sections."""

def __init__(self, filename: str, renderer_class: type[ValidRenderers]) -> None:
"""Create a changelog reader bound to a renderer implementation."""
self.filename = filename
self.renderer_class = renderer_class

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

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


def main():
def main() -> None:
"""Main handling function."""

# Run main script.
parser = argparse.ArgumentParser(
description="Announce CHANGELOG changes on Slack and Microsoft Teams"
Expand Down
Loading