forked from heavy-duty/stoke
feat: extract publishable changelog sections
This commit is contained in:
parent
1aa6dc26a1
commit
e3f4703e13
2 changed files with 75 additions and 2 deletions
73
scripts/changelog-section.sh
Executable file
73
scripts/changelog-section.sh
Executable file
|
|
@ -0,0 +1,73 @@
|
|||
#!/usr/bin/env bash
|
||||
# Vendored from heavy-duty/ceremony 0.6.3:
|
||||
# lib/changelog.sh (changelog_section + changelog_section_problem)
|
||||
# bin/changelog-section
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
changelog_section() {
|
||||
awk -v ver="$2" '
|
||||
/^## / { if (found) exit; found = ($2 == ver); next }
|
||||
found && !body && /^[[:space:]]*$/ { next }
|
||||
found { body = 1; print }
|
||||
' "$1"
|
||||
}
|
||||
|
||||
changelog_section_problem() {
|
||||
local file="$1" ver="$2" notes problem
|
||||
|
||||
if ! awk -v ver="$ver" '/^## / && $2 == ver { found = 1; exit } END { exit !found }' "$file"; then
|
||||
printf "no section for '%s'\n" "$ver"
|
||||
return 1
|
||||
fi
|
||||
|
||||
[ "$ver" = "Unreleased" ] && return 0
|
||||
|
||||
notes="$(changelog_section "$file" "$ver")"
|
||||
if ! printf '%s\n' "$notes" | awk '/^[[:space:]]*[-*][[:space:]]/ { found = 1; exit } END { exit !found }'; then
|
||||
printf "section '%s' has no entries — a heading is not an entry\n" "$ver"
|
||||
return 1
|
||||
fi
|
||||
|
||||
problem="$(
|
||||
printf '%s\n' "$notes" | awk '
|
||||
/^### / {
|
||||
if (heading != "" && !entry) {
|
||||
reported = 1
|
||||
print heading
|
||||
exit
|
||||
}
|
||||
heading = $0
|
||||
entry = 0
|
||||
next
|
||||
}
|
||||
heading != "" && /^[[:space:]]*[-*][[:space:]]/ { entry = 1 }
|
||||
END {
|
||||
if (!reported && heading != "" && !entry) print heading
|
||||
}
|
||||
'
|
||||
)"
|
||||
if [ -n "$problem" ]; then
|
||||
printf "section '%s' has an empty heading: '%s'\n" "$ver" "$problem"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
ver="${1:-}"
|
||||
changelog="${2:-CHANGELOG.md}"
|
||||
if [ -z "$ver" ]; then
|
||||
echo "usage: changelog-section.sh <version> [<changelog>]" >&2
|
||||
exit 2
|
||||
fi
|
||||
[ -f "$changelog" ] || {
|
||||
echo "changelog-section: no such file: $changelog" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
if ! diagnosis="$(changelog_section_problem "$changelog" "$ver")"; then
|
||||
echo "changelog-section: $changelog has no publishable section for '$ver'" >&2
|
||||
printf 'changelog-section: %s\n' "$diagnosis" >&2
|
||||
exit 1
|
||||
fi
|
||||
notes="$(changelog_section "$changelog" "$ver")"
|
||||
printf '%s\n' "$notes"
|
||||
|
|
@ -48,7 +48,7 @@ test('heading without a list entry is rejected as empty', () => {
|
|||
|
||||
assert.equal(result.status, 1);
|
||||
assert.equal(result.stdout, '');
|
||||
assert.match(result.stderr, /section for '2\.0\.0' has no changelog entries/);
|
||||
assert.match(result.stderr, /section '2\.0\.0' has no entries/);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -70,7 +70,7 @@ test('extraction stops before the next version heading', () => {
|
|||
const result = extract('2.0.0', changelog);
|
||||
|
||||
assert.equal(result.status, 0, result.stderr);
|
||||
assert.equal(result.stdout, '### Added\n\n- Current change.\n\n');
|
||||
assert.equal(result.stdout, '### Added\n\n- Current change.\n');
|
||||
assert.doesNotMatch(result.stdout, /Older change/);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue