-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Parse Trac component, priority, and keywords into GitHub labels.
- Loading branch information
Showing
3 changed files
with
160 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
import unittest | ||
|
||
from ticket_migrate import get_repo, get_labels, labels_from_keywords | ||
|
||
|
||
class TestRepositoryMapping(unittest.TestCase): | ||
""" | ||
Trac components map to the configured GitHub repositories. | ||
These tests depend on `config.py` having the contents | ||
from `config.py.sample`. | ||
""" | ||
|
||
def test_get_repo(self): | ||
""" | ||
Check that the issue is opened in the correct GitHub repository | ||
based on the Trac component. | ||
""" | ||
self.assertEqual(get_repo('client'), 'client') | ||
self.assertEqual(get_repo('commons'), 'commons') | ||
self.assertEqual(get_repo('fallback'), 'server') | ||
|
||
|
||
class TestLabelMapping(unittest.TestCase): | ||
""" | ||
Trac labels are parsed based on component, priority, and keywords_string. | ||
These tests depend on `config.py` having the contents | ||
from `config.py.sample`. | ||
""" | ||
|
||
def test_labels_from_keywords(self): | ||
""" | ||
Parse and clean the Trac keywords. | ||
""" | ||
# Split by space. | ||
self.assertEqual( | ||
{'easy', 'tech-debt'}, | ||
labels_from_keywords('easy tech-debt')) | ||
|
||
# Remove commas. | ||
self.assertEqual({'tech-debt'}, labels_from_keywords('tech-debt,')) | ||
self.assertEqual( | ||
{'tech-debt', 'feature'}, | ||
labels_from_keywords('tech-debt, feature')) | ||
|
||
# Fix typos. | ||
self.assertEqual( | ||
{'tech-debt', 'easy'}, | ||
labels_from_keywords('tech-dept easy')) | ||
self.assertEqual( | ||
{'tech-debt'}, | ||
labels_from_keywords('tech-deb')) | ||
|
||
# Discard unknown words to prevent tag explosion. | ||
self.assertEqual( | ||
set(), | ||
labels_from_keywords('unknown-tag')) | ||
|
||
# Deduplicate. | ||
self.assertEqual( | ||
{'tech-debt'}, | ||
labels_from_keywords('tech-deb, tech-debt tech-dept')) | ||
|
||
def test_get_labels_none(self): | ||
""" | ||
The issues that do not map to the fallback repository | ||
get no label based on the component. | ||
""" | ||
self.assertEqual( | ||
{'priority-low', 'tech-debt'}, | ||
get_labels( | ||
component='client', priority='Low', keywords='tech-dept')) | ||
self.assertEqual( | ||
{'priority-high'}, | ||
get_labels( | ||
component='client', priority='High', keywords='')) | ||
|
||
def test_get_labels_component_name(self): | ||
self.assertEqual( | ||
{'priority-low', 'fallback'}, | ||
get_labels('fallback', 'Low', '')) | ||
|
||
|
||
if __name__ == '__main__': | ||
unittest.main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
# Migrate Trac tickets to GitHub. | ||
from config import REPOSITORY_MAPPING, FALLBACK_REPOSITORY | ||
|
||
|
||
def get_repo(component): | ||
""" | ||
Given the Trac component, | ||
choose the GitHub repository to create the issue in. | ||
""" | ||
return REPOSITORY_MAPPING.get(component, FALLBACK_REPOSITORY) | ||
|
||
|
||
def labels_from_component(component: str): | ||
""" | ||
Given the Trac component, | ||
choose the labels to apply on the GitHub issue, if any. | ||
""" | ||
if component in REPOSITORY_MAPPING: | ||
return [] | ||
|
||
return [component] | ||
|
||
|
||
def labels_from_keywords(keywords: str): | ||
""" | ||
Given the Trac `keywords` string, clean it up and parse it into a list. | ||
""" | ||
keywords = keywords.replace(',', '') | ||
keywords = keywords.split(' ') | ||
|
||
allowed_keyword_labels = { | ||
'design', | ||
'easy', | ||
'feature', | ||
'happy-hacking', | ||
'onboarding', | ||
'password-management', | ||
'perf-test', | ||
'remote-management', | ||
'salt', | ||
'scp', | ||
'security', | ||
'tech-debt', | ||
'twisted', | ||
'ux', | ||
} | ||
typo_fixes = {'tech-dept': 'tech-debt', 'tech-deb': 'tech-debt'} | ||
|
||
keywords = [typo_fixes.get(kw, kw) for kw in keywords] | ||
discarded = [kw for kw in keywords if kw not in allowed_keyword_labels] | ||
|
||
if discarded: | ||
print("Warning: discarded keywords:", discarded) | ||
|
||
return {kw for kw in keywords if kw in allowed_keyword_labels} | ||
|
||
|
||
def get_labels(component: str, priority: str, keywords: str): | ||
""" | ||
Given the Trac component, priority, and keywords, | ||
return the labels to apply on the GitHub issue. | ||
""" | ||
priority_label = 'priority-{}'.format(priority.lower()) | ||
keyword_labels = labels_from_keywords(keywords) | ||
component_labels = labels_from_component(component) | ||
return {priority_label}.union(keyword_labels).union(component_labels) |