Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add shell and exec commands #118

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 15 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,23 @@ default build command as configured in .cqfdrc, use:

$ cqfd

Alternatively, you may want to specify a custom build command to be
Alternatively, you may want to specify a single custom command to be
executed from inside the build container.

$ cqfd run make clean
$ cqfd exec make clean

Or custom commands composed with shell grammar:

$ 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 +201,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
28 changes: 23 additions & 5 deletions bash-completion
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,9 @@ _cqfd() {

local arg=
_get_first_arg
if [[ "$arg" == run ]]; then
if [[ "$arg" =~ ^(exec|run)$ ]]; then
for (( i=1; i <= cword; i++ )); do
if [[ ${words[i]} == run ]]; then
if [[ ${words[i]} =~ ^(exec|run)$ ]]; then
if [[ $((i+1)) -eq $cword ]]; then
break
elif [[ ${words[i+1]} == -c ]]; then
Expand All @@ -61,7 +61,24 @@ _cqfd() {
fi
done

COMPREPLY=( $(compgen -c -W "-c" -- "$cur") )
if [[ "$arg" == exec ]]; then
COMPREPLY=( $(compgen -c -- "$cur") )
else
COMPREPLY=( $(compgen -c -W "-c" -- "$cur") )
fi
return
elif [[ "$arg" =~ ^(shell|sh|ash|dash|bash|ksh|zsh|csh|tcsh|fish)$ ]]; then
for (( i=1; i <= cword; i++ )); do
if [[ ${words[i]} == "$arg" ]]; 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

Expand All @@ -71,7 +88,8 @@ _cqfd() {
return
fi

local cmds="init flavors run release version help"
COMPREPLY=( $(compgen -W "$cmds $opts" -- "$cur") )
local shells="sh ash dash bash ksh zsh csh tcsh fish"
local cmds="init flavors exec run release shell version help"
COMPREPLY=( $(compgen -W "$shells $cmds $opts" -- "$cur") )
} &&
complete -F _cqfd cqfd
29 changes: 27 additions & 2 deletions cqfd
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,10 @@ Options:
Commands:
init Initialize project build container.
flavors List flavors from config file to stdout.
exec cmd [args] Run argument(s) inside build container.
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 @@ -141,9 +143,9 @@ docker_run() {
die "The docker image doesn't exist, launch 'cqfd init' to create it"
fi

local interactive_options
local interactive_options="-i"
if tty -s; then
interactive_options="-ti"
interactive_options+=" -t"
fi

# If possible, map cqfd_user from the calling user's
Expand Down Expand Up @@ -492,6 +494,16 @@ while [ $# -gt 0 ]; do
-q)
quiet=true
;;
exec)
if [ "$#" -lt 2 ]; then
die "command exec requires arguments"
fi
shift
config_load $flavor
command_string="${@@Q}"
docker_run "$command_string"
exit
;;
run|release)
if [ "$1" = "release" ]; then
has_to_release=true
Expand All @@ -517,6 +529,19 @@ while [ $# -gt 0 ]; do
build_cmd_alt="$*"
break
;;
sh|ash|dash|bash|ksh|zsh|csh|tcsh|fish|shell)
if [ "$1" != "shell" ]; then
CQFD_SHELL="$1"
fi
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"
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
40 changes: 40 additions & 0 deletions tests/07-cqfd_exec
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#!/usr/bin/env bash
#
# validate the behavior of exec command

set -o pipefail

. "$(dirname "$0")"/jtest.inc "$1"
cqfd="$TDIR/.cqfd/cqfd"

cd $TDIR/

jtest_prepare "cqfd exec with no argument should fail"
if ! $cqfd exec; then
jtest_result pass
else
jtest_result fail
fi

jtest_prepare "cqfd exec with argument should succeed"
if $cqfd exec true; then
jtest_result pass
else
jtest_result fail
fi

jtest_prepare "cqfd exec should return same status"
if $cqfd exec exit 10;
test "$?" -eq 10; then
jtest_result pass
else
jtest_result fail
fi

jtest_prepare "cqfd exec should preserve the arguments"
if $cqfd exec /bin/sh -c 'printf "0=$0,*=$*,#=$#"' zero one two three \
| grep "0=zero,\*=one two three,#=3$"; then
jtest_result pass
else
jtest_result fail
fi
74 changes: 74 additions & 0 deletions tests/08-cqfd_shell
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
#!/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

jtest_prepare "cqfd sh should succeed and use sh"
if $cqfd sh <<<'printf "$0"' \
| grep "^sh$"; then
jtest_result pass
else
jtest_result fail
fi

jtest_prepare "cqfd bash should succeed and use bash"
if $cqfd bash <<<'printf "$0"' \
| grep "^bash$"; then
jtest_result pass
else
jtest_result fail
fi

jtest_prepare "cqfd dash should succeed and use dash"
if $cqfd dash <<<'printf "$0"' \
| grep "dash"; then
jtest_result pass
else
jtest_result fail
fi

jtest_prepare "cqfd zsh should fail with 127"
if $cqfd zsh <<<'printf "$0"';
test "$?" -eq 127; then
jtest_result pass
else
jtest_result fail
fi