Skip to content

Commit

Permalink
cqfd: add shell command
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
gportay committed Jan 14, 2024
1 parent b7b0682 commit 916c84f
Show file tree
Hide file tree
Showing 5 changed files with 97 additions and 3 deletions.
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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.
Expand Down
15 changes: 14 additions & 1 deletion bash-completion
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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
15 changes: 13 additions & 2 deletions cqfd
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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"
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down
18 changes: 18 additions & 0 deletions tests/05-cqfd_run_do_not_preserve_arguments
Original file line number Diff line number Diff line change
@@ -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
42 changes: 42 additions & 0 deletions tests/08-cqfd_shell
Original file line number Diff line number Diff line change
@@ -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 </dev/null; then
jtest_result pass
else
jtest_result fail
fi

jtest_prepare "cqfd shell should read commands from stdin"
if ( ! $cqfd shell <<<"tty" ) | grep "not a tty"; then
jtest_result pass
else
jtest_result fail
fi

jtest_prepare "cqfd shell should preserve the arguments"
if $cqfd shell -c 'printf "0=$0,*=$*,#=$#"' zero one two three \
| grep "0=zero,\*=one two three,#=3$"; then
jtest_result pass
else
jtest_result fail
fi

jtest_prepare "cqfd shell should fail with 127 if \$CQFD_SHELL is not found"
if CQFD_SHELL=/bin/non-existant-shell $cqfd shell <<<"tty";
test "$?" -eq 127; then
jtest_result pass
else
jtest_result fail
fi

0 comments on commit 916c84f

Please sign in to comment.