ci: Add more checks to ci_verify_version.sh; refactor
In addition to png.h, configure.ac and CMakeLists.txt, the script
ci_verify_version.sh is now able to verify libpng-config-head.in also.
For the benefit of readability, the old script ci_shellify.sh has been
split into smaller, independent scriptlets: libexec/ci_shellify_*.sh.
The linting script ci_lint.sh has been updated as needed.
diff --git a/ci/ci_lint.sh b/ci/ci_lint.sh
index 163d955..674e55f 100755
--- a/ci/ci_lint.sh
+++ b/ci/ci_lint.sh
@@ -1,7 +1,7 @@
#!/usr/bin/env bash
set -o errexit -o pipefail -o posix
-# Copyright (c) 2019-2024 Cosmin Truta.
+# Copyright (c) 2019-2025 Cosmin Truta.
#
# Use, modification and distribution are subject to the MIT License.
# Please see the accompanying file LICENSE_MIT.txt
@@ -61,7 +61,7 @@
}
ci_info "## LINTING: CI scripts ##"
ci_spawn "$CI_SHELLCHECK" --version
- find ./ci -maxdepth 1 -name "*.sh" | {
+ find ./ci -name "ci_*.sh" -not -name "ci_env.*.sh" | {
local my_file
while IFS="" read -r my_file
do
diff --git a/ci/ci_shellify.sh b/ci/ci_shellify.sh
deleted file mode 100755
index e6693af..0000000
--- a/ci/ci_shellify.sh
+++ /dev/null
@@ -1,92 +0,0 @@
-#!/usr/bin/env bash
-set -o errexit -o pipefail -o posix
-
-# Copyright (c) 2019-2024 Cosmin Truta.
-#
-# Use, modification and distribution are subject to the MIT License.
-# Please see the accompanying file LICENSE_MIT.txt
-#
-# SPDX-License-Identifier: MIT
-
-# shellcheck source=ci/lib/ci.lib.sh
-source "$(dirname "$0")/lib/ci.lib.sh"
-cd "$CI_TOPLEVEL_DIR"
-
-function ci_shellify_c {
- # Convert C preprocessor text, specifically originating
- # from png.h, to shell scripting text.
- # Select only the easy-to-parse definitions of PNG_LIBPNG_*.
- sed -n -e '/^\# *define * PNG_LIBPNG_[^ ]* * ["0-9A-Za-z_]/ p' |
- sed -e 's/^\# *define * PNG\([^ ]*\) * \([^ ]*\)/PNG\1=\2/' \
- -e 's/=PNG\([0-9A-Za-z_]*\)/=\${PNG\1}/' \
- -e 's/^\([^ ]*=[^ ]*\).*$/export \1;/'
-}
-
-function ci_shellify_autoconf {
- # Convert autoconf (M4) text, specifically originating
- # from configure.ac, to shell scripting text.
- # Select only the easy-to-parse definitions of PNGLIB_*.
- sed -n -e '/^ *PNGLIB_[^ ]*=[$"0-9A-Za-z_]/ p' |
- sed -e 's/^ *PNG\([0-9A-Za-z_]*\)=\([^# ]*\).*$/PNG\1=\2/' \
- -e 's/^\([^ ]*=[^ ]*\).*$/export \1;/'
-}
-
-function ci_shellify_cmake {
- # Convert CMake lists text, specifically originating
- # from CMakeLists.txt, to shell scripting text.
- # Select only the easy-to-parse definitions of PNGLIB_*.
- sed -n -e '/^ *set *(PNGLIB_[^ ]* * [$"0-9A-Za-z_].*)/ p' |
- sed -e 's/^ *set *(PNG\([^ ]*\) * \([^() ]*\)).*$/PNG\1=\2/' \
- -e 's/^\([^ ]*=[^ ]*\).*$/export \1;/'
-}
-
-function ci_shellify {
- local arg filename
- for arg in "$@"
- do
- test -f "$arg" || ci_err "no such file: '$arg'"
- filename="$(basename -- "$arg")"
- case "$filename" in
- ( *.[ch] )
- [[ $filename == png.h ]] || {
- ci_err "unable to shellify: '$filename' (expecting: 'png.h')"
- }
- ci_shellify_c <"$arg" ;;
- ( config* | *.ac )
- [[ $filename == configure.ac ]] || {
- ci_err "unable to shellify: '$filename' (expecting: 'configure.ac')"
- }
- ci_shellify_autoconf <"$arg" ;;
- ( *CMake* | *cmake* | *.txt )
- [[ $filename == [Cc][Mm]ake[Ll]ists.txt ]] || {
- ci_err "unable to shellify: '$filename' (expecting: 'CMakeLists.txt')"
- }
- ci_shellify_cmake <"$arg" ;;
- ( * )
- ci_err "unable to shellify: '$arg'" ;;
- esac
- done
-}
-
-function usage {
- echo "usage: $CI_SCRIPT_NAME [<options>] <files>..."
- echo "options: -?|-h|--help"
- echo "files: png.h|configure.ac|CMakeLists.txt"
- exit "${@:-0}"
-}
-
-function main {
- local opt
- while getopts ":" opt
- do
- # This ain't a while-loop. It only pretends to be.
- [[ $1 == -[?h]* || $1 == --help || $1 == --help=* ]] && usage 0
- ci_err "unknown option: '$1'"
- done
- shift $((OPTIND - 1))
- [[ $# -eq 0 ]] && usage 2
- # And... go!
- ci_shellify "$@"
-}
-
-main "$@"
diff --git a/ci/ci_verify_version.sh b/ci/ci_verify_version.sh
index 3203b20..5908724 100755
--- a/ci/ci_verify_version.sh
+++ b/ci/ci_verify_version.sh
@@ -1,7 +1,7 @@
#!/usr/bin/env bash
set -o errexit -o pipefail -o posix
-# Copyright (c) 2019-2024 Cosmin Truta.
+# Copyright (c) 2019-2025 Cosmin Truta.
#
# Use, modification and distribution are subject to the MIT License.
# Please see the accompanying file LICENSE_MIT.txt
@@ -12,33 +12,43 @@
source "$(dirname "$0")/lib/ci.lib.sh"
cd "$CI_TOPLEVEL_DIR"
-function ci_init_shellify {
- [[ -f $CI_SCRIPT_DIR/ci_shellify.sh ]] || {
- ci_err_internal "missing script: '$CI_SCRIPT_DIR/ci_shellify.sh'"
- }
-}
+# Declare the global environments collected from various sources.
+declare CI_ENV_LIBPNG_VER # collected from png.h
+declare CI_ENV_AUTOCONF_VER # collected from configure.ac
+declare CI_ENV_CMAKE_VER # collected from CMakeLists.txt
+declare CI_ENV_LIBPNGCONFIG_VER # collected from scripts/libpng-config-head.in
function ci_run_shellify {
+ local my_script my_result
+ my_script="$CI_SCRIPT_DIR/libexec/ci_shellify_${1#--}.sh"
+ shift 1
+ [[ -f $my_script ]] || {
+ ci_err_internal "missing script: '$my_script'"
+ }
ci_info "shellifying:" "$@"
- local my_result
- "$BASH" "$CI_SCRIPT_DIR/ci_shellify.sh" "$@"
+ "$BASH" "$my_script" "$@"
echo "$my_result" | "$BASH" --posix || ci_err "bad shellify output"
echo "$my_result"
}
-function ci_verify_version {
+function ci_init_version_verification {
ci_info "## START OF VERIFICATION ##"
- local my_env_libpng_ver my_env_autoconf_ver my_env_cmake_ver my_expect
- ci_init_shellify
- my_env_libpng_ver="$(ci_run_shellify png.h)"
- echo "$my_env_libpng_ver"
- my_env_autoconf_ver="$(ci_run_shellify configure.ac)"
- echo "$my_env_autoconf_ver"
- my_env_cmake_ver="$(ci_run_shellify CMakeLists.txt)"
- echo "$my_env_cmake_ver"
- ci_info "## VERIFYING: png.h version definitions ##"
- eval "$my_env_libpng_ver"
- local my_expect="${PNG_LIBPNG_VER_MAJOR}.${PNG_LIBPNG_VER_MINOR}.${PNG_LIBPNG_VER_RELEASE}"
+ CI_ENV_LIBPNG_VER="$(ci_run_shellify --c png.h)"
+ echo "$CI_ENV_LIBPNG_VER"
+ CI_ENV_AUTOCONF_VER="$(ci_run_shellify --autoconf configure.ac)"
+ echo "$CI_ENV_AUTOCONF_VER"
+ CI_ENV_CMAKE_VER="$(ci_run_shellify --cmake CMakeLists.txt)"
+ echo "$CI_ENV_CMAKE_VER"
+ CI_ENV_LIBPNGCONFIG_VER="$(ci_run_shellify --shell scripts/libpng-config-head.in)"
+ echo "$CI_ENV_LIBPNGCONFIG_VER"
+}
+
+# shellcheck disable=SC2154
+function ci_do_version_verification {
+ local my_expect
+ ci_info "## VERIFYING: version definitions in 'png.h' ##"
+ eval "$CI_ENV_LIBPNG_VER"
+ my_expect="${PNG_LIBPNG_VER_MAJOR}.${PNG_LIBPNG_VER_MINOR}.${PNG_LIBPNG_VER_RELEASE}"
if [[ "$PNG_LIBPNG_VER_STRING" == "$my_expect"* ]]
then
ci_info "matched: \$PNG_LIBPNG_VER_STRING == $my_expect*"
@@ -77,7 +87,7 @@
else
ci_err "mismatched: \$PNG_LIBPNG_VER_BUILD != [01]"
fi
- ci_info "## VERIFYING: png.h build definitions ##"
+ ci_info "## VERIFYING: build definitions in 'png.h' ##"
my_expect="${PNG_LIBPNG_VER_MAJOR}.${PNG_LIBPNG_VER_MINOR}.${PNG_LIBPNG_VER_RELEASE}"
if [[ "$PNG_LIBPNG_VER_STRING" == "$my_expect" ]]
then
@@ -110,19 +120,19 @@
else
ci_err "unexpected: \$PNG_LIBPNG_VER_STRING == '$PNG_LIBPNG_VER_STRING'"
fi
- ci_info "## VERIFYING: png.h type definitions ##"
+ ci_info "## VERIFYING: type definitions in 'png.h' ##"
my_expect="$(echo "png_libpng_version_${PNG_LIBPNG_VER_STRING}" | tr . _)"
ci_spawn grep -w -e "$my_expect" png.h
- ci_info "## VERIFYING: configure.ac version definitions ##"
- eval "$my_env_autoconf_ver"
+ ci_info "## VERIFYING: version definitions in 'configure.ac' ##"
+ eval "$CI_ENV_AUTOCONF_VER"
if [[ "$PNGLIB_VERSION" == "$PNG_LIBPNG_VER_STRING" ]]
then
ci_info "matched: \$PNGLIB_VERSION == \$PNG_LIBPNG_VER_STRING"
else
ci_err "mismatched: \$PNGLIB_VERSION != \$PNG_LIBPNG_VER_STRING"
fi
- ci_info "## VERIFYING: CMakeLists.txt version definitions ##"
- eval "$my_env_cmake_ver"
+ ci_info "## VERIFYING: version definitions in 'CMakeLists.txt' ##"
+ eval "$CI_ENV_CMAKE_VER"
if [[ "$PNGLIB_VERSION" == "$PNG_LIBPNG_VER_STRING" && "$PNGLIB_SUBREVISION" == 0 ]]
then
ci_info "matched: \$PNGLIB_VERSION == \$PNG_LIBPNG_VER_STRING"
@@ -133,8 +143,26 @@
else
ci_err "mismatched: \$PNGLIB_VERSION != \$PNG_LIBPNG_VER_STRING"
fi
+ ci_info "## VERIFYING: version definitions in 'scripts/libpng-config-head.in' ##"
+ eval "$CI_ENV_LIBPNGCONFIG_VER"
+ if [[ "$version" == "$PNG_LIBPNG_VER_STRING" ]]
+ then
+ ci_info "matched: \$version == \$PNG_LIBPNG_VER_STRING"
+ else
+ ci_err "mismatched: \$version != \$PNG_LIBPNG_VER_STRING"
+ fi
+}
+
+function ci_finish_version_verification {
ci_info "## END OF VERIFICATION ##"
- ci_info "success!"
+ # Relying on "set -o errexit" to not reach here in case of error.
+ ci_info "## SUCCESS ##"
+}
+
+function ci_verify_version {
+ ci_init_version_verification
+ ci_do_version_verification
+ ci_finish_version_verification
}
function usage {
diff --git a/ci/libexec/ci_shellify_autoconf.sh b/ci/libexec/ci_shellify_autoconf.sh
new file mode 100755
index 0000000..bf37f0d
--- /dev/null
+++ b/ci/libexec/ci_shellify_autoconf.sh
@@ -0,0 +1,48 @@
+#!/usr/bin/env bash
+set -o errexit -o pipefail -o posix
+
+# Copyright (c) 2019-2025 Cosmin Truta.
+#
+# Use, modification and distribution are subject to the MIT License.
+# Please see the accompanying file LICENSE_MIT.txt
+#
+# SPDX-License-Identifier: MIT
+
+# shellcheck source=ci/lib/ci.lib.sh
+source "$(dirname "$0")/../lib/ci.lib.sh"
+
+function ci_shellify_autoconf {
+ # Convert autoconf (M4) text, specifically originating
+ # from configure.ac, to shell scripting text.
+ # Select only the easy-to-parse definitions of PNGLIB_*.
+ sed -n -e '/^ *PNGLIB_[^ ]*=[$"0-9A-Za-z_]/ p' |
+ sed -e 's/^ *PNG\([0-9A-Za-z_]*\)=\([^# ]*\).*$/PNG\1=\2/' \
+ -e 's/^\([^ ]*=[^ ]*\).*$/export \1;/'
+}
+
+function usage {
+ echo "usage: $CI_SCRIPT_NAME [<options>] configure.ac"
+ echo "options: -?|-h|--help"
+ exit "${@:-0}"
+}
+
+function main {
+ local opt
+ while getopts ":" opt
+ do
+ # This ain't a while-loop. It only pretends to be.
+ [[ $1 == -[?h]* || $1 == --help || $1 == --help=* ]] && usage 0
+ ci_err "unknown option: '$1'"
+ done
+ shift $((OPTIND - 1))
+ [[ $# -eq 0 ]] && usage 2
+ [[ $# -eq 1 ]] || ci_err "too many operands"
+ # And... go!
+ test -e "$1" || ci_err "no such file: '$1'"
+ [[ $(basename -- "$1") == configure.ac ]] || {
+ ci_err "incorrect operand: '$1' (expecting: 'configure.ac')"
+ }
+ ci_shellify_autoconf <"$1"
+}
+
+main "$@"
diff --git a/ci/libexec/ci_shellify_c.sh b/ci/libexec/ci_shellify_c.sh
new file mode 100755
index 0000000..244fc22
--- /dev/null
+++ b/ci/libexec/ci_shellify_c.sh
@@ -0,0 +1,49 @@
+#!/usr/bin/env bash
+set -o errexit -o pipefail -o posix
+
+# Copyright (c) 2019-2025 Cosmin Truta.
+#
+# Use, modification and distribution are subject to the MIT License.
+# Please see the accompanying file LICENSE_MIT.txt
+#
+# SPDX-License-Identifier: MIT
+
+# shellcheck source=ci/lib/ci.lib.sh
+source "$(dirname "$0")/../lib/ci.lib.sh"
+
+function ci_shellify_c {
+ # Convert C preprocessor text, specifically originating
+ # from png.h, to shell scripting text.
+ # Select only the easy-to-parse definitions of PNG_LIBPNG_*.
+ sed -n -e '/^\# *define * PNG_LIBPNG_[^ ]* * ["0-9A-Za-z_]/ p' |
+ sed -e 's/^\# *define * PNG\([^ ]*\) * \([^ ]*\)/PNG\1=\2/' \
+ -e 's/=PNG\([0-9A-Za-z_]*\)/=\${PNG\1}/' \
+ -e 's/^\([^ ]*=[^ ]*\).*$/export \1;/'
+}
+
+function usage {
+ echo "usage: $CI_SCRIPT_NAME [<options>] png.h"
+ echo "options: -?|-h|--help"
+ exit "${@:-0}"
+}
+
+function main {
+ local opt
+ while getopts ":" opt
+ do
+ # This ain't a while-loop. It only pretends to be.
+ [[ $1 == -[?h]* || $1 == --help || $1 == --help=* ]] && usage 0
+ ci_err "unknown option: '$1'"
+ done
+ shift $((OPTIND - 1))
+ [[ $# -eq 0 ]] && usage 2
+ [[ $# -eq 1 ]] || ci_err "too many operands"
+ # And... go!
+ test -e "$1" || ci_err "no such file: '$1'"
+ [[ $(basename -- "$1") == png.h ]] || {
+ ci_err "incorrect operand: '$1' (expecting: 'png.h')"
+ }
+ ci_shellify_c <"$1"
+}
+
+main "$@"
diff --git a/ci/libexec/ci_shellify_cmake.sh b/ci/libexec/ci_shellify_cmake.sh
new file mode 100755
index 0000000..5596241
--- /dev/null
+++ b/ci/libexec/ci_shellify_cmake.sh
@@ -0,0 +1,49 @@
+#!/usr/bin/env bash
+set -o errexit -o pipefail -o posix
+
+# Copyright (c) 2019-2025 Cosmin Truta.
+#
+# Use, modification and distribution are subject to the MIT License.
+# Please see the accompanying file LICENSE_MIT.txt
+#
+# SPDX-License-Identifier: MIT
+
+# shellcheck source=ci/lib/ci.lib.sh
+source "$(dirname "$0")/../lib/ci.lib.sh"
+
+function ci_shellify_cmake {
+ # Convert CMake lists text, specifically originating
+ # from CMakeLists.txt, to shell scripting text.
+ # Select only the easy-to-parse definitions of PNGLIB_*.
+ sed -n -e '/^ *set *(PNGLIB_[^ ]* * [$"0-9A-Za-z_].*)/ p' |
+ sed -e 's/^ *set *(PNG\([^ ]*\) * \([^() ]*\)).*$/PNG\1=\2/' \
+ -e 's/^\([^ ]*=[^ ]*\).*$/export \1;/'
+}
+
+function usage {
+ echo "usage: $CI_SCRIPT_NAME [<options>] CMakeLists.txt"
+ echo "options: -?|-h|--help"
+ exit "${@:-0}"
+}
+
+function main {
+ local opt
+ while getopts ":" opt
+ do
+ # This ain't a while-loop. It only pretends to be.
+ [[ $1 == -[?h]* || $1 == --help || $1 == --help=* ]] && usage 0
+ ci_err "unknown option: '$1'"
+ done
+ shift $((OPTIND - 1))
+ [[ $# -eq 0 ]] && usage 2
+ [[ $# -eq 1 ]] || ci_err "too many operands"
+ # And... go!
+ test -e "$1" || ci_err "no such file: '$1'"
+ filename="$(basename -- "$1")"
+ [[ $filename == [Cc][Mm]ake[Ll]ists.txt ]] || {
+ ci_err "incorrect operand: '$1' (expecting: 'CMakeLists.txt')"
+ }
+ ci_shellify_cmake <"$1"
+}
+
+main "$@"
diff --git a/ci/libexec/ci_shellify_shell.sh b/ci/libexec/ci_shellify_shell.sh
new file mode 100755
index 0000000..4170063
--- /dev/null
+++ b/ci/libexec/ci_shellify_shell.sh
@@ -0,0 +1,46 @@
+#!/usr/bin/env bash
+set -o errexit -o pipefail -o posix
+
+# Copyright (c) 2019-2025 Cosmin Truta.
+#
+# Use, modification and distribution are subject to the MIT License.
+# Please see the accompanying file LICENSE_MIT.txt
+#
+# SPDX-License-Identifier: MIT
+
+# shellcheck source=ci/lib/ci.lib.sh
+source "$(dirname "$0")/../lib/ci.lib.sh"
+
+function ci_shellify_shell {
+ # Convert shell scripting text to shell scripting text.
+ # Select only the easy-to-parse version definitions.
+ sed -n -e '/^ *[A-Za-z_][0-9A-Za-z_]*=[0-9][^ #]* *$/ p' |
+ sed -e 's/^ *\([^ ]*=[^ ]*\) *$/export \1;/'
+}
+
+function usage {
+ echo "usage: $CI_SCRIPT_NAME [<options>] libpng-config-head.in"
+ echo "options: -?|-h|--help"
+ exit "${@:-0}"
+}
+
+function main {
+ local opt
+ while getopts ":" opt
+ do
+ # This ain't a while-loop. It only pretends to be.
+ [[ $1 == -[?h]* || $1 == --help || $1 == --help=* ]] && usage 0
+ ci_err "unknown option: '$1'"
+ done
+ shift $((OPTIND - 1))
+ [[ $# -eq 0 ]] && usage 2
+ [[ $# -eq 1 ]] || ci_err "too many operands"
+ # And... go!
+ test -e "$1" || ci_err "no such file: '$1'"
+ [[ $(basename -- "$1") == libpng-config-head.in ]] || {
+ ci_err "incorrect operand: '$1' (expecting: 'libpng-config-head.in')"
+ }
+ ci_shellify_shell <"$1"
+}
+
+main "$@"