怎样实现统一代码注释风格脚本

wen 实用脚本 24

本文目录导读:

怎样实现统一代码注释风格脚本

  1. Python 实现版本(功能最完整)
  2. 简单的 Bash 脚本版本
  3. 使用 pre-commit 钩子(推荐)
  4. ESLint 配置(JavaScript/TypeScript)
  5. 使用示例

我来帮你实现一个统一的代码注释风格检测和格式化脚本,这里提供几个不同语言的实现方案:

Python 实现版本(功能最完整)

#!/usr/bin/env python3
"""
代码注释风格统一检查与格式化工具
支持:Python, JavaScript, TypeScript, Java, C/C++
"""
import re
import os
import sys
from pathlib import Path
class CommentStyleChecker:
    def __init__(self, config=None):
        self.config = config or {
            'max_line_length': 80,
            'require_space_after_marker': True,  # # 后面要有空格
            'require_capital_start': True,       # 注释首字母大写
            'require_period_end': True,          # 注释结尾需要句号
            'block_comment_style': 'consistent', # 块注释风格:consistent, asterisk, star
        }
        self.errors = []
    def check_line_comment(self, line, line_num, file_path):
        """检查单行注释"""
        # Python样式 (#)
        if line.strip().startswith('#'):
            return self._check_python_line_comment(line, line_num)
        # // 样式
        elif '//' in line:
            return self._check_double_slash_comment(line, line_num)
        return True
    def _check_python_line_comment(self, line, line_num):
        """检查Python风格注释"""
        stripped = line.strip()
        if stripped == '#':
            return True
        # 检查#后面是否有空格
        if self.config['require_space_after_marker']:
            match = re.match(r'^#(\S)', stripped)
            if match:
                self.errors.append(f"缺少空格: {line_num}: {stripped}")
                return False
        # 检查首字母大写
        if self.config['require_capital_start']:
            content = stripped.lstrip('#').strip()
            if content and content[0].islower():
                self.errors.append(f"首字母需大写: {line_num}: {stripped}")
                return False
        # 检查结尾句号
        if self.config['require_period_end'] and not stripped.endswith('.'):
            # 跳过空注释和URL等
            if not any(stripped.endswith(s) for s in [':', ';', ')']):
                self.errors.append(f"需要句号结尾: {line_num}: {stripped}")
                return False
        return True
    def _check_double_slash_comment(self, line, line_num):
        """检查//风格注释"""
        # 提取注释内容
        comment_match = re.search(r'//(.+)$', line)
        if not comment_match:
            return True
        comment = comment_match.group(1)
        # 检查//后面是否有空格
        if self.config['require_space_after_marker']:
            if comment and not comment.startswith(' '):
                self.errors.append(f"//后需空格: {line_num}: {line.strip()}")
                return False
        return True
    def check_block_comment(self, content, file_path):
        """检查块注释"""
        lines = content.split('\n')
        in_block = False
        block_start = 0
        for i, line in enumerate(lines, 1):
            stripped = line.strip()
            if not in_block:
                if stripped.startswith('/*') or stripped.startswith('"""'):
                    in_block = True
                    block_start = i
                    # 检查开始标记
                    if not self._check_block_start(stripped):
                        self.errors.append(f"块注释开始格式: {i}: {stripped}")
            else:
                if stripped.endswith('*/') or stripped.endswith('"""'):
                    in_block = False
                elif self.config['block_comment_style'] == 'asterisk':
                    # 中间行需要*对齐
                    if not stripped.startswith('*') and stripped:
                        self.errors.append(f"块注释对齐: {i}: {stripped}")
        return len(self.errors) == 0
    def _check_block_start(self, line):
        """检查块注释开始"""
        if line.startswith('/*'):
            return True
        if line.startswith('"""'):
            return True
        return False
    def auto_fix_line_comment(self, line):
        """自动修复单行注释"""
        stripped = line
        # 修复Python注释 (#后面加空格)
        if line.strip().startswith('#'):
            stripped = re.sub(r'^(\s*#)(\S)', r'\1 \2', line)
        # 修复//注释 (//后面加空格)
        if '//' in line:
            stripped = re.sub(r'(//)(\S)', r'\1 \2', stripped)
        # 首字母大写
        if self.config['require_capital_start']:
            if stripped.strip().startswith('#') or '//' in stripped:
                # 提取注释内容
                if stripped.strip().startswith('#'):
                    content = stripped.strip().lstrip('#').strip()
                    if content and content[0].islower():
                        content = content[0].upper() + content[1:]
                        # 替换回原位置
                        indent = len(line) - len(line.lstrip())
                        stripped = ' ' * indent + '# ' + content + '\n'
        return stripped
def format_file(file_path, checker):
    """格式化单个文件"""
    try:
        with open(file_path, 'r', encoding='utf-8') as f:
            content = f.read()
    except UnicodeDecodeError:
        try:
            with open(file_path, 'r', encoding='gbk') as f:
                content = f.read()
        except:
            return False
    # 检查注释
    lines = content.split('\n')
    formatted_lines = []
    has_changes = False
    for i, line in enumerate(lines, 1):
        if '#' in line or '//' in line or '/*' in line:
            fixed = checker.auto_fix_line_comment(line)
            if fixed != line:
                has_changes = True
                formatted_lines.append(fixed)
            else:
                formatted_lines.append(line)
        else:
            formatted_lines.append(line)
    if has_changes:
        with open(file_path, 'w', encoding='utf-8') as f:
            f.write('\n'.join(formatted_lines))
        print(f"✅ 已修复: {file_path}")
        return True
    return False
def main():
    """主函数"""
    import argparse
    parser = argparse.ArgumentParser(description='统一代码注释风格工具')
    parser.add_argument('paths', nargs='+', help='要检查的文件或目录路径')
    parser.add_argument('--fix', action='store_true', help='自动修复注释风格')
    parser.add_argument('--extensions', nargs='+', default=['.py', '.js', '.ts', '.java', '.c', '.cpp'],
                       help='要处理的文件扩展名')
    args = parser.parse_args()
    checker = CommentStyleChecker()
    # 收集文件
    files = []
    for path in args.paths:
        p = Path(path)
        if p.is_file():
            files.append(p)
        elif p.is_dir():
            for ext in args.extensions:
                files.extend(p.rglob(f'*{ext}'))
    # 处理文件
    total_errors = 0
    for file_path in files:
        try:
            with open(file_path, 'r', encoding='utf-8') as f:
                content = f.read()
        except:
            continue
        # 检查
        errors_before = len(checker.errors)
        checker.check_line_comment(content, 0, file_path)
        checker.check_block_comment(content, file_path)
        errors_after = len(checker.errors)
        if errors_after > errors_before:
            total_errors += (errors_after - errors_before)
            print(f"❌ 检查失败: {file_path}")
            for error in checker.errors[errors_before:]:
                print(f"   {error}")
        # 修复
        if args.fix:
            format_file(file_path, checker)
    if total_errors == 0:
        print("✅ 所有文件注释风格一致!")
    else:
        print(f"⚠️  发现 {total_errors} 个注释风格问题")
        if not args.fix:
            print("  使用 --fix 参数自动修复")
if __name__ == '__main__':
    main()

简单的 Bash 脚本版本

#!/bin/bash
# 统一代码注释风格检查脚本
# 支持 Python, JavaScript, TypeScript
check_comments() {
    local file=$1
    local errors=0
    echo "检查文件: $file"
    # 读取文件
    while IFS= read -r line; do
        line_num=$((line_num + 1))
        # 检查 Python 注释 (#)
        if [[ $line == *"#"* ]] && [[ ! $line == *"#!"* ]]; then
            # 提取注释部分
            comment=${line##*#}
            if [[ -n $comment ]]; then
                # 检查#后面是否有空格
                if [[ $comment != " "* ]]; then
                    echo "  ⚠️  第 $line_num 行: # 后缺少空格"
                    ((errors++))
                fi
                # 检查注释内容
                content=$(echo "$comment" | sed 's/^ *//')
                if [[ -n $content ]]; then
                    # 检查首字母大写
                    first_char=${content:0:1}
                    if [[ $first_char =~ [a-z] ]]; then
                        echo "  ⚠️  第 $line_num 行: 注释首字母需大写"
                        ((errors++))
                    fi
                fi
            fi
        fi
        # 检查 // 注释
        if [[ $line == *"//"* ]]; then
            if [[ ! $line == *"https://"* ]] && [[ ! $line == *"http://"* ]]; then
                echo "  ⚠️  第 $line_num 行: 发现 // 注释"
                ((errors++))
            fi
        fi
    done < "$file"
    return $errors
}
# 主逻辑
if [[ -z $1 ]]; then
    echo "用法: $0 <文件或目录>"
    echo "示例: $0 ./src"
    exit 1
fi
total_errors=0
if [[ -f $1 ]]; then
    check_comments "$1"
    total_errors=$?
elif [[ -d $1 ]]; then
    find "$1" -type f \( -name "*.py" -o -name "*.js" -o -name "*.ts" \) | while read file; do
        check_comments "$file"
        total_errors=$((total_errors + $?))
    done
fi
if [[ $total_errors -eq 0 ]]; then
    echo "✅ 所有注释风格一致!"
else
    echo "⚠️  发现 $total_errors 个问题"
fi

使用 pre-commit 钩子(推荐)

创建 .pre-commit-config.yaml 文件:

repos:
  - repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v4.4.0
    hooks:
      - id: check-added-large-files
      - id: check-merge-conflict
      - id: check-yaml
  # Python 注释检查
  - repo: https://github.com/PyCQA/pydocstyle
    rev: 6.3.0
    hooks:
      - id: pydocstyle
        args: ["--convention=google"]
  # JavaScript/TypeScript 注释检查
  - repo: https://github.com/eslint/eslint
    rev: v8.56.0
    hooks:
      - id: eslint
        args: ["--rule", "spaced-comment: [error, always]"]
  # 通用注释格式化
  - repo: local
    hooks:
      - id: comment-style
        name: comment-style-check
        entry: python3 scripts/comment_style.py
        language: python
        types: [python, javascript, typescript]
        args: ["--fix"]

ESLint 配置(JavaScript/TypeScript)

创建 .eslintrc.json

{
  "rules": {
    "spaced-comment": ["error", "always", {
      "line": {
        "markers": ["/", "#"],
        "exceptions": ["-", "+", "*"]
      },
      "block": {
        "markers": ["!"],
        "exceptions": ["*", "**"],
        "balanced": true
      }
    }],
    "capitalized-comments": ["warn", "always", {
      "ignoreConsecutiveComments": true,
      "ignoreInlineComments": true
    }],
    "multiline-comment-style": ["warn", "starred-block"]
  }
}

使用示例

# 安装依赖
pip install pre-commit
npm install -g eslint
# 检查注释风格
python3 comment_style.py ./src --extensions .py .js .ts
# 自动修复
python3 comment_style.py ./src --fix
# 使用 pre-commit
pre-commit install
pre-commit run --all-files

这个脚本可以根据你的需求定制,主要功能包括:

  1. 检查注释格式:空格、大小写、标点符号
  2. 自动修复:一键格式化所有注释
  3. 多语言支持:Python、JavaScript、TypeScript、Java等
  4. 集成 pre-commit:提交代码前自动检查
  5. 灵活配置:通过配置文件自定义规则

你可以根据团队的具体规范调整配置文件中的参数。

抱歉,评论功能暂时关闭!