Skip to content

Commit 00351a4

Browse files
committed
Add markdown template processing to embed includes
1 parent 34d2f69 commit 00351a4

File tree

4 files changed

+166
-10
lines changed

4 files changed

+166
-10
lines changed
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
#!/usr/bin/env bash
2+
3+
# Processes a template_markdown_file markdown file, replacing placeholders like "<!-- include:intro.md -->" with the contents of the specified markdown files. The files to include needs to be in the "includes" subdirectory.
4+
5+
# Fail on any error ("-e" = exit on first error, "-o pipefail" exist on errors within piped commands)
6+
set -o errexit -o pipefail
7+
8+
## Get this "scripts" directory if not already set
9+
# Even if $BASH_SOURCE is made for Bourne-like shells it is also supported by others and therefore here the preferred solution.
10+
# CDPATH reduces the scope of the cd command to potentially prevent unintended directory changes.
11+
# This way non-standard tools like readlink aren't needed.
12+
MARKDOWN_SCRIPTS_DIR=${MARKDOWN_SCRIPTS_DIR:-$( CDPATH=. cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P )} # Repository directory containing the shell scripts
13+
#echo "embedMarkdownIncludes: MARKDOWN_SCRIPTS_DIR=${MARKDOWN_SCRIPTS_DIR}" >&2
14+
15+
template_markdown_file="$1"
16+
include_directory="includes"
17+
18+
awk -v include_directory="${include_directory}" '
19+
# Check if the filename is safe
20+
function is_safe(path) {
21+
if (substr(path, 1, 1) == "/") return 0
22+
if (path ~ /\.\./) return 0
23+
return 1
24+
}
25+
26+
function include_file(path, fullpath, line) {
27+
fullpath = include_directory "/" path
28+
29+
if (!is_safe(path)) {
30+
print "ERROR: illegal include path: " path > "/dev/stderr"
31+
exit 1
32+
}
33+
34+
if ((getline test < fullpath) < 0) {
35+
print "ERROR: missing file " fullpath > "/dev/stderr"
36+
exit 1
37+
}
38+
close(fullpath)
39+
40+
while ((getline line < fullpath) > 0) {
41+
print line
42+
}
43+
close(fullpath)
44+
}
45+
46+
{
47+
# Look for the include marker using index+substr (portable)
48+
if ($0 ~ /<!-- include:/) {
49+
start = index($0, "include:") + 8
50+
end = index($0, "-->")
51+
fname = substr($0, start, end - start)
52+
gsub(/^[ \t]+|[ \t]+$/, "", fname) # trim spaces
53+
54+
include_file(fname)
55+
} else {
56+
print
57+
}
58+
}
59+
' "${template_markdown_file}"
60+
61+
#echo "embedMarkdownIncludes: $(date +'%Y-%m-%dT%H:%M:%S%z') Successfully finished." >&2
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
#!/usr/bin/env bash
2+
3+
# Tests template processing for markdown by embedding includes.
4+
5+
# Requires embedMarkdownIncludes.sh
6+
7+
# Fail on any error ("-e" = exit on first error, "-o pipefail" exist on errors within piped commands)
8+
set -o errexit -o pipefail
9+
10+
## Get this "scripts" directory if not already set
11+
# Even if $BASH_SOURCE is made for Bourne-like shells it is also supported by others and therefore here the preferred solution.
12+
# CDPATH reduces the scope of the cd command to potentially prevent unintended directory changes.
13+
# This way non-standard tools like readlink aren't needed.
14+
MARKDOWN_SCRIPTS_DIR=${MARKDOWN_SCRIPTS_DIR:-$( CDPATH=. cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P )} # Repository directory containing the shell scripts
15+
echo "testEmbedMarkdownIncludes: MARKDOWN_SCRIPTS_DIR=${MARKDOWN_SCRIPTS_DIR}" >&2
16+
17+
tearDown() {
18+
# echo "testEmbedMarkdownIncludes: Tear down tests...."
19+
rm -rf "${temporaryTestDirectory}"
20+
}
21+
22+
successful() {
23+
local COLOR_SUCCESSFUL="\033[0;32m" # green
24+
local COLOR_DEFAULT='\033[0m'
25+
26+
echo -e "testEmbedMarkdownIncludes: ${COLOR_SUCCESSFUL}Tests finished successfully.${COLOR_DEFAULT}"
27+
28+
tearDown
29+
}
30+
31+
fail() {
32+
local COLOR_ERROR='\033[0;31m' # red
33+
local COLOR_DEFAULT='\033[0m'
34+
35+
local errorMessage="${1}"
36+
37+
echo -e "testEmbedMarkdownIncludes: ${COLOR_ERROR}${errorMessage}${COLOR_DEFAULT}"
38+
tearDown
39+
return 1
40+
}
41+
42+
echo "testEmbedMarkdownIncludes: Starting tests...."
43+
44+
# Create testing resources
45+
temporaryTestDirectory=$(mktemp -d 2>/dev/null || mktemp -d -t 'temporaryTestDirectory')
46+
47+
testMarkdownTemplate="${temporaryTestDirectory}/testMarkdownTemplate.md"
48+
echo "<!-- include:testInclude.md -->" > "${testMarkdownTemplate}"
49+
50+
# Setup test files
51+
mkdir -p "${temporaryTestDirectory}/includes"
52+
53+
# ------------------------------------------------------------
54+
# Test case --
55+
# ------------------------------------------------------------
56+
echo "testEmbedMarkdownIncludes: 1.) An existing include file is correctly embedded."
57+
58+
# - Setup
59+
testIncludeFile="includes/testInclude.md"
60+
expected_test_include_content="This is the included content for the test."
61+
echo "${expected_test_include_content}" > "${temporaryTestDirectory}/${testIncludeFile}"
62+
63+
# - Execute script under test
64+
embeddedContent=$(cd "${temporaryTestDirectory}"; "${MARKDOWN_SCRIPTS_DIR}/embedMarkdownIncludes.sh" "${testMarkdownTemplate}" )
65+
66+
# - Verify results
67+
if [ "${embeddedContent}" != "${expected_test_include_content}" ]; then
68+
fail "1.) Test failed: Expected embedded content to be '${expected_test_include_content}', but got '${embeddedContent}'."
69+
fi
70+
71+
# ------------------------------------------------------------
72+
# Test case --
73+
# ------------------------------------------------------------
74+
echo "testEmbedMarkdownIncludes: 2.) A missing include file results in an error."
75+
76+
# - Setup
77+
testMarkdownTemplateMissingInclude="testMarkdownTemplateMissingInclude.md"
78+
echo "<!-- include:nonExistentFile.md -->" > "${temporaryTestDirectory}/${testMarkdownTemplateMissingInclude}"
79+
80+
# - Execute script under test
81+
set +o errexit
82+
errorOutput=$(cd "${temporaryTestDirectory}"; { "${MARKDOWN_SCRIPTS_DIR}/embedMarkdownIncludes.sh" "${testMarkdownTemplateMissingInclude}" 2>&1 1>/dev/null; } )
83+
exitCode=$?
84+
set -o errexit
85+
86+
# - Verify results
87+
if [ ${exitCode} -eq 0 ]; then
88+
fail "2.) Test failed: Expected an error due to missing include file, but the script succeeded."
89+
fi
90+
if [[ "${errorOutput}" != *"ERROR: missing file"* ]]; then
91+
fail "2.) Test failed: Expected error message to contain 'ERROR: missing file', but got '${errorOutput}'."
92+
fi
93+
94+
successful
95+
return 0

scripts/runTests.sh

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,18 @@ LOG_GROUP_END=${LOG_GROUP_END:-"::endgroup::"} # Prefix to end a log group. Defa
1515
# CDPATH reduces the scope of the cd command to potentially prevent unintended directory changes.
1616
# This way non-standard tools like readlink aren't needed.
1717
SCRIPTS_DIR=${SCRIPTS_DIR:-$( CDPATH=. cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P )} # Repository directory containing the shell scripts
18-
echo "runTests: SCRIPTS_DIR=${SCRIPTS_DIR}" >&2
18+
# echo "runTests: SCRIPTS_DIR=${SCRIPTS_DIR}" >&2
1919

2020
# Run all report scripts
21-
for test_script_file in "${SCRIPTS_DIR}"/test*.sh; do
22-
test_script_filename=$(basename -- "${test_script_file}");
21+
find "${SCRIPTS_DIR}" -type f -name 'test*.sh' | while read -r test_script_file; do
22+
test_script_filename=$(basename -- "${test_script_file}")
2323
test_script_filename="${test_script_filename%.*}" # Remove file extension
2424

25-
echo "${LOG_GROUP_START}Run ${test_script_filename}";
26-
echo "runTests: $(date +'%Y-%m-%dT%H:%M:%S%z') Starting ${test_script_filename}...";
25+
echo "${LOG_GROUP_START}Run ${test_script_filename}"
26+
echo "runTests: $(date +'%Y-%m-%dT%H:%M:%S%z') Starting ${test_script_filename}..."
2727

2828
source "${test_script_file}"
2929

30-
echo "runTests: $(date +'%Y-%m-%dT%H:%M:%S%z') Finished ${test_script_filename}";
31-
echo "${LOG_GROUP_END}";
30+
echo "runTests: $(date +'%Y-%m-%dT%H:%M:%S%z') Finished ${test_script_filename}"
31+
echo "${LOG_GROUP_END}"
3232
done

scripts/testDetectChangedFiles.sh

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ successful() {
2424
echo -e "testDetectChangedFiles: ${COLOR_SUCCESSFUL}Tests finished successfully.${COLOR_DEFAULT}"
2525

2626
tearDown
27-
exit 0
2827
}
2928

3029
fail() {
@@ -35,7 +34,7 @@ fail() {
3534

3635
echo -e "testDetectChangedFiles: ${COLOR_ERROR}${errorMessage}${COLOR_DEFAULT}"
3736
tearDown
38-
exit 1
37+
return 1
3938
}
4039

4140
echo "testDetectChangedFiles: Starting tests...."
@@ -129,4 +128,5 @@ if [ "${changeDetectionReturnCode}" = "0" ]; then
129128
fail "13.) Tests failed: Expected return code 0 if nothing changed with a protocol prefixed file, but got ${changeDetectionReturnCode}."
130129
fi
131130

132-
successful
131+
successful
132+
return 0

0 commit comments

Comments
 (0)