Skip to content

Commit 4a30725

Browse files
committed
Add check_code_formatting
Fixes #14
1 parent 282aff3 commit 4a30725

File tree

6 files changed

+287
-2
lines changed

6 files changed

+287
-2
lines changed

.travis.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ matrix:
8282
- cd ..
8383
- git clone https://github.com/per1234/arduino-ci-script-tests
8484
- cd arduino-ci-script-tests
85-
- git checkout 2cb113ce9bfa1503dff3faf68e55f03ab99e13a6
85+
- git checkout 6b9758211e957689803b05008e705cb88758bd2b
8686
script:
8787
- bats check_keywords_txt.bats
8888
- bats check_library_manager_compliance.bats
@@ -190,6 +190,8 @@ script:
190190

191191
- check_library_manager_compliance "${SKETCHBOOK_FOLDER}/libraries/NewPing"
192192

193+
- check_code_formatting "1" "" "${APPLICATION_FOLDER}/arduino/examples/01.Basics/BareMinimum"
194+
193195
# Test library installed from .zip with rename
194196
# Test library installed from .zip with dot in the folder name
195197
# Test board from hardware package manually installed from compressed file download

README.md

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ Control the level of verbosity of the script's output in the Travis CI log. Verb
5252
- Parameter: **SCRIPT_VERBOSITY_LEVEL** - `0`, `1` or `2` (least to most verbosity).
5353

5454
##### `set_application_folder APPLICATION_FOLDER`
55-
- Parameter: **APPLICATION_FOLDER** - The folder to install the Arduino IDE to. This should be set to `/usr/local/share` or a subfolder of that location. The folder will be created if it doesn't already exist. The Arduino IDE will be installed in the `arduino` subfolder.
55+
- Parameter: **APPLICATION_FOLDER** - The folder to install the Arduino IDE (and Artistic Style if you use `check_code_formatting`) to. This should be set to `/usr/local/share` or a subfolder of that location. The folder will be created if it doesn't already exist. The Arduino IDE will be installed in the `arduino` subfolder.
5656

5757
##### `set_sketchbook_folder SKETCHBOOK_FOLDER`
5858
- Parameter: **SKETCHBOOK_FOLDER** - The folder to be set as the Arduino IDE's sketchbook folder. The folder will be created if it doesn't already exist. Libraries installed via `install_library` will be installed to the `libraries` subfolder. Non-Boards Manager hardware packages installed via `install_package` will be installed to the `hardware` subfolder. This setting is only supported by Arduino IDE 1.5.6 and newer.
@@ -142,6 +142,15 @@ Check [keywords.txt](https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5:-Li
142142
Make some additional checks for compliance with the requirements for adding a library to the [Library Manager index](https://github.com/arduino/Arduino/wiki/Library-Manager-FAQ). This function should be used in combination with `check_library_structure' and 'check_library_properties' to ensure full compliance with the requirements.
143143
- Parameter: **libraryPath** - Path of the library to check.
144144

145+
##### `check_code_formatting strictness excludedPathList targetPath`
146+
Check code formatting for compliance with the Arduino code style. The [Artistic Style](http://astyle.sourceforge.net) formatter tool is used for this check. If it's not already installed, it will be installed to the `astyle` subfolder of the folder specified to `set_application_folder`.
147+
- Parameter: **strictness** - Determines how strict to be about code formatting compliance: 1 (least strict) - 3 (most strict). Each strictness level is based on the previous one, but with additional requirements.
148+
- `1`: The Arduino IDE's auto format configuration.
149+
- `2`: The configuration Arduino uses to format their example sketches.
150+
- `3`: A custom configuration based on a study of the prevailing styles used in official Arduino code.
151+
- Parameter: **excludedPathList** - A comma-separated list of paths to exclude from the check.
152+
- Parameter: **targetPath** - The path to run the check on. All code files will be checked recursively.
153+
145154
##### `build_sketch sketchPath boardID allowFail IDEversion`
146155
##### `build_sketch sketchPath boardID allowFail [IDEversionList]`
147156
##### `build_sketch sketchPath boardID allowFail startIDEversion endIDEversion`

arduino-ci-script.sh

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2333,6 +2333,76 @@ function check_library_manager_compliance() {
23332333
return "$exitStatus"
23342334
}
23352335

2336+
function check_code_formatting() {
2337+
local -r strictness="$1"
2338+
local -r excludedPathList="$2"
2339+
local -r targetPath="$3"
2340+
2341+
local -r astyleConfigurationFolder="etc/astyle-configurations"
2342+
local -r astyleConfigurationExtension=".conf"
2343+
2344+
# Fold the output in the Travis CI log
2345+
echo -e -n 'travis_fold:start:check_code_formatting\r'
2346+
2347+
if [[ $strictness -lt 1 ]] || [[ $strictness -gt 3 ]]; then
2348+
echo "ERROR: Invalid strictness parameter value. Valid values are 1 (least strict) - 3 (most strict)"
2349+
return "$ARDUINO_CI_SCRIPT_FAILURE_EXIT_STATUS"
2350+
fi
2351+
2352+
if ! [[ -d "$targetPath" ]]; then
2353+
echo "ERROR: targetPath doesn't exist"
2354+
return "$ARDUINO_CI_SCRIPT_FAILURE_EXIT_STATUS"
2355+
fi
2356+
2357+
local scriptFolder
2358+
# https://stackoverflow.com/a/246128
2359+
local scriptSource="${BASH_SOURCE[0]}"
2360+
while [ -h "$scriptSource" ]; do # Resolve $scriptSource until the file is no longer a symlink
2361+
scriptFolder="$(cd -P "$(dirname "$scriptSource")" >/dev/null 2>&1 && pwd)"
2362+
scriptSource="$(readlink "$scriptSource")"
2363+
[[ $scriptSource != /* ]] && scriptSource="$scriptFolder/$scriptSource" # If $scriptSource was a relative symlink, we need to resolve it relative to the path where the symlink file was located
2364+
done
2365+
scriptFolder="$(cd -P "$(dirname "$scriptSource")" >/dev/null 2>&1 && pwd)"
2366+
2367+
# Assemble the find options for the excluded paths from the list
2368+
for excludedPath in ${excludedPathList//,/ }; do
2369+
excludeOptions="$excludeOptions -path $excludedPath -prune -or"
2370+
done
2371+
2372+
local astylePath
2373+
astylePath=$(command -v astyle)
2374+
if [[ ! -e "$astylePath" ]]; then
2375+
# Install astyle
2376+
# Save the current folder
2377+
local -r previousFolder="$PWD"
2378+
mkdir "${ARDUINO_CI_SCRIPT_APPLICATION_FOLDER}/astyle"
2379+
wget --no-verbose $ARDUINO_CI_SCRIPT_QUIET_OPTION --output-document="${ARDUINO_CI_SCRIPT_TEMPORARY_FOLDER}/astyle.tar.gz" "https://iweb.dl.sourceforge.net/project/astyle/astyle/astyle%203.1/astyle_3.1_linux.tar.gz"
2380+
tar --extract --file="${ARDUINO_CI_SCRIPT_TEMPORARY_FOLDER}/astyle.tar.gz" --directory="${ARDUINO_CI_SCRIPT_APPLICATION_FOLDER}"
2381+
cd "${ARDUINO_CI_SCRIPT_APPLICATION_FOLDER}/astyle/build/gcc"
2382+
eval "make $ARDUINO_CI_SCRIPT_VERBOSITY_REDIRECT"
2383+
astylePath="${ARDUINO_CI_SCRIPT_APPLICATION_FOLDER}/astyle/build/gcc/bin/astyle"
2384+
# Return to the previous folder
2385+
cd "$previousFolder"
2386+
fi
2387+
2388+
# Set default exit status
2389+
exitStatus="$ARDUINO_CI_SCRIPT_SUCCESS_EXIT_STATUS"
2390+
2391+
while read -r filename; do
2392+
# Check if it's a file (find matches on pruned folders)
2393+
if [[ -f "$filename" ]]; then
2394+
if ! diff --strip-trailing-cr "$filename" <("${astylePath}" --options="${scriptFolder}/${astyleConfigurationFolder}/${strictness}${astyleConfigurationExtension}" --dry-run <"$filename"); then
2395+
echo "ERROR: Non-compliant code formatting in $filename"
2396+
# Make the function fail
2397+
exitStatus="$ARDUINO_CI_SCRIPT_FAILURE_EXIT_STATUS"
2398+
fi
2399+
fi
2400+
done <<<"$(eval "find $targetPath -regextype posix-extended $excludeOptions \( -iregex '.*\.((ino)|(h)|(hpp)|(hh)|(hxx)|(h\+\+)|(cpp)|(cc)|(cxx)|(c\+\+)|(cp)|(c)|(ipp)|(ii)|(ixx)|(inl)|(tpp)|(txx)|(tpl))$' -and -type f \)")"
2401+
2402+
echo -e -n 'travis_fold:end:check_code_formatting\r'
2403+
return "$exitStatus"
2404+
}
2405+
23362406
# Set default verbosity (must be called after the function definitions
23372407
set_script_verbosity 0
23382408

etc/astyle-configurations/1.conf

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# source: https://raw.githubusercontent.com/arduino/Arduino/1.8.9/build/shared/lib/formatter.conf
2+
3+
# This configuration file contains a selection of the available options provided by the formatting tool "Artistic Style"
4+
# http://astyle.sourceforge.net/astyle.html
5+
#
6+
# If you wish to change them, don't edit this file.
7+
# Instead, copy it in the same folder of file "preferences.txt" and modify the copy. This way, you won't lose your custom formatter settings when upgrading the IDE
8+
# If you don't know where file preferences.txt is stored, open the IDE, File -> Preferences and you'll find a link
9+
10+
mode=c
11+
12+
# 2 spaces indentation
13+
indent=spaces=2
14+
15+
# also indent macros
16+
indent-preprocessor
17+
18+
# indent classes, switches (and cases), comments starting at column 1
19+
indent-classes
20+
indent-switches
21+
indent-cases
22+
indent-col1-comments
23+
24+
# put a space around operators
25+
pad-oper
26+
27+
# put a space after if/for/while
28+
pad-header
29+
30+
# if you like one-liners, keep them
31+
keep-one-line-statements
32+
33+
remove-comment-prefix

etc/astyle-configurations/2.conf

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# source: https://raw.githubusercontent.com/arduino/Arduino/1.8.9/build/shared/examples_formatter.conf
2+
3+
# This configuration file contains a selection of the available options provided by the formatting tool "Artistic Style"
4+
# http://astyle.sourceforge.net/astyle.html
5+
#
6+
# If you wish to change them, don't edit this file.
7+
# Instead, copy it in the same folder of file "preferences.txt" and modify the copy. This way, you won't lose your custom formatter settings when upgrading the IDE
8+
# If you don't know where file preferences.txt is stored, open the IDE, File -> Preferences and you'll find a link
9+
10+
mode=c
11+
12+
# 2 spaces indentation
13+
indent=spaces=2
14+
15+
# also indent macros
16+
indent-preprocessor
17+
18+
# indent classes, switches (and cases), comments starting at column 1
19+
indent-classes
20+
indent-switches
21+
indent-cases
22+
indent-col1-comments
23+
24+
# put a space around operators
25+
pad-oper
26+
27+
# put a space after if/for/while
28+
pad-header
29+
30+
# if you like one-liners, keep them
31+
keep-one-line-statements
32+
33+
style=java
34+
attach-namespaces
35+
attach-classes
36+
attach-inlines
37+
attach-extern-c
38+
indent-modifiers
39+
indent-namespaces
40+
indent-labels
41+
indent-preproc-block
42+
indent-preproc-define
43+
indent-preproc-cond
44+
unpad-paren
45+
add-brackets
46+
remove-comment-prefix

etc/astyle-configurations/3.conf

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
# source: https://github.com/arduino/ArduinoCore-avr/issues/71#issuecomment-466763471 2019-06-09
2+
3+
# formatter.conf, examples_formatter.conf
4+
mode=c
5+
6+
7+
# examples_formatter.conf
8+
# http://astyle.sourceforge.net/astyle.html#_style=java
9+
# Considering changing this to the synonym "style=attach", which seems more descriptive
10+
style=java
11+
12+
13+
# examples_formatter.conf
14+
attach-namespaces
15+
16+
# examples_formatter.conf
17+
attach-classes
18+
19+
# examples_formatter.conf
20+
attach-inlines
21+
22+
# examples_formatter.conf
23+
attach-extern-c
24+
25+
26+
# formatter.conf, examples_formatter.conf
27+
indent=spaces=2
28+
29+
# formatter.conf, examples_formatter.conf
30+
indent-classes
31+
32+
# formatter.conf, examples_formatter.conf
33+
indent-switches
34+
35+
# formatter.conf, examples_formatter.conf
36+
indent-cases
37+
38+
# formatter.conf, examples_formatter.conf
39+
indent-col1-comments
40+
41+
# examples_formatter.conf
42+
indent-modifiers
43+
44+
# examples_formatter.conf
45+
indent-namespaces
46+
47+
# examples_formatter.conf
48+
indent-labels
49+
50+
# examples_formatter.conf
51+
indent-preproc-define
52+
53+
54+
# formatter.conf, examples_formatter.conf
55+
pad-header
56+
57+
# formatter.conf, examples_formatter.conf
58+
pad-oper
59+
60+
# examples_formatter.conf
61+
unpad-paren
62+
63+
64+
# formatter.conf, examples_formatter.conf
65+
remove-comment-prefix
66+
67+
# formatter.conf, examples_formatter.conf
68+
# http://astyle.sourceforge.net/astyle.html#_keep-one-line-statements
69+
# "Don't break complex statements and multiple statements residing on a single line."
70+
# I don't like one line complex statements, but I guess since it's in formatter.conf it must stay.
71+
keep-one-line-statements
72+
73+
74+
75+
# Options from examples_formatter.conf that I think should be removed:
76+
77+
# http://astyle.sourceforge.net/astyle.html#_indent-preproc-block
78+
# "Indent preprocessor blocks at brace level zero and immediately within a namespace. There are restrictions on what will be indented. Blocks within methods, classes, arrays, etc., will not be indented. Blocks containing braces or multi-line define statements will not be indented. Without this option the preprocessor block is not indented."
79+
# This does indent for #ifdef, but not for #ifndef, so it's quite inconsistent
80+
# Indentation of preprocessor directives as done by this option is not very common in Arduino AVR Boards core, and where it is used, it's typically done inconsistently throughout the file
81+
indent-preproc-block
82+
83+
# http://astyle.sourceforge.net/astyle.html#_indent-preproc-cond
84+
# "Indent preprocessor conditional statements to the same level as the source code."
85+
# Indentation of preprocessor directives as done by this option is very rare in Arduino AVR Boards core
86+
indent-preproc-cond
87+
88+
89+
90+
# Options I have not implemented from formatter.conf or examples_formatter.conf:
91+
92+
# examples_formatter.conf
93+
# Not a valid option in the latest version of AStyle. I think the correct option name is "add-braces", which I do use in my configuration
94+
# add-brackets
95+
96+
# formatter.conf, examples_formatter.conf
97+
# Not a valid option in the latest version of AStyle.
98+
# indent-preprocessor
99+
100+
101+
102+
# Options I have added:
103+
104+
# http://astyle.sourceforge.net/astyle.html#_add-braces
105+
# "I believe this is the correct option name to use instead the "add-brackets" option used in examples_formatter.conf. "add-brackets" is not a valid option in the latest version of AStyle"
106+
add-braces
107+
108+
# http://astyle.sourceforge.net/astyle.html#_convert-tabs
109+
# "Converts tabs into spaces in the non-indentation part of the line."
110+
# AStyle is already configured to use spaces for indentation by indent=spaces=2. The Arduino IDE uses spaces instead of tabs by default.
111+
convert-tabs
112+
113+
# http://astyle.sourceforge.net/astyle.html#_attach-return-type
114+
# "Attach the return type to the function name in function definitions."
115+
attach-return-type
116+
117+
# http://astyle.sourceforge.net/astyle.html#_attach-return-type
118+
# "Attach the return type to the function name in function declarations."
119+
attach-return-type-decl
120+
121+
# http://astyle.sourceforge.net/astyle.html#_align-pointer
122+
# "Attach a pointer or reference operator (*, &, or ^) to either the variable type (left) or variable name (right), or place it between the type and name (middle)."
123+
# In Arduino AVR Boards core, name alignment of pointers is somewhat more common, though all possible styles are used
124+
# I don't care which style is chosen (type, middle, name), but I do think one should be chosen and used.
125+
align-pointer=name

0 commit comments

Comments
 (0)