Skip to content

Commit 87936b1

Browse files
committed
build: 修改 .clang-format,添加格式化脚本
Signed-off-by: YdrMaster <[email protected]>
1 parent 9eddc91 commit 87936b1

File tree

2 files changed

+185
-54
lines changed

2 files changed

+185
-54
lines changed

.clang-format

Lines changed: 19 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,66 +1,31 @@
1-
# Generated from CLion C/C++ Code Style settings
1+
---
22
BasedOnStyle: LLVM
3-
AccessModifierOffset: -4
4-
AlignAfterOpenBracket: Align
5-
# AlignConsecutiveAssignments: None
6-
AlignOperands: Align
7-
AllowAllArgumentsOnNextLine: false
8-
AllowAllConstructorInitializersOnNextLine: false
9-
AllowAllParametersOfDeclarationOnNextLine: false
10-
AllowShortBlocksOnASingleLine: Always
11-
AllowShortCaseLabelsOnASingleLine: false
12-
AllowShortFunctionsOnASingleLine: All
13-
AllowShortIfStatementsOnASingleLine: Always
14-
AllowShortLambdasOnASingleLine: All
15-
AllowShortLoopsOnASingleLine: true
16-
AlwaysBreakAfterReturnType: None
17-
AlwaysBreakTemplateDeclarations: No
18-
BreakBeforeBraces: Custom
3+
IndentWidth: 4 # 缩进宽度,LLVM 默认值为 2,改为 4
4+
AccessModifierOffset: -4 # public/protected/private 访问控制符相对成员的偏移,与 IndentWidth 配合,LLVM 默认值为 -2
5+
AlignAfterOpenBracket: DontAlign # 函数参数换行时是否行间对齐,LLVM 默认值为 Align,改为不对齐,建议需要换行时连第一个参数一起换行
6+
AlignOperands: AlignAfterOperator # 双目运算符的行间对齐,LLVM 默认值为 Align,改为带符号一起换行
7+
AlignTrailingComments: # 尾随注释是否行间对齐
8+
OverEmptyLines: 1 # LLVM 默认值为 0,改为允许跨越一个空行对齐
9+
BreakBeforeBraces: Custom # 大括号换行配置,LLVM 默认值为 LLVM,改为自定义以使 BraceWrapping 生效
1910
BraceWrapping:
2011
AfterCaseLabel: false
2112
AfterClass: false
22-
AfterControlStatement: Never
13+
AfterControlStatement: MultiLine
2314
AfterEnum: false
2415
AfterFunction: false
2516
AfterNamespace: false
17+
AfterObjCDeclaration: false
18+
AfterStruct: false
2619
AfterUnion: false
20+
AfterExternBlock: false
2721
BeforeCatch: false
2822
BeforeElse: false
23+
BeforeLambdaBody: false
24+
BeforeWhile: false
2925
IndentBraces: false
30-
SplitEmptyFunction: false
26+
SplitEmptyFunction: true
3127
SplitEmptyRecord: true
32-
BreakBeforeBinaryOperators: None
33-
BreakBeforeTernaryOperators: true
34-
BreakConstructorInitializers: BeforeColon
35-
BreakInheritanceList: BeforeColon
36-
ColumnLimit: 0
37-
CompactNamespaces: true
38-
ContinuationIndentWidth: 4
39-
IndentCaseLabels: true
40-
IndentPPDirectives: None
41-
IndentWidth: 4
42-
KeepEmptyLinesAtTheStartOfBlocks: true
43-
MaxEmptyLinesToKeep: 2
44-
NamespaceIndentation: All
45-
ObjCSpaceAfterProperty: false
46-
ObjCSpaceBeforeProtocolList: true
47-
PointerAlignment: Right
48-
ReflowComments: false
49-
SpaceAfterCStyleCast: true
50-
SpaceAfterLogicalNot: false
51-
SpaceAfterTemplateKeyword: false
52-
SpaceBeforeAssignmentOperators: true
53-
SpaceBeforeCpp11BracedList: false
54-
SpaceBeforeCtorInitializerColon: true
55-
SpaceBeforeInheritanceColon: true
56-
SpaceBeforeParens: ControlStatements
57-
SpaceBeforeRangeBasedForLoopColon: true
58-
SpaceInEmptyParentheses: false
59-
SpacesBeforeTrailingComments: 0
60-
SpacesInAngles: false
61-
SpacesInCStyleCastParentheses: false
62-
SpacesInContainerLiterals: false
63-
SpacesInParentheses: false
64-
SpacesInSquareBrackets: false
65-
TabWidth: 4
66-
UseTab: Never
28+
SplitEmptyNamespace: true
29+
BreakBeforeBinaryOperators: All # 在双目运算符之前换行,LLVM 默认值为 None,改为换行时总是把双目运算符放在行首,包括赋值(=)
30+
BreakConstructorInitializers: BeforeComma # 构造函数初始值设定项换行,LLVM 默认值为 BeforeColon,改为将逗号放在行首,此时增删除第一项外的初始设定项只需要改动一行
31+
ColumnLimit: 0 # 列限制,LLVM 默认值为 80,改为不限制

format.py

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
import argparse
2+
import subprocess
3+
import os
4+
from pathlib import Path
5+
from colorama import Fore, Style
6+
7+
# 支持的文件类型
8+
SUPPORTED_FILES = {
9+
".h": "c",
10+
".hh": "c",
11+
".hpp": "c",
12+
".c": "c",
13+
".cc": "c",
14+
".cpp": "c",
15+
".cxx": "c",
16+
".cu": "c",
17+
".mlu": "c",
18+
".cl": "c",
19+
".py": "py",
20+
}
21+
22+
def format_file(file: Path, check: bool, formatter) -> bool:
23+
formatter = formatter.get(SUPPORTED_FILES.get(file.suffix, None), None)
24+
if not formatter:
25+
return True # 文件类型不支持,跳过
26+
27+
try:
28+
cmd = []
29+
if formatter.startswith("clang-format"):
30+
cmd = [formatter, "-style=file", "-i", file]
31+
if check:
32+
cmd.insert(2, "-dry-run")
33+
process = subprocess.run(
34+
cmd,
35+
capture_output=True,
36+
text=True,
37+
check=True,
38+
)
39+
if process.stderr:
40+
print(f"{Fore.YELLOW}{file} is not formatted.{Style.RESET_ALL}")
41+
print(f"Use {Fore.CYAN}{formatter} -style=file -i {file}{Style.RESET_ALL} to format it.")
42+
return False
43+
else:
44+
subprocess.run(
45+
cmd,
46+
capture_output=True,
47+
text=True,
48+
check=True,
49+
)
50+
print(f"{Fore.CYAN}Formatted: {file}{Style.RESET_ALL}")
51+
elif formatter == "black":
52+
cmd = [formatter, file]
53+
if check:
54+
cmd.insert(1, "--check")
55+
process = subprocess.run(
56+
cmd,
57+
capture_output=True,
58+
text=True,
59+
check=True,
60+
)
61+
if process.stderr:
62+
print(f"{Fore.YELLOW}{file} is not formatted.{Style.RESET_ALL}")
63+
print(f"Use {Fore.CYAN}{formatter} {file}{Style.RESET_ALL} to format it.")
64+
return False
65+
else:
66+
subprocess.run(
67+
cmd,
68+
capture_output=True,
69+
text=True,
70+
check=True,
71+
)
72+
print(f"{Fore.CYAN}Formatted: {file}{Style.RESET_ALL}")
73+
except FileNotFoundError:
74+
print(f"{Fore.RED}Formatter {formatter} not found, {file} skipped.{Style.RESET_ALL}")
75+
except subprocess.CalledProcessError as e:
76+
print(f"{Fore.RED}Formatter {formatter} failed: {e}{Style.RESET_ALL}")
77+
78+
return True
79+
80+
def git_added_files():
81+
"""获取所有已暂存更改的文件"""
82+
try:
83+
# 使用 git diff --cached --name-only 获取所有已添加到暂存区的文件
84+
result = subprocess.run(
85+
["git", "diff", "--cached", "--name-only"],
86+
capture_output=True,
87+
text=True,
88+
check=True,
89+
)
90+
for file in result.stdout.splitlines():
91+
yield Path(file.strip())
92+
except subprocess.CalledProcessError as e:
93+
print(f"{Fore.RED}Git diff failed: {e}{Style.RESET_ALL}")
94+
95+
def git_modified_since_ref(ref):
96+
"""获取从指定的 Git 引用到当前状态的修改文件列表"""
97+
try:
98+
result = subprocess.run(
99+
["git", "diff", f"{ref}..", "--diff-filter=AMR", "--name-only"],
100+
capture_output=True,
101+
text=True,
102+
check=True,
103+
)
104+
for file in result.stdout.splitlines():
105+
yield Path(file.strip())
106+
except subprocess.CalledProcessError as e:
107+
print(f"{Fore.RED}Git diff failed: {e}{Style.RESET_ALL}")
108+
109+
def list_files(paths):
110+
"""递归获取指定路径下的所有文件"""
111+
files = []
112+
for path in paths:
113+
if path.is_file():
114+
yield path
115+
elif path.is_dir():
116+
for dirpath, _, filenames in os.walk(path):
117+
for name in filenames:
118+
yield Path(dirpath) / name
119+
else:
120+
print(f"{Fore.RED}Error: {path} is not a file or directory.{Style.RESET_ALL}")
121+
122+
def filter_in_path(file: Path, path) -> bool:
123+
"""判断文件是否在指定路径下"""
124+
for p in path:
125+
if file.is_relative_to(p):
126+
return True
127+
return False
128+
129+
def main():
130+
parser = argparse.ArgumentParser()
131+
parser.add_argument("--ref", type=str, help="Git reference (commit hash) to compare against.")
132+
parser.add_argument("--path", nargs="*", type=Path, help="Files to format or check.")
133+
parser.add_argument("--check", action="store_true", help="Check files without modifying them.")
134+
parser.add_argument("--c", default="clang-format-16", help="C formatter (default: clang-format-16)")
135+
parser.add_argument("--py", default="black", help="Python formatter (default: black)")
136+
args = parser.parse_args()
137+
138+
if args.ref is None and args.path is None:
139+
# Last commit.
140+
print("{Fore.GREEN}Formating git added files.{Style.RESET_ALL}")
141+
files = git_added_files()
142+
143+
else:
144+
if args.ref is None:
145+
print(f"{Fore.GREEN}Formating files in {args.path}.{Style.RESET_ALL}")
146+
files = list_files(args.path)
147+
elif args.path is None:
148+
print(f"{Fore.GREEN}Formating git modified files from {args.ref}.{Style.RESET_ALL}")
149+
files = git_modified_since_ref(args.ref)
150+
else:
151+
print(f"{Fore.GREEN}Formating git modified files from {args.ref} in {args.path}.{Style.RESET_ALL}")
152+
files = (file for file in git_modified_since_ref(args.ref) if filter_in_path(file, args.path))
153+
154+
formatted = True
155+
for file in files:
156+
if not format_file(file, args.check,{
157+
"c": args.c,
158+
"py": args.py,
159+
}):
160+
formatted = False
161+
162+
if not formatted:
163+
exit(1)
164+
165+
if __name__ == "__main__":
166+
main()

0 commit comments

Comments
 (0)