Skip to content

Commit

Permalink
Add coding style check
Browse files Browse the repository at this point in the history
  • Loading branch information
penglei0 committed May 27, 2024
1 parent 93c60bf commit 7245240
Show file tree
Hide file tree
Showing 4 changed files with 390 additions and 0 deletions.
192 changes: 192 additions & 0 deletions .clang-format
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
---
Language: Cpp
# BasedOnStyle: LLVM
AccessModifierOffset: -2
AlignAfterOpenBracket: Align
AlignArrayOfStructures: None
AlignConsecutiveMacros: None
AlignConsecutiveAssignments: None
AlignConsecutiveBitFields: None
AlignConsecutiveDeclarations: None
AlignEscapedNewlines: Right
AlignOperands: Align
AlignTrailingComments: true
AllowAllArgumentsOnNextLine: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortEnumsOnASingleLine: true
AllowShortBlocksOnASingleLine: Never
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: All
AllowShortLambdasOnASingleLine: All
AllowShortIfStatementsOnASingleLine: Never
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: MultiLine
AttributeMacros:
- __capability
BinPackArguments: true
BinPackParameters: true
BraceWrapping:
AfterCaseLabel: false
AfterClass: false
AfterControlStatement: Never
AfterEnum: false
AfterFunction: false
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
AfterExternBlock: false
BeforeCatch: false
BeforeElse: false
BeforeLambdaBody: false
BeforeWhile: false
IndentBraces: false
SplitEmptyFunction: true
SplitEmptyRecord: true
SplitEmptyNamespace: true
BreakBeforeBinaryOperators: None
BreakBeforeConceptDeclarations: true
BreakBeforeBraces: Attach
BreakBeforeInheritanceComma: false
BreakInheritanceList: BeforeColon
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
BreakConstructorInitializers: BeforeColon
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: true
ColumnLimit: 80
CommentPragmas: "^ IWYU pragma:"
QualifierAlignment: Leave
CompactNamespaces: false
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
DeriveLineEnding: true
DerivePointerAlignment: false
DisableFormat: false
EmptyLineAfterAccessModifier: Never
EmptyLineBeforeAccessModifier: LogicalBlock
ExperimentalAutoDetectBinPacking: false
PackConstructorInitializers: BinPack
BasedOnStyle: ""
ConstructorInitializerAllOnOneLineOrOnePerLine: false
AllowAllConstructorInitializersOnNextLine: true
FixNamespaceComments: true
ForEachMacros:
- foreach
- Q_FOREACH
- BOOST_FOREACH
IfMacros:
- KJ_IF_MAYBE
IncludeBlocks: Preserve
IncludeCategories:
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
Priority: 2
SortPriority: 0
CaseSensitive: false
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
Priority: 3
SortPriority: 0
CaseSensitive: false
- Regex: ".*"
Priority: 1
SortPriority: 0
CaseSensitive: false
IncludeIsMainRegex: "(Test)?$"
IncludeIsMainSourceRegex: ""
IndentAccessModifiers: false
IndentCaseLabels: false
IndentCaseBlocks: false
IndentGotoLabels: true
IndentPPDirectives: None
IndentExternBlock: AfterExternBlock
IndentRequires: false
IndentWidth: 2
IndentWrappedFunctionNames: false
InsertTrailingCommas: None
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: true
LambdaBodyIndentation: Signature
MacroBlockBegin: ""
MacroBlockEnd: ""
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCBinPackProtocolList: Auto
ObjCBlockIndentWidth: 2
ObjCBreakBeforeNestedBlockParam: true
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakOpenParenthesis: 0
PenaltyBreakString: 1000
PenaltyBreakTemplateDeclaration: 10
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 60
PenaltyIndentedWhitespace: 0
PointerAlignment: Right
PPIndentWidth: -1
ReferenceAlignment: Pointer
ReflowComments: true
RemoveBracesLLVM: false
SeparateDefinitionBlocks: Leave
ShortNamespaceLines: 1
SortIncludes: CaseSensitive
SortJavaStaticImport: Before
SortUsingDeclarations: true
SpaceAfterCStyleCast: false
SpaceAfterLogicalNot: false
SpaceAfterTemplateKeyword: true
SpaceBeforeAssignmentOperators: true
SpaceBeforeCaseColon: false
SpaceBeforeCpp11BracedList: false
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements
SpaceBeforeParensOptions:
AfterControlStatements: true
AfterForeachMacros: true
AfterFunctionDefinitionName: false
AfterFunctionDeclarationName: false
AfterIfMacros: true
AfterOverloadedOperator: false
BeforeNonEmptyParentheses: false
SpaceAroundPointerQualifiers: Default
SpaceBeforeRangeBasedForLoopColon: true
SpaceInEmptyBlock: false
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: Never
SpacesInConditionalStatement: false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInLineCommentPrefix:
Minimum: 1
Maximum: -1
SpacesInParentheses: false
SpacesInSquareBrackets: false
SpaceBeforeSquareBrackets: false
BitFieldColonSpacing: Both
Standard: Latest
StatementAttributeLikeMacros:
- Q_EMIT
StatementMacros:
- Q_UNUSED
- QT_REQUIRE_VERSION
TabWidth: 8
UseCRLF: false
UseTab: Never
WhitespaceSensitiveMacros:
- STRINGIZE
- PP_STRINGIZE
- BOOST_PP_STRINGIZE
- NS_SWIFT_NAME
- CF_SWIFT_NAME
---

18 changes: 18 additions & 0 deletions .github/workflows/style_check.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name: code style check
on: [pull_request]
jobs:
code-style-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: install dependencies
run: |
sudo apt-get -y update && sudo apt-get install -y clang-format
- name: check code style
run: |
workspace_path=$(echo "${{github.workspace}}" | sed 's/\//\\\//g')
impacted_files=$(git diff --name-only -r HEAD^1 HEAD | grep 'src\/' | grep -E '\.(cc|h)$' | sed "s/^/${workspace_path}\//" | tr '\n' ' ')
if [ ! -z "$impacted_files" ]
then
python3 tools/code_formatting.py --format-style=.clang-format --mode=0 ${impacted_files}
fi
78 changes: 78 additions & 0 deletions tools/CODE_FORMAT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# Coding style

## 1. Coding style

In order to make the code more readable, we recommend the following coding style:
[LLVM Coding Standards](https://llvm.org/docs/CodingStandards.html)

## 2. Wrapper formatting tool

For the convenience of formatting the code in the project, a wrapper script to format the code is provided. The script is located at `tools/code_formatting.py`, and it's based on `clang-format`.

Before running the script, the ``clang-format` should be installed. On Ubuntu, you can install it by running, or follow the instructions from the official documentation [llvm](https://apt.llvm.org/):

```bash
sudo apt-get install clang-format
```

Then run the script to format the specified files:

```bash
python3 tools/code_formatting.py --format-style=.clang-format --mode=0 src/iperf_server_api.c
```

## 3. IDE integration

IDE integration is a convenient way to format your code automatically when files are saved. You can follow the instructions from the official documentation [IDE integration]([tools/vim/README.md](https://clang.llvm.org/docs/ClangFormat.html#vim-integration)) to set up the integration.

## 4. Github CI integration

To ensure the code format is consistent, the code format check is added to the CI. Any illegal code format will cause the CI to fail.

# Context

* Version of iperf3: Any

* Hardware: Any

* Operating system (and distribution, if any): Any


* Other relevant information (for example, non-default compilers,
libraries, cross-compiling, etc.):


# Bug Report

In order to make the code more readable, I suggest we can follow one of the coding styles:

- LLVM
- GNU
- Google
- Chromium
- Microsoft
- Mozilla
- WebKit

Maybe `LLVM` is more suitable for this project.

* Expected Behavior

All developers should have a consistent coding style.

* Actual Behavior

The code is not formatted consistently. For example, some files use tabs for indentation, while others use spaces.

* Steps to Reproduce

* Possible Solution

# Enhancement Request

* Current behavior

* Desired behavior

* Implementation notes

102 changes: 102 additions & 0 deletions tools/code_formatting.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import subprocess # subprocess.run
import argparse
import logging
import sys


def parse_args():
"""
Parse command line arguments.
"""
parser = argparse.ArgumentParser()
parser.add_argument('--format-style',
help='Style for formatting code around applied fixes',
dest='format_style',
type=str,
default=".clang-format")
parser.add_argument('--mode',
help='0: Show formatting issues without make the formatting changes.'
'1: Inplace edit <file>s.',
dest='mode',
type=str,
default="0")
return parser


CLANG_FORMAT_INPLACE = "clang-format --Werror -style=file:{format_style} -i {files}"
CLANG_FORMAT_DRY_RUN = "clang-format --Werror -style=file:{format_style} --dry-run {files}"


def print_usage() -> None:
"""
Print the usage of the script.
"""
logging.info(
"Usage: python3 code_formatting.py [options] <source0> <source1> ... <sourceN>")
logging.info("Options:")
logging.info(
" --format-style Style for formatting code around applied fixes")
logging.info(
" --mode 0: Show formatting issues without make the formatting changes.' \
' 1: Inplace edit <file>s")


if __name__ == '__main__':
logging.basicConfig(level=logging.INFO)
local_parser = parse_args()
ns, args = local_parser.parse_known_args()
if not ns.format_style:
logging.error("Format style is required")
print_usage()
sys.exit(1)
if not ns.mode:
logging.error("Mode is required")
print_usage()
sys.exit(1)
if not args:
logging.error("Source files are required")
print_usage()
sys.exit(1)
# get the source files from args
INPUT_FILES = ""
logging.info("Start analyzing the following source files:")
for file in args:
# Skip `examples` folder
if any(substring in file for substring in ["examples/"]):
continue
logging.info("%s", file)
INPUT_FILES += " "
INPUT_FILES += file
if not INPUT_FILES:
logging.error("No source files to analyze")
sys.exit(1)
# format input arguments to clang-format command
CLANG_FORMAT_CMD = ""
if ns.mode == "1":
CLANG_FORMAT_CMD = CLANG_FORMAT_INPLACE.format(
format_style=ns.format_style, files=INPUT_FILES)
elif ns.mode == "0":
CLANG_FORMAT_CMD = CLANG_FORMAT_DRY_RUN.format(
format_style=ns.format_style, files=INPUT_FILES)
else:
logging.error("Invalid mode")
print_usage()
sys.exit(1)
logging.info("Executing clang-format command: %s", CLANG_FORMAT_CMD)

# Split the command into a list as required by subprocess.run()
command_list = CLANG_FORMAT_CMD.split()

# Run the command and capture the output
completed_process = subprocess.run(
command_list, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, check=False)
# Get the output from the CompletedProcess instance
console_error = completed_process.stderr
if not console_error:
logging.info("Code formatting check passed")
else:
logging.info("console_error: %s", console_error)
logging.error("##############################################")
logging.error("## Code formatting check failed ##")
logging.error("##############################################")
sys.exit(1)

0 comments on commit 7245240

Please sign in to comment.