Skip to content

Commit

Permalink
Enforce clang format (#599) (#601)
Browse files Browse the repository at this point in the history
* Apply clangformat

* Add test sources

* Test pep8

* Fix workflow

* Fix workflow

* Fix script

* pep8 fixes

* Cpp fixes

* Remove ament pep257 & flake8

* Update urdf2webots submodule

* Revert "Update urdf2webots submodule"

This reverts commit fa45543.

* Revert "Remove ament pep257 & flake8"

This reverts commit 92df8a3.

* Revert "Cpp fixes"

This reverts commit c3a497c.

* Revert "pep8 fixes"

This reverts commit 141b0c8.

* Revert "Revert "pep8 fixes""

This reverts commit ad007a4.

* Test

* Revert "Test"

This reverts commit 25934ef.

* Revert "Revert "Cpp fixes""

This reverts commit 8462d81.

* Revert "Revert "Remove ament pep257 & flake8""

This reverts commit c689352.

* Revert "Revert "Update urdf2webots submodule""

This reverts commit e2ed2b3.

* Order fixes

* Skip submodule tests

* Finalize
  • Loading branch information
ad-daniel authored Jan 19, 2023
1 parent 001285d commit 3da50ad
Show file tree
Hide file tree
Showing 77 changed files with 1,212 additions and 1,213 deletions.
88 changes: 88 additions & 0 deletions .clang-format
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
---
Language: Cpp
AccessModifierOffset: -2
AlignAfterOpenBracket: Align
AlignEscapedNewlines: Left
AlignOperands: true
AllowAllConstructorInitializersOnNextLine: false
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: InlineOnly
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: false
BinPackArguments: true
BinPackParameters: true
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Attach
BreakBeforeInheritanceComma: false
BreakBeforeTernaryOperators: false
BreakConstructorInitializersBeforeComma: false
BreakConstructorInitializers: AfterColon
BreakStringLiterals: true
ColumnLimit: 128
CommentPragmas: '^ IWYU pragma:'
CompactNamespaces: false
ConstructorInitializerAllOnOneLineOrOnePerLine: true
ConstructorInitializerIndentWidth: 2
ContinuationIndentWidth: 2
Cpp11BracedListStyle: true
DerivePointerAlignment: false
DisableFormat: false
ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: true
ForEachMacros:
- foreach
- Q_FOREACH
- BOOST_FOREACH
IncludeCategories:
- Regex: '^<.*\.h>'
Priority: 1
- Regex: '^<.*'
Priority: 2
- Regex: '.*'
Priority: 3
IncludeIsMainRegex: '([-_](test|unittest))?$'
IndentCaseLabels: true
IndentWidth: 2
IndentWrappedFunctionNames: true
JavaScriptQuotes: Single
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: false
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 1
NamespaceIndentation: All
ObjCBlockIndentWidth: 2
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: false
PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 1
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 200
PointerAlignment: Right
ReflowComments: true
SortIncludes: true
SortUsingDeclarations: true
SpaceAfterCStyleCast: false
SpaceAfterTemplateKeyword: false
SpaceBeforeAssignmentOperators: true
SpaceBeforeParens: ControlStatements
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 2
SpacesInAngles: false
SpacesInContainerLiterals: false
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: Cpp11
TabWidth: 8
UseTab: Never
...
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ If applicable, add screenshots to help explain your problem.

**System**
- Webots Version: [e.g., R2019b, R2020a revision 1]
- ROS Version: [e.g., Dashing, Eloquent]
- ROS Version: [e.g., Dashing, Eloquent]
- Operating System: [e.g., Windows 10, Linux Ubuntu 18.04, macOS Mojave]
- Graphics Card: [e.g., NVIDIA GeForce RTX 2080 11 GB, AMD Radeon RX 580 8GB, etc.]

Expand Down
45 changes: 45 additions & 0 deletions .github/workflows/tests_sources.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
name: Test Sources

on:
pull_request:
types: [opened, synchronize, reopened, labeled, unlabeled]
branches-ignore:
- 'released'
schedule:
- cron: '0 22 * * *'

defaults:
run:
shell: bash

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
test-sources:
strategy:
fail-fast: false
matrix:
os: [ubuntu-20.04]
python: ['3.10']
include:
- os: ubuntu-20.04
DEPENDENCIES_INSTALLATION: "sudo apt -y install clang-format-10 cppcheck"
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v3
if: github.event_name == 'schedule' || github.event.pull_request.draft == false || contains(github.event.pull_request.labels.*.name, 'test sources')
with:
submodules: true
- name: Set up Python 3.10
if: github.event_name == 'schedule' || github.event.pull_request.draft == false || contains(github.event.pull_request.labels.*.name, 'test sources')
uses: actions/setup-python@v4
with:
python-version: '3.10'
- name: Test Sources
if: github.event_name == 'schedule' || github.event.pull_request.draft == false || contains(github.event.pull_request.labels.*.name, 'test sources')
run: |
${{ matrix.DEPENDENCIES_INSTALLATION }}
pip install -r tests/sources/requirements.txt
python3 -m unittest discover -s tests/sources/
1 change: 1 addition & 0 deletions tests/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/cppcheck_report.txt
3 changes: 3 additions & 0 deletions tests/sources/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
pycodestyle
pyflakes
image
152 changes: 152 additions & 0 deletions tests/sources/test_clang_format.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
#!/usr/bin/env python

# Copyright 1996-2023 Cyberbotics Ltd.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Test that the C, C++ and shader source code is compliant with ClangFormat."""
import unittest

import difflib
import os
import shutil
import subprocess

from io import open


class TestClangFormat(unittest.TestCase):
"""Unit test for ClangFormat compliance."""

def setUp(self):
"""Set up called before each test."""
self.ROOT_FOLDER = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
print(self.ROOT_FOLDER)

def _runClangFormat(self, f):
"""Run clang format on 'f' file."""
return subprocess.check_output(['clang-format', '-style=file', f])

def test_clang_format_is_correctly_installed(self):
"""Test ClangFormat is correctly installed."""
self.assertTrue(
shutil.which('clang-format') is not None,
msg='ClangFormat is not installed on this computer.'
)
clangFormatConfigFile = os.path.join(self.ROOT_FOLDER, '.clang-format')
self.assertTrue(
os.path.exists(clangFormatConfigFile),
msg=clangFormatConfigFile + ' not found.'
)

def test_sources_are_clang_format_compliant(self):
"""Test that sources are ClangFormat compliant."""
directories = [
'webots_ros2',
'webots_ros2_control',
'webots_ros2_driver',
'webots_ros2_epuck',
'webots_ros2_importer',
'webots_ros2_mavic',
'webots_ros2_msgs',
'webots_ros2_tesla',
'webots_ros2_tests',
'webots_ros2_tiago',
'webots_ros2_turtlebot',
'webots_ros2_universal_robot'
]
skippedPaths = [
'webots_ros2_driver/webots/',
'webots_ros2_importer/webots_ros2_importer/urdf2webots/tests'
]
skippedFiles = [
]
skippedDirectories = [
]
skippedPathsFull = [os.path.join(self.ROOT_FOLDER, os.path.normpath(path)) for path in skippedPaths]
skippedFilesFull = [os.path.join(self.ROOT_FOLDER, os.path.normpath(file)) for file in skippedFiles]

extensions = ['c', 'h', 'cpp', 'hpp', 'cc', 'hh', 'c++', 'h++', 'vert', 'frag']
modified_files = os.path.join(self.ROOT_FOLDER, 'tests', 'sources', 'modified_files.txt')
sources = []
if os.path.isfile(modified_files):
with open(modified_files, 'r') as file:
for line in file:
line = line.strip()
extension = os.path.splitext(line)[1][1:].lower()
if extension not in extensions:
continue
found = False
for directory in directories:
if line.startswith(directory):
found = True
break
if not found:
continue
found = False
for directory in skippedPaths + skippedFiles:
if line.startswith(directory):
found = True
break
if found:
continue
for directory in skippedDirectories:
currentDirectories = line.split(os.sep)
if directory in currentDirectories:
found = True
if found:
continue
sources.append(os.path.normpath(line))
else:
for directory in directories:
path = os.path.join(self.ROOT_FOLDER, os.path.normpath(directory))
for rootPath, dirNames, fileNames in os.walk(path):
shouldContinue = False
for skippedPath in skippedPathsFull:
if rootPath.startswith(skippedPath):
shouldContinue = True
break
for directory in skippedDirectories:
currentDirectories = rootPath.replace(self.ROOT_FOLDER + os.sep, '').split(os.sep)
if directory in currentDirectories:
shouldContinue = True
break
if shouldContinue:
continue
for fileName in fileNames:
extension = os.path.splitext(fileName)[1][1:].lower()
if extension not in extensions:
continue
path = os.path.normpath(os.path.join(rootPath, fileName))
if path not in skippedFilesFull:
sources.append(path)
curdir = os.getcwd()
os.chdir(self.ROOT_FOLDER)
for source in sources:
diff = ''
with open(source, encoding='utf8') as file:
try:
for line in difflib.context_diff(self._runClangFormat(source).decode('utf-8').splitlines(),
file.read().splitlines()):
diff += line + '\n'
except UnicodeDecodeError:
self.assertTrue(False, msg='utf-8 decode problem in %s' % source)
self.assertTrue(
len(diff) == 0,
msg='Source file "%s" is not compliant with ClangFormat:\n\nDIFF:%s' % (source, diff)
)
os.chdir(curdir)


if __name__ == '__main__':
unittest.main()
Loading

0 comments on commit 3da50ad

Please sign in to comment.