This commit is contained in:
parent
02d6d34b02
commit
f0a74c1122
21
.github/workflows/pyruff.yml
vendored
21
.github/workflows/pyruff.yml
vendored
@ -48,8 +48,19 @@ jobs:
|
||||
- name: pull_request message with Ruff Lint results
|
||||
id: prMessageRuffLint
|
||||
run: |
|
||||
curl -v -X POST \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: token ${{ secrets.GITEA_TOKEN }}" \
|
||||
-d @lint-result.json \
|
||||
${{ gitea.server_url }}/api/v1/repos/${{ gitea.repository }}/issues/8/comments
|
||||
# イベントがプルリクエストの場合はPRにコメントを追加する
|
||||
if [ "${{ github.event_name }}" = "pull_request" ]; then
|
||||
echo "Posting Ruff Lint results to Pull Request..."
|
||||
curl -v -X POST \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: token ${{ secrets.GITEA_TOKEN }}" \
|
||||
-d @lint-result.json \
|
||||
${{ gitea.server_url }}/api/v1/repos/${{ gitea.repository }}/issues/${{ github.event.pull_request.number }}/comments
|
||||
else
|
||||
echo "Not a pull request event."
|
||||
echo "Ruff Lint results:"
|
||||
echo "-------------------"
|
||||
cat lint-result.md
|
||||
echo "-------------------"
|
||||
echo "No PR detected. Skipping API comment."
|
||||
fi
|
||||
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@ -4,7 +4,9 @@ __pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
ruff-report.*
|
||||
lint-result.md
|
||||
lint-result.json
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
|
||||
@ -11,7 +11,7 @@ logger = get_logger(__name__)
|
||||
|
||||
def example():
|
||||
logger.info("Application started")
|
||||
print("Hello, World!")
|
||||
print("Hello, World!")
|
||||
|
||||
|
||||
example()
|
||||
|
||||
@ -1,15 +0,0 @@
|
||||
## Linter(リンタ)レビュー
|
||||
|
||||
以下の指摘事項があります。コードを見直してください。
|
||||
|
||||
総数:6個
|
||||
|
||||
### 指摘事項一覧
|
||||
|コード|重要性|項目|ファイル名|行数|
|
||||
|---|---|---|---|---|
|
||||
|W291|🟢低|行末に不要な空白があります。|examples/example.py|14行目27列 〜 14行目28列|
|
||||
|W291|🟢低|行末に不要な空白があります。|scripts/generate_coverage.py|5行目23列 〜 5行目24列|
|
||||
|E501|🟢低|行が長すぎます。79文字以内にしてください。|scripts/generate_coverage.py|38行目89列 〜 38行目107列|
|
||||
|W291|🟢低|行末に不要な空白があります。|scripts/generate_linter_from_json.py|4行目23列 〜 4行目24列|
|
||||
|W291|🟢低|行末に不要な空白があります。|scripts/generate_linter_from_json.py|25行目31列 〜 25行目39列|
|
||||
|W292|🟢低|ファイルの最後に改行がありません。|scripts/generate_linter_from_json.py|53行目42列 〜 53行目42列|
|
||||
@ -1,6 +1,12 @@
|
||||
line-length = 88
|
||||
|
||||
# 末尾スペース・空行まわりをチェックするのは E と W系のルール
|
||||
# E7xx/E9xx(構文/実行時エラーの可能性)
|
||||
# W1xx/W5xx(スタイル・フォーマット関連)
|
||||
# DXXX(ドキュメンテーション文字列関連)
|
||||
# F (未使用インポートなどのエラー)
|
||||
# BXX(バグの可能性)
|
||||
|
||||
[lint]
|
||||
select = ["E", "W"]
|
||||
select = ["F", "E", "W", "D101", "B"]
|
||||
ignore = []
|
||||
@ -2,9 +2,11 @@ import re
|
||||
|
||||
|
||||
class GenerateCoverage:
|
||||
def __init__(self,
|
||||
coverage_file="pytest-coverage.txt",
|
||||
output_file="coverage_table.md"):
|
||||
"""カバレッジ結果を解析して Markdown テーブルを生成"""
|
||||
|
||||
def __init__(
|
||||
self, coverage_file="pytest-coverage.txt", output_file="coverage_table.md"
|
||||
):
|
||||
"""
|
||||
初期化
|
||||
|
||||
@ -35,26 +37,28 @@ class GenerateCoverage:
|
||||
if in_coverage_section and line.strip().startswith("---"):
|
||||
continue
|
||||
# Coverage セクションの終わりを検出(TOTAL行の次の空行)
|
||||
if in_coverage_section and (line.strip().startswith("TOTAL") or line.strip().startswith("=")):
|
||||
if in_coverage_section and (
|
||||
line.strip().startswith("TOTAL") or line.strip().startswith("=")
|
||||
):
|
||||
break
|
||||
# Coverage データを抽出
|
||||
if in_coverage_section:
|
||||
match = re.match(
|
||||
r"(.+?)\s+(\d+)\s+(\d+)\s+(\d+%)\s*(.*)", line)
|
||||
match = re.match(r"(.+?)\s+(\d+)\s+(\d+)\s+(\d+%)\s*(.*)", line)
|
||||
if match:
|
||||
filename = match.group(1).strip()
|
||||
statements = match.group(2).strip()
|
||||
missed = match.group(3).strip()
|
||||
coverage = match.group(4).strip()
|
||||
missing_lines = match.group(
|
||||
5).strip() if match.group(5) else "-"
|
||||
coverage_info.append({
|
||||
"filename": filename,
|
||||
"statements": statements,
|
||||
"missed": missed,
|
||||
"coverage": coverage,
|
||||
"missing_lines": missing_lines
|
||||
})
|
||||
missing_lines = match.group(5).strip() if match.group(5) else "-"
|
||||
coverage_info.append(
|
||||
{
|
||||
"filename": filename,
|
||||
"statements": statements,
|
||||
"missed": missed,
|
||||
"coverage": coverage,
|
||||
"missing_lines": missing_lines,
|
||||
}
|
||||
)
|
||||
|
||||
self.coverage_data = coverage_info
|
||||
|
||||
@ -72,9 +76,11 @@ class GenerateCoverage:
|
||||
|
||||
# テーブル行を生成
|
||||
table_rows = [
|
||||
(f"| {data['filename']} | {data['statements']} | "
|
||||
f"{data['missed']} | {data['coverage']} | "
|
||||
f"{data['missing_lines']} |")
|
||||
(
|
||||
f"| {data['filename']} | {data['statements']} | "
|
||||
f"{data['missed']} | {data['coverage']} | "
|
||||
f"{data['missing_lines']} |"
|
||||
)
|
||||
for data in self.coverage_data
|
||||
]
|
||||
|
||||
|
||||
@ -7,13 +7,18 @@ print(f"Project Name: {PROJECT_NAME}")
|
||||
|
||||
CODE_MAP = {
|
||||
"W291": {"message": "行末に不要な空白があります。", "severity": "🟢低"},
|
||||
"W292": {"message": "ファイルの最後に改行がありません。", "severity": "🟢低"} ,
|
||||
"W292": {"message": "ファイルの最後に改行がありません。", "severity": "🟢低"},
|
||||
"E501": {
|
||||
"message": "行が長すぎます。79文字以内にしてください。",
|
||||
"severity": "🟢低",
|
||||
},
|
||||
"D101": {
|
||||
"message": "クラスにドキュメンテーション文字列がありません。",
|
||||
"severity": "⚪️無害",
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
def get_relative_path(absolute_path: str) -> str:
|
||||
"""
|
||||
絶対パスからプロジェクトルートからの相対パスを取得
|
||||
@ -26,7 +31,8 @@ def get_relative_path(absolute_path: str) -> str:
|
||||
|
||||
|
||||
class GenerateLinter:
|
||||
def __init__(self, json_file="ruff-report.json", output_file="lint-result.json"):
|
||||
"""Linterレポートを生成するクラス"""
|
||||
def __init__(self, json_file="ruff-report.json", output_file="lint-result"):
|
||||
"""
|
||||
初期化
|
||||
"""
|
||||
@ -46,43 +52,56 @@ class GenerateLinter:
|
||||
_str += f"総数:{len(data)}個\n"
|
||||
|
||||
_str += "### 指摘事項一覧\n"
|
||||
_str += "|コード|重要性|項目|ファイル名|行数|\n"
|
||||
_str += "|---|---|---|---|---|\n"
|
||||
_str += "|コード|重要性|項目|ファイル名|行数|自動修正|\n"
|
||||
_str += "|---|---|---|---|---|---|\n"
|
||||
for issue in data:
|
||||
code = issue.get("code", "-")
|
||||
severity = (
|
||||
CODE_MAP.get(code, {}).get("severity", "❓不明")
|
||||
if code != "-"
|
||||
else "-"
|
||||
CODE_MAP.get(code, {}).get("severity", "❓不明") if code != "-" else "-"
|
||||
)
|
||||
message = CODE_MAP.get(code, {}).get("message", issue.get("message", "-"))
|
||||
filename = get_relative_path(issue.get("filename", "-"))
|
||||
file_link = f"./{filename}"
|
||||
|
||||
line = ""
|
||||
if issue.get("location") and issue["location"].get("row"):
|
||||
line = f"{issue['location']['row']}行目"
|
||||
if issue["location"].get("column"):
|
||||
line += f"{issue['location']['column']}列"
|
||||
|
||||
if issue.get("end_location"):
|
||||
if issue["end_location"].get("row"):
|
||||
line += f" 〜 {issue['end_location']['row']}行目"
|
||||
if issue["end_location"].get("column"):
|
||||
line += f"{issue['end_location']['column']}列"
|
||||
auto_fix = "✅" if issue.get("fix") else "❌"
|
||||
|
||||
_str += f"|{code}|{severity}|{message}|"
|
||||
_str += f"[{filename}]({file_link})|{line}|{auto_fix}|\n"
|
||||
|
||||
_str += "\n\n"
|
||||
_str += "### 自動修正コマンド\n"
|
||||
_str += ("自動修正が可能な指摘事項については、"
|
||||
"以下のコマンドで自動修正を試みることができます。\n\n"
|
||||
)
|
||||
_str += "```bash\n"
|
||||
_str += "ruff check --fix .\n"
|
||||
_str += "```\n\n"
|
||||
|
||||
_str += f"|{code}|{severity}|{message}|{filename}|{line}|\n"
|
||||
return _str
|
||||
|
||||
def generate_lint_report_json(self):
|
||||
with open(self.json_file, "r") as f:
|
||||
data = json.load(f)
|
||||
|
||||
with open(self.output_file, "w") as f:
|
||||
# report_body = self._genarate_lint_report(data)
|
||||
# f.write(report_body)
|
||||
with open(f"{self.output_file}.md", "w") as f:
|
||||
report_body = self._genarate_lint_report(data)
|
||||
f.write(report_body)
|
||||
|
||||
with open(f"{self.output_file}.json", "w") as f:
|
||||
report = {"body": self._genarate_lint_report(data)}
|
||||
json.dump(report, f, ensure_ascii=False, indent=4)
|
||||
|
||||
print(f"Linter report generated: {self.output_file}")
|
||||
print(f"Linter report generated: {self.output_file}.md, {self.output_file}.json")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@ -11,6 +11,7 @@ import threading
|
||||
|
||||
|
||||
class Singleton(object):
|
||||
"""シングルトンパターンの基底クラス"""
|
||||
_instances = {}
|
||||
_lock = threading.Lock()
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user