Skip to content

fix: 型安全性の改善 (#787) - #788

Merged
keito4 merged 1 commit into
mainfrom
claude/issue-787-20260602-0301
Jun 2, 2026
Merged

fix: 型安全性の改善 (#787)#788
keito4 merged 1 commit into
mainfrom
claude/issue-787-20260602-0301

Conversation

@keito4

@keito4 keito4 commented Jun 2, 2026

Copy link
Copy Markdown
Owner

Closes #787

変更内容

  • script/lib/brew_categories.py: Python型アノテーション完全追加
  • commitlint.config.js: JSDoc型アノテーション追加

Generated with Claude Code

Summary by CodeRabbit

  • Chores
    • Improved code documentation for internal utilities.
    • Enhanced type safety and code clarity with type annotations.

- script/lib/brew_categories.py: 型アノテーション完全追加
  - from typing import Any を追加
  - load_manifest: dict -> dict[str, Any]
  - matches: dict -> dict[str, Any]
  - categorize: 引数・戻り値の型アノテーション追加
  - emit_human/emit_brew: 型アノテーション追加
  - main: 戻り値 -> None を追加
- commitlint.config.js: JSDoc型アノテーション追加
  - getStagedFiles: @returns {string[]} 追加
  - releaseTypeRule: @param/@returns 追加

Closes #787

Co-authored-by: keito4 <keito4@users.noreply.github.com>
@coderabbitai

coderabbitai Bot commented Jun 2, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

This PR improves type safety across two utility files. JSDoc comments document helper function contracts in commitlint.config.js. Python type-hinting is added to all functions in script/lib/brew_categories.py, including structured return types and container annotations, without changing runtime behavior.

Changes

JavaScript Documentation

Layer / File(s) Summary
JSDoc comments for staged files and commit validation helpers
commitlint.config.js
Added JSDoc blocks documenting the staged-files helper that returns a list of staged file paths, and the commit validation helper that returns a validation tuple.

Python Type Safety

Layer / File(s) Summary
Type imports and basic function annotations
script/lib/brew_categories.py
Imported Any from typing and annotated load_manifest and matches with dict[str, Any] types for parameters and return values.
Structured return types and output function annotations
script/lib/brew_categories.py
Annotated categorize with a fully structured return type, typed both emit_human and emit_brew output functions, and added explicit -> None return annotation to main.

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

  • keito4/config#202: Both PRs modify script/lib/brew_categories.py and update type annotations/signatures for functions like emit_brew that handle uncategorized items.

Poem

Docs and types bloom so bright,
Brewing code with structured light.
Safety checks in every line,
Functions dance in form divine.
— A helpful hop from CodeRabbit 🐰✨

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description deviates from the required template structure, omitting key sections like 'Why', 'How to test', and 'Checklist', though it does specify which files were changed and their modifications. Follow the repository's PR template by including all sections: Summary, Why, What, How to test, Checklist, and Related sections with complete information.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: improving type safety (型安全性の改善) with type annotations added to Python and JavaScript files.
Linked Issues check ✅ Passed The PR successfully addresses all primary objectives from issue #787: type safety improvements by adding type annotations to Python (brew_categories.py with typing.Any, function signatures) and JavaScript (commitlint.config.js with JSDoc), directly resolving the issue's core requirements.
Out of Scope Changes check ✅ Passed All changes are strictly within scope of issue #787: only type annotations and JSDoc blocks were added without runtime logic modifications, behavior changes, or unrelated alterations to either file.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/issue-787-20260602-0301

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@claude

claude Bot commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

Claude finished @keito4's task in 1m 9s —— View job


コードレビュー: fix: 型安全性の改善

  • コンテキスト収集
  • 変更ファイルの確認
  • コードレビュー実施
  • フィードバック投稿

全体として型安全性を向上させる良い変更です。2点ほど確認事項があります。


commitlint.config.js

[minor] releaseTypeRule の戻り値型に抜け漏れ

現在のJSDoc:

 * @returns {[true] | [false, string]} Validation result

実際の関数は3パターンを返します:

  1. [true] — リリースセンシティブなファイルに触れていない場合
  2. [true, string] — ファイルに触れていて、かつコミットタイプが許可リストに含まれる場合
  3. [false, string] — ファイルに触れていて、コミットタイプが不正な場合
return [isReleaseType, `Changes in ${touched.join(', ')} require ...`];
// isReleaseType が true の場合も [true, string] を返す

正しい型は [true] | [boolean, string] または [true] | [true, string] | [false, string] になります。現状のままだと型が不正確でレビュアーを誤解させる可能性があります。

Fix this →


script/lib/brew_categories.py

[recommendation] Python 3.9+ 限定の組み込みジェネリクス構文

dict[str, Any]list[str]tuple[...] などの組み込み型を型アノテーションとして直接使用するには Python 3.9+ が必要です(PEP 585)。

Python 3.8 以前をサポートする場合は from __future__ import annotations の追加か、typing.Dict / typing.List / typing.Tuple が必要ですが、devcontainer ベースイメージ(ghcr.io/keito4/config-base:latest)で Python 3.9+ が保証されているなら現状で問題ありません。

現在 from typing import Any を追加しているので、Python バージョン要件を READMEpyproject.toml 等に明記しておくとさらに良いでしょう。


総評

brew_categories.py の変更は全て正確で問題ありません。categorize() の完全な戻り値型 tuple[list[tuple[str, list[str]]], list[str]] も適切です。commitlint.config.js の JSDoc は releaseTypeRule の戻り値型が不完全である点以外は良好です。

verdict: APPROVE(minor指摘のみ)

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a600d322b8

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".



def load_manifest(path: Path) -> dict:
def load_manifest(path: Path) -> dict[str, Any]:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep brew_categories compatible with Python 3.8

When brew-deps.sh runs on a machine where python3 is still Python 3.8, this annotation is evaluated at import time and dict[str, Any] raises TypeError: 'type' object is not subscriptable before the script can do any work. The wrapper only checks that python3 exists and the docs advertise this as a generic Homebrew helper, so this change regresses users with older but still common python3 installations unless annotations are postponed or typing.Dict/List style is used.

Useful? React with 👍 / 👎.

@keito4 keito4 self-assigned this Jun 2, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
commitlint.config.js (1)

36-39: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Fix the return value to match the JSDoc and correct the logic.

The JSDoc documents that the function should return [true] on pass, but the implementation always returns a 2-element tuple [isReleaseType, message]. When isReleaseType is true, the function returns [true, "Changes in ... require..."], which includes an error message even though validation passed. This contradicts the JSDoc and is semantically incorrect.

🐛 Proposed fix to match JSDoc behavior
  const isReleaseType = releaseTypeAllowList.has(parsed.type || '');
-  return [
-    isReleaseType,
-    `Changes in ${touched.join(', ')} require a release-triggering type (feat|fix|perf|revert|docs) to keep semantic-release automated.`,
-  ];
+  return isReleaseType
+    ? [true]
+    : [false, `Changes in ${touched.join(', ')} require a release-triggering type (feat|fix|perf|revert|docs) to keep semantic-release automated.`];
};
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@commitlint.config.js` around lines 36 - 39, The function currently always
returns a two-element tuple [isReleaseType, message], which causes a success
case to include an error message; update the return logic so that when
isReleaseType is true it returns [true] (matching the JSDoc), and when false it
returns [false, `Changes in ${touched.join(', ')} require a release-triggering
type (feat|fix|perf|revert|docs) to keep semantic-release automated.`]; locate
the variables isReleaseType and touched in commitlint.config.js and implement
this conditional return to match the documented behavior.
🧹 Nitpick comments (1)
script/lib/brew_categories.py (1)

37-37: ⚡ Quick win

Consider TypedDict for match specification structure.

The match_spec dictionary has a known structure with keys "exact", "prefix", and "regex" (all mapping to lists of strings). Defining this with a TypedDict would provide better type safety than dict[str, Any] and align with the PR's goal to reduce any usage.

♻️ Proposed TypedDict definition
+from typing import Any, TypedDict
+
+
+class MatchSpec(TypedDict, total=False):
+    exact: list[str]
+    prefix: list[str]
+    regex: list[str]
+
+
+class CategorySpec(TypedDict, total=False):
+    id: str
+    title: str
+    match: MatchSpec

Then update the function signature:

-def matches(match_spec: dict[str, Any], item: str) -> bool:
+def matches(match_spec: MatchSpec, item: str) -> bool:

And update categorize:

 def categorize(
     items: list[str],
-    categories: list[dict[str, Any]],
+    categories: list[CategorySpec],
 ) -> tuple[list[tuple[str, list[str]]], list[str]]:
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@script/lib/brew_categories.py` at line 37, Define a TypedDict (e.g.,
MatchSpec) describing the match specification with keys "exact", "prefix", and
"regex" each typed as list[str], import TypedDict and List from typing, then
change the matches function signature from matches(match_spec: dict[str, Any],
item: str) to matches(match_spec: MatchSpec, item: str) and update any callers
such as categorize to accept/annotate MatchSpec instead of dict[str, Any] so the
structure is strongly typed across the module.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@commitlint.config.js`:
- Around line 36-39: The function currently always returns a two-element tuple
[isReleaseType, message], which causes a success case to include an error
message; update the return logic so that when isReleaseType is true it returns
[true] (matching the JSDoc), and when false it returns [false, `Changes in
${touched.join(', ')} require a release-triggering type
(feat|fix|perf|revert|docs) to keep semantic-release automated.`]; locate the
variables isReleaseType and touched in commitlint.config.js and implement this
conditional return to match the documented behavior.

---

Nitpick comments:
In `@script/lib/brew_categories.py`:
- Line 37: Define a TypedDict (e.g., MatchSpec) describing the match
specification with keys "exact", "prefix", and "regex" each typed as list[str],
import TypedDict and List from typing, then change the matches function
signature from matches(match_spec: dict[str, Any], item: str) to
matches(match_spec: MatchSpec, item: str) and update any callers such as
categorize to accept/annotate MatchSpec instead of dict[str, Any] so the
structure is strongly typed across the module.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 9fa5c4f8-ed87-443e-b7ea-ccefae23d317

📥 Commits

Reviewing files that changed from the base of the PR and between 1165eb9 and a600d32.

📒 Files selected for processing (2)
  • commitlint.config.js
  • script/lib/brew_categories.py

@keito4
keito4 merged commit a671a88 into main Jun 2, 2026
21 checks passed
@keito4
keito4 deleted the claude/issue-787-20260602-0301 branch June 2, 2026 04:14
@github-actions

github-actions Bot commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

🎉 This PR is included in version 1.113.2 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

@github-actions github-actions Bot added the released リリース済み label Jun 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

released リリース済み

Projects

None yet

Development

Successfully merging this pull request may close these issues.

型安全性の改善

1 participant