From 916c84ff551a16c81e70dbb298b18239f9cd38ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20PORTAY?= Date: Thu, 9 Nov 2023 15:26:37 +0100 Subject: [PATCH] cqfd: add shell command This adds the shell command to run a $CQFD_SHELL (or /bin/sh) command from within the container. It is a convenient frontend to "cqfd run bash", which also respects the arguments: $ cqfd shell -c 'printf "0=$0,*=$*,#=$#\n"' zero one two three 0=zero,*=one two three,#=3 While the run command does not: $ cqfd run /bin/bash -c 'printf "0=$0,*=$*,#=$#\n"' zero one two three printf: usage: printf [-v var] format [arguments] $ cqfd run /bin/sh -c 'printf "0=$0,*=$*,#=$#\n"' zero one two three 0=bash,*=,#=0\n: 1: printf: usage: printf format [arg ...] Note: The command shell does not run the command= set in the file .cqfdrc. --- README.md | 10 +++++ bash-completion | 15 +++++++- cqfd | 15 +++++++- tests/05-cqfd_run_do_not_preserve_arguments | 18 +++++++++ tests/08-cqfd_shell | 42 +++++++++++++++++++++ 5 files changed, 97 insertions(+), 3 deletions(-) create mode 100755 tests/05-cqfd_run_do_not_preserve_arguments create mode 100755 tests/08-cqfd_shell diff --git a/README.md b/README.md index df7db28..8173341 100644 --- a/README.md +++ b/README.md @@ -48,6 +48,14 @@ executed from inside the build container. $ cqfd run make clean $ cqfd run "make linux-dirclean && make foobar-dirclean" +Additionally, you may want to open an interactive shell: + + $ cqfd shell + +Or run a shell script with arguments: + + $ cqfd shell ./build.sh debug + When ``cqfd`` is running, the current directory is mounted by Docker as a volume. As a result, all the build artefacts generated inside the container are still accessible in this directory after the container @@ -190,6 +198,8 @@ The following environment variables are supported by cqfd to provide the user with extra flexibility during his day-to-day development tasks: +``CQFD_SHELL``: A string specifying the shell to run with `cqfd shell`. + ``CQFD_EXTRA_RUN_ARGS``: A space-separated list of additional docker-run options to be append to the starting container. Format is the same as (and passed to) docker-run’s options. diff --git a/bash-completion b/bash-completion index 09ec5e5..cdd6fa8 100644 --- a/bash-completion +++ b/bash-completion @@ -63,6 +63,19 @@ _cqfd() { COMPREPLY=( $(compgen -c -W "-c" -- "$cur") ) return + elif [[ "$arg" == shell ]]; then + for (( i=1; i <= cword; i++ )); do + if [[ ${words[i]} == shell ]]; then + ((i++)) + break + fi + done + + COMP_WORDS=("${SHELL:-/bin/sh}" "${COMP_WORDS[@]:$i}" "$cur") + COMP_LINE="${COMP_WORDS[*]}" + COMP_POINT="${#COMP_LINE}" + _command_offset 0 + return fi local opts="-C -d -f -b -q -V --version -h --help" @@ -71,7 +84,7 @@ _cqfd() { return fi - local cmds="init flavors run release version help" + local cmds="init flavors run release shell version help" COMPREPLY=( $(compgen -W "$cmds $opts" -- "$cur") ) } && complete -F _cqfd cqfd diff --git a/cqfd b/cqfd index a942b46..0c064f0 100755 --- a/cqfd +++ b/cqfd @@ -46,6 +46,7 @@ Commands: flavors List flavors from config file to stdout. run [cmdstring] Run argument(s) inside build container. release [cmdstring] Run argument(s) and release software. + shell [shargs] Run shell command inside build container. help Show this help text. By default, the 'run' command is assumed, with the default @@ -136,7 +137,7 @@ docker_build() { # arg$1: the command string to execute as $cqfd_user # docker_run() { - local args=(--privileged) + local args=(--privileged -i) if ! docker image inspect $docker_img_name &> /dev/null; then die "The docker image doesn't exist, launch 'cqfd init' to create it" @@ -160,7 +161,7 @@ docker_run() { # Set the interactive options if standard input is connected to a tty if tty -s; then - args+=(-ti) + args+=(-t) fi # If possible, map cqfd_user from the calling user's @@ -542,6 +543,16 @@ while [ $# -gt 0 ]; do has_alternate_command=true break ;; + shell) + shift + config_load $flavor + command_string="${CQFD_SHELL:-/bin/sh}" + if [ "$#" -ne 0 ]; then + command_string+=" ${@@Q}" + fi + docker_run "$command_string" + exit + ;; ?*) echo "Unknown command: $1" >&2 usage diff --git a/tests/05-cqfd_run_do_not_preserve_arguments b/tests/05-cqfd_run_do_not_preserve_arguments new file mode 100755 index 0000000..b00f2af --- /dev/null +++ b/tests/05-cqfd_run_do_not_preserve_arguments @@ -0,0 +1,18 @@ +#!/usr/bin/env bash +# +# validate the behavior of run command that do not preserve arguments + +set -o pipefail + +. "$(dirname "$0")"/jtest.inc "$1" +cqfd="$TDIR/.cqfd/cqfd" + +cd $TDIR/ + +jtest_prepare "cqfd run do not preserve the arguments" +if ( ! $cqfd run /bin/sh -c 'printf "0=$0,*=$*,#=$#"' zero one two three ) \ + | grep "0=sh,\*=,#=0"; then + jtest_result pass +else + jtest_result fail +fi diff --git a/tests/08-cqfd_shell b/tests/08-cqfd_shell new file mode 100755 index 0000000..2ae0758 --- /dev/null +++ b/tests/08-cqfd_shell @@ -0,0 +1,42 @@ +#!/usr/bin/env bash +# +# validate the behavior of shell command + +set -o pipefail + +unset CQFD_SHELL + +. "$(dirname "$0")"/jtest.inc "$1" +cqfd="$TDIR/.cqfd/cqfd" + +cd $TDIR/ + +jtest_prepare "cqfd shell should succeed with no stdin" +if $cqfd shell