[enh] CI - add shell script formatter

Implement rules and functions to format shell scripts:

    $ make format.shell

or alternatively to format all source code:

    $ make format

The formatter `shfmt` reads the rules from the editorconfig[1]

  If any EditorConfig files are found, they will be used to apply formatting
  options.  If any parser or printer flags are given to the tool, no
  EditorConfig files will be used.

[1] https://github.com/patrickvane/shfmt?tab=readme-ov-file#description

Signed-off-by: Markus Heiser <markus.heiser@darmarit.de>
This commit is contained in:
Markus Heiser 2025-07-16 15:54:54 +02:00 committed by Markus Heiser
parent 7ee3dc9d74
commit 67e423edb2
6 changed files with 48 additions and 20 deletions

View file

@ -14,6 +14,14 @@ charset = utf-8
# code formatter accepts length of 120, but editor should prefer 80
max_line_length = 80
[{*.sh,manage}]
indent_style = space
indent_size = 4
# shfmt options
shell_variant = bash
switch_case_indent = true
[*.html]
# in the jinja templates we use indent size of 2 and we do not use tabs
indent_size = 2

View file

@ -47,8 +47,8 @@ search.checker.%: install
$(Q)./manage pyenv.cmd searxng-checker -v "$(subst _, ,$(patsubst search.checker.%,%,$@))"
PHONY += test ci.test test.shell
ci.test: test.yamllint test.black test.types.ci test.pylint test.unit test.robot test.rst test.shell test.pybabel
test: test.yamllint test.black test.types.dev test.pylint test.unit test.robot test.rst test.shell
ci.test: test.yamllint test.black test.types.ci test.pylint test.unit test.robot test.rst test.shell test.shfmt test.pybabel
test: test.yamllint test.black test.types.dev test.pylint test.unit test.robot test.rst test.shell test.shfmt
test.shell:
$(Q)shellcheck -x -s dash \
container/entrypoint.sh
@ -64,6 +64,8 @@ test.shell:
utils/searxng.sh
$(Q)$(MTOOLS) build_msg TEST "$@ OK"
PHONY += format
format: format.python format.shell
# wrap ./manage script
@ -77,8 +79,8 @@ MANAGE += gecko.driver
MANAGE += node.env node.env.dev node.clean
MANAGE += py.build py.clean
MANAGE += pyenv pyenv.install pyenv.uninstall
MANAGE += format.python
MANAGE += test.yamllint test.pylint test.black test.pybabel test.unit test.coverage test.robot test.rst test.clean test.themes test.types.dev test.types.ci
MANAGE += format.python format.shell
MANAGE += test.yamllint test.pylint test.black test.pybabel test.unit test.coverage test.robot test.rst test.clean test.themes test.types.dev test.types.ci test.shfmt
MANAGE += themes.all themes.simple themes.fix themes.lint themes.test
MANAGE += static.build.commit static.build.drop static.build.restore
MANAGE += nvm.install nvm.clean nvm.status nvm.nodejs

View file

@ -188,24 +188,22 @@ sources of the theme need to be rebuild. You can do that by running::
$ LIVE_THEME=simple make run
.. _make format.python:
.. _make format:
``make format.python``
``make format``
======================
Format Python source code using `Black code style`_. See ``$BLACK_OPTIONS``
and ``$BLACK_TARGETS`` in :origin:`Makefile`.
.. attention::
We stuck at Black 22.12.0, please read comment in PR `Bump black from 22.12.0
to 23.1.0`_
.. _Bump black from 22.12.0 to 23.1.0:
https://github.com/searxng/searxng/pull/2159#pullrequestreview-1284094735
.. _Black code style:
https://black.readthedocs.io/en/stable/the_black_code_style/current_style.html
.. _shfmt: https://github.com/mvdan/sh?tab=readme-ov-file#shfmt
.. _EditorConfig: https://github.com/patrickvane/shfmt?tab=readme-ov-file#description
- Format Python source code using `Black code style`_. See ``$BLACK_OPTIONS``
and ``$BLACK_TARGETS`` in :origin:`Makefile`.
- Format Shell scripts using shfmt_. The formatter ``shfmt`` reads the rules
from the EditorConfig_ files.
.. _make clean:

View file

@ -27,7 +27,7 @@ Here is how a minimal workflow looks like:
1. *start* hacking
2. *run* your code: :ref:`make run`
3. *format & test* your code: :ref:`make format.python` and :ref:`make test`
3. *format & test* your code: :ref:`make format` and :ref:`make test`
If you think at some point something fails, go back to *start*. Otherwise,
choose a meaningful commit message and we are happy to receive your pull

15
manage
View file

@ -64,6 +64,12 @@ RST_FILES=(
'README.rst'
)
SHFMT_SCRIPTS=(
"./manage"
"./container"
"./utils"
)
help() {
nvm.help
cat <<EOF
@ -90,6 +96,7 @@ pyenv.:
OK : test if virtualenv is OK
format.:
python : format Python code source using black
shell : format Shell scripts using shfmt
EOF
go.help
node.help
@ -248,11 +255,17 @@ pyenv.uninstall() {
}
format.python() {
build_msg TEST "[format.python] black \$BLACK_TARGETS"
build_msg TEST "[format.python] black ${BLACK_TARGETS[*]}"
pyenv.cmd black "${BLACK_OPTIONS[@]}" "${BLACK_TARGETS[@]}"
dump_return $?
}
format.shell() {
build_msg TEST "[shfmt] shfmt ${SHFMT_SCRIPTS[*]}"
go.tool shfmt --list --write "${SHFMT_SCRIPTS[@]}"
dump_return $?
}
docs.prebuild() {
build_msg DOCS "build ${DOCS_BUILD}/includes"
(

View file

@ -6,8 +6,9 @@ test.help(){
test.:
yamllint : lint YAML files (YAMLLINT_FILES)
pylint : lint ./searx, ./searxng_extra and ./tests
pyright : static type check of python sources (.dev or .ci)
black : check black code format
shfmt : check shfmt code format
shfmt : check Shell script code format
unit : run unit tests
coverage : run unit tests with coverage
robot : run robot test
@ -105,6 +106,12 @@ test.black() {
dump_return $?
}
test.shfmt() {
build_msg TEST "[shfmt] ${SHFMT_SCRIPTS[*]}"
go.tool shfmt --list --diff "${SHFMT_SCRIPTS[@]}"
dump_return $?
}
test.unit() {
build_msg TEST 'tests/unit'
# shellcheck disable=SC2086