diff --git a/debian-pkg/opt/tinypilot-privileged/scripts/print-marker-sections b/debian-pkg/opt/tinypilot-privileged/scripts/print-marker-sections new file mode 100755 index 000000000..4b14e0b25 --- /dev/null +++ b/debian-pkg/opt/tinypilot-privileged/scripts/print-marker-sections @@ -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[@]}" diff --git a/debian-pkg/opt/tinypilot-privileged/scripts/print-marker-sections.bats b/debian-pkg/opt/tinypilot-privileged/scripts/print-marker-sections.bats new file mode 100644 index 000000000..a7df658d3 --- /dev/null +++ b/debian-pkg/opt/tinypilot-privileged/scripts/print-marker-sections.bats @@ -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' ]] +} diff --git a/dev-scripts/mock-scripts/print-marker-sections b/dev-scripts/mock-scripts/print-marker-sections new file mode 100755 index 000000000..947e0f489 --- /dev/null +++ b/dev-scripts/mock-scripts/print-marker-sections @@ -0,0 +1,3 @@ +#!/bin/bash + +# Mock version of /opt/tinypilot-privileged/scripts/print-marker-sections