Skip to content

Commit e5fe9fd

Browse files
authored
feat: add recommended shell flags to executed scripts (#7)
- Recommended shell flags: `set -o errexit -o nounset -o pipefail`. Closes #3.
1 parent b357837 commit e5fe9fd

File tree

5 files changed

+84
-0
lines changed

5 files changed

+84
-0
lines changed

.github/workflows/ci.yaml

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,51 @@ jobs:
8989
)"
9090
[[ "${output}" == "${expected}" ]] || \
9191
(echo >&2 "Ouptput from integration test does not match:" "${output}"; exit 1)
92+
- name: Execute without recommended shell flags
93+
uses: ./
94+
with:
95+
verbose: true
96+
derivation-path: ./tests/integration_tests
97+
shell-flags: ''
98+
run: |
99+
rm -f integration_test3.out
100+
# This fails. If the recommended flags are set, we should not reach the following
101+
# statement.
102+
ls does_not_exist
103+
echo "HELLO" > integration_test3.out
104+
- name: Confirm output for Execute without recommended shell flags
105+
shell: bash
106+
run: |
107+
[[ -e integration_test3.out ]] || \
108+
(echo >&2 "The integration_test3.out does not exist."; exit 1)
109+
output="$(<./integration_test3.out)"
110+
expected="$(cat <<-EOF
111+
HELLO
112+
EOF
113+
)"
114+
[[ "${output}" == "${expected}" ]] || \
115+
(echo >&2 "Ouptput from integration test does not match:" "${output}"; exit 1)
116+
- name: Execute with recommended shell flags
117+
# This step should fail. We will confirm that it failed as expected in the next step.
118+
continue-on-error: true
119+
uses: ./
120+
with:
121+
verbose: true
122+
derivation-path: ./tests/integration_tests
123+
run: |
124+
rm -f integration_test4.out
125+
# This fails. If the recommended flags are set, we should not reach the following
126+
# statement.
127+
ls does_not_exist
128+
echo "HELLO" > integration_test4.out
129+
- name: Confirm output for Execute with recommended shell flags
130+
shell: bash
131+
run: |
132+
if [[ -e integration_test4.out ]]; then
133+
echo >&2 "The integration_test4.out exists."
134+
exit 1
135+
fi
136+
echo "SUCCESS"
92137
93138
all_ci_tests:
94139
runs-on: ubuntu-latest

action.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ inputs:
2222
description: |
2323
The path to directory or the shell.nix or default.nix to use to set up the environment. This
2424
is the directory where nix-shell is executed.
25+
shell-flags:
26+
type: string
27+
default: set -o errexit -o nounset -o pipefail
28+
description: These flags will be set before executing the script.
2529
verbose:
2630
type: boolean
2731
description: Enable debug output written to stderr.
@@ -38,4 +42,7 @@ runs:
3842
RNS_PURE: ${{ inputs.pure }}
3943
RNS_DERIVATION_PATH: ${{ inputs.derivation-path }}
4044
RNS_VERBOSE: ${{ inputs.verbose }}
45+
# If the client specifies an empty string for the flags, we need to set the RNS_SHELL_FLAGS
46+
# env variable to the special value false.
47+
RNS_SHELL_FLAGS: ${{ inputs.shell-flags == '' && 'false' || inputs.shell-flags }}
4148
run: ${GITHUB_ACTION_PATH}/tools/run_nix_shell.sh

tests/tools_tests/BUILD.bazel

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ run_nix_shell_test(name = "rns_opts_test")
1414

1515
run_nix_shell_test(name = "script_file_test")
1616

17+
run_nix_shell_test(name = "shell_flags_test")
18+
1719
run_nix_shell_test(name = "simple_script_test")
1820

1921
run_nix_shell_test(name = "verbose_test")
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
assert_msg="default flags will exit with an error code on failure"
2+
failed=false
3+
"${run_nix_shell_sh}" '
4+
[[ "true" == "false" ]]
5+
echo "This should not be seen."
6+
' > output.txt || failed=true
7+
output="$( <output.txt )"
8+
assert_equal "" "${output}" "${assert_msg}"
9+
assert_equal "true" "${failed}" "${assert_msg}"
10+
11+
assert_msg="with no shell flags, script will exit without an error code on failure"
12+
success=false
13+
RNS_SHELL_FLAGS="false" "${run_nix_shell_sh}" '
14+
[[ "true" == "false" ]]
15+
echo "This should be seen."
16+
' > output.txt && success=true
17+
output="$( <output.txt )"
18+
assert_equal "This should be seen." "${output}" "${assert_msg}"
19+
assert_equal "true" "${success}" "${assert_msg}"

tools/run_nix_shell.sh

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ absolute_path() {
2828
cwd="${RNS_CWD:-}"
2929
script="${RNS_RUN:-}"
3030
derivation_path="${RNS_DERIVATION_PATH:-}"
31+
# The default flags listed below are equivalent to `set -euo pipefail`.
32+
shell_flags="${RNS_SHELL_FLAGS:-set -o errexit -o nounset -o pipefail}"
3133

3234
pure="${RNS_PURE:-true}"
3335
verbose="${RNS_VERBOSE:-false}"
@@ -82,9 +84,11 @@ RNS_OPTS: ${RNS_OPTS:-}
8284
RNS_RUN: ${RNS_RUN:-}
8385
RNS_DERIVATION_PATH: ${RNS_DERIVATION_PATH:-}
8486
RNS_PURE: ${RNS_PURE:-}
87+
RNS_SHELL_FLAGS: ${RNS_SHELL_FLAGS:-}
8588
cwd: ${cwd:-}
8689
nix_shell_opts: $( printf "%q " "${nix_shell_opts[@]}" )
8790
pure: ${pure:-}
91+
shell_flags: ${shell_flags:-}
8892
script: ${script:-}
8993
derivation_path: ${derivation_path:-}
9094
===
@@ -136,6 +140,12 @@ if [[ -n "${RNS_OPTS:-}" ]]; then
136140
fi
137141
fi
138142

143+
# If the client does not want any shell flags, we use the special value "false"
144+
# to indicate that no flags should be applied.
145+
if [[ "${shell_flags:-}" == "false" ]]; then
146+
shell_flags=""
147+
fi
148+
139149
if [[ -z "${script:-}" ]]; then
140150
fail "A script or a path to a file must be provided."
141151
fi
@@ -148,6 +158,7 @@ if [[ -n "${cwd:-}" ]]; then
148158
fi
149159

150160
script="$(cat <<-EOF
161+
${shell_flags:-}
151162
${cd_cmd:-}
152163
${script}
153164
EOF

0 commit comments

Comments
 (0)