Skip to content

Commit

Permalink
WiFi dialog: add script for printing marker section contents (#1811)
Browse files Browse the repository at this point in the history
Related #131, part (b).
Stacked on #1804.

I realized that we need to add another privileged script for reading
files with marker sections, because we are unable to read those directly
via the Python process in case those files are owned by the `root` user.

Usage is demonstrated in [the subsequent backend
PR](#1812); it’s basically …

```bash
/opt/tinypilot-privileged/scripts/print-marker-sections /path/to/file.txt
```

… where the entire invocation has to be unblocked in the sudoers file.

<a data-ca-tag
href="https://codeapprove.com/pr/tiny-pilot/tinypilot/1811"><img
src="https://codeapprove.com/external/github-tag-allbg.png" alt="Review
on CodeApprove" /></a>

---------

Co-authored-by: Jan Heuermann <[email protected]>
  • Loading branch information
jotaen4tinypilot and jotaen authored Jul 5, 2024
1 parent 40a3191 commit 01ac3f3
Show file tree
Hide file tree
Showing 3 changed files with 261 additions and 0 deletions.
96 changes: 96 additions & 0 deletions debian-pkg/opt/tinypilot-privileged/scripts/print-marker-sections
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
#!/bin/bash
#
# Prints the contents of marker sections from a file.
#
# If the target file doesn’t contain marker sections, the script doesn’t output
# anything.
# If the target file contains unmatched/orphaned markers, this script fails.

# We don’t use `set -x`, because it would output every single iteration of the
# while loop when iterating through the lines of the target file, and hence
# generate a lot of noise.

# Exit on first failure.
set -e

# Exit on unset variable.
set -u

SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
readonly SCRIPT_DIR
# shellcheck source=lib/markers.sh
. "${SCRIPT_DIR}/lib/markers.sh"

print_help() {
cat << EOF
Usage: ${0##*/} [--help] TARGET_FILE
Prints the contents of marker sections from a file.
TARGET_FILE Path to file with marker sections.
--help Display this help and exit.
EOF
}

# Parse command-line arguments.
TARGET_FILE=''
while (( "$#" > 0 )); do
case "$1" in
--help)
print_help
exit
;;
-*)
>&2 echo "Unknown flag: $1"
>&2 echo "Use the '--help' flag for more information"
exit 1
;;
*)
TARGET_FILE="$1"
shift
;;
esac
done
readonly TARGET_FILE

# Ensure target file is specified.
if [[ -z "${TARGET_FILE}" ]]; then
>&2 echo 'Input parameter missing: TARGET_FILE'
>&2 echo "Use the '--help' flag for more information"
exit 1
fi

# Ensure target file exists and is a file.
if [[ ! -f "${TARGET_FILE}" ]]; then
>&2 echo "Not a file: ${TARGET_FILE}"
>&2 echo "Use the '--help' flag for more information"
exit 1
fi

# Read the original file line by line, and preserve all lines that reside
# between the start and end markers (i.e., the section contents).
is_in_marker_section='false'
section_contents=()
while IFS='' read -r line; do
if [[ "${line}" == "${MARKER_END}" ]]; then
if ! "${is_in_marker_section}"; then
>&2 echo 'Unmatched end marker'
exit 1
fi
is_in_marker_section='false'
continue
fi
if [[ "${line}" == "${MARKER_START}" ]]; then
is_in_marker_section='true'
continue
fi
if "${is_in_marker_section}"; then
section_contents+=("${line}")
fi
done < "${TARGET_FILE}"

if "${is_in_marker_section}"; then
>&2 echo 'Unmatched start marker'
exit 1
fi

# Print all lines of the section contents.
printf "%s\n" "${section_contents[@]}"
162 changes: 162 additions & 0 deletions debian-pkg/opt/tinypilot-privileged/scripts/print-marker-sections.bats
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
#!/bin/bash

{
# Silence shellcheck for global bats variables.
# https://github.com/tiny-pilot/tinypilot/issues/1718
# shellcheck disable=SC2154
echo "${output}" "${status}" "${lines}" >/dev/null
}

# Wrapper for invoking the script under test as command.
print-marker-sections() {
bash "${BATS_TEST_DIRNAME}/print-marker-sections" "$@"
}

prints-help() { #@test
run print-marker-sections --help
expected_output="$(cat << EOF
Usage: print-marker-sections [--help] TARGET_FILE
Prints the contents of marker sections from a file.
TARGET_FILE Path to file with marker sections.
--help Display this help and exit.
EOF
)"

[[ "${status}" == 0 ]]
[[ "${output}" == "${expected_output}" ]]
}

rejects-missing-input-arg() { #@test
run print-marker-sections
expected_output="$(cat << EOF
Input parameter missing: TARGET_FILE
Use the '--help' flag for more information
EOF
)"

[[ "${status}" == 1 ]]
[[ "${output}" == "${expected_output}" ]]
}

rejects-illegal-flag() { #@test
run print-marker-sections --foo
expected_output="$(cat << EOF
Unknown flag: --foo
Use the '--help' flag for more information
EOF
)"

[[ "${status}" == 1 ]]
[[ "${output}" == "${expected_output}" ]]
}

rejects-non-existing-file() { #@test
run print-marker-sections foo-file.txt
expected_output="$(cat << EOF
Not a file: foo-file.txt
Use the '--help' flag for more information
EOF
)"

[[ "${status}" == 1 ]]
[[ "${output}" == "${expected_output}" ]]
}

rejects-non-file() { #@test
tmp_dir="$(mktemp --directory)"
run print-marker-sections "${tmp_dir}"
expected_output="$(cat << EOF
Not a file: ${tmp_dir}
Use the '--help' flag for more information
EOF
)"

[[ "${status}" == 1 ]]
[[ "${output}" == "${expected_output}" ]]
}

empty-output-if-file-has-no-markers() { #@test
target_file="$(mktemp)"
cat << EOF > "${target_file}"
line 1
line 2
line 3
EOF
run print-marker-sections "${target_file}"

[[ "${status}" == 0 ]]
[[ "${output}" == "" ]]
}

prints-marker-section() { #@test
target_file="$(mktemp)"
cat << EOF > "${target_file}"
some line
some other line
# --- AUTOGENERATED BY TINYPILOT - START ---
to be
printed
# --- AUTOGENERATED BY TINYPILOT - END ---
final line
EOF
run print-marker-sections "${target_file}"
expected_output="$(cat << EOF
to be
printed
EOF
)"

[[ "${status}" == 0 ]]
[[ "${output}" == "${expected_output}" ]]
}

prints-multiple-marker-sections() { #@test
target_file="$(mktemp)"
cat << EOF > "${target_file}"
some line
some other line
# --- AUTOGENERATED BY TINYPILOT - START ---
to be
# --- AUTOGENERATED BY TINYPILOT - END ---
intermediate line
# --- AUTOGENERATED BY TINYPILOT - START ---
printed
# --- AUTOGENERATED BY TINYPILOT - END ---
final line
EOF
run print-marker-sections "${target_file}"
expected_output="$(cat << EOF
to be
printed
EOF
)"

[[ "${status}" == 0 ]]
[[ "${output}" == "${expected_output}" ]]
}

fails-for-unmatched-start-marker() { #@test
target_file="$(mktemp)"
cat << EOF > "${target_file}"
some line
# --- AUTOGENERATED BY TINYPILOT - START ---
to be printed
EOF
run print-marker-sections "${target_file}"

[[ "${status}" == 1 ]]
[[ "${output}" == "Unmatched start marker" ]]
}

fails-for-unmatched-end-marker() { #@test
target_file="$(mktemp)"
cat << EOF > "${target_file}"
some line
# --- AUTOGENERATED BY TINYPILOT - END ---
final line
EOF
run print-marker-sections "${target_file}"

[[ "${status}" == 1 ]]
[[ "${output}" == 'Unmatched end marker' ]]
}
3 changes: 3 additions & 0 deletions dev-scripts/mock-scripts/print-marker-sections
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/bash

# Mock version of /opt/tinypilot-privileged/scripts/print-marker-sections

0 comments on commit 01ac3f3

Please sign in to comment.