diff --git a/configs/git/.gitconfig b/configs/git/.gitconfig index 9e7aada..7b20dc5 100644 --- a/configs/git/.gitconfig +++ b/configs/git/.gitconfig @@ -23,7 +23,8 @@ branches = branch -a -l -vv overview = log --all --pretty=format:'%C(green)commit %C(yellow)%h%C(green) by %C(reset)%C(yellow)%aN %C(dim white)(%ar) %n%C(dim white)%S%n%B%n' lscommits = ! ( echo -e "Commits\tFile" && git log --pretty=format: --name-only | sed '/^$/d' | sort | uniq -c | sort -g -r ) | less - lsc = lscommits + lsc = lscommits + diff-against = diff --merge-base [filter "lfs"] clean = git-lfs clean -- %f diff --git a/configs/scripts/github-to-trello b/configs/scripts/github-to-trello index cbb19bc..6cf0063 100755 --- a/configs/scripts/github-to-trello +++ b/configs/scripts/github-to-trello @@ -67,6 +67,19 @@ def get_all_issues() -> List[Dict[str, Any]]: ) response.raise_for_status() issues.extend(response.json()) + + # Get all issues that I have made in other people's repos + response = requests.get( + "https://api.github.com/user/issues", + headers={ + "Authorization": f"token {GITHUB_PAT}", + "Accept": "application/vnd.github.raw+json", + "X-GitHub-Api-Version": GITHUB_API_VERSION, + }, + params={"state": "open", "per_page": 100, "filter": "subscribed"}, + ) + response.raise_for_status() + issues.extend(response.json()) # De-dupe issues issues = list({issue["id"]: issue for issue in issues}.values()) diff --git a/configs/scripts/guru-shell b/configs/scripts/guru-shell index bcf5560..ec4bd21 100755 --- a/configs/scripts/guru-shell +++ b/configs/scripts/guru-shell @@ -31,7 +31,7 @@ fi echo -n "Do you want to force debugging for all processes? (y/N)" read force_debug if [ "$force_debug" == "y" ]; then - export GURU_DEBUG=1 + export GURU_DEBUG=10 fi # Set PYTHONPATH based on the data we learned diff --git a/configs/scripts/guru-sync-issues b/configs/scripts/guru-sync-issues index b71d109..111b56a 100755 --- a/configs/scripts/guru-sync-issues +++ b/configs/scripts/guru-sync-issues @@ -42,6 +42,7 @@ class GitLabIssue: title: str issue_id: int global_id: int + kind: str state: IssueState created: datetime updated: datetime @@ -49,9 +50,21 @@ class GitLabIssue: reference_string: str due_date: Optional[datetime] = None + def get_fmt_id(self) -> str: + if self.kind == "merge_request": + return f"!{self.global_id}" + return f"#{self.global_id}" + + def list_contains_this(self, list_of_ids: List[str]) -> bool: + if self.kind == "issue" and self.global_id in list_of_ids: + return True + + return self.get_fmt_id() in [str(x) for x in list_of_ids] + def get_personal_gitlab_issues(user_id: int = MY_USER_ID) -> List[GitLabIssue]: # Make an API call + issues = [] response = requests.get( f"{GITLAB_ENDPOINT}/issues", params={ @@ -62,22 +75,36 @@ def get_personal_gitlab_issues(user_id: int = MY_USER_ID) -> List[GitLabIssue]: }, ) response.raise_for_status() + issues.extend(response.json()) + response = requests.get( + f"{GITLAB_ENDPOINT}/merge_requests", + params={ + "assignee_id": user_id, + "private_token": GITLAB_PAT, + "per_page": 100, + "scope": "all", + "state": "opened", + }, + ) + response.raise_for_status() + issues.extend(response.json()) # Parse the response output = [] - for issue in response.json(): + for issue in issues: output.append( GitLabIssue( title=issue["title"], issue_id=issue["iid"], global_id=issue["id"], + kind=issue.get("type", "merge_request").lower(), state=IssueState(issue["state"]), created=datetime.fromisoformat(issue["created_at"]), updated=datetime.fromisoformat(issue["updated_at"]), web_url=issue["web_url"], reference_string=issue["references"]["full"], due_date=datetime.fromisoformat(issue["due_date"]) - if issue["due_date"] + if issue.get("due_date") else None, ) ) @@ -86,7 +113,7 @@ def get_personal_gitlab_issues(user_id: int = MY_USER_ID) -> List[GitLabIssue]: def find_or_create_trello_issue_for( - trello_cards: List[Dict[str, Any]], gitlab_issue: GitLabIssue + trello_cards: List[Dict[str, Any]], gitlab_issue: GitLabIssue, dry_run: bool = False ) -> TrelloCardId: # Look for a card that matches the issue for card in trello_cards: @@ -100,8 +127,8 @@ def find_or_create_trello_issue_for( metadata = json.loads(desc_first_line.split("`")[1]) # Check if the card matches - if metadata.get("ns") == "guru-gitlab" and ( - gitlab_issue.global_id in metadata.get("ids", []) + if metadata.get("ns") == "guru-gitlab" and gitlab_issue.list_contains_this( + metadata.get("ids", []) ): print(card["labels"], card["idLabels"]) logger.info(f"Found matching card {card['id']}") @@ -110,28 +137,33 @@ def find_or_create_trello_issue_for( # Build the description card_description = "\n\n".join( [ - f"**Sync Metadata:** `{json.dumps({'ns': 'guru-gitlab', 'ids': [gitlab_issue.global_id]})}`", + f"**Sync Metadata:** `{json.dumps({'ns': 'guru-gitlab', 'ids': [gitlab_issue.get_fmt_id()]})}`", f"**GitLab Issue:** [`{gitlab_issue.reference_string}`]({gitlab_issue.web_url})\n", "---", ] ) # Make a new card - return create_card( - list_id=PERSONAL_TASKS_BOARD.lists["To Do"], - name=gitlab_issue.title, - description=card_description, - label_ids=[PERSONAL_TASKS_BOARD.tags["GURU"]], - position="top", - api_key=TRELLO_API_KEY, - api_token=TRELLO_API_TOKEN, - ) + if not dry_run: + return create_card( + list_id=PERSONAL_TASKS_BOARD.lists["To Do"], + name=gitlab_issue.title, + description=card_description, + label_ids=[PERSONAL_TASKS_BOARD.tags["GURU"]], + position="top", + api_key=TRELLO_API_KEY, + api_token=TRELLO_API_TOKEN, + ) + else: + return "dry-run" def main() -> int: # Handle program arguments ap = argparse.ArgumentParser(description="Syncs issues from GitLab to Trello") - + ap.add_argument( + "--dry-run", help="Don't actually make any changes", action="store_true" + ) ap.add_argument( "-v", "--verbose", help="Enable verbose logging", action="store_true" ) @@ -158,7 +190,9 @@ def main() -> int: # Handle each issue for issue in issues: # Find the trello card id for this issue - trello_card_id = find_or_create_trello_issue_for(trello_cards, issue) + trello_card_id = find_or_create_trello_issue_for( + trello_cards, issue, dry_run=args.dry_run + ) logger.info(f"GitLab Issue {issue.global_id} is Trello Card {trello_card_id}") return 0