diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 32753dd..83e1fb6 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -4,8 +4,10 @@ name: 'Run tests' on: push: pull_request: - schedule: - - cron: '0 7 * * *' + # Disabled, because Github appears to disable the whole workflow if you have a schedule + # and no updates for 60 days... + # schedule: + #- cron: '0 7 * * *' jobs: tests: @@ -20,6 +22,8 @@ jobs: with: fetch-depth: 5 submodules: recursive + - run: ./test-templating.sh + working-directory: ./templating - run: ./tests/test_versioning.sh working-directory: . - run: ./prepare.sh @@ -34,6 +38,6 @@ jobs: - run: ./builder/build.sh -c -B MYCOOLARG=iLikeTests centos-7 # - Third one is very fast due to the Docker layer cache - run: ./builder/build.sh -c -B MYCOOLARG=iLikeTests centos-7 - # Do a reproducible centos-8 build (does not work for centos-7) - - run: ../tests/test-centos-8-reproducible.sh + # Do a reproducible rocky-8 build (does not work for centos-7) + - run: ../tests/test-rocky-8-reproducible.sh diff --git a/demo/builder-support/dockerfiles/Dockerfile.target.centos-8 b/demo/builder-support/dockerfiles/Dockerfile.target.rocky-8 similarity index 66% rename from demo/builder-support/dockerfiles/Dockerfile.target.centos-8 rename to demo/builder-support/dockerfiles/Dockerfile.target.rocky-8 index 2e1831f..0138a71 100644 --- a/demo/builder-support/dockerfiles/Dockerfile.target.centos-8 +++ b/demo/builder-support/dockerfiles/Dockerfile.target.rocky-8 @@ -3,13 +3,14 @@ # This defines the distribution base layer # Put only the bare minimum of common commands here, without dev tools -FROM centos:8 as dist-base +FROM rockylinux:8 as dist-base ARG BUILDER_CACHE_BUSTER= -RUN yum install -y epel-release +#RUN dnf install -y epel-release # Python 3.4+ is needed for the builder helpers -RUN yum install -y /usr/bin/python3 -RUN yum install -y dnf-plugins-core -RUN yum config-manager --set-enabled powertools +RUN dnf install -y /usr/bin/python3 +RUN dnf install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm +RUN dnf install -y dnf-plugins-core +RUN dnf config-manager --set-enabled powertools # Do the actual rpm build @INCLUDE Dockerfile.rpmbuild diff --git a/templating/templating.sh b/templating/templating.sh index 3dd73dc..380c3e1 100755 --- a/templating/templating.sh +++ b/templating/templating.sh @@ -12,14 +12,14 @@ if [ "$1" = "" ]; then echo '@EXEC uname -a' echo '@EXEC [ "$foo" = "bar" ] && include bar.txt' echo '@IF [ "$foo" = "bar" ]' - echo 'This line is only printed if $foo = "bar" (cannot be nested)' + echo 'This line is only printed if $foo = "bar"' echo '@ENDIF' echo 'Other lines are printed unchanged.' echo echo "Environment variables:" echo " tmpl_debug: If set, markers are printed around included files" echo " tmpl_comment: Characters to use to start the marker comments (default: #)" - echo " tmpl_prefix: Characters to start processing directives (default: @)" + echo " tmpl_prefix: Regexp to match processing directive prefixes (default: @)" exit 1 fi @@ -28,41 +28,63 @@ tmpl_prefix=${tmpl_prefix:-@} include() { [ "$tmpl_debug" != "" ] && echo "$tmpl_comment $1" - local skip + # Current level of @IF we are in + local iflevel=0 + # Set to the @IF level that disabled the current block, if any + local ifdisablelevel=0 local line local condition ( cat "$1" && echo ) | while IFS= read -r line; do - if [[ $line = ${tmpl_prefix}ENDIF* ]]; then - skip= + + if [[ $line =~ ^${tmpl_prefix}\ *IF\ (.*) ]]; then + [ "$tmpl_debug" != "" ] && echo "$tmpl_comment $line" + iflevel=$((iflevel+1)) + if ! [ $ifdisablelevel -gt 0 ]; then + # Only if not already in a disabled IF statement + condition="${BASH_REMATCH[1]}" + if ! eval "$condition" ; then + # Disabled at the current IF level + ifdisablelevel=$iflevel + fi + fi + + elif [[ $line =~ ^${tmpl_prefix}\ *ENDIF ]]; then [ "$tmpl_debug" != "" ] && echo "$tmpl_comment $line" + if [ $iflevel = 0 ] ; then + echo "ERROR: @ENDIF without matching @IF in file $1" > /dev/stderr + exit 30 + fi + iflevel=$((iflevel-1)) + if [ $ifdisablelevel -gt $iflevel ]; then + # We left the IF block level that was disabled + ifdisablelevel=0 + fi - elif [ ! -z "$skip" ]; then + elif [ $ifdisablelevel -gt 0 ]; then # nothing, in IF that evaluated to false [ "$tmpl_debug" != "" ] && echo "$tmpl_comment $line" - elif [[ $line = ${tmpl_prefix}INCLUDE\ * ]]; then - include=${line#* } + elif [[ $line =~ ^${tmpl_prefix}\ *INCLUDE\ +([^ ]*) ]]; then + include="${BASH_REMATCH[1]}" include $include - elif [[ $line = ${tmpl_prefix}EVAL\ * ]]; then - line=${line#* } + elif [[ $line =~ ^${tmpl_prefix}\ *EVAL\ (.*) ]]; then + line="${BASH_REMATCH[1]}" eval echo "\"$line\"" - elif [[ $line = ${tmpl_prefix}EXEC\ * ]]; then - line=${line#* } + elif [[ $line =~ ^${tmpl_prefix}\ *EXEC\ (.*) ]]; then + line="${BASH_REMATCH[1]}" eval "$line" - elif [[ $line = ${tmpl_prefix}IF\ * ]]; then - condition=${line#* } - [ "$tmpl_debug" != "" ] && echo "$tmpl_comment $line" - eval "$condition" || skip=1 - else echo "$line" fi + done [ "$tmpl_debug" != "" ] && echo "$tmpl_comment /$1" } include "$1" + +exit 0 diff --git a/templating/test-templating.sh b/templating/test-templating.sh new file mode 100755 index 0000000..75bd8ad --- /dev/null +++ b/templating/test-templating.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash + +set -e + +cd testdata + +if ! diff -u test-expected.txt <(../templating.sh test-template.txt) ; then + echo + echo "FAILED" + exit 1 +fi + +echo "PASSED" + diff --git a/templating/testdata/test-expected.txt b/templating/testdata/test-expected.txt new file mode 100644 index 0000000..e07ae80 --- /dev/null +++ b/templating/testdata/test-expected.txt @@ -0,0 +1,51 @@ +Lines can start with @INCLUDE, @EVAL or @EXEC for special processing, they +have no effect when not at the start of a line. + + +Direct @INCLUDE: +[Include file 1 start] +value of FOO in include is also 123 +[Include file 1 end] + + +The value of FOO is 123 + +Empty @EXEC: +@EXEC + +Conditional include in @EXEC: +[Second include start] +Hello world! +[Second include end] + + +This line is only printed if $FOO = "123", which is the case. +Nested IF that is true. +In between IFs. +Last line of first IF. + +Triple nested IF that is true. +Also true. +Second level. +First level. + + +true1 +true1 + +true1 +true2 +true2 +true1 + +# Test @IF with extra indenting after the @ + +true1 +true2 +true2 +Other directives also get indenting +true1 + + +Other lines are printed unchanged. + diff --git a/templating/testdata/test-template-include1.txt b/templating/testdata/test-template-include1.txt new file mode 100644 index 0000000..d508a36 --- /dev/null +++ b/templating/testdata/test-template-include1.txt @@ -0,0 +1,3 @@ +[Include file 1 start] +@EVAL value of FOO in include is also $FOO +[Include file 1 end] diff --git a/templating/testdata/test-template-include2.txt b/templating/testdata/test-template-include2.txt new file mode 100644 index 0000000..4b56018 --- /dev/null +++ b/templating/testdata/test-template-include2.txt @@ -0,0 +1,3 @@ +[Second include start] +@EXEC echo "Hello world!" +[Second include end] diff --git a/templating/testdata/test-template.txt b/templating/testdata/test-template.txt new file mode 100644 index 0000000..407cf6c --- /dev/null +++ b/templating/testdata/test-template.txt @@ -0,0 +1,90 @@ +Lines can start with @INCLUDE, @EVAL or @EXEC for special processing, they +have no effect when not at the start of a line. + +@EXEC FOO=123 + +Direct @INCLUDE: +@INCLUDE test-template-include1.txt + +@EVAL The value of FOO is $FOO + +Empty @EXEC: +@EXEC + +Conditional include in @EXEC: +@EXEC [ "$FOO" = "123" ] && include test-template-include2.txt + +@IF [ "$FOO" = "123" ] +This line is only printed if $FOO = "123", which is the case. +@IF true +Nested IF that is true. +@ENDIF +In between IFs. +@IF [ "$FOO" = "wrong" ] +THIS WILL NEVER BE PRINTED. +@ENDIF +Last line of first IF. +@ENDIF + +@IF true +@IF true +@IF true +Triple nested IF that is true. +@ENDIF +@IF true +Also true. +@ENDIF +Second level. +@ENDIF +First level. +@ENDIF + +@IF false +@IF true +@IF true +Triple nested IF that is FALSE. +@ENDIF +@ENDIF +@ENDIF + +@IF true +true1 +@IF false +false2 +@IF true +Triple nested IF that is FALSE. +@ENDIF +false2 MUST NOT APPEAR, BUG! +@ENDIF +true1 +@ENDIF + +@IF true +true1 +@IF true +true2 +@IF false +Triple nested IF that is FALSE. +@ENDIF +true2 +@ENDIF +true1 +@ENDIF + +# Test @IF with extra indenting after the @ + +@IF true +true1 +@ IF true +true2 +@ IF false +Triple nested IF that is FALSE. +@ ENDIF +true2 +@ EXEC echo "Other directives also get indenting" +@ ENDIF +true1 +@ENDIF + + +Other lines are printed unchanged. diff --git a/tests/test-centos-8-reproducible.sh b/tests/test-rocky-8-reproducible.sh similarity index 57% rename from tests/test-centos-8-reproducible.sh rename to tests/test-rocky-8-reproducible.sh index 7a8247f..c9700fe 100755 --- a/tests/test-centos-8-reproducible.sh +++ b/tests/test-rocky-8-reproducible.sh @@ -1,22 +1,22 @@ #!/bin/sh -# Test if centos-8 RPM builds are reproducible +# Test if rocky-8 RPM builds are reproducible # Must be run from demo dir set -ex # First build -./builder/build.sh -B MYCOOLARG=iLikeTests centos-8 +./builder/build.sh -B MYCOOLARG=iLikeTests rocky-8 # Record hashes sha256sum \ - builder/tmp/latest/centos-8/dist/noarch/*.rpm \ + builder/tmp/latest/rocky-8/dist/noarch/*.rpm \ builder/tmp/latest/sdist/*.tar.gz \ > /tmp/sha256sum.txt # Second build after cleaning and adding a file to invalidate the build context -rm -rf ./builder/tmp/latest/centos-8 +rm -rf ./builder/tmp/latest/rocky-8 rm -rf ./builder/tmp/latest/sdist -./builder/build.sh -B MYCOOLARG=iLikeTests -b build-again centos-8 +./builder/build.sh -B MYCOOLARG=iLikeTests -b build-again rocky-8 # Check hashes, should be identical sha256sum -c /tmp/sha256sum.txt