From c7db455a45609f7c2a591d7b78b88b66148eb6f5 Mon Sep 17 00:00:00 2001 From: Thomas Ballasi Date: Fri, 9 Jun 2023 13:38:57 -0400 Subject: [PATCH 1/3] cqfd: default to cqfd run In order to have cqfd to run similarly to known tools, such as sudo, the cqfd run command has been removed as the default command is now "run". Tests have been updated automatically using the following commands: $ sed -i 's/cqfd run/cqfd/g' tests/0* $ sed -i -s 's/cqfd(.*) init/cqfd\1 --init/g' tests/0* $ sed -i -s 's/cqfd(.*) release/cqfd\1 --release/g' tests/0* $ sed -i -s 's/cqfd(.*) flavors/cqfd\1 --flavors/g' tests/0* $ sed -i -s 's/cqfd(.*) version/cqfd\1 --version/g' tests/0* and by manually running the test suite for missing $ cqfd.+ run commands. --- README.md | 10 ++-- cqfd | 68 ++++++++++++---------------- tests/00-setup | 16 +++---- tests/01-cqfd_init | 26 +++++------ tests/03-cqfd_error | 4 +- tests/03-cqfd_help | 10 ++-- tests/03-cqfd_version | 14 +++--- tests/04-cqfd_init_context | 16 +++---- tests/05-cqfd_init_alt_ext | 12 ++--- tests/05-cqfd_init_extra_env | 12 ++--- tests/05-cqfd_init_flavor | 22 ++++----- tests/05-cqfd_run | 12 ++--- tests/05-cqfd_run_c | 8 ++-- tests/05-cqfd_run_c_flavor | 4 +- tests/05-cqfd_run_check_dependencies | 22 ++++----- tests/05-cqfd_run_command | 8 ++-- tests/05-cqfd_run_config | 18 ++++---- tests/05-cqfd_run_extra_env | 4 +- tests/05-cqfd_run_extra_groups | 12 ++--- tests/05-cqfd_run_extra_hosts | 6 +-- tests/05-cqfd_run_flavor | 8 ++-- tests/05-cqfd_run_from_subdirectory | 2 +- tests/05-cqfd_run_home_env_var | 20 ++++---- tests/05-cqfd_run_spaces_in_path | 4 +- tests/05-cqfd_run_tty | 4 +- tests/06-cqfd_release | 32 ++++++------- 26 files changed, 181 insertions(+), 193 deletions(-) diff --git a/README.md b/README.md index 106f042..91d04b2 100644 --- a/README.md +++ b/README.md @@ -21,14 +21,14 @@ Just follow these steps: * Go into your project's directory * Create a .cqfdrc file * Put a Dockerfile and save it as .cqfd/docker/Dockerfile -* Run ``cqfd init`` +* Run ``cqfd --init`` Examples are available in the samples/ directory. cqfd will use the provided Dockerfile to create a normalized runtime build environment for your project. -Warning: Running cqfd init creates and names a new Docker image each +Warning: Running cqfd --init creates and names a new Docker image each time the Dockerfile is modified, which may lead to a large number of unused images that cannot be automatically purged. Currently, cqfd does not have a systematic clean-up system in place. @@ -45,8 +45,8 @@ default build command as configured in .cqfdrc, use: Alternatively, you may want to specify a custom build command to be executed from inside the build container. - $ cqfd run make clean - $ cqfd run "make linux-dirclean && make foobar-dirclean" + $ cqfd make clean + $ cqfd "make linux-dirclean && make foobar-dirclean" When ``cqfd`` is running, the current directory is mounted by Docker as a volume. As a result, all the build artefacts generated inside the @@ -59,7 +59,7 @@ The release command behaves exactly like run, but creates a release tarball for your project additionally. The release files (as specified in your ``.cqfdrc``) will be included inside the release archive. - $ cqfd release + $ cqfd --release The resulting release file is then called according to the archive template, which defaults to ``%Po-%Pn.tar.xz``. diff --git a/cqfd b/cqfd index 070c286..5e32406 100755 --- a/cqfd +++ b/cqfd @@ -42,11 +42,9 @@ Options: -h or --help Show this help text. Commands: - init Initialize project build container - flavors List flavors from config file to stdout - run Run argument(s) inside build container - release Run argument(s) and release software - help Show this help text + --init Initialize project build container + --flavors List flavors from config file to stdout + --release Run argument(s) and release software By default, run is assumed, and the run command is the one configured in .cqfdrc. @@ -138,7 +136,7 @@ docker_build() { docker_run() { if ! docker image inspect $docker_img_name &> /dev/null; then - die "The docker image doesn't exist, launch 'cqfd init' to create it" + die "The docker image doesn't exist, launch 'cqfd --init' to create it" fi local interactive_options @@ -456,20 +454,20 @@ has_custom_cqfdrc=false has_to_release=false while [ $# -gt 0 ]; do case "$1" in - help|-h|"--help") + -h|"--help") usage exit 0 ;; - version|-v|"--version") + -v|"--version") echo $VERSION exit 0 ;; - init) + "--init") config_load $flavor docker_build exit $? ;; - flavors) + "--flavors") config_load echo $build_flavors exit 0 @@ -494,43 +492,33 @@ while [ $# -gt 0 ]; do -q) quiet=true ;; - run|release) - if [ "$1" = "release" ]; then - has_to_release=true - fi - - shift - - # No more args? run default command - [ "$#" -eq 0 ] && break - - # -c appends following args to the default command - if [ "$1" = "-c" ]; then - if [ $# -lt 2 ]; then - die "option -c requires arguments" - fi - - shift - build_cmd_append="$*" - break - fi - - # Run alternate command - build_cmd_alt="$@" - break - ;; - ?*) - echo "Unknown command: $1" - usage - exit 1 + "--release") + has_to_release=true ;; *) - # empty or no argument case + # run a command + break ;; esac shift done +# No more args? run default command +if [ "$#" -ne 0 ]; then + # -c appends following args to the default command + if [ "$1" = "-c" ]; then + if [ $# -lt 2 ]; then + die "option -c requires arguments" + fi + + shift + build_cmd_append="$*" + else + # Run alternate command + build_cmd_alt="$@" + fi +fi + config_load $flavor if [ -n "$build_cmd_alt" ]; then diff --git a/tests/00-setup b/tests/00-setup index 812fe8d..daece69 100755 --- a/tests/00-setup +++ b/tests/00-setup @@ -12,31 +12,31 @@ cp -a test_data/. $TDIR/. cd $TDIR/ ################################################################################ -# running 'cqfd init' should fail, as there's no proper config +# running 'cqfd --init' should fail, as there's no proper config ################################################################################ -if $TDIR/.cqfd/cqfd init; then +if $TDIR/.cqfd/cqfd --init; then jtest_result fail else jtest_result pass fi ################################################################################ -# running 'cqfd init' should fail, as there's an empty config +# running 'cqfd --init' should fail, as there's an empty config ################################################################################ -jtest_prepare "cqfd init complains with an empty .cqfdrc" +jtest_prepare "cqfd --init complains with an empty .cqfdrc" touch $TDIR/.cqfdrc -if $TDIR/.cqfd/cqfd init; then +if $TDIR/.cqfd/cqfd --init; then jtest_result fail else jtest_result pass fi ################################################################################ -# running 'cqfd init' should fail, as there's an incomplete config +# running 'cqfd --init' should fail, as there's an incomplete config ################################################################################ -jtest_prepare "cqfd init complains with an incomplete .cqfdrc" +jtest_prepare "cqfd --init complains with an incomplete .cqfdrc" echo '[project]' >$TDIR/.cqfdrc -if $TDIR/.cqfd/cqfd init; then +if $TDIR/.cqfd/cqfd --init; then jtest_result fail else jtest_result pass diff --git a/tests/01-cqfd_init b/tests/01-cqfd_init index a9dc3ba..486c8c4 100755 --- a/tests/01-cqfd_init +++ b/tests/01-cqfd_init @@ -5,10 +5,10 @@ cd $TDIR/ ################################################################################ -# 'cqfd init' with a proper .cqfdrc should pass +# 'cqfd --init' with a proper .cqfdrc should pass ################################################################################ -jtest_prepare "run cqfd init" -if $TDIR/.cqfd/cqfd init; then +jtest_prepare "run cqfd --init" +if $TDIR/.cqfd/cqfd --init; then jtest_result pass else jtest_result fail @@ -16,13 +16,13 @@ fi ################################################################################ -# 'cqfd init' with a nonexistent Dockerfile should fail +# 'cqfd --init' with a nonexistent Dockerfile should fail ################################################################################ cqfdrc_old=$(mktemp) jtest_prepare "init with a nonexisting dockerfile shall fail" cp -f .cqfdrc $cqfdrc_old sed -i -e "s/\[build\]/[build]\ndistro='thisshouldfail'/" .cqfdrc -if $TDIR/.cqfd/cqfd init; then +if $TDIR/.cqfd/cqfd --init; then jtest_result fail else jtest_result pass @@ -30,11 +30,11 @@ fi ################################################################################ -# 'cqfd init' with a proper Dockerfile should pass +# 'cqfd --init' with a proper Dockerfile should pass ################################################################################ -jtest_prepare "run cqfd init with an other Dockerfile" +jtest_prepare "run cqfd --init with an other Dockerfile" sed -i -e "s/thisshouldfail/centos/" .cqfdrc -if $TDIR/.cqfd/cqfd init; then +if $TDIR/.cqfd/cqfd --init; then jtest_result pass else jtest_result fail @@ -44,14 +44,14 @@ mv -f $cqfdrc_old .cqfdrc ################################################################################ -# 'cqfd init' with same uid/gid dummy user should pass +# 'cqfd --init' with same uid/gid dummy user should pass ################################################################################ jtest_prepare "add dummy user and dummy group with same uid/gid" cat <>.cqfd/docker/Dockerfile RUN groupadd -og $GROUPS -f dummy && \ useradd -s /bin/bash -ou $UID -g $GROUPS dummy EOF -if $TDIR/.cqfd/cqfd init; then +if $TDIR/.cqfd/cqfd --init; then jtest_result pass else jtest_result fail @@ -59,10 +59,10 @@ fi ################################################################################ -# 'cqfd init' in quiet mode should be quiet +# 'cqfd --init' in quiet mode should be quiet ################################################################################ -jtest_prepare "cqfd -q init should remain quiet" -if ! $TDIR/.cqfd/cqfd -q init | grep -E "^sha256:"; then +jtest_prepare "cqfd -q --init should remain quiet" +if ! $TDIR/.cqfd/cqfd -q --init | grep -E "^sha256:"; then jtest_result fail else jtest_result pass diff --git a/tests/03-cqfd_error b/tests/03-cqfd_error index f672632..a757101 100755 --- a/tests/03-cqfd_error +++ b/tests/03-cqfd_error @@ -17,12 +17,12 @@ fi ################################################################################ # Running cqfd without a .cqfdrc file in the current directory shall fail ################################################################################ -jtest_prepare "'cqfd run' with no config file shall fail" +jtest_prepare "'cqfd' with no config file shall fail" empty_dir=$(mktemp -d) pushd "$empty_dir" >/dev/null || exit 1 -if "$cqfd" run true; then +if "$cqfd" true; then jtest_result fail else jtest_result pass diff --git a/tests/03-cqfd_help b/tests/03-cqfd_help index f322e24..ed5c7d9 100755 --- a/tests/03-cqfd_help +++ b/tests/03-cqfd_help @@ -3,12 +3,12 @@ . "$(dirname $0)"/jtest.inc "$1" ################################################################################ -# 'cqfd help' shall be an accepted command +# 'cqfd --help' shall be an accepted command ################################################################################ -jtest_prepare "cqfd help shall exit normally" +jtest_prepare "cqfd --help shall exit normally" TEST=$(mktemp) -if ! $TDIR/.cqfd/cqfd help >$TEST; then +if ! $TDIR/.cqfd/cqfd --help >$TEST; then jtest_result fail rm -f $TEST else @@ -17,9 +17,9 @@ fi ################################################################################ -# 'cqfd help' shall produce a useful help message +# 'cqfd --help' shall produce a useful help message ################################################################################ -jtest_prepare "cqfd help shall produce an help message" +jtest_prepare "cqfd --help shall produce an help message" # Those words shall be present in the output for word in Usage Options Commands; do if ! grep -q "^$word:" $TEST; then diff --git a/tests/03-cqfd_version b/tests/03-cqfd_version index 7a3f70d..c652ff8 100755 --- a/tests/03-cqfd_version +++ b/tests/03-cqfd_version @@ -3,12 +3,12 @@ . "$(dirname $0)"/jtest.inc "$1" ################################################################################ -# 'cqfd version' shall be an accepted command +# 'cqfd --version' shall be an accepted command ################################################################################ -jtest_prepare "cqfd version shall exit normally" +jtest_prepare "cqfd --version shall exit normally" TEST=$(mktemp) -if ! $TDIR/.cqfd/cqfd version >$TEST; then +if ! $TDIR/.cqfd/cqfd --version >$TEST; then jtest_result fail rm -f $TEST else @@ -16,9 +16,9 @@ else fi ################################################################################ -# 'cqfd version' shall produce a version message +# 'cqfd --version' shall produce a version message ################################################################################ -jtest_prepare "cqfd version shall produce a version string" +jtest_prepare "cqfd --version shall produce a version string" if grep -qE "^[0-9.]+(-[a-z]+)?\$" $TEST; then jtest_result pass @@ -29,9 +29,9 @@ cat $TEST >&2 fi ################################################################################ -# 'cqfd version' shall match the latest documented version +# 'cqfd --version' shall match the latest documented version ################################################################################ -jtest_prepare "cqfd version major number shall match the latest documented version" +jtest_prepare "cqfd --version major number shall match the latest documented version" doc=$(grep '^## Version' $TDIR/CHANGELOG.md | head -1 | grep -Eo '[0-9.]+(-[a-z]+)?' | head -1) version="$(cat $TEST)" diff --git a/tests/04-cqfd_init_context b/tests/04-cqfd_init_context index 33a5bce..2995179 100755 --- a/tests/04-cqfd_init_context +++ b/tests/04-cqfd_init_context @@ -8,11 +8,11 @@ cqfd="$TDIR/.cqfd/cqfd" cd $TDIR/ ################################################################################ -# 'cqfd init' without context should fail the context +# 'cqfd --init' without context should fail the context ################################################################################ -jtest_prepare "cqfd init without using build_context" -if $cqfd init && - $cqfd run "grep '^build_context=' /tmp/cqfdrc-build_context" | grep -q '^build_cont'; then +jtest_prepare "cqfd --init without using build_context" +if $cqfd --init && + $cqfd "grep '^build_context=' /tmp/cqfdrc-build_context" | grep -q '^build_cont'; then jtest_result fail else jtest_result pass @@ -26,11 +26,11 @@ cp -f .cqfd/docker/Dockerfile.build_context .cqfd/docker/Dockerfile cp -f cqfdrc-build_context .cqfdrc ################################################################################ -# 'cqfd init' with context changes the context +# 'cqfd --init' with context changes the context ################################################################################ -jtest_prepare "cqfd init using build_context" -if $cqfd init && - $cqfd run "grep '^build_context=' /tmp/cqfdrc-build_context" | grep -q '^build_cont'; then +jtest_prepare "cqfd --init using build_context" +if $cqfd --init && + $cqfd "grep '^build_context=' /tmp/cqfdrc-build_context" | grep -q '^build_cont'; then jtest_result pass else jtest_result fail diff --git a/tests/05-cqfd_init_alt_ext b/tests/05-cqfd_init_alt_ext index d1f833c..9160932 100755 --- a/tests/05-cqfd_init_alt_ext +++ b/tests/05-cqfd_init_alt_ext @@ -14,20 +14,20 @@ mv .cqfdrc ${extdir}/cqfdrc cqfd="$TDIR/${extdir}/cqfd/cqfd" ################################################################################ -# 'cqfd init' without local files should fail +# 'cqfd --init' without local files should fail ################################################################################ -jtest_prepare "cqfd init without local files should fail" -if $cqfd init; then +jtest_prepare "cqfd --init without local files should fail" +if $cqfd --init; then jtest_result fail else jtest_result pass fi ################################################################################ -# 'cqfd init' using alternate filenames in an external directory should work +# 'cqfd --init' using alternate filenames in an external directory should work ################################################################################ -jtest_prepare "cqfd init using alternate filenames in an external directory should work" -if $cqfd -C ${extdir} -d cqfd -f cqfdrc init; then +jtest_prepare "cqfd --init using alternate filenames in an external directory should work" +if $cqfd -C ${extdir} -d cqfd -f cqfdrc --init; then jtest_result pass else jtest_result fail diff --git a/tests/05-cqfd_init_extra_env b/tests/05-cqfd_init_extra_env index 9f9cda3..6058660 100755 --- a/tests/05-cqfd_init_extra_env +++ b/tests/05-cqfd_init_extra_env @@ -14,21 +14,21 @@ cp -f .cqfd/docker/Dockerfile .cqfd/docker/Dockerfile.orig cp -f .cqfd/docker/Dockerfile.init_extra_env .cqfd/docker/Dockerfile ################################################################################ -# 'cqfd init' without CQFD_EXTRA_BUILD_ARGS should fail +# 'cqfd --init' without CQFD_EXTRA_BUILD_ARGS should fail ################################################################################ -jtest_prepare "cqfd init without using CQFD_EXTRA_BUILD_ARGS" -if $cqfd init; then +jtest_prepare "cqfd --init without using CQFD_EXTRA_BUILD_ARGS" +if $cqfd --init; then jtest_result fail else jtest_result pass fi ################################################################################ -# 'cqfd init' with CQFD_EXTRA_BUILD_ARGS should lead +# 'cqfd --init' with CQFD_EXTRA_BUILD_ARGS should lead ################################################################################ -jtest_prepare "cqfd init using CQFD_EXTRA_BUILD_ARGS" +jtest_prepare "cqfd --init using CQFD_EXTRA_BUILD_ARGS" export CQFD_EXTRA_BUILD_ARGS="--build-arg FOO=foo --no-cache" -if $cqfd init; then +if $cqfd --init; then jtest_result pass else jtest_result fail diff --git a/tests/05-cqfd_init_flavor b/tests/05-cqfd_init_flavor index 73cfbe9..b9a9745 100755 --- a/tests/05-cqfd_init_flavor +++ b/tests/05-cqfd_init_flavor @@ -7,39 +7,39 @@ flavor="foo" cd $TDIR/ ################################################################################ -# 'cqfd init' with different flavor makes a different container +# 'cqfd --init' with different flavor makes a different container ################################################################################ cqfdrc_old=$(mktemp) cp -f .cqfdrc $cqfdrc_old sed -i -e "s/\[foo\]/[foo]\ndistro='centos'/" .cqfdrc -jtest_prepare "cqfd init using '$flavor' flavor" -if $cqfd -b $flavor init && - $cqfd -b $flavor run "grep '^NAME=' /etc/*release" | grep -q 'NAME="CentOS Linux"'; then +jtest_prepare "cqfd --init using '$flavor' flavor" +if $cqfd -b $flavor --init && + $cqfd -b $flavor "grep '^NAME=' /etc/*release" | grep -q 'NAME="CentOS Linux"'; then jtest_result pass else jtest_result fail fi ################################################################################ -# 'cqfd init' with invalid flavor should fail +# 'cqfd --init' with invalid flavor should fail ################################################################################ flavorPart="${flavor:0:2}" -jtest_prepare "cqfd init using part of '$flavor' flavor should fail" -if $cqfd -b $flavorPart init; then +jtest_prepare "cqfd --init using part of '$flavor' flavor should fail" +if $cqfd -b $flavorPart --init; then jtest_result fail else jtest_result pass fi ################################################################################ -# 'cqfd init' without flavor generates our regular container +# 'cqfd --init' without flavor generates our regular container ################################################################################ mv -f $cqfdrc_old .cqfdrc -jtest_prepare "cqfd init without flavor" -if $cqfd init && - $cqfd run "grep '^NAME=' /etc/*release" | grep -q 'NAME="Ubuntu"'; then +jtest_prepare "cqfd --init without flavor" +if $cqfd --init && + $cqfd "grep '^NAME=' /etc/*release" | grep -q 'NAME="Ubuntu"'; then jtest_result pass else jtest_result fail diff --git a/tests/05-cqfd_run b/tests/05-cqfd_run index 9c488ba..3a35750 100755 --- a/tests/05-cqfd_run +++ b/tests/05-cqfd_run @@ -6,7 +6,7 @@ test_file="a/cqfd_a.txt" cd $TDIR/ -# Here we test cqfd run, which is also invoked without any argument +# Here we test cqfd, which is also invoked without any argument for i in 0 1; do # Data set shall produce a/cqfd_a.txt: @@ -17,8 +17,8 @@ for i in 0 1; do fi if [ "$i" = "1" ]; then - jtest_prepare "running \"cqfd run\" makes it run" - $cqfd run + jtest_prepare "running \"cqfd\" makes it run" + $cqfd else jtest_prepare "running \"cqfd\" with no argument makes it run" $cqfd @@ -38,12 +38,12 @@ for i in 0 1; do done ################################################################################ -# If the Dockerfile changed and no init is done again, 'cqfd run' should fail +# If the Dockerfile changed and no init is done again, 'cqfd' should fail ################################################################################ -jtest_prepare "Modifying the Dockerfile should require running 'cqfd init' again" +jtest_prepare "Modifying the Dockerfile should require running 'cqfd --init' again" dockerfile=.cqfd/docker/Dockerfile echo "RUN echo $RANDOM" >> $dockerfile -if $TDIR/.cqfd/cqfd run; then +if $TDIR/.cqfd/cqfd; then jtest_result fail else jtest_result pass diff --git a/tests/05-cqfd_run_c b/tests/05-cqfd_run_c index 5717e41..b485393 100755 --- a/tests/05-cqfd_run_c +++ b/tests/05-cqfd_run_c @@ -24,8 +24,8 @@ test_cleanup() { # Append default command build with an additional option test_step1() { - jtest_prepare "running \"cqfd run -c\" makes it run with appended arguments" - $cqfd run -c --debug >> $test_run_c_file + jtest_prepare "running \"cqfd -c\" makes it run with appended arguments" + $cqfd -c --debug >> $test_run_c_file # at the end of this test, $test_run_c_file is populated if ! grep -qw "target \`build'" $test_run_c_file; then @@ -48,8 +48,8 @@ test_step1() { # Build the default command with run -c test_step2() { - jtest_prepare "running \"cqfd run -c\" with no argument makes it fail" - $cqfd run -c + jtest_prepare "running \"cqfd -c\" with no argument makes it fail" + $cqfd -c [ $? -eq 0 ] && jtest_result fail || jtest_result pass } diff --git a/tests/05-cqfd_run_c_flavor b/tests/05-cqfd_run_c_flavor index 14d147c..d48e00b 100755 --- a/tests/05-cqfd_run_c_flavor +++ b/tests/05-cqfd_run_c_flavor @@ -9,7 +9,7 @@ test_run_c_file="test_run_c.txt" cd $TDIR/ # concatenate flavor build with an additional option -jtest_log info "run cqfd run -c with a given '$flavor' flavor" +jtest_log info "run cqfd -c with a given '$flavor' flavor" if [ -f "$test_file" ] || [ -f "$test_run_c_file" ]; then jtest_log fatal "$test_file or $test_run_c_file already present before test" @@ -19,7 +19,7 @@ if [ -f "$test_file" ] || [ -f "$test_run_c_file" ]; then fi jtest_prepare "build cmd for '$flavor' flavor and concatenate with an additional option" -$cqfd -b $flavor run -c --debug >> $test_run_c_file +$cqfd -b $flavor -c --debug >> $test_run_c_file # at the end of this test, $test_run_c_file is populated if ! grep -qw "target \`foo'" $test_run_c_file; then diff --git a/tests/05-cqfd_run_check_dependencies b/tests/05-cqfd_run_check_dependencies index 94e884e..8781b88 100755 --- a/tests/05-cqfd_run_check_dependencies +++ b/tests/05-cqfd_run_check_dependencies @@ -16,8 +16,8 @@ cp -f .cqfd/docker/Dockerfile.missing_dependencies .cqfd/docker/Dockerfile ################################################################################ # Missing all core dependencies for the launch script ################################################################################ -jtest_prepare "cqfd run fails when the Docker image lacks required commands" -if $cqfd init && $cqfd run; then +jtest_prepare "cqfd fails when the Docker image lacks required commands" +if $cqfd --init && $cqfd; then jtest_result fail else jtest_result pass @@ -30,11 +30,11 @@ echo 'RUN apk add bash shadow' >> .cqfd/docker/Dockerfile echo 'ENV CQFD_DEBUG=1' >> .cqfd/docker/Dockerfile ################################################################################ -# cqfd run should now be happy with the required commands, using su. +# cqfd should now be happy with the required commands, using su. ################################################################################ -jtest_prepare "cqfd run with satisfied command requirements, using su" -$cqfd init && \ - $cqfd run true \ +jtest_prepare "cqfd with satisfied command requirements, using su" +$cqfd --init && \ + $cqfd true \ | awk -v rc=1 '/Using "su"/ { rc=0 } 1; END {exit rc}' \ && jtest_result pass || jtest_result fail @@ -44,11 +44,11 @@ $cqfd init && \ echo 'RUN apk add sudo' >> .cqfd/docker/Dockerfile ################################################################################ -# cqfd run should now be happy with the required commands, using sudo +# cqfd should now be happy with the required commands, using sudo ################################################################################ -jtest_prepare "cqfd run with satisfied command requirements, using sudo" -$cqfd init && \ - $cqfd run true \ +jtest_prepare "cqfd with satisfied command requirements, using sudo" +$cqfd --init && \ + $cqfd true \ | awk -v rc=1 '/Using "sudo"/ { rc=0 } 1; END {exit rc}' \ && jtest_result pass || jtest_result fail @@ -56,4 +56,4 @@ $cqfd init && \ # restore initial Dockerfile ################################################################################ mv -f .cqfd/docker/Dockerfile.orig .cqfd/docker/Dockerfile -$cqfd init +$cqfd --init diff --git a/tests/05-cqfd_run_command b/tests/05-cqfd_run_command index 182dd6f..b89683d 100755 --- a/tests/05-cqfd_run_command +++ b/tests/05-cqfd_run_command @@ -21,11 +21,11 @@ for i in 0 1; do fi if [ "$i" = "0" ]; then - jtest_prepare "cqfd run \"touch somefile\" creates the file" - $cqfd run "touch $test_file" + jtest_prepare "cqfd \"touch somefile\" creates the file" + $cqfd "touch $test_file" else - jtest_prepare "cqfd run touch somefile (no quotes) creates the file" - $cqfd run touch $test_file + jtest_prepare "cqfd touch somefile (no quotes) creates the file" + $cqfd touch $test_file fi if [ $? != 0 -o ! -f "$test_file" ]; then diff --git a/tests/05-cqfd_run_config b/tests/05-cqfd_run_config index ebc4572..2d1caf0 100755 --- a/tests/05-cqfd_run_config +++ b/tests/05-cqfd_run_config @@ -17,28 +17,28 @@ touch .cqfdrc # Third pass: run with non default config file and flavor # Fourth pass: run with flavor non default config file for i in 0 1 2 3; do - jtest_log info "cqfd run, custom cqfdrc: $confdir/mycqfdrc, pass $i" + jtest_log info "cqfd, custom cqfdrc: $confdir/mycqfdrc, pass $i" case $i in 0) test_file="a/cqfd_a.txt" # from mycqfdrc - jtest_prepare "cqfd run with config in $confdir/mycqfdrc" - $cqfd -f "$confdir"/mycqfdrc run + jtest_prepare "cqfd with config in $confdir/mycqfdrc" + $cqfd -f "$confdir"/mycqfdrc ;; 1) test_file="file.$RANDOM" - jtest_prepare "cqfd run and override with additionnal cmd" - $cqfd -f "$confdir"/mycqfdrc run touch $test_file + jtest_prepare "cqfd and override with additionnal cmd" + $cqfd -f "$confdir"/mycqfdrc touch $test_file ;; 2) test_file="$flavor.$RANDOM" - jtest_prepare "cqfd run and build a given '$flavor' flavor" - $cqfd -f "$confdir"/mycqfdrc -b $flavor run touch $test_file + jtest_prepare "cqfd and build a given '$flavor' flavor" + $cqfd -f "$confdir"/mycqfdrc -b $flavor touch $test_file ;; 3) test_file="$flavor.$RANDOM" - jtest_prepare "cqfd run and build a given '$flavor' flavor (inverted args)" - $cqfd -b $flavor -f "$confdir"/mycqfdrc run touch $test_file + jtest_prepare "cqfd and build a given '$flavor' flavor (inverted args)" + $cqfd -b $flavor -f "$confdir"/mycqfdrc touch $test_file ;; *) ;; diff --git a/tests/05-cqfd_run_extra_env b/tests/05-cqfd_run_extra_env index 6c5a579..ea68549 100755 --- a/tests/05-cqfd_run_extra_env +++ b/tests/05-cqfd_run_extra_env @@ -6,7 +6,7 @@ cqfd="$TDIR/.cqfd/cqfd" cd $TDIR/ ################################################################################ -# 'cqfd run' passes environment variables to the container when using +# 'cqfd' passes environment variables to the container when using # CQFD_EXTRA_RUN_ARGS ################################################################################ jtest_prepare "run cqfd with extra environment variables" @@ -15,7 +15,7 @@ val1="value-$RANDOM" val2="value-$RANDOM" result=$(CQFD_EXTRA_RUN_ARGS="-e FOO=$val1 -e BAR=$val2" \ - $cqfd run 'echo -n $FOO $BAR' | grep value) + $cqfd 'echo -n $FOO $BAR' | grep value) if [ "$result" = "$val1 $val2" ]; then jtest_result pass diff --git a/tests/05-cqfd_run_extra_groups b/tests/05-cqfd_run_extra_groups index c803414..8b18848 100755 --- a/tests/05-cqfd_run_extra_groups +++ b/tests/05-cqfd_run_extra_groups @@ -6,10 +6,10 @@ cqfd="$TDIR/.cqfd/cqfd" cd $TDIR/ ################################################################################ -# 'cqfd run' should add extra_groups provided by an environment variable +# 'cqfd' should add extra_groups provided by an environment variable ################################################################################ -jtest_prepare "'cqfd run' should add extra_groups provided by an env variable" -result=$(user_extra_groups="docker newgroup:12345" $cqfd run 'groups' | grep docker | grep newgroup) +jtest_prepare "'cqfd' should add extra_groups provided by an env variable" +result=$(user_extra_groups="docker newgroup:12345" $cqfd 'groups' | grep docker | grep newgroup) if [ -n "$result" ]; then jtest_result pass @@ -18,11 +18,11 @@ else fi ################################################################################ -# 'cqfd run' should add extra_groups provided by the config +# 'cqfd' should add extra_groups provided by the config ################################################################################ -jtest_prepare "'cqfd run' should add config's extra_groups to the local user" +jtest_prepare "'cqfd' should add config's extra_groups to the local user" echo 'user_extra_groups="docker newgroup:12345"' >> .cqfdrc -result=$($cqfd run 'groups' | grep docker | grep newgroup) +result=$($cqfd 'groups' | grep docker | grep newgroup) if [ -n "$result" ]; then jtest_result pass diff --git a/tests/05-cqfd_run_extra_hosts b/tests/05-cqfd_run_extra_hosts index 3564025..e58aa12 100755 --- a/tests/05-cqfd_run_extra_hosts +++ b/tests/05-cqfd_run_extra_hosts @@ -7,7 +7,7 @@ getent_cmd="getent hosts 1.2.3.4" cd $TDIR/ jtest_prepare "run cqfd without extra hosts" -output=$($cqfd run $getent_cmd ; exit 0) +output=$($cqfd $getent_cmd ; exit 0) if [ "$output" = "" ]; then jtest_result pass @@ -17,7 +17,7 @@ fi jtest_prepare "run cqfd with extra hosts" output=$(CQFD_EXTRA_RUN_ARGS="--add-host testhost:1.2.3.4" \ - $cqfd run $getent_cmd ; exit 0) + $cqfd $getent_cmd ; exit 0) if [[ "$output" == *"1.2.3.4"*"testhost"* ]]; then jtest_result pass @@ -29,7 +29,7 @@ jtest_prepare "run cqfd with docker_run_args in config" # setup -- add the docker_run_args option to config sed '/\[build\]/adocker_run_args="--add-host testhost:1.2.3.4"'\ -i "$TDIR/.cqfdrc" -output=$($cqfd run $getent_cmd; exit 0) +output=$($cqfd $getent_cmd; exit 0) if [[ "$output" == *"1.2.3.4"*"testhost"* ]]; then jtest_result pass diff --git a/tests/05-cqfd_run_flavor b/tests/05-cqfd_run_flavor index 12178cf..a442fca 100755 --- a/tests/05-cqfd_run_flavor +++ b/tests/05-cqfd_run_flavor @@ -14,12 +14,12 @@ for i in 0 1; do if [ "$i" = "0" ]; then test_file=$flavor - jtest_prepare "cqfd run build cmd for '$flavor' flavor" - $cqfd -b $flavor run + jtest_prepare "cqfd build cmd for '$flavor' flavor" + $cqfd -b $flavor else test_file="file.$RANDOM" - jtest_prepare "cqfd run and override with additional cmd" - $cqfd -b $flavor run touch $test_file + jtest_prepare "cqfd and override with additional cmd" + $cqfd -b $flavor touch $test_file fi if [ $? != 0 -o ! -f "$test_file" ]; then diff --git a/tests/05-cqfd_run_from_subdirectory b/tests/05-cqfd_run_from_subdirectory index 32e75c6..92a8f05 100755 --- a/tests/05-cqfd_run_from_subdirectory +++ b/tests/05-cqfd_run_from_subdirectory @@ -14,7 +14,7 @@ pushd "$sub_dir" >/dev/null || exit 1 # the two paths should be identical p1=$(pwd | strings) -p2=$($cqfd run pwd | strings) +p2=$($cqfd pwd | strings) if [ "$p1" = "$p2" ]; then jtest_result pass diff --git a/tests/05-cqfd_run_home_env_var b/tests/05-cqfd_run_home_env_var index 01e0893..56484d5 100755 --- a/tests/05-cqfd_run_home_env_var +++ b/tests/05-cqfd_run_home_env_var @@ -7,10 +7,10 @@ cd $TDIR/ ################################################################################ -# 'cqfd run' sets HOME environment variable for the local user +# 'cqfd' sets HOME environment variable for the local user ################################################################################ jtest_prepare "run cqfd sets HOME environment variable for the local user" -result=$($cqfd run 'echo -n $HOME') +result=$($cqfd 'echo -n $HOME') if [ "$result" = "$HOME" ]; then jtest_result pass @@ -20,7 +20,7 @@ fi ################################################################################ -# 'cqfd run' does not override HOME environment explicitely set via +# 'cqfd' does not override HOME environment explicitely set via # CQFD_EXTRA_RUN_ARGS ################################################################################ jtest_prepare "run doesn't override HOME env when set via CQFD_EXTRA_RUN_ARGS" @@ -28,7 +28,7 @@ val1="value-$RANDOM" val2="value-$RANDOM" result=$(CQFD_EXTRA_RUN_ARGS="-e FOO=$val1 -e HOME=$val2" \ - $cqfd run 'echo -n $FOO $HOME' | grep value) + $cqfd 'echo -n $FOO $HOME' | grep value) if [ "$result" = "$val1 $val2" ]; then jtest_result pass @@ -37,14 +37,14 @@ else fi ################################################################################ -# 'cqfd run' does not override HOME environment when it is the only entry in +# 'cqfd' does not override HOME environment when it is the only entry in # CQFD_EXTRA_RUN_ARGS ################################################################################ jtest_prepare "run doesn't override HOME env when the only entry in CQFD_EXTRA_RUN_ARGS" val1="value-$RANDOM" result=$(CQFD_EXTRA_RUN_ARGS="-e HOME=$val1" \ - $cqfd run 'echo -n $FOO $HOME' | grep value) + $cqfd 'echo -n $FOO $HOME' | grep value) if [ "$result" = "$val1" ]; then jtest_result pass @@ -53,7 +53,7 @@ else fi ################################################################################ -# 'cqfd run' does not confuse JAVA_HOME and the like with HOME when set via +# 'cqfd' does not confuse JAVA_HOME and the like with HOME when set via # CQFD_EXTRA_RUN_ARGS ################################################################################ jtest_prepare "run doesn't confuse JAVA_HOME and the like with HOME" @@ -61,7 +61,7 @@ val1="value-$RANDOM" val2="value-$RANDOM" result=$(CQFD_EXTRA_RUN_ARGS="-e JAVA_HOME=$val1 -e HOME=$val2" \ - $cqfd run 'echo -n $JAVA_HOME $HOME' | grep value) + $cqfd 'echo -n $JAVA_HOME $HOME' | grep value) if [ "$result" = "$val1 $val2" ]; then jtest_result pass @@ -74,8 +74,8 @@ fi # directory. ################################################################################ jtest_prepare "the user's home in passwd == \$HOME" -passwd_home=$($cqfd run "grep ^$(whoami): /etc/passwd |cut -d: -f6") -user_home=$($cqfd run "echo \$HOME") +passwd_home=$($cqfd "grep ^$(whoami): /etc/passwd |cut -d: -f6") +user_home=$($cqfd "echo \$HOME") if [ "$passwd_home" = "$user_home" ]; then jtest_result pass diff --git a/tests/05-cqfd_run_spaces_in_path b/tests/05-cqfd_run_spaces_in_path index b1e3b09..867b986 100755 --- a/tests/05-cqfd_run_spaces_in_path +++ b/tests/05-cqfd_run_spaces_in_path @@ -17,10 +17,10 @@ cp -a .cqfd .cqfdrc "$spaces_dir"/"$spaces_dir2" pushd "$spaces_dir"/"$spaces_dir2" >/dev/null || exit 1 -jtest_prepare "cqfd run from a directory with spaces" +jtest_prepare "cqfd from a directory with spaces" file="rand.$RANDOM" -$cqfd run touch "$file" +$cqfd touch "$file" if [ -f "$file" ]; then rm -f "$file" diff --git a/tests/05-cqfd_run_tty b/tests/05-cqfd_run_tty index ae08dcd..606375c 100755 --- a/tests/05-cqfd_run_tty +++ b/tests/05-cqfd_run_tty @@ -7,14 +7,14 @@ cqfd="$TDIR/.cqfd/cqfd" ################################################################################ -# 'cqfd run' accepts running when not in a tty +# 'cqfd' accepts running when not in a tty ################################################################################ jtest_prepare "cqfd works when not in a tty" cd $TDIR/ # the key here is to use /dev/null as stdin -$cqfd run cat /etc/passwd >.cqfdrc -jtest_prepare "cqfd release now with a files parameter" -if $cqfd release; then +jtest_prepare "cqfd --release now with a files parameter" +if $cqfd --release; then jtest_result pass else jtest_result fail @@ -54,7 +54,7 @@ rm -f cqfd-test.tar.xz # now use tar_transform=no jtest_prepare "archived files NOT at root of tar archive if tar_transform=no" echo "tar_transform=no" >>.cqfdrc -$cqfd release +$cqfd --release result="pass" for f in $rel_files; do if ! tar tf cqfd-test.tar.xz | grep -q "^${f}$"; then @@ -68,7 +68,7 @@ rm -f cqfd-test.tar.xz # now use tar_transform=yes jtest_prepare "archived files at root of tar archive if tar_transform=yes" echo "tar_transform=yes" >>.cqfdrc -$cqfd release +$cqfd --release result="pass" for f in $rel_files; do if ! tar tf cqfd-test.tar.xz | grep -q "^$(basename $f)$"; then @@ -85,13 +85,13 @@ rm -f cqfd-test.tar.xz ################################################################################ jtest_prepare "symlink files are copied in the tar archive" -$cqfd run ln -s a/cqfd_a.txt link.txt +$cqfd ln -s a/cqfd_a.txt link.txt rel_files_link="a/cqfd_a.txt link.txt" sed -i '/files=/d' .cqfdrc echo "files=\"$rel_files_link\"" >>.cqfdrc echo "tar_options=-h" >>.cqfdrc -$cqfd release +$cqfd --release result="pass" tmp_dir=$(mktemp -d) if ! tar xf cqfd-test.tar.xz -C "${tmp_dir}"; then @@ -105,7 +105,7 @@ fi jtest_result $result # revert the changes in .cqfdrc file -$cqfd run rm link.txt +$cqfd rm link.txt sed -i '/tar_options/d' .cqfdrc sed -i '/files=/d' .cqfdrc echo "files=\"$rel_files\"" >>.cqfdrc @@ -123,7 +123,7 @@ d3=$(date --rfc-3339='date') echo 'archive=cqfd-%D3-$CTEST.tar.xz' >> .cqfdrc # Generate the release archive -$cqfd release +$cqfd --release if tar tf cqfd-$d3-foobar.tar.xz >/dev/null 2>&1; then jtest_result pass @@ -137,7 +137,7 @@ rm -f cqfd-$d3-foobar.tar.xz ################################################################################ jtest_prepare "build.archive can make a .tar.gz archive" sed -i -e '$ s!^archive=.*xz!archive=cqfd-$CTEST.tar.gz!' .cqfdrc -$cqfd release +$cqfd --release if tar ztf cqfd-$CTEST.tar.gz >/dev/null 2>&1; then jtest_result pass else @@ -150,7 +150,7 @@ rm -f cqfd-$CTEST.tar.gz ################################################################################ jtest_prepare "build.archive can make a .zip archive" sed -i -e '$ s!^archive=.*gz!archive=cqfd-$CTEST.zip!' .cqfdrc -$cqfd release +$cqfd --release if unzip -l cqfd-$CTEST.zip >/dev/null 2>&1; then jtest_result pass else @@ -165,7 +165,7 @@ for flav in foo bar; do filename=cqfd-$flav.tar.xz jtest_prepare "release for flavor $flav creates $filename" - $cqfd -b $flav release + $cqfd -b $flav --release if tar tf $filename >/dev/null 2>&1; then jtest_result pass else @@ -179,7 +179,7 @@ done ################################################################################ jtest_prepare "cqfd fails on missing file in build.files" sed -i -e 's!^files=.*$!files="ThisFileDoesNotExist.txt"!' .cqfdrc -if ! $cqfd release; then +if ! $cqfd --release; then jtest_result pass else jtest_result fail @@ -192,8 +192,8 @@ jtest_prepare "cqfd resolves globs in build.files" sed -i -e 's!^archive=.*$!archive=cqfd-$CTEST.tar.xz!' .cqfdrc sed -i -e 's!^files=.*$!files=".cq*rc Ma*"!' .cqfdrc -# cqfd release must work witout error -if ! $cqfd release; then +# cqfd --release must work witout error +if ! $cqfd --release; then jtest_result fail else jtest_result pass From 6b96effa7e23e56f1232359312703d49318cdacc Mon Sep 17 00:00:00 2001 From: Thomas Ballasi Date: Fri, 27 Oct 2023 19:23:24 -0400 Subject: [PATCH 2/3] docker_build: add throbber As the cqfd --init command is going, in the future, to be ran automatically, work has been done to make it less instrusive. Rather than showing all of the Docker log, it just shows a throbber with the current step status, and shows the full log only if the docker build command failed. --- cqfd | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 58 insertions(+), 3 deletions(-) diff --git a/cqfd b/cqfd index 5e32406..52c5ed2 100755 --- a/cqfd +++ b/cqfd @@ -109,13 +109,66 @@ die() { exit 1 } +# loading_throbber() - Loading throbber process for Docker build initialization +loading_throbber() { + pid=$1 + delay=0.1 + spinstr='-\|/' + + while kill -0 "$pid" 2>/dev/null + do + temp=${spinstr#?} + state=$(awk '$2 ~ /(\[[0-9]+\/[0-9]+)\]/ { print $2 }' "$TEMP_OUTPUT" | sed 's/^.\(.*\).$/\1/' | tail -n 1) + # if not using buildx, use previous format + [ "$state" ] || state=$(awk '$1 == "Step" { print $2 }' "$TEMP_OUTPUT" | tail -n 1) + spinstr=$temp${spinstr%"$temp"} + # Getting the last line of the output of the long command + if [ "$state" ]; then + printf '\r[%c] %s: Initialization of the environment (%s)' "$spinstr" "$PROGNAME" "$state" + line_length=$((46 + ${#state})) + else + printf '\r[%c] %s: Initialization of the environment' "$spinstr" "$PROGNAME" + fi + sleep $delay + done +} + # docker_build() - Initialize build container docker_build() { + export BUILDKIT_PROGRESS=plain + TEMP_OUTPUT=$(mktemp -u) + line_length=46 + if [ -z "$project_build_context" ]; then - docker build ${quiet:+-q} $CQFD_EXTRA_BUILD_ARGS -t "$docker_img_name" "$(dirname "$dockerfile")" + docker build ${quiet:+-q} $CQFD_EXTRA_BUILD_ARGS -t "$docker_img_name" "$(dirname "$dockerfile")" > "$TEMP_OUTPUT" 2>&1 & else - docker build ${quiet:+-q} $CQFD_EXTRA_BUILD_ARGS -t "$docker_img_name" "${project_build_context}" -f "$dockerfile" + docker build ${quiet:+-q} $CQFD_EXTRA_BUILD_ARGS -t "$docker_img_name" "${project_build_context}" -f "$dockerfile" > "$TEMP_OUTPUT" 2>&1 & + fi + container_init_command_pid=$! + + if [ "$quiet" ]; then + # If quiet mode is enabled, we don't display the throbber + # and we wait for the docker build to finish + wait $container_init_command_pid + cat "$TEMP_OUTPUT" + rm "$TEMP_OUTPUT" + return 0 fi + + # Start the throbber + loading_throbber $container_init_command_pid + + # Wait for the docker build to finish + if ! wait $container_init_command_pid; then + printf "\r%${line_length}s\r" + cat "$TEMP_OUTPUT" 1>&2 + rm "$TEMP_OUTPUT" + die 'Initialization of environment failed' + fi + + # Clean up the output file and the console + printf "\r%${line_length}s\r" + rm "$TEMP_OUTPUT" } # docker_run() - run command in configured container @@ -465,7 +518,9 @@ while [ $# -gt 0 ]; do "--init") config_load $flavor docker_build - exit $? + ret=$? + [ "$quiet" ] || echo "$PROGNAME: Initialization of environment successful" + exit $ret ;; "--flavors") config_load From c69f5201aeb7d5bb8269f97c6a7f8fbb159fd0d0 Mon Sep 17 00:00:00 2001 From: Thomas Ballasi Date: Fri, 27 Oct 2023 19:26:24 -0400 Subject: [PATCH 3/3] docker_run: run docker_build if the image does not exist As an effort to make cqfd run similarily to known tools, such as sudo, the docker image is automatically built if necessary rather than dying. --- README.md | 1 - cqfd | 3 +-- tests/05-cqfd_run | 5 ++++- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 91d04b2..d5e0678 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,6 @@ Just follow these steps: * Go into your project's directory * Create a .cqfdrc file * Put a Dockerfile and save it as .cqfd/docker/Dockerfile -* Run ``cqfd --init`` Examples are available in the samples/ directory. diff --git a/cqfd b/cqfd index 52c5ed2..4dd9977 100755 --- a/cqfd +++ b/cqfd @@ -187,9 +187,8 @@ docker_build() { # arg$1: the command string to execute as $cqfd_user # docker_run() { - if ! docker image inspect $docker_img_name &> /dev/null; then - die "The docker image doesn't exist, launch 'cqfd --init' to create it" + docker_build fi local interactive_options diff --git a/tests/05-cqfd_run b/tests/05-cqfd_run index 3a35750..dddb526 100755 --- a/tests/05-cqfd_run +++ b/tests/05-cqfd_run @@ -42,8 +42,11 @@ done ################################################################################ jtest_prepare "Modifying the Dockerfile should require running 'cqfd --init' again" dockerfile=.cqfd/docker/Dockerfile +prev_img_count=$(docker images | grep cqfd_test | wc -l) echo "RUN echo $RANDOM" >> $dockerfile -if $TDIR/.cqfd/cqfd; then +$cqfd +new_img_count=$(docker images | grep cqfd_test | wc -l) +if [ "$prev_img_count" -eq "$new_img_count" ]; then jtest_result fail else jtest_result pass