Skip to content

Commit 5b309e4

Browse files
authored
Merge pull request #230 from InsightSoftwareConsortium/black-pre-commit
ENH: Add black style pre-commit hook
2 parents 80fc7fe + 6dd9407 commit 5b309e4

File tree

75 files changed

+650
-448
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

75 files changed

+650
-448
lines changed

.gitattributes

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
*.txx our-c-style
99
*.txt whitespace=tab-in-indent,no-lf-at-eof
1010
*.cmake whitespace=tab-in-indent,no-lf-at-eof
11+
*.py hooks.style=black
1112

1213
# ExternalData content links must have LF newlines
1314
*.md5 crlf=input

.github/workflows/clang-format-linter.yml

Lines changed: 0 additions & 13 deletions
This file was deleted.

.github/workflows/lint.yml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
name: Lint
2+
3+
on: [push,pull_request]
4+
5+
jobs:
6+
lint:
7+
runs-on: ubuntu-latest
8+
9+
steps:
10+
- uses: actions/checkout@v1
11+
with:
12+
fetch-depth: 1
13+
14+
- name: Lint C++
15+
uses: InsightSoftwareConsortium/ITKClangFormatLinterAction@master
16+
17+
- name: Set up Python
18+
uses: actions/setup-python@v1
19+
with:
20+
python-version: 3.9
21+
22+
- name: Install Python dependencies
23+
run: pip install black
24+
25+
- name: Lint Python
26+
uses: wearerequired/lint-action@v1
27+
with:
28+
black: true
29+
black_dir: src/

Superbuild/External-Python.cmake

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,19 @@ set(_itk_venv "${CMAKE_CURRENT_BINARY_DIR}/itkpython")
44
if(WIN32)
55
set(ITKPYTHON_EXECUTABLE "${_itk_venv}/python.exe" CACHE FILEPATH "Python executable with the ITK package installed" FORCE)
66
set(SPHINX_EXECUTABLE "${_itk_venv}/Scripts/sphinx-build.exe" CACHE FILEPATH "Sphinx executable" FORCE)
7+
set(BLACK_EXECUTABLE "${_itk_venv}/Scripts/black.exe" CACHE FILEPATH "black executable" FORCE)
78
else()
89
set(ITKPYTHON_EXECUTABLE "${_itk_venv}/bin/python" CACHE FILEPATH "Python executable with the ITK package installed" FORCE)
910
set(SPHINX_EXECUTABLE "${_itk_venv}/bin/sphinx-build" CACHE FILEPATH "Sphinx executable" FORCE)
11+
set(BLACK_EXECUTABLE "${_itk_venv}/bin/black" CACHE FILEPATH "black executable" FORCE)
1012
endif()
13+
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/ITKBlackConfig.cmake.in"
14+
"${CMAKE_CURRENT_BINARY_DIR}/ITKBlackConfig.cmake" @ONLY)
1115

1216
ExternalProject_Add(ITKPython
1317
DOWNLOAD_COMMAND ""
1418
CONFIGURE_COMMAND ${PYTHON_EXECUTABLE} -m venv "${_itk_venv}"
1519
BUILD_COMMAND ${ITKPYTHON_EXECUTABLE} -m pip install --upgrade pip
16-
INSTALL_COMMAND ${ITKPYTHON_EXECUTABLE} -m pip install --ignore-installed itk>=5.2rc3 sphinx==3.0.4 six
20+
INSTALL_COMMAND ${ITKPYTHON_EXECUTABLE} -m pip install --ignore-installed itk>=5.2rc3 sphinx==3.0.4 six black
21+
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/ITKBlackConfig.cmake
1722
)

Superbuild/ITKBlackConfig.cmake.in

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
set(ITKExamples_SOURCE_DIR "@ITKExamples_SOURCE_DIR@")
2+
set(CMAKE_SOURCE_DIR "@CMAKE_SOURCE_DIR@")
3+
set(BLACK_EXECUTABLE "@BLACK_EXECUTABLE@")
4+
5+
set(WORKING_DIR "")
6+
if(ITKExamples_SOURCE_DIR)
7+
set(WORKING_DIR "${ITKExamples_SOURCE_DIR}/..")
8+
else()
9+
set(WORKING_DIR "${CMAKE_SOURCE_DIR}/..")
10+
endif()
11+
12+
find_package(Git)
13+
if(GIT_FOUND AND EXISTS "${WORKING_DIR}/.git/config")
14+
execute_process(COMMAND ${GIT_EXECUTABLE} config black.executable
15+
"${BLACK_EXECUTABLE}"
16+
WORKING_DIRECTORY ${WORKING_DIR})
17+
endif()

Utilities/Hooks/pre-commit-style.bash

Lines changed: 77 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
# limitations under the License.
1515
#=============================================================================
1616

17-
# Run clangformat and KWStyle pre-commit hooks.
17+
# Run clangformat, KWStyle, black pre-commit hooks.
1818
#
1919
# 'git config' is used to enable the hooks and set their configuration files.
2020
# The repository .gitattributes must also enable the hooks on the targeted
@@ -32,6 +32,8 @@ do_KWStyle=$(git config --bool hooks.KWStyle) || do_KWStyle=false
3232

3333
do_clangformat=$(git config --bool hooks.clangformat) || do_clangformat=true
3434

35+
do_black=$(git config --bool hooks.blackformat) || do_blackformat=true
36+
3537
#-----------------------------------------------------------------------------
3638
# Check if we want to run the style on a given file. Uses git attributes. If
3739
# the hook.style attribute is set, then all styles are executed. If the
@@ -164,8 +166,8 @@ check_for_clangformat() {
164166
clangformat_path=$(type -p "$system_clang_format" >/dev/null) ||
165167
die "clang-format executable was not found.
166168
167-
A clang-format binary will be downloaded and configured when ITK
168-
is built with the BUILD_TESTING CMake configuration option enabled.
169+
A clang-format binary will be downloaded and configured when the ITKExamples
170+
Superbuild is built with the BUILD_TESTING CMake configuration option enabled.
169171
170172
Alternatively, install clang-format version $clangformat_required_version or set the executable location with
171173
@@ -292,25 +294,81 @@ For more information, see
292294
done # end for changed files
293295
}
294296

297+
#-----------------------------------------------------------------------------
298+
# black.
299+
check_for_black() {
300+
system_black=""
301+
if type -p "black" >/dev/null; then
302+
system_black="black"
303+
fi
304+
black_path=$(git config black.executable) ||
305+
black_path=$(type -p "$system_black" >/dev/null) ||
306+
die "black executable was not found.
307+
308+
A black Python formatting tool will be downloaded and configured when the ITKExamples
309+
Superbuild is built with the BUILD_TESTING CMake configuration option enabled.
310+
311+
Alternatively, install black with:
312+
313+
python -m pip install black
314+
315+
and set the executable location with
316+
317+
git config black.executable /path/to/black
318+
319+
if it is not in the system's PATH.
320+
"
321+
}
322+
323+
run_black_on_file() {
324+
"$black_path" "$1"
325+
326+
if test $? -ne 0; then
327+
die "black style application failed."
328+
fi
329+
return 0
330+
}
331+
332+
run_black() {
333+
$do_black && check_for_black
334+
if test $?; then
335+
have_black=true
336+
else
337+
have_black=false
338+
fi
339+
340+
git diff-index --cached --diff-filter=ACMR --name-only HEAD -- |
341+
while read f; do
342+
if run_style_on_file "$f" "black"; then
343+
run_black_on_file "$f"
344+
fi || return
345+
done
346+
}
347+
295348
# Do not run during merge commits for now.
296349
if test -f "$GIT_DIR/MERGE_HEAD"; then
297350
:
298-
elif $do_clangformat; then
299-
# We use git-mergetool settings to review the clangformat changes.
300-
TOOL_MODE=merge
301-
. "$(git --exec-path)/git-mergetool--lib"
302-
# Redefine check_unchanged because we do not need to check if the merge was
303-
# successful.
304-
check_unchanged() {
305-
status=0
306-
}
307-
check_for_clangformat
308-
run_clangformat || exit 1
309-
# do_clangformat will run KWStyle on the files incrementally so excessive
310-
# clangformat merges do not have to occur.
311-
elif $do_KWStyle; then
312-
if check_for_KWStyle; then
313-
run_KWStyle || exit 1
351+
else
352+
if $do_clangformat; then
353+
# We use git-mergetool settings to review the clangformat changes.
354+
TOOL_MODE=merge
355+
. "$(git --exec-path)/git-mergetool--lib"
356+
# Redefine check_unchanged because we do not need to check if the merge was
357+
# successful.
358+
check_unchanged() {
359+
status=0
360+
}
361+
check_for_clangformat
362+
run_clangformat || exit 1
363+
# do_clangformat will run KWStyle on the files incrementally so excessive
364+
# clangformat merges do not have to occur.
365+
elif $do_KWStyle; then
366+
if check_for_KWStyle; then
367+
run_KWStyle || exit 1
368+
fi
369+
fi
370+
if $do_black; then
371+
run_black || exit 1
314372
fi
315373
fi
316374

src/Bridge/VtkGlue/ConvertAnRGBitkImageTovtkImageData/Code.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,13 @@
1818
import itk
1919

2020
from distutils.version import StrictVersion as VS
21+
2122
if VS(itk.Version.GetITKVersion()) < VS("4.10.0"):
2223
print("ITK 4.10.0 is required.")
2324
sys.exit(1)
2425

2526
if len(sys.argv) != 2:
26-
print('Usage: ' + sys.argv[0] + ' <InputFileName>')
27+
print("Usage: " + sys.argv[0] + " <InputFileName>")
2728
sys.exit(1)
2829
imageFileName = sys.argv[1]
2930

src/Bridge/VtkGlue/ConvertAnitkImageTovtkImageData/Code.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
import itk
1919

2020
if len(sys.argv) != 2:
21-
print('Usage: ' + sys.argv[0] + ' <InputFileName>')
21+
print("Usage: " + sys.argv[0] + " <InputFileName>")
2222
sys.exit(1)
2323
imageFileName = sys.argv[1]
2424

src/Bridge/VtkGlue/ConvertRGBvtkImageDataToAnitkImage/Code.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
import vtk
2020

2121
if len(sys.argv) < 2:
22-
print('Usage: ' + sys.argv[0] + ' <InputFileName>')
22+
print("Usage: " + sys.argv[0] + " <InputFileName>")
2323
sys.exit(1)
2424
imageFileName = sys.argv[1]
2525

src/Bridge/VtkGlue/ConvertvtkImageDataToAnitkImage/Code.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
import vtk
2020

2121
if len(sys.argv) < 2:
22-
print('Usage: ' + sys.argv[0] + ' <InputFileName>')
22+
print("Usage: " + sys.argv[0] + " <InputFileName>")
2323
sys.exit(1)
2424
imageFileName = sys.argv[1]
2525

0 commit comments

Comments
 (0)