Skip to content

Commit

Permalink
fix #20 assume assignee is owner @geminixiang (#21)
Browse files Browse the repository at this point in the history
* fix #20 assume assignee is owner

* test

* test
  • Loading branch information
lucemia authored Jun 26, 2024
1 parent 8cb730c commit b1f5967
Show file tree
Hide file tree
Showing 6 changed files with 138 additions and 35 deletions.
3 changes: 1 addition & 2 deletions .github/workflows/pr-lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,8 @@ jobs:

steps:
- id: pr-lint
uses: livingbio/pr-lint@fix-10-compose-action
uses: livingbio/pr-lint@main
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
github_repository: ${{ github.repository }}
pr_number: ${{ github.event.number }}

37 changes: 8 additions & 29 deletions src/pr_lint/formatter.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,9 @@
import re
from typing import Iterable

from github.Label import Label
from github.PullRequest import PullRequest

emoji_pattern = re.compile(
"["
"\U0001F600-\U0001F64F" # Emoticons
"\U0001F300-\U0001F5FF" # Symbols & pictographs
"\U0001F680-\U0001F6FF" # Transport & map symbols
"\U0001F1E0-\U0001F1FF" # Flags (iOS)
"\U0001F900-\U0001F9FF" # Supplemental Symbols and Pictographs
"\U0001FA70-\U0001FAFF" # Symbols and Pictographs Extended-A
"\u2600-\u26FF" # Miscellaneous Symbols
"\u2700-\u27BF" # Dingbats
"]"
)
from .utils import collect_emojis_from_labels, extract_pure_title, get_owner


def format(pr: PullRequest) -> None:
Expand All @@ -30,22 +18,13 @@ def format(pr: PullRequest) -> None:

labels: Iterable[Label] = pr.get_labels()
# remove all emojis from the left of title
cleaned_title = pr.title.lstrip("".join(emoji_pattern.findall(pr.title))).strip()

# Sort the labels in the following order
# any label with "Impact:"
# any label with "Type:"
# other labels
labels = sorted(labels, key=lambda label: ("Impact:" in label.name, "Type:" in label.name), reverse=True)

emojis = []
for label in labels:
if _emjojis := emoji_pattern.findall(label.name):
for _emjoin in _emjojis:
if _emjoin not in emojis:
emojis.append(_emjoin)

new_title = f"{''.join(emojis)} {cleaned_title}"
cleaned_title = extract_pure_title(pr.title)

emojis = collect_emojis_from_labels(label.name for label in labels)

owner = get_owner(pr)

new_title = f"{''.join(emojis)} {cleaned_title} @{owner}"
if new_title != pr.title:
print(f"Updated PR title: {pr.title} -> {new_title}")
pr.edit(title=new_title)
8 changes: 4 additions & 4 deletions src/pr_lint/linter.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import re

from github.Label import Label
from github.PullRequest import PullRequest

from .utils import get_owner


def lint(pr: PullRequest) -> None:
"""
Expand All @@ -15,9 +15,9 @@ def lint(pr: PullRequest) -> None:
Args:
pr: The pull request to lint
"""
owner = get_owner(pr)
assert owner, "PR title should end with a GitHub username"

pr_owners = re.findall(r"(@[\w-]+)$", pr.title.strip())
assert pr_owners, "PR title should end with a GitHub username"
# FIXME: for some reason the has_in_collaborators method is not working
# pr_owner = pr_owners[0][1:]
# assert repo.has_in_collaborators(pr_owner), f"{pr_owner} is not a collaborator"
Expand Down
Empty file added src/pr_lint/tests/__init__.py
Empty file.
29 changes: 29 additions & 0 deletions src/pr_lint/tests/test_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
from ..utils import collect_emojis_from_labels, extract_owner_from_title, extract_pure_title


def test_extract_owner_from_title() -> None:
title = "This is a PR title @owner"
assert extract_owner_from_title(title) == "owner"

title = "This is a PR title"
assert extract_owner_from_title(title) is None


def test_extract_pure_title() -> None:
title = "🚀 This is a PR title @owner"
assert extract_pure_title(title) == "This is a PR title"

title = "This is a PR title @owner"
assert extract_pure_title(title) == "This is a PR title"

title = "This is a PR title"
assert extract_pure_title(title) == title


def test_collect_emojis_from_labels() -> None:
labels = ["🚀 Type: Feature", "🔥 Impact: Major"]
assert collect_emojis_from_labels(labels) == ["🔥", "🚀"]

# different order
labels = ["🔥 Impact: Major", "🚀 Type: Feature"]
assert collect_emojis_from_labels(labels) == ["🔥", "🚀"]
96 changes: 96 additions & 0 deletions src/pr_lint/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import re
from typing import Iterable

from github.PullRequest import PullRequest

emoji_pattern = (
"["
"\U0001F600-\U0001F64F" # Emoticons
"\U0001F300-\U0001F5FF" # Symbols & pictographs
"\U0001F680-\U0001F6FF" # Transport & map symbols
"\U0001F1E0-\U0001F1FF" # Flags (iOS)
"\U0001F900-\U0001F9FF" # Supplemental Symbols and Pictographs
"\U0001FA70-\U0001FAFF" # Symbols and Pictographs Extended-A
"\u2600-\u26FF" # Miscellaneous Symbols
"\u2700-\u27BF" # Dingbats
"]"
)


def extract_owner_from_title(title: str) -> str | None:
"""
Extract the owner from the title.
Args:
title: The title of the pull request
Returns:
The owner of the pull request
"""
pr_owners = re.findall(r"(@[\w-]+)$", title.strip())
if pr_owners:
return pr_owners[0][1:]

return None


def get_owner(pr: PullRequest) -> str | None:
"""
Get the owner of a pull request.
Args:
pr: The pull request
Returns:
The owner of the pull request
"""
if owner := extract_owner_from_title(pr.title):
return owner

# if the PR title does not end with a username, check if there is an assignee
if pr.assignee:
return pr.assignee.login
return None


def extract_pure_title(title: str) -> str:
"""
Extract the title without emojis and the owner.
Args:
title: The title to clean
Returns:
The title without emojis and the owner
"""
match_title = re.findall(rf"^{emoji_pattern}*(.*?)(@[\w-]+)?$", title)
assert match_title, "cannot extract title"
return match_title[0][0].strip()


def collect_emojis_from_labels(labels: Iterable[str]) -> list[str]:
"""
Collect emojis from labels.
Args:
labels: The labels to collect emojis from
Returns:
The emojis from the labels
"""

# Sort the labels in the following order
# any label with "Impact:"
# any label with "Type:"
# other labels

labels = sorted(labels, key=lambda label: ("Impact:" in label, "Type:" in label), reverse=True)

emojis = []
for label in labels:
if _emojis := re.findall(emoji_pattern, label):
for _emoji in _emojis:
if _emoji not in emojis:
emojis.append(_emoji)

return emojis

0 comments on commit b1f5967

Please sign in to comment.