Skip to content

Commit ba65078

Browse files
authored
Merge pull request #2437 from Shopify/setup-clang-format
2 parents a483b26 + 013584a commit ba65078

37 files changed

+28246
-11797
lines changed

.clang-format

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
---
2+
Language: Cpp
3+
4+
# Indentation
5+
UseTab: Never
6+
IndentWidth: 4
7+
BreakBeforeBraces: Attach
8+
IndentCaseLabels: false
9+
NamespaceIndentation: None
10+
ContinuationIndentWidth: 4
11+
IndentPPDirectives: None
12+
IndentWrappedFunctionNames: false
13+
AccessModifierOffset: -2
14+
15+
# Alignment
16+
AlignAfterOpenBracket: BlockIndent
17+
AlignConsecutiveAssignments: false
18+
AlignConsecutiveDeclarations: false
19+
AlignConsecutiveMacros: false
20+
AlignEscapedNewlines: Left
21+
AlignOperands: false
22+
AlignTrailingComments: true
23+
DerivePointerAlignment: false
24+
PointerAlignment: Right
25+
26+
# Function calls formatting
27+
BinPackArguments: false
28+
BinPackParameters: false
29+
AllowAllArgumentsOnNextLine: false
30+
ExperimentalAutoDetectBinPacking: false
31+
PenaltyBreakBeforeFirstCallParameter: 1
32+
AlwaysBreakAfterDefinitionReturnType: None
33+
34+
# Wrapping and Breaking
35+
ColumnLimit: 0
36+
AllowShortBlocksOnASingleLine: Never
37+
AllowShortCaseLabelsOnASingleLine: false
38+
AllowShortFunctionsOnASingleLine: All
39+
AllowShortIfStatementsOnASingleLine: Always
40+
AllowShortLoopsOnASingleLine: false
41+
AlwaysBreakAfterReturnType: None
42+
AlwaysBreakBeforeMultilineStrings: false
43+
AlwaysBreakTemplateDeclarations: No
44+
BreakBeforeBinaryOperators: None
45+
BreakBeforeTernaryOperators: false
46+
BreakConstructorInitializers: BeforeColon
47+
BreakInheritanceList: BeforeColon
48+
BreakStringLiterals: false
49+
CompactNamespaces: false
50+
ConstructorInitializerAllOnOneLineOrOnePerLine: false
51+
Cpp11BracedListStyle: false
52+
ReflowComments: false
53+
SortIncludes: Never
54+
55+
# Spaces
56+
SpaceAfterCStyleCast: true
57+
SpaceAfterLogicalNot: false
58+
SpaceAfterTemplateKeyword: true
59+
SpaceBeforeAssignmentOperators: true
60+
SpaceBeforeCpp11BracedList: true
61+
SpaceBeforeCtorInitializerColon: true
62+
SpaceBeforeInheritanceColon: true
63+
SpaceBeforeParens: ControlStatements
64+
SpaceBeforeRangeBasedForLoopColon: true
65+
SpaceBeforeSquareBrackets: false
66+
SpaceInEmptyBlock: false
67+
SpaceInEmptyParentheses: false
68+
SpacesBeforeTrailingComments: 1
69+
SpacesInAngles: false
70+
SpacesInCStyleCastParentheses: false
71+
SpacesInConditionalStatement: false
72+
SpacesInContainerLiterals: true
73+
SpacesInParentheses: false
74+
SpacesInSquareBrackets: false

.github/workflows/c-check.yml

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
name: C Code Generation and Formatting Check
2+
3+
on:
4+
push:
5+
pull_request: {}
6+
merge_group: {}
7+
8+
jobs:
9+
format-check:
10+
runs-on: ubuntu-latest
11+
steps:
12+
- uses: actions/checkout@v4
13+
- uses: ruby/setup-ruby@v1
14+
with:
15+
ruby-version: "3.4"
16+
bundler-cache: none
17+
- name: Set working directory as safe
18+
run: git config --global --add safe.directory $(pwd)
19+
- name: Set up permission
20+
run: chmod -R o-w /opt/hostedtoolcache/Ruby
21+
- name: Install dependencies
22+
run: |
23+
sudo apt-get update
24+
sudo apt-get install -y libdb-dev curl autoconf automake m4 libtool
25+
- name: Install clang-format from LLVM
26+
run: |
27+
wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -
28+
sudo apt-add-repository "deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy main"
29+
sudo apt-get update
30+
sudo apt-get install -y clang-format
31+
clang-format --version
32+
- name: Install Re2c
33+
run: |
34+
cd /tmp
35+
curl -L https://github.com/skvadrik/re2c/archive/refs/tags/3.1.tar.gz > re2c-3.1.tar.gz
36+
tar xf re2c-3.1.tar.gz
37+
cd re2c-3.1
38+
autoreconf -i -W all
39+
./configure
40+
make
41+
sudo make install
42+
- name: Update rubygems & bundler
43+
run: |
44+
ruby -v
45+
gem update --system
46+
- name: bin/setup
47+
run: |
48+
bin/setup
49+
- name: Check C code generation and formatting
50+
run: |
51+
clang-format --version
52+
bundle exec rake lexer templates compile confirm_lexer confirm_templates
53+
bundle exec rake format:c_check

.github/workflows/ruby.yml

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,6 @@ jobs:
2828
- ruby: "3.4"
2929
job: stdlib_test
3030
rubyopt: "--enable-frozen-string-literal"
31-
- ruby: "3.4"
32-
job: lexer templates compile confirm_lexer confirm_templates
3331
- ruby: "3.4"
3432
job: rubocop validate test_doc build test_generate_stdlib raap
3533
- ruby: "3.4"
@@ -48,17 +46,6 @@ jobs:
4846
run: |
4947
sudo apt-get update
5048
sudo apt-get install -y libdb-dev curl autoconf automake m4 libtool python3
51-
- name: Install Re2c
52-
if: ${{ contains(matrix.job, 'lexer') }}
53-
run: |
54-
cd /tmp
55-
curl -L https://github.com/skvadrik/re2c/archive/refs/tags/3.1.tar.gz > re2c-3.1.tar.gz
56-
tar xf re2c-3.1.tar.gz
57-
cd re2c-3.1
58-
autoreconf -i -W all
59-
./configure
60-
make
61-
sudo make install
6249
- name: Update rubygems & bundler
6350
run: |
6451
ruby -v

.vscode/extensions.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"recommendations": [
3+
"llvm-vs-code-extensions.vscode-clangd"
4+
]
5+
}

.vscode/settings.json

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"clangd.onConfigChanged": "restart",
3+
"[c]": {
4+
"editor.formatOnSave": true,
5+
"editor.defaultFormatter": "llvm-vs-code-extensions.vscode-clangd"
6+
},
7+
"[cpp]": {
8+
"editor.formatOnSave": true,
9+
"editor.defaultFormatter": "llvm-vs-code-extensions.vscode-clangd"
10+
},
11+
"[h]": {
12+
"editor.formatOnSave": true,
13+
"editor.defaultFormatter": "llvm-vs-code-extensions.vscode-clangd"
14+
},
15+
"[hpp]": {
16+
"editor.formatOnSave": true,
17+
"editor.defaultFormatter": "llvm-vs-code-extensions.vscode-clangd"
18+
}
19+
}

README.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,43 @@ After checking out the repo, run `bin/setup` to install dependencies. Then, run
198198

199199
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
200200

201+
### C Code Formatting
202+
203+
This project uses `clang-format` to enforce consistent formatting of C code with a `.clang-format` configuration in the root directory.
204+
205+
#### Setup
206+
207+
First, install clang-format:
208+
209+
```bash
210+
# macOS
211+
brew install clang-format
212+
213+
# Ubuntu/Debian
214+
sudo apt-get install clang-format
215+
216+
# Windows
217+
choco install llvm
218+
```
219+
220+
#### Usage
221+
222+
Format all C source files:
223+
224+
```bash
225+
rake format:c
226+
```
227+
228+
Check formatting without making changes:
229+
230+
```bash
231+
rake format:c_check
232+
```
233+
234+
#### Editor Integration
235+
236+
For VS Code users, install the "clangd" extension which will automatically use the project's `.clang-format` file.
237+
201238
## Contributing
202239

203240
Bug reports and pull requests are welcome on GitHub at https://github.com/ruby/rbs.

Rakefile

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ multitask :default => [:test, :stdlib_test, :typecheck_test, :rubocop, :validate
3737

3838
task :lexer do
3939
sh "re2c -W --no-generation-date -o src/lexer.c src/lexer.re"
40+
sh "clang-format -i -style=file src/lexer.c"
4041
end
4142

4243
task :confirm_lexer => :lexer do
@@ -49,6 +50,84 @@ task :confirm_templates => :templates do
4950
sh "git diff --exit-code -- include src"
5051
end
5152

53+
# Task to format C code using clang-format
54+
namespace :format do
55+
dirs = ["src", "ext", "include"]
56+
57+
# Find all C source and header files
58+
files = `find #{dirs.join(" ")} -type f \\( -name "*.c" -o -name "*.h" \\)`.split("\n")
59+
60+
desc "Format C source files using clang-format"
61+
task :c do
62+
puts "Formatting C files..."
63+
64+
# Check if clang-format is installed
65+
unless system("which clang-format > /dev/null 2>&1")
66+
abort "Error: clang-format not found. Please install clang-format first."
67+
end
68+
69+
if files.empty?
70+
puts "No C files found to format"
71+
next
72+
end
73+
74+
puts "Found #{files.length} files to format (excluding generated files)"
75+
76+
exit_status = 0
77+
files.each do |file|
78+
puts "Formatting #{file}"
79+
unless system("clang-format -i -style=file #{file}")
80+
puts "❌ Error formatting #{file}"
81+
exit_status = 1
82+
end
83+
end
84+
85+
exit exit_status unless exit_status == 0
86+
puts "✅ All files formatted successfully"
87+
end
88+
89+
desc "Check if C source files are properly formatted"
90+
task :c_check do
91+
puts "Checking C file formatting..."
92+
93+
# Check if clang-format is installed
94+
unless system("which clang-format > /dev/null 2>&1")
95+
abort "Error: clang-format not found. Please install clang-format first."
96+
end
97+
98+
if files.empty?
99+
puts "No C files found to check"
100+
next
101+
end
102+
103+
puts "Found #{files.length} files to check (excluding generated files)"
104+
105+
needs_format = false
106+
files.each do |file|
107+
formatted = `clang-format -style=file #{file}`
108+
original = File.read(file)
109+
110+
if formatted != original
111+
puts "❌ #{file} needs formatting"
112+
puts "Diff:"
113+
# Save formatted version to temp file and run diff
114+
temp_file = "#{file}.formatted"
115+
File.write(temp_file, formatted)
116+
system("diff -u #{file} #{temp_file}")
117+
File.unlink(temp_file)
118+
needs_format = true
119+
end
120+
end
121+
122+
if needs_format
123+
warn "Some files need formatting. Run 'rake format:c' to format them."
124+
exit 1
125+
else
126+
puts "✅ All files are properly formatted"
127+
end
128+
end
129+
end
130+
52131
rule ".c" => ".re" do |t|
53132
puts "⚠️⚠️⚠️ #{t.name} is older than #{t.source}. You may need to run `rake lexer` ⚠️⚠️⚠️"
54133
end
@@ -78,6 +157,9 @@ task :templates do
78157

79158
sh "#{ruby} templates/template.rb include/rbs/ast.h"
80159
sh "#{ruby} templates/template.rb src/ast.c"
160+
161+
# Format the generated files
162+
Rake::Task["format:c"].invoke
81163
end
82164

83165
task :compile => "ext/rbs_extension/class_constants.h"

0 commit comments

Comments
 (0)