summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.editorconfig4
-rw-r--r--GNUmakefile38
-rwxr-xr-xbuild-aux/get-dscname36
-rwxr-xr-xbuild-aux/lint-generic62
-rwxr-xr-xbuild-aux/lint-h27
-rwxr-xr-xbuild-aux/lint-src142
-rwxr-xr-xbuild-aux/lint-unknown19
7 files changed, 155 insertions, 173 deletions
diff --git a/.editorconfig b/.editorconfig
index 9540302..47bf81b 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -45,10 +45,10 @@ _mode = gitignore
# By specific filename (non-lib9p) #############################################
-[{build-aux/lint-unknown,build-aux/embed-sources.h.gen}]
+[build-aux/embed-sources.h.gen]
_mode = sh
-[{build-aux/lint-{bin,h,generic},build-aux/get-dscname,build-aux/valgrind,build-aux/gcov-prune,libusb/include/libusb/tusb_helpers.h.gen}]
+[{build-aux/lint-{src,bin},build-aux/valgrind,build-aux/gcov-prune,libusb/include/libusb/tusb_helpers.h.gen}]
_mode = bash
[build-aux/stack.c.gen]
diff --git a/GNUmakefile b/GNUmakefile
index 758c5aa..fa76266 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -125,33 +125,17 @@ build-aux/venv: build-aux/requirements.txt
touch --no-create $@
# `lint` ###############################
-# generic ##########
lint:
- $(MAKE) -k INNER=t $(patsubst sources_%,lint/%,$(filter sources_%,$(.VARIABLES)))
# Only lint binaries if the build scripts pass lint.
- $(MAKE) INNER=t lint/bin
+ $(MAKE) -k INNER=t lint/src
+ $(MAKE) INNER=t lint/bin
+lint/src: $(patsubst sources_%,lint/%,$(filter-out sources_all,$(filter sources_%,$(.VARIABLES))))
lint/bin: build build-aux/lint-bin
./build-aux/lint-bin $(foreach t,$(build_types),build/rp2040-$t/cmd/sbc_harness/sbc_harness.elf)
-lint/all: lint/%: build-aux/lint-generic build-aux/get-dscname
- ./build-aux/lint-generic $(sources_$*)
-lint/unknown: lint/%: build-aux/lint-unknown
- ./build-aux/lint-unknown $(sources_$*)
+lint/unknown lint/c lint/sh lint/bash lint/python3 lint/make lint/cmake lint/gitignore lint/ini lint/9p-idl lint/9p-log lint/markdown lint/pip lint/man-cat: build-aux/lint-src
+ ./build-aux/lint-src $(@F) $(sources_$(@F))
+lint/python3: build-aux/venv
.PHONY: lint lint/%
-# specific #########
-lint/c: lint/%: build-aux/lint-h build-aux/get-dscname
- ./build-aux/lint-h $(filter %.h,$(sources_$*))
-lint/sh lint/bash: lint/%:
- shellcheck $(sources_$*)
- shfmt --diff --case-indent --simplify $(sources_$*)
-lint/python3: lint/%: build-aux/venv
- ./build-aux/venv/bin/mypy --strict --scripts-are-modules $(sources_$*)
- ./build-aux/venv/bin/black --check $(sources_$*)
- ./build-aux/venv/bin/isort --check $(sources_$*)
- ./build-aux/venv/bin/pylint $(sources_$*)
- ! grep -nh 'SPECIAL$$' -- lib9p/core.gen lib9p/core_gen/*.py
- ./build-aux/venv/bin/pytest $(foreach f,$(sources_python3),$(if $(filter test_%.py,$(notdir $f)),$f))
-lint/make lint/cmake lint/gitignore lint/ini lint/9p-idl lint/9p-log lint/markdown lint/pip lint/man-cat: lint/%:
- @: TODO: Write/adopt linters for these file types
# `format` #############################
# generic ##########
@@ -162,9 +146,9 @@ format:
format/c: format/%:
@: TODO: Adopt a C code-formatter
format/sh format/bash: format/%:
- shfmt --write --case-indent --simplify $(sources_$*)
-format/python3: format/%: ./build-aux/venv
- ./build-aux/venv/bin/black $(sources_$*)
- ./build-aux/venv/bin/isort $(sources_$*)
-format/make format/cmake format/gitignore format/ini format/9p-idl format/9p-log format/markdown format/pip format/man-cat: format/%:
+ shfmt --write --case-indent --simplify $(sources_$(@F))
+format/python3: ./build-aux/venv
+ ./build-aux/venv/bin/black $(sources_$(@F))
+ ./build-aux/venv/bin/isort $(sources_$(@F))
+format/make format/cmake format/gitignore format/ini format/9p-idl format/9p-log format/markdown format/pip format/man-cat:
@: TODO: Write/adopt formatters for these file types
diff --git a/build-aux/get-dscname b/build-aux/get-dscname
deleted file mode 100755
index 34a1b08..0000000
--- a/build-aux/get-dscname
+++ /dev/null
@@ -1,36 +0,0 @@
-#!/usr/bin/env bash
-# build-aux/get-dscname - Get a file's self-described filename
-#
-# Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
-# SPDX-License-Identifier: AGPL-3.0-or-later
-
-if [ $# -ne 1 ]; then
- echo "$0: expected exactly 1 argument"
- exit 2
-fi
-
-if [[ $1 == */Documentation/* ]] && [[ "$(sed 1q -- "$1")" == 'NAME' ]]; then
- sed -n '
- 2{
- s,[/.],_,g;
- s,^\s*_,Documentation/,;
- s,$,.txt,;
-
- p;
- q;
- }
- ' -- "$1"
-else
- sed -n '
- 1,3{
- /^\#!/d;
- /^<!--$/d;
- /-\*- .* -\*-/d;
- s,[/*\# ]*,,;
- s/ - .*//;
-
- p;
- q;
- }
- ' -- "$1"
-fi
diff --git a/build-aux/lint-generic b/build-aux/lint-generic
deleted file mode 100755
index 9bf88dd..0000000
--- a/build-aux/lint-generic
+++ /dev/null
@@ -1,62 +0,0 @@
-#!/usr/bin/env bash
-# build-aux/lint-generic - Non-language-specific lint checks
-#
-# Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
-# SPDX-License-Identifier: AGPL-3.0-or-later
-
-RED=$(tput setaf 1)
-RESET=$(tput sgr0)
-
-err() {
- printf "${RED}%s${RESET}: %s\n" "$1" "$2" >&2
- r=1
-}
-
-r=0
-for filename in "$@"; do
- # File header ##########################################################
-
- shebang="$(sed -n '1{/^#!/p;}' "$filename")"
- if [[ -x $filename && (-z $shebang || $shebang == '#!/hint/'*) ]]; then
- err "$filename" 'is executable but does not have a shebang'
- elif [[ (-n $shebang && $shebang != '#!/hint/'*) && ! -x $filename ]]; then
- err "$filename" 'has a shebang but is not executable'
- fi
- case "$shebang" in
- '') : ;;
- '#!/bin/sh') : ;;
- '#!/usr/bin/env bash') : ;;
- '#!/usr/bin/env python3') : ;;
- *) err "$filename" 'has an unrecognized shebang' ;;
- esac
-
- if ! grep -E -q 'Copyright \(C\) 202[4-9]((-|, )202[5-9])* Luke T. Shumaker' "$filename"; then
- err "$filename" 'is missing a copyright statement'
- fi
- if test -e .git && ! git diff --quiet milestone/2025-01-01 HEAD -- "$filename"; then
- if ! grep -E -q 'Copyright \(C\) .*2025 Luke T. Shumaker' "$filename"; then
- err "$filename" 'has an outdated copyright statement'
- fi
- fi
- if ! grep -q '\sSPDX-License-Identifier[:] ' "$filename"; then
- err "$filename" 'is missing an SPDX-License-Identifier'
- fi
-
- dscname_act=$(./build-aux/get-dscname "$filename")
- dscname_exp=$(echo "$filename" | sed \
- -e 's,.*/config/,,' \
- -e 's,.*/config\.h$,config.h,' \
- -e 's,.*include/,,' \
- -e 's,.*static/,,' \
- -e 's/\.wip$//')
- if [ "$dscname_act" != "$dscname_exp" ] && [ "cmd/$dscname_act" != "$dscname_exp" ]; then
- err "$filename" "self-identifies as $dscname_act (expected $dscname_exp)"
- fi
-
- # File body ############################################################
-
- if grep -n --color=auto "$(printf '\\S\t')" "$filename"; then
- err "$filename" 'uses tabs for alignment'
- fi
-done
-exit $r
diff --git a/build-aux/lint-h b/build-aux/lint-h
deleted file mode 100755
index 7459032..0000000
--- a/build-aux/lint-h
+++ /dev/null
@@ -1,27 +0,0 @@
-#!/usr/bin/env bash
-# build-aux/lint-h - Lint checks for C header files
-#
-# Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
-# SPDX-License-Identifier: AGPL-3.0-or-later
-
-RED=$(tput setaf 1)
-RESET=$(tput sgr0)
-
-err() {
- printf "${RED}%s${RESET}: %s\n" "$1" "$2" >&2
- r=1
-}
-
-r=0
-for filename in "$@"; do
- dscname=$(./build-aux/get-dscname "$filename")
- guard=${dscname//'/'/'_'}
- guard=${guard//'.'/'_'}
- guard="_${guard^^}_"
- if ! { grep -Fxq "#ifndef ${guard}" "$filename" &&
- grep -Fxq "#define ${guard}" "$filename" &&
- grep -Fxq "#endif /* ${guard} */" "$filename"; }; then
- err "$filename" "does not have ${guard} guard"
- fi
-done
-exit $r
diff --git a/build-aux/lint-src b/build-aux/lint-src
new file mode 100755
index 0000000..4207bad
--- /dev/null
+++ b/build-aux/lint-src
@@ -0,0 +1,142 @@
+#!/usr/bin/env bash
+# build-aux/lint-src - Lint checks for source files
+#
+# Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
+# SPDX-License-Identifier: AGPL-3.0-or-later
+
+RED=$(tput setaf 1)
+RESET=$(tput sgr0)
+
+err() {
+ printf "${RED}%s${RESET}: %s\n" "$1" "$2" >&2
+ r=1
+}
+
+get-dscname() {
+ if [[ $1 == */Documentation/* ]] && [[ "$(sed 1q -- "$1")" == 'NAME' ]]; then
+ sed -n '
+ 2{
+ s,[/.],_,g;
+ s,^\s*_,Documentation/,;
+ s,$,.txt,;
+
+ p;
+ q;
+ }
+ ' -- "$1"
+ else
+ sed -n '
+ 1,3{
+ /^\#!/d;
+ /^<!--$/d;
+ /-\*- .* -\*-/d;
+ s,[/*\# ]*,,;
+ s/ - .*//;
+
+ p;
+ q;
+ }
+ ' -- "$1"
+ fi
+}
+
+{
+ filetype=$1
+ filenames=("${@:2}")
+
+ r=0
+ for filename in "${filenames[@]}"; do
+ # File header ##########################################################
+
+ shebang="$(sed -n '1{/^#!/p;}' "$filename")"
+ if [[ -x $filename && (-z $shebang || $shebang == '#!/hint/'*) ]]; then
+ err "$filename" 'is executable but does not have a shebang'
+ elif [[ (-n $shebang && $shebang != '#!/hint/'*) && ! -x $filename ]]; then
+ err "$filename" 'has a shebang but is not executable'
+ fi
+ case "$shebang" in
+ '') : ;;
+ '#!/bin/sh') : ;;
+ '#!/usr/bin/env bash') : ;;
+ '#!/usr/bin/env python3') : ;;
+ *) err "$filename" 'has an unrecognized shebang' ;;
+ esac
+
+ if ! grep -E -q 'Copyright \(C\) 202[4-9]((-|, )202[5-9])* Luke T. Shumaker' "$filename"; then
+ err "$filename" 'is missing a copyright statement'
+ fi
+ if test -e .git && ! git diff --quiet milestone/2025-01-01 HEAD -- "$filename"; then
+ if ! grep -E -q 'Copyright \(C\) .*2025 Luke T. Shumaker' "$filename"; then
+ err "$filename" 'has an outdated copyright statement'
+ fi
+ fi
+ if ! grep -q '\sSPDX-License-Identifier[:] ' "$filename"; then
+ err "$filename" 'is missing an SPDX-License-Identifier'
+ fi
+
+ dscname_act=$(get-dscname "$filename")
+ dscname_exp=$(echo "$filename" | sed \
+ -e 's,.*/config/,,' \
+ -e 's,.*/config\.h$,config.h,' \
+ -e 's,.*include/,,' \
+ -e 's,.*static/,,' \
+ -e 's/\.wip$//')
+ if [ "$dscname_act" != "$dscname_exp" ] && [ "cmd/$dscname_act" != "$dscname_exp" ]; then
+ err "$filename" "self-identifies as $dscname_act (expected $dscname_exp)"
+ fi
+
+ # File body ############################################################
+
+ if grep -n --color=auto "$(printf '\\S\t')" "$filename"; then
+ err "$filename" 'uses tabs for alignment'
+ fi
+ done
+ case "$filetype" in
+ unknown)
+ for filename in "${filenames[@]}"; do
+ err "$filename" 'cannot lint unknown file type'
+ done
+ ;;
+ c)
+ for filename in "${filenames[@]}"; do
+ if [[ $filename == *.h ]]; then
+ dscname=$(get-dscname "$filename")
+ guard=${dscname//'/'/'_'}
+ guard=${guard//'.'/'_'}
+ guard="_${guard^^}_"
+ if ! { grep -Fxq "#ifndef ${guard}" "$filename" &&
+ grep -Fxq "#define ${guard}" "$filename" &&
+ grep -Fxq "#endif /* ${guard} */" "$filename"; }; then
+ err "$filename" "does not have ${guard} guard"
+ fi
+ fi
+ done
+ ;;
+ sh | bash)
+ shellcheck "${filenames[@]}" || exit $?
+ shfmt --diff --case-indent --simplify "${filenames[@]}" || exit $?
+ ;;
+ python3)
+ ./build-aux/venv/bin/mypy --strict --scripts-are-modules "${filenames[@]}" || exit $?
+ ./build-aux/venv/bin/black --check "${filenames[@]}" || exit $?
+ ./build-aux/venv/bin/isort --check "${filenames[@]}" || exit $?
+ ./build-aux/venv/bin/pylint "${filenames[@]}" || exit $?
+ if grep -nh 'SPECIAL$$' -- lib9p/core.gen lib9p/core_gen/*.py; then exit 1; fi
+ testfiles=()
+ for filename in "${filenames[@]}"; do
+ if [[ ${filename##*/} == test_*.py ]]; then
+ testfiles+=("$filename")
+ fi
+ done
+ ./build-aux/venv/bin/pytest "${testfiles[@]}" || exit $?
+ ;;
+ make | cmake | gitignore | ini | 9p-idl | 9p-log | markdown | pip | man-cat)
+ # TODO: Write/adopt linters for these file types
+ :
+ ;;
+ *)
+ err "$0" "unknown filetype: ${filetype}"
+ ;;
+ esac
+ exit $r
+}
diff --git a/build-aux/lint-unknown b/build-aux/lint-unknown
deleted file mode 100755
index bc23a81..0000000
--- a/build-aux/lint-unknown
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/bin/sh
-# build-aux/lint-unknown - Lint checks for unknown files
-#
-# Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
-# SPDX-License-Identifier: AGPL-3.0-or-later
-
-RED=$(tput setaf 1)
-RESET=$(tput sgr0)
-
-err() {
- printf "${RED}%s${RESET}: %s\n" "$1" "$2" >&2
- r=1
-}
-
-r=0
-for filename in "$@"; do
- err "$filename" 'cannot lint unknown file type'
-done
-exit $r