Skip to content

Commit 3cdc5e2

Browse files
committed
Options: Add --format=mrkdwn option, improving Slack messages
1 parent d131cde commit 3cdc5e2

File tree

8 files changed

+60
-18
lines changed

8 files changed

+60
-18
lines changed

CHANGES.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
- GitHub/Backup: Added wrapper around `github-backup`
99
- Options: Use `aika` for parsing time intervals.
1010
Also, rename command-line option `--timerange` to `--when`.
11+
- Options: Added `--format=mrkdwn` option, improving Slack messages
1112

1213
## v0.1.0, 2025-02-20
1314
- Started using `GH_TOKEN` environment variable instead of `GITHUB_TOKEN`,

docs/guide/options.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,15 @@ or relative human-readable notations.
3131
- this month
3232

3333

34+
## Output options
35+
36+
### Slack flavored Markdown
37+
38+
The program can output two flavors of Markdown. Standard Markdown is default,
39+
while the [Slack `mrkdwn` format] can be produced using the `--format=mrkdwn`
40+
command-line option. Rapporto uses the [markdown-to-mrkdwn] package here.
41+
42+
3443
[aika]: https://pypi.org/project/aika/
44+
[markdown-to-mrkdwn]: https://pypi.org/project/markdown-to-mrkdwn/
45+
[Slack `mrkdwn` format]: https://api.slack.com/reference/surfaces/formatting#basic-formatting

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ dependencies = [
101101
"dataclasses-json<1",
102102
"github-backup<1",
103103
"importlib-metadata; python_version<'3.8'",
104+
"markdown-to-mrkdwn<0.2",
104105
"munch<5",
105106
"pueblo<1",
106107
"python-dateutil<3",

src/rapporto/github/actions.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,6 @@ def markdown(self):
6262
{mdc.render()}
6363
""".strip() # noqa: E501
6464

65-
def print(self):
66-
print(self.markdown)
67-
6865

6966
class GitHubActionsRequest:
7067
"""

src/rapporto/github/activity.py

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import dataclasses
2+
import io
23
import logging
34
import typing as t
5+
from contextlib import redirect_stdout
46
from operator import attrgetter
57
from textwrap import dedent
68

@@ -112,14 +114,18 @@ def format_pr(item: "PullRequestMetadata"):
112114
f"comments: {item.comments_total}, files: {item.changed_files}, size: {item.code_size}"
113115
)
114116

115-
def print(self):
117+
@property
118+
def markdown(self) -> str:
116119
timerange = self.inquiry.created and f"for {self.inquiry.created}" or ""
117-
print(f"# PPP report {timerange}")
118-
# print("## Overview")
119-
print(self.markdown_overview)
120-
print()
121-
print("*Top changes:*")
122-
print(self.markdown_significant)
120+
with redirect_stdout(io.StringIO()) as buffer:
121+
print(f"# PPP report {timerange}")
122+
# print("## Overview")
123+
print(self.markdown_overview)
124+
print()
125+
print("*Top changes:*")
126+
print(self.markdown_significant)
127+
buffer.seek(0)
128+
return buffer.read()
123129

124130

125131
@dataclass_json(undefined=Undefined.INCLUDE)

src/rapporto/github/attention.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,3 @@ def markdown(self):
110110
Time range: {self.search.query_builder.timerange or "n/a"}
111111
{mdc.render()}
112112
""".strip() # noqa: E501
113-
114-
def print(self):
115-
print(self.markdown)

src/rapporto/github/cli.py

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,12 @@
99
from rapporto.github.attention import GitHubAttentionReport
1010
from rapporto.github.backup import GitHubBackup
1111
from rapporto.github.model import GitHubInquiry
12+
from rapporto.util import to_mrkdwn
1213

1314
organization_option = click.option("--organization", "--org", type=str, required=False)
1415
author_option = click.option("--author", type=str, required=False)
1516
when_option = click.option("--when", type=str, required=False)
17+
format_option = click.option("--format", "format_", type=str, required=False, default="markdown")
1618
repository_option = click.option("--repository", type=str, required=False)
1719
repositories_file_option = click.option("--repositories-file", type=Path, required=False)
1820

@@ -30,23 +32,35 @@ def cli(ctx: click.Context):
3032
@organization_option
3133
@author_option
3234
@when_option
35+
@format_option
3336
def activity(
3437
organization: t.Optional[str] = None,
3538
author: t.Optional[str] = None,
3639
when: t.Optional[str] = None,
40+
format_: t.Optional[str] = None,
3741
):
3842
"""
3943
Activities of individual authors.
4044
"""
4145
inquiry = GitHubInquiry(organization=organization, author=author, created=when)
4246
report = GitHubActivityReport(inquiry=inquiry)
43-
report.print()
47+
print_output(report, format_)
48+
49+
50+
def print_output(report, format_):
51+
if format_ == "markdown":
52+
print(report.markdown)
53+
elif format_ == "mrkdwn":
54+
print(to_mrkdwn(report.markdown))
55+
else:
56+
raise NotImplementedError(f"Unknown output format: {format_}")
4457

4558

4659
@cli.command(aliases=["ci"])
4760
@repository_option
4861
@repositories_file_option
49-
def actions(repository: str, repositories_file: Path = None):
62+
@format_option
63+
def actions(repository: str, repositories_file: Path = None, format_: t.Optional[str] = None):
5064
"""
5165
CI/GHA failures.
5266
"""
@@ -60,19 +74,24 @@ def actions(repository: str, repositories_file: Path = None):
6074
)
6175
raise SystemExit(1) from ex
6276
report = GitHubActionsReport(inquiry=inquiry)
63-
report.print()
77+
print_output(report, format_)
6478

6579

6680
@cli.command(aliases=["att"])
6781
@organization_option
6882
@when_option
69-
def attention(organization: t.Optional[str] = None, when: t.Optional[str] = None):
83+
@format_option
84+
def attention(
85+
organization: t.Optional[str] = None,
86+
when: t.Optional[str] = None,
87+
format_: t.Optional[str] = None,
88+
):
7089
"""
7190
Important items that deserve attention.
7291
"""
7392
inquiry = GitHubInquiry(organization=organization, created=when)
7493
report = GitHubAttentionReport(inquiry=inquiry)
75-
report.print()
94+
print_output(report, format_)
7695

7796

7897
@cli.command(

src/rapporto/util.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
from markdown_to_mrkdwn import SlackMarkdownConverter
2+
3+
14
def sanitize_title(title: str) -> str:
25
"""
36
Strip characters that are unfortunate in Markdown link titles.
@@ -12,3 +15,10 @@ def goosefeet(text: str) -> str:
1215
if " " in text:
1316
return f'"{text}"'
1417
return text
18+
19+
20+
mrkdwn_converter = SlackMarkdownConverter()
21+
22+
23+
def to_mrkdwn(markdown: str) -> str:
24+
return mrkdwn_converter.convert(markdown)

0 commit comments

Comments
 (0)