Skip to content
Merged
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
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ dist/doc-$(VERSION).tar.gz: $(DOC_SRC) bash/bashadoc

dist/bin-$(VERSION).tar.gz: $(DOC_SRC) $(BIN_SRC) bash/pack-script
mkdir -p dist/bin
for s in $$(find bash -type f -exec grep -q "includer" {} \; -print|grep -v ".sh$$"); do \
for s in $$(find bash -type f ! -name '*.sh' -exec grep -q "includer" {} \; -print); do \
base=$$(basename $$s) ; \
bash/pack-script -v -f $$s -o dist/bin/$$base ; \
done
Expand Down
13 changes: 13 additions & 0 deletions bash/daml-export
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,19 @@ function build {
popd >/dev/null || return 1
}

# SUR-2838 test seam: when sourced from bats, skip the main entry
# point so individual helpers can be exercised in isolation. Mirrors
# the K8S_SUPPORT_COLLECTOR_SOURCE_ONLY guard. Defaults to executing
# the main loop when the env var is unset, so unwrapped invocations
# (including tests/sur-1871-daml-export.sh) are unchanged.
if [ "${DAML_EXPORT_SOURCE_ONLY:-}" = "true" ]; then
if [[ "${BASH_SOURCE[0]}" != "${0}" ]]; then
return 0
else
exit 0
fi
fi

CUR_INT=$(hex_to_dec "$START_OFFSET")
STOP_INT=$(hex_to_dec "$STOP_OFFSET")

Expand Down
5 changes: 5 additions & 0 deletions bash/k8s-support-collector
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,11 @@ function describe_pods {
local out_dir_ns="${OUT_DIR}/$ns"
log::notice "Describing pods for namespace $ns"
dirs::ensure "$out_dir_ns"
# SUR-2844: load-bearing. `k8s::get_pod_names` returns the literal
# `pod/<name>` form from `kubectl get pods -o name`, so the redirect
# below expands to `$out_dir_ns/pod/<name>.describe`. Dropping this
# `dirs::ensure` (as the original issue suggested) breaks the redirect
# with "No such file or directory" — keep it.
dirs::ensure "$out_dir_ns/pod"
for pod in $(k8s::get_pod_names -n "$ns"); do
k8s::describe -n "$ns" "$pod" >"${out_dir_ns}/$pod.describe"
Expand Down
15 changes: 14 additions & 1 deletion bash/pack-script
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,20 @@ shift "$((OPTIND - 1))"

function ::get_includes() {
local file=${1:?}
grep "^@include" "$file" | awk '{print $NF}'
# SUR-2842: anchor on a literal `@include` directive followed by at
# least one whitespace character, strip any trailing `# comment`, and
# emit the include name (field 2). The previous implementation
# (`grep "^@include" | awk '{print $NF}'`) misparsed three concrete
# shapes: trailing-comment lines surfaced the ticket-name token,
# multi-arg lines surfaced the trailing token, and a bare `@include`
# with no argument fed an empty string downstream into
# `includer::find`.
awk '
/^@include[[:space:]]+/ {
sub(/[[:space:]]*#.*/, "")
if (NF >= 2) { print $2 }
}
' "$file"
}

function get_all_includes() {
Expand Down
84 changes: 54 additions & 30 deletions tests/bashadoc.bats
Original file line number Diff line number Diff line change
@@ -1,50 +1,74 @@
#!/usr/bin/env bats
# SUR-2829: bashadoc must anchor @package extraction. The previous
# `grep "@package"` matched `function @package() {` in doc.sh, yielding
# `{` as the "package" and shipping garbage markdown into doc-*.tar.gz.
bats_require_minimum_version 1.5.0
# SUR-2835: bashadoc has direct coverage for the five contract points
# called out in the issue:
# 1. `@package` header rendering.
# 2. No-`@package` fallback to filename + bare-name functions.
# 3. `@doc` + `@arg` ordering with semicolon stripping in @doc.
# 4. `function @package() {` non-pollution regression (SUR-2829).
# 5. Non-`.sh` argument fails with exit 1 and the documented stderr.
#
# Fixtures live under tests/fixtures/bashadoc/ rather than heredoc'd
# inline so each case can be inspected directly.

setup() {
load 'helpers.bash'
helpers::isolate_home
FIXTURE_DIR=$(mktemp -d)
BASHADOC="$REPO_ROOT/bash/bashadoc"
FIXTURES="$REPO_ROOT/tests/fixtures/bashadoc"
}

teardown() {
rm -rf "$FIXTURE_DIR"
}

@test "bashadoc renders a header from @package and lists pkg::* functions (SUR-2829)" {
cat >"$FIXTURE_DIR/mypkg.sh" <<'EOF'
source "$(dirname "${BASH_SOURCE[0]}")/../bash/includer.sh"
@include doc

@package mypkg

function mypkg::fn() {
@doc Does the thing.
return 0
}
EOF
out=$(bash "$BASHADOC" "$FIXTURE_DIR/mypkg.sh")
@test "bashadoc renders @package header and namespaced functions (SUR-2835 case 1)" {
out=$(bash "$BASHADOC" "$FIXTURES/with-package.sh")
[[ "$out" == *"# \`mypkg\` package"* ]]
[[ "$out" == *"## \`mypkg::fn\`"* ]]
[[ "$out" != *"\`{\`"* ]]
}

@test "bashadoc falls back to filename for libraries without @package (SUR-2829)" {
cat >"$FIXTURE_DIR/nopkg.sh" <<'EOF'
function bare_fn() {
return 0
}
EOF
out=$(bash "$BASHADOC" "$FIXTURE_DIR/nopkg.sh")
[[ "$out" == *"# $FIXTURE_DIR/nopkg.sh package"* ]]
@test "bashadoc falls back to filename when @package is missing (SUR-2835 case 2)" {
out=$(bash "$BASHADOC" "$FIXTURES/no-package.sh")
[[ "$out" == *"# $FIXTURES/no-package.sh package"* ]]
[[ "$out" == *"## \`bare_fn\`"* ]]
[[ "$out" != *"::"* ]]
}

@test "bashadoc renders @doc then @arg with semicolons stripped (SUR-2835 case 3)" {
out=$(bash "$BASHADOC" "$FIXTURES/annotations.sh")
[[ "$out" == *"## \`annpkg::fn\`"* ]]
# The doc body renders verbatim, with no trailing semicolon (the
# production script runs `tr ';' ' '` over the captured @doc/@arg
# text to strip the semicolons that `declare -f` inserts at the end
# of every statement in the function body).
[[ "$out" == *"One-line description of annpkg::fn."* ]]
# @arg lines appear under an `### Arguments` heading, as bullets, and
# carry no trailing semicolon from declare -f.
[[ "$out" == *"### Arguments"* ]]
[[ "$out" == *"- _1_ first positional arg"* ]]
[[ "$out" == *"- -o \"<arg>\" the -o flag"* ]]
[[ "$out" != *"first positional arg;"* ]]
[[ "$out" != *"the -o flag;"* ]]
# Doc body comes before the Arguments section.
doc_line=$(printf '%s\n' "$out" | grep -n "One-line description" | head -1 | cut -d: -f1)
args_line=$(printf '%s\n' "$out" | grep -n "### Arguments" | head -1 | cut -d: -f1)
[ "$doc_line" -lt "$args_line" ]
}

@test "bashadoc ignores 'function @package() {' as a directive (SUR-2835 case 4)" {
out=$(bash "$BASHADOC" "$FIXTURES/at-package-noise.sh")
# The previous unanchored grep produced a title of "`{` package";
# the anchored awk extracts no directive, so the fallback file-path
# title is used instead.
[[ "$out" != *"\`{\`"* ]]
[[ "$out" == *"# $FIXTURES/at-package-noise.sh package"* ]]
}

@test "bashadoc rejects non-.sh argument with exit 1 (SUR-2835 case 5)" {
run bash "$BASHADOC" "$FIXTURES/not-a-shell-file.txt"
[ "$status" -eq 1 ]
[[ "$output" == *"expected a .sh file"* ]]
}

@test "bashadoc handles doc.sh (which defines function @package) without emitting '{' (SUR-2829)" {
@test "bashadoc handles doc.sh (defines function @package) without emitting '{' (SUR-2829)" {
out=$(bash "$BASHADOC" "$REPO_ROOT/bash/doc.sh")
[[ "$out" != *"\`{\`"* ]]
[[ "$out" == *"package"* ]]
Expand Down
166 changes: 166 additions & 0 deletions tests/daml-export.bats
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
#!/usr/bin/env bats
bats_require_minimum_version 1.5.0
# SUR-2838: direct helper-level coverage for bash/daml-export.
# Complements (does not replace) the end-to-end SUR-1871 regression
# under tests/sur-1871-daml-export.sh; this spec exercises the
# documented contract points in isolation:
#
# 1. hex_to_dec / dec_to_hex round-trip and padding.
# 2. verifyExport three-state return code.
# 3. correct_archives sed rewrite + idempotency.
# 4. correct_export dual-file rewrite (daml.yaml + Export.daml).
#
# Uses the DAML_EXPORT_SOURCE_ONLY guard added in this sprint to source
# the script without firing the main offset-walking loop. Test bodies
# run inside `bash -c` to keep bats' `set -e` from tripping on the
# trailing `&&` in `options::add` when sourced helpers are defined.

setup() {
load 'helpers.bash'
helpers::isolate_home
DAML_EXPORT="$REPO_ROOT/bash/daml-export"
export LOGFILE_DISABLE=true LOG_DISABLE_DEBUG=true LOG_DISABLE_INFO=true
export DAML_EXPORT_SOURCE_ONLY=true
}

@test "DAML_EXPORT_SOURCE_ONLY exits 0 when executed (no main body) (SUR-2838)" {
out=$(mktemp -d)
run env DAML_EXPORT_SOURCE_ONLY=true bash "$DAML_EXPORT" -d "$out" -e ffff
rm -rf "$out"
[ "$status" -eq 0 ]
# The main loop's "Exporting from offset" log lines must not appear.
[[ "$output" != *"Exporting from offset"* ]]
}

@test "hex_to_dec converts hex strings to decimal (SUR-2838 case 1)" {
tmp=$(mktemp -d)
run bash -c "
source '$DAML_EXPORT' -d '$tmp' -e ffff
printf '%s|%s|%s\n' \"\$(hex_to_dec 0a)\" \"\$(hex_to_dec 0)\" \"\$(hex_to_dec ff)\"
"
rm -rf "$tmp"
[ "$status" -eq 0 ]
[[ "$output" == *"10|0|255"* ]]
}

@test "dec_to_hex pads to 16 hex chars (SUR-2838 case 2)" {
tmp=$(mktemp -d)
run bash -c "
source '$DAML_EXPORT' -d '$tmp' -e ffff
printf '%s|%s|%s\n' \"\$(dec_to_hex 10)\" \"\$(dec_to_hex 0)\" \"\$(dec_to_hex 65535)\"
"
rm -rf "$tmp"
[ "$status" -eq 0 ]
[[ "$output" == *"000000000000000a|0000000000000000|000000000000ffff"* ]]
}

@test "verifyExport returns 2 for an empty directory (SUR-2838 case 3)" {
tmp=$(mktemp -d)
run bash -c "
source '$DAML_EXPORT' -d '$tmp' -e ffff
verifyExport '$tmp'
echo rc=\$?
"
rm -rf "$tmp"
[ "$status" -eq 0 ]
[[ "$output" == *"rc=2"* ]]
}

@test "verifyExport returns 2 when export.good missing (SUR-2838 case 3)" {
tmp=$(mktemp -d)
touch "$tmp/Export.daml"
run bash -c "
source '$DAML_EXPORT' -d '$tmp' -e ffff
verifyExport '$tmp'
echo rc=\$?
"
rm -rf "$tmp"
[ "$status" -eq 0 ]
[[ "$output" == *"rc=2"* ]]
}

@test "verifyExport returns 1 when export.good + Export.daml present but no dar (SUR-2838 case 3)" {
tmp=$(mktemp -d)
touch "$tmp/export.good" "$tmp/Export.daml"
run bash -c "
source '$DAML_EXPORT' -d '$tmp' -e ffff
verifyExport '$tmp'
echo rc=\$?
"
rm -rf "$tmp"
[ "$status" -eq 0 ]
[[ "$output" == *"rc=1"* ]]
}

@test "verifyExport returns 0 when export.good + Export.daml + dar all present (SUR-2838 case 3)" {
tmp=$(mktemp -d)
touch "$tmp/export.good" "$tmp/Export.daml"
mkdir -p "$tmp/.daml/dist"
touch "$tmp/.daml/dist/export-1.0.0.dar"
run bash -c "
source '$DAML_EXPORT' -d '$tmp' -e ffff
verifyExport '$tmp'
echo rc=\$?
"
rm -rf "$tmp"
[ "$status" -eq 0 ]
[[ "$output" == *"rc=0"* ]]
}

@test "correct_archives rewrites exerciseCmd … DA.Internal.Template.Archive to archiveCmd (SUR-2838 case 4)" {
tmp=$(mktemp -d)
cat >"$tmp/Export.daml" <<'EOF'
exerciseCmd foo DA.Internal.Template.Archive
exerciseCmd bar DA.Internal.Template.Archive
something else entirely
EOF
run bash -c "
source '$DAML_EXPORT' -d '$tmp' -e ffff
correct_archives '$tmp'
"
[ "$status" -eq 0 ]
grep -q "^archiveCmd foo$" "$tmp/Export.daml"
grep -q "^archiveCmd bar$" "$tmp/Export.daml"
grep -q "^something else entirely$" "$tmp/Export.daml"
run ! grep -q "DA.Internal.Template.Archive" "$tmp/Export.daml"
rm -rf "$tmp"
}

@test "correct_archives is idempotent on a second invocation (SUR-2838 case 4)" {
tmp=$(mktemp -d)
cat >"$tmp/Export.daml" <<'EOF'
exerciseCmd foo DA.Internal.Template.Archive
EOF
run bash -c "
source '$DAML_EXPORT' -d '$tmp' -e ffff
correct_archives '$tmp'
sum1=\$(cksum '$tmp/Export.daml')
correct_archives '$tmp'
sum2=\$(cksum '$tmp/Export.daml')
[ \"\$sum1\" = \"\$sum2\" ] && echo SAME || echo DIFFERENT
"
rm -rf "$tmp"
[ "$status" -eq 0 ]
[[ "$output" == *"SAME"* ]]
}

@test "correct_export rewrites both daml.yaml and Export.daml (SUR-2838 case 5)" {
tmp=$(mktemp -d)
cat >"$tmp/daml.yaml" <<'EOF'
sdk-version: 1.13.1
build-options: ["--target=1.14"]
EOF
cat >"$tmp/Export.daml" <<'EOF'
import qualified DA.Internal.Template
exerciseCmd foo DA.Internal.Template.Archive
EOF
run bash -c "
source '$DAML_EXPORT' -d '$tmp' -e ffff >/dev/null
correct_export '$tmp' >/dev/null
"
[ "$status" -eq 0 ]
grep -q "build-options: \[\"--target=1.12\"\]" "$tmp/daml.yaml"
run ! grep -q "import qualified DA.Internal.Template$" "$tmp/Export.daml"
grep -q "^archiveCmd foo$" "$tmp/Export.daml"
rm -rf "$tmp"
}
18 changes: 18 additions & 0 deletions tests/fixtures/bashadoc/annotations.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# shellcheck shell=bash disable=SC1091,SC2218
# SUR-2835 fixture: a function carrying `@doc` and `@arg` annotations.
# bashadoc must emit the doc text first, then an `### Arguments` block
# listing the @arg lines as a bullet list. The production script also
# translates `;` to ` ` to scrub the trailing semicolons that
# `declare -f` introduces at the end of every statement in the body.

source "$(dirname "${BASH_SOURCE[0]}")/../../../bash/includer.sh"
@include doc

@package annpkg

function annpkg::fn() {
@doc One-line description of annpkg::fn.
@arg _1_ first positional arg
@arg -o "<arg>" the -o flag
return 0
}
13 changes: 13 additions & 0 deletions tests/fixtures/bashadoc/at-package-noise.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# shellcheck shell=bash disable=SC1091,SC2218
# SUR-2835 / SUR-2829 fixture: a library that defines a function named
# `@package` (mirroring the shape of `doc.sh`). The bashadoc
# `@package`-name extraction must not pick up `function @package() {`
# as a directive — the regression that produced `{` as the resolved
# "package name" and shipped garbage markdown.

source "$(dirname "${BASH_SOURCE[0]}")/../../../bash/includer.sh"
@include doc

function @package() {
:
}
8 changes: 8 additions & 0 deletions tests/fixtures/bashadoc/no-package.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# shellcheck shell=bash
# SUR-2835 fixture: a library with no `@package` directive. bashadoc
# must fall back to using the file path as the title and list only
# bare-name functions (no `pkg::` prefix).

function bare_fn() {
return 0
}
1 change: 1 addition & 0 deletions tests/fixtures/bashadoc/not-a-shell-file.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Not a .sh file. bashadoc must refuse this with exit 1.
14 changes: 14 additions & 0 deletions tests/fixtures/bashadoc/with-package.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# shellcheck shell=bash disable=SC1091,SC2218
# SUR-2835 fixture: a library that declares `@package` and one
# namespaced function. The bashadoc header must read `# `mypkg` package`
# and the function section must list `mypkg::fn` (and only that).

source "$(dirname "${BASH_SOURCE[0]}")/../../../bash/includer.sh"
@include doc

@package mypkg

function mypkg::fn() {
@doc Does the thing.
return 0
}
Loading
Loading