Skip to content

Commit

Permalink
Standardize ClangFormat configuration file format
Browse files Browse the repository at this point in the history
The LLVM/Clang/ClangFormat project is under very active development, with configuration keys regularly being added,
changed to a different data type, or removed.

When a key is set in the configuration file, the default LLVM style value is used. This means that updating to a new
version of ClangFormat might result in unintended changes to the results from the configuration file. In the case of a
change of type, it seems the ClangFormat developers generally will provide backwards compatibility of some sort, but
there is no guarantee that the resulting configuration will be exactly the same as was intended when the value of the
key was selected for use in Arduino's configuration file.

ClangFormat has a useful `--dump-config` flag which outputs the effective configuration. This allows us to determine
whether there are any differences between the intended configuration as defined by Arduino's configuration file and the
actual configuration of the tool.

In order to accomplish this, it is best to use the exact format output by `clang-format --dump-config`, which allows any
differences to be detected and seen clearly using a simple diff command.

The only exception is the insertion of a comment providing the source URL of the configuration file in order to
facilitate the syncing of changes with the downstream copies of the file in the various projects that use it.
  • Loading branch information
per1234 committed Jul 26, 2022
1 parent 6f774b2 commit 4613cfd
Show file tree
Hide file tree
Showing 7 changed files with 208 additions and 60 deletions.
1 change: 1 addition & 0 deletions .ecrc
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"__pycache__[/\\\\]",
"node_modules[/\\\\]",
"^other[/\\\\]clang-format-configuration[/\\\\]testdata[/\\\\]",
"^other[/\\\\]clang-format-configuration[/\\\\]\\.clang-format",
"^LICENSE\\.txt$",
"^poetry\\.lock$"
]
Expand Down
59 changes: 59 additions & 0 deletions .github/workflows/check-clang-format.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,65 @@ jobs:
- name: Validate ClangFormat configuration files
run: task --silent clang-format:validate

check-config:
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v3

- name: Install Task
uses: arduino/setup-task@v1
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
version: 3.x

- name: Set environment variables
run: |
# See: https://docs.github.com/actions/using-workflows/workflow-commands-for-github-actions#setting-an-environment-variable
if [[ "${{ github.event.inputs.clang-format-version }}" == "" ]]; then
echo "CLANG_FORMAT_VERSION=$(task clang-format:get-version)" >> "$GITHUB_ENV"
else
echo "CLANG_FORMAT_VERSION=${{ github.event.inputs.clang-format-version }}" >> "$GITHUB_ENV"
fi
echo "CLANG_FORMAT_INSTALL_PATH=${{ runner.temp }}/clang-format" >> "$GITHUB_ENV"
echo "WORKING_FOLDER=${{ runner.temp }}" >> "$GITHUB_ENV"
- name: Download ClangFormat
id: download
uses: MrOctopus/download-asset-action@1.0
with:
repository: arduino/clang-static-binaries
tag: ${{ env.CLANG_FORMAT_VERSION }}
asset: clang-format_${{ env.CLANG_FORMAT_VERSION }}_Linux_64bit.tar.bz2
target: ${{ env.CLANG_FORMAT_INSTALL_PATH }}

- name: Install ClangFormat
run: |
cd "${{ env.CLANG_FORMAT_INSTALL_PATH }}"
tar --extract --file="${{ steps.download.outputs.name }}"
# Add installation to PATH:
# See: https://docs.github.com/actions/using-workflows/workflow-commands-for-github-actions#adding-a-system-path
echo "${{ env.CLANG_FORMAT_INSTALL_PATH }}/clang_Linux_64bit" >> "$GITHUB_PATH"
- name: Check ClangFormat configuration file
id: check
run: |
task \
--silent \
clang-format:check-config \
CLANG_FORMAT_VERSION="${{ env.CLANG_FORMAT_VERSION }}"
- name: Save effective configuration file to a workflow artifact
if: >
always() &&
steps.check.outcome == 'failure'
uses: actions/upload-artifact@v3
with:
path: ${{ env.WORKING_FOLDER }}/expected/.clang-format
if-no-files-found: error
name: config-output

check-output:
runs-on: ubuntu-latest

Expand Down
1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ __pycache__/
node_modules/
/other/clang-format-configuration/testdata/golden/samples/
/other/clang-format-configuration/testdata/input/samples/
/other/clang-format-configuration/.clang-format
1 change: 1 addition & 0 deletions .yamllint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -72,5 +72,6 @@ yaml-files:

ignore: |
/.git/
/other/clang-format-configuration/.clang-format
__pycache__/
node_modules/
52 changes: 51 additions & 1 deletion Taskfile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ tasks:
desc: Check for problems with the project
deps:
- task: ci:validate
- task: clang-format:check-config
- task: clang-format:check-output
- task: clang-format:check-testdata
- task: clang-format:validate
Expand Down Expand Up @@ -111,6 +112,32 @@ tasks:
-s "{{.WORKFLOW_SCHEMA_PATH}}" \
-d "{{.TEMPLATE_WORKFLOWS_DATA_PATH}}"
clang-format:check-config:
desc: Check that ClangFormat configuration file matches effective tool configuration
vars:
WORKING_FOLDER:
sh: |
if [[ "{{.WORKING_FOLDER}}" == "" ]]; then
# Generate a path
task utility:mktemp-folder TEMPLATE="clang-format-check-config-XXXXXXXXXX"
else
# A path was specified via the command line
echo "{{.WORKING_FOLDER}}"
fi
ACTUAL_CONFIGURATION_PATH: "{{.WORKING_FOLDER}}/actual/.clang-format"
EXPECTED_CONFIGURATION_PATH: "{{.WORKING_FOLDER}}/expected/.clang-format"
cmds:
- |
mkdir "{{.WORKING_FOLDER}}/actual"
mkdir "{{.WORKING_FOLDER}}/expected"
cp "{{.CLANG_FORMAT_CONFIGURATION_PATH}}" "{{.WORKING_FOLDER}}/actual/"
- task: clang-format:dump-config
vars:
TARGET_PATH: "{{.WORKING_FOLDER}}/expected/.clang-format"
- |
cd "{{.WORKING_FOLDER}}"
diff --color=always --unified "actual/.clang-format" "expected/.clang-format"
# Check if ClangFormat is installed and the expected version
clang-format:check-installed:
vars:
Expand Down Expand Up @@ -198,6 +225,23 @@ tasks:
"{{.CLANG_FORMAT_CONFIGURATION_PATH}}" \
"{{.OUTPUT_PATH}}"
# Write the effective ClangFormat configuration to the path specified by the TARGET_PATH variable
clang-format:dump-config:
deps:
- task: clang-format:check-installed
cmds:
- |
# Add source comment
echo \
"# Source: https://github.com/arduino/tooling-project-assets/tree/main/other/clang-format-configuration" > \
"{{.TARGET_PATH}}"
# Dump the effective configuration to the target file
clang-format \
--dump-config \
--style=file:"{{.CLANG_FORMAT_CONFIGURATION_PATH}}" >> \
"{{.TARGET_PATH}}"
# Use ClangFormat to format the files under the path specified by TARGET_FOLDER recursively
clang-format:format:
cmds:
Expand Down Expand Up @@ -226,6 +270,13 @@ tasks:
cmds:
- echo "{{.DEFAULT_CLANG_FORMAT_VERSION}}"

clang-format:update-config:
desc: Update ClangFormat configuration file to match effective tool configuration
cmds:
- task: clang-format:dump-config
vars:
TARGET_PATH: "{{.CLANG_FORMAT_CONFIGURATION_PATH}}"

clang-format:update-golden:
desc: Update golden master test data for current configuration
deps:
Expand Down Expand Up @@ -276,7 +327,6 @@ tasks:
"{{.WORKFLOW_TEMPLATE_ASSETS_PATH}}/general/.editorconfig" \
"{{.WORKFLOW_TEMPLATE_ASSETS_PATH}}/check-python/.flake8" \
"{{.WORKFLOW_TEMPLATE_ASSETS_PATH}}/check-markdown/.markdownlint.yml" \
"{{.WORKFLOW_TEMPLATE_ASSETS_PATH}}/check-yaml/.yamllint.yml" \
"{{.REPOSITORY_ROOT_PATH}}"
dependabot:validate:
Expand Down
134 changes: 75 additions & 59 deletions other/clang-format-configuration/.clang-format
Original file line number Diff line number Diff line change
@@ -1,25 +1,24 @@
# Source: https://github.com/arduino/tooling-project-assets/tree/main/other/clang-format-configuration
---
Language: Cpp
BasedOnStyle: LLVM
Language: Cpp
AccessModifierOffset: -2
AlignAfterOpenBracket: Align
AlignConsecutiveMacros: false
AlignConsecutiveAssignments: false
AlignConsecutiveBitFields: false
AlignConsecutiveDeclarations: false
AlignConsecutiveMacros: false
AlignEscapedNewlines: DontAlign
AlignOperands: Align
AlignOperands: Align
AlignTrailingComments: true
AllowAllArgumentsOnNextLine: true
AllowAllConstructorInitializersOnNextLine: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortEnumsOnASingleLine: true
AllowShortBlocksOnASingleLine: Always
AllowShortCaseLabelsOnASingleLine: true
AllowShortEnumsOnASingleLine: true
AllowShortFunctionsOnASingleLine: Empty
AllowShortIfStatementsOnASingleLine: Always
AllowShortLambdasOnASingleLine: Empty
AllowShortIfStatementsOnASingleLine: Always
AllowShortLoopsOnASingleLine: true
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
Expand All @@ -28,70 +27,82 @@ AlwaysBreakTemplateDeclarations: No
BinPackArguments: true
BinPackParameters: true
BraceWrapping:
AfterCaseLabel: false
AfterClass: false
AfterCaseLabel: false
AfterClass: false
AfterControlStatement: Never
AfterEnum: false
AfterFunction: false
AfterNamespace: false
#AfterObjCDeclaration:
AfterStruct: false
AfterUnion: false
AfterEnum: false
AfterFunction: false
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
AfterExternBlock: false
BeforeCatch: false
BeforeElse: false
BeforeCatch: false
BeforeElse: false
BeforeLambdaBody: false
BeforeWhile: false
IndentBraces: false
SplitEmptyFunction: false
SplitEmptyRecord: false
SplitEmptyNamespace: false
#BreakAfterJavaFieldAnnotations:
BeforeWhile: false
IndentBraces: false
SplitEmptyFunction: true
SplitEmptyRecord: true
SplitEmptyNamespace: true
BreakBeforeBinaryOperators: NonAssignment
BreakBeforeBraces: Attach
BreakBeforeInheritanceComma: false
BreakInheritanceList: BeforeColon
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
BreakConstructorInitializers: BeforeColon
BreakInheritanceList: BeforeColon
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: false
ColumnLimit: 0
CommentPragmas: ""
ColumnLimit: 0
CommentPragmas: ''
CompactNamespaces: false
ConstructorInitializerAllOnOneLineOrOnePerLine: true
ConstructorInitializerIndentWidth: 2
ContinuationIndentWidth: 2
Cpp11BracedListStyle: false
DeriveLineEnding: true
DerivePointerAlignment: true
DisableFormat: false
#ExperimentalAutoDetectBinPacking:
DisableFormat: false
ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: false
ForEachMacros: []
IncludeBlocks: Preserve
IncludeCategories: []
IncludeIsMainRegex: ""
IncludeIsMainSourceRegex: ""
IndentCaseBlocks: true
ForEachMacros:
- foreach
- Q_FOREACH
- BOOST_FOREACH
IncludeBlocks: Preserve
IncludeCategories:
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
Priority: 2
SortPriority: 0
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
Priority: 3
SortPriority: 0
- Regex: '.*'
Priority: 1
SortPriority: 0
IncludeIsMainRegex: ''
IncludeIsMainSourceRegex: ''
IndentCaseLabels: true
IndentExternBlock: Indent
IndentCaseBlocks: true
IndentGotoLabels: false
IndentPPDirectives: None
IndentWidth: 2
IndentExternBlock: Indent
IndentWidth: 2
IndentWrappedFunctionNames: false
InsertTrailingCommas: None
#JavaImportGroups:
#JavaScriptQuotes:
#JavaScriptWrapImports:
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: true
MacroBlockBegin: ""
MacroBlockEnd: ""
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 100000
NamespaceIndentation: None
NamespaceMacros: []
#ObjCBinPackProtocolList:
#ObjCBlockIndentWidth:
#ObjCBreakBeforeNestedBlockParam:
#ObjCSpaceAfterProperty:
#ObjCSpaceBeforeProtocolList:
ObjCBinPackProtocolList: Auto
ObjCBlockIndentWidth: 2
ObjCBreakBeforeNestedBlockParam: true
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PenaltyBreakAssignment: 1
PenaltyBreakBeforeFirstCallParameter: 1
PenaltyBreakComment: 1
Expand All @@ -101,9 +112,8 @@ PenaltyBreakTemplateDeclaration: 1
PenaltyExcessCharacter: 1
PenaltyReturnTypeOnItsOwnLine: 1
PointerAlignment: Right
RawStringFormats: []
ReflowComments: false
SortIncludes: false
ReflowComments: false
SortIncludes: false
SortUsingDeclarations: false
SpaceAfterCStyleCast: false
SpaceAfterLogicalNot: false
Expand All @@ -114,20 +124,26 @@ SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements
SpaceBeforeRangeBasedForLoopColon: true
SpaceBeforeSquareBrackets: false
SpaceInEmptyBlock: false
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 2
SpacesInAngles: false
SpacesInCStyleCastParentheses: false
SpacesInAngles: false
SpacesInConditionalStatement: false
SpacesInContainerLiterals: false
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: Auto
StatementMacros: []
TabWidth: 2
TypenameMacros: []
UseCRLF: false
UseTab: Never
WhitespaceSensitiveMacros: []
SpaceBeforeSquareBrackets: false
Standard: Auto
StatementMacros:
- Q_UNUSED
- QT_REQUIRE_VERSION
TabWidth: 2
UseCRLF: false
UseTab: Never
WhitespaceSensitiveMacros:
- STRINGIZE
- PP_STRINGIZE
- BOOST_PP_STRINGIZE
...

Loading

0 comments on commit 4613cfd

Please sign in to comment.