From c61815e304bc80872751a0cc910de57f16697fff Mon Sep 17 00:00:00 2001 From: Bharat Kunwar Date: Mon, 24 Jun 2024 07:46:54 +0100 Subject: [PATCH 1/2] T-17808/feat: Grab linear title and body from linear ref if API key is present --- .gitignore | 4 ++ .pre-commit-config.yaml | 24 +++++++++ git_hooks/commit_msg.py | 10 ++-- git_hooks/prepare_commit_msg.py | 95 +++++++++++++++++++++------------ 4 files changed, 94 insertions(+), 39 deletions(-) diff --git a/.gitignore b/.gitignore index 7ec2d62..23ca4ed 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,7 @@ +# direnv +.envrc +.direnv/ + # folders .vscode/ venv/ diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 85efe94..d76c408 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,5 +1,29 @@ default_install_hook_types: [commit-msg, prepare-commit-msg] repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.5.0 + hooks: + - id: check-ast + - id: check-added-large-files + - id: check-json + - id: check-merge-conflict + - id: check-toml + - id: check-yaml + - id: detect-private-key + - id: end-of-file-fixer + - id: pretty-format-json + args: ["--indent=\t", "--no-sort-keys"] + - id: requirements-txt-fixer + - id: trailing-whitespace + - repo: https://github.com/astral-sh/ruff-pre-commit + # Ruff version. + rev: v0.4.8 + hooks: + # Run the linter. + - id: ruff + args: ["--fix"] + # Run the formatter. + - id: ruff-format - repo: local hooks: - name: commit-msg diff --git a/git_hooks/commit_msg.py b/git_hooks/commit_msg.py index 70b606c..d1b2c8a 100644 --- a/git_hooks/commit_msg.py +++ b/git_hooks/commit_msg.py @@ -1,9 +1,7 @@ -""" This hook verifies that the commit message contains a reference to a Linear issue - as well as a conventional commit type at the start - The commit message needs to conform to - /[!]: - e.g. T-5482/feat: Amazing new commit-msg hook - See https://www.conventionalcommits.org for details on conventional commits +"""This hook verifies that the commit message contains a reference to a Linear issue as well as a conventional commit type. +The commit message needs to conform to /[!]: . e.g. + T-5482/feat: Amazing new commit-msg hook +See https://www.conventionalcommits.org for examples of conventional commit types. """ import sys diff --git a/git_hooks/prepare_commit_msg.py b/git_hooks/prepare_commit_msg.py index 9e70f73..3f72f71 100644 --- a/git_hooks/prepare_commit_msg.py +++ b/git_hooks/prepare_commit_msg.py @@ -1,3 +1,9 @@ +"""This hook prepares a commit message containing a reference to a Linear issue as well as a conventional commit type. +It uses the branch name to determine the issue number and the commit message title as well as the conventional commit type. +If LINEAR_API_KEY is set, it fetches the issue title and description from Linear and populates the commit message with it. +See https://www.conventionalcommits.org for examples of conventional commit types. +""" + import os import re import sys @@ -107,47 +113,70 @@ def extract_branch_data(branch: str) -> dict[str, str]: } +def retrieve_linear_data(issue: str, edit_mode: bool) -> dict[str, str]: + # If LINEAR_API_KEY is set and issue number is not empty, fetch issue details + if LINEAR_API_KEY: + try: + linear_issue = retrieve_linear_issue(issue) + return { + "commit_msg_title": linear_issue["title"], + "commit_msg_body": linear_issue["description"], + } + except Exception as exception: + if not edit_mode: + return {} + error_details = [ + "# Error fetching issue details from Linear:", + "#", + ] + if hasattr(exception, "errors") and isinstance(exception.errors, list): + error_details += [f"#\t{e['message']}" for e in exception.errors] + else: + error_details += [f"#\t{str(exception)}"] + error_details += ["#"] + return { + "commit_msg_body": "\n".join(error_details), + } + else: + if not edit_mode: + return {} + linear_info = [ + "# NEW FEATURE: Use Linear API key to fetch commit title and description:", + "#", + "#\tTo populate commit message with title and description for an issue number detected", + "#\tin the branch name, ensure that the environment variable LINEAR_API_KEY is set.", + "#\tGet this from Personal API keys section at linear.app/tillit/settings/api.", + "#", + ] + return { + "commit_msg_body": "\n".join(linear_info), + } + + def prepare_commit_msg(raw_commit_msg: str, branch: str) -> str: - commit_msg_lines = raw_commit_msg.strip().splitlines() + commit_msg_lines = raw_commit_msg.splitlines() + edit_mode = EDITOR_TEXT in raw_commit_msg branch_data = extract_branch_data(branch) + raw_commit_msg_title = commit_msg_lines[0] if len(commit_msg_lines) > 0 else "" + + linear_data = {} + if (issue := branch_data["issue"]) and not raw_commit_msg_title: + linear_data = retrieve_linear_data(issue, edit_mode) + commit_msg_title_data = extract_commit_msg_title_data( - commit_msg_lines[0] if len(commit_msg_lines) > 0 else "" + linear_data.get("commit_msg_title") or raw_commit_msg_title ) - issue = commit_msg_title_data["issue"] or branch_data["issue"] commit_type = commit_msg_title_data["commit_type"] or branch_data["commit_type"] commit_msg_title = ( commit_msg_title_data["commit_msg_title"] or branch_data["commit_msg_title"] ) - commit_msg_body = "\n".join(commit_msg_lines[1:]) - if EDITOR_TEXT in raw_commit_msg: - commit_msg_body += f"\n{common.commented_commit_type_doc}" - # If LINEAR_API_KEY is set and issue number is not empty, fetch issue details - if LINEAR_API_KEY and issue: - try: - linear_issue = retrieve_linear_issue(issue) - commit_msg_title = linear_issue["title"] or commit_msg_title - commit_msg_body = linear_issue["description"] + commit_msg_body - except Exception as exception: - error_details = [ - "# Error while fetching issue details from Linear:", - "#", - ] - if hasattr(exception, "errors") and isinstance(exception.errors, list): - error_details += [f"#\t{e['message']}" for e in exception.errors] - else: - error_details += [f"#\t{str(exception)}"] - error_details += ["#"] - commit_msg_body += "\n" + "\n".join(error_details) - else: - linear_info = [ - "# Fetching issue details from Linear using API key:", - "#", - "#\tTo populate commit message with title and description for an issue number detected", - "#\tin the branch name, ensure that the environment variable LINEAR_API_KEY is set.", - "#\tGet this from Personal API keys section at linear.app/tillit/settings/api.", - "#", - ] - commit_msg_body += "\n" + "\n".join(linear_info) + commit_type_lines = [common.commented_commit_type_doc] if edit_mode else [] + linear_commit_msg_lines = ( + [linear_data["commit_msg_body"]] if linear_data.get("commit_msg_body") else [] + ) + commit_msg_body = "\n".join( + linear_commit_msg_lines + commit_msg_lines[1:] + commit_type_lines + ) # Write to commit message message = commit_msg_title From 2dced18599d4088438443dd2c5910c6ea2edf9cc Mon Sep 17 00:00:00 2001 From: Bharat Kunwar <bkunwar@two.inc> Date: Mon, 24 Jun 2024 08:34:18 +0100 Subject: [PATCH 2/2] Bump version 24.06.18 -> 24.06.24 --- README.md | 6 +++--- git_hooks/commit_msg.py | 2 +- pyproject.toml | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index ec65677..7db4864 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ To only check for a reference to a Linear issue in your commit message, add this ```yaml # .pre-commit-config.yaml - repo: https://github.com/two-inc/git-hooks.git - rev: 24.06.18 + rev: 24.06.24 hooks: - id: linear-ref ``` @@ -23,7 +23,7 @@ To check for both a reference to a Linear issue as well as a conventional commit ```yaml # .pre-commit-config.yaml - repo: https://github.com/two-inc/git-hooks.git - rev: 24.06.18 + rev: 24.06.24 hooks: - id: commit-type-with-linear-ref ``` @@ -33,7 +33,7 @@ Alternatively, you can use ssh ```yaml # .pre-commit-config.yaml - repo: git@github.com:two-inc/git-hooks.git - rev: 24.06.18 + rev: 24.06.24 hooks: - id: commit-type-with-linear-ref ``` diff --git a/git_hooks/commit_msg.py b/git_hooks/commit_msg.py index d1b2c8a..239f29a 100644 --- a/git_hooks/commit_msg.py +++ b/git_hooks/commit_msg.py @@ -21,7 +21,7 @@ T-5482/feat: Amazing new feature -See https://github.com/two-inc/git-hooks/blob/24.06.18/README.md for more info. +See https://github.com/two-inc/git-hooks/blob/24.06.24/README.md for more info. {ENDC} {common.commit_type_doc} """ diff --git a/pyproject.toml b/pyproject.toml index ee3b973..9e352d4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "git-hooks" -version = "24.06.18" +version = "24.06.24" dependencies = [ "gql[requests]==3.4.1", ] @@ -17,7 +17,7 @@ prepare-commit-msg = "git_hooks.prepare_commit_msg:main" commit-msg = "git_hooks.commit_msg:main" [tool.bumpver] -current_version = "24.06.18" +current_version = "24.06.24" version_pattern = "0Y.0M.0D[-INC0]" commit_message = "Bump version {old_version} -> {new_version}" commit = true