mirror of
https://github.com/ben-grande/qusal.git
synced 2025-05-02 14:26:21 -04:00
refactor: initial commit
This commit is contained in:
commit
5eebd789ed
591 changed files with 18598 additions and 0 deletions
41
scripts/salt-fix.sh
Executable file
41
scripts/salt-fix.sh
Executable file
|
@ -0,0 +1,41 @@
|
|||
#!/bin/sh
|
||||
|
||||
## SPDX-FileCopyrightText: 2013-2018 Will Thames will@thames.id.au
|
||||
## SPDX-FileCopyrightText: 2018 Ansible by Red Hat
|
||||
## SPDX-FileCopyrightText: 2020 - 2023 Warpnet B.V.
|
||||
## SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. <ben.grande.b@gmail.com>
|
||||
##
|
||||
## SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
## Credits: https://salt-lint.readthedocs.io/en/latest/#fix-common-issues
|
||||
|
||||
# shellcheck disable=SC2086
|
||||
set -eu
|
||||
|
||||
command -v git >/dev/null ||
|
||||
{ printf "Missing program: git\n" >&2; exit 1; }
|
||||
cd "$(git rev-parse --show-toplevel)" || exit 1
|
||||
|
||||
find_tool="find"
|
||||
if command -v fd; then
|
||||
find_tool="fd"
|
||||
elif command -v fdfind >/dev/null; then
|
||||
find_tool="fdfind"
|
||||
fi
|
||||
|
||||
case "${find_tool}" in
|
||||
fd|fdfind) files="$(${find_tool} . minion.d/ --extension=conf) $(${find_tool} . salt/ --max-depth=2 --type=f --extension=sls)";;
|
||||
find) files="$(find minion.d/ -type f -name "*.conf") $(find salt/ -maxdepth 2 -type f -name '*.sls')";;
|
||||
esac
|
||||
|
||||
## 201 - Fix trailing whitespace:
|
||||
sed -i'' -e's/[[:space:]]*$//' ${files}
|
||||
|
||||
## 206 - Fix spacing around {{ var_name }}, eg. {{env}} --> {{ env }}:
|
||||
sed -i'' -E "s/\{\{\s?([^}]*[^} ])\s?\}\}/\{\{ \1 \}\}/g" ${files}
|
||||
|
||||
## 207 - Add quotes around numeric values that start with a 0:
|
||||
sed -i'' -E "s/\b(minute|hour): (0[0-7]?)\$/\1: '\2'/" ${files}
|
||||
|
||||
## 208 - Make dir_mode, file_mode and mode arguments in the desired syntax:
|
||||
sed -i'' -E "s/\b(dir_|file_|)mode: 0?([0-7]{3})/\1mode: '0\2'/" ${files}
|
46
scripts/salt-lint.sh
Executable file
46
scripts/salt-lint.sh
Executable file
|
@ -0,0 +1,46 @@
|
|||
#!/bin/sh
|
||||
|
||||
## SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. <ben.grande.b@gmail.com>
|
||||
##
|
||||
## SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
# shellcheck disable=SC2086
|
||||
set -eu
|
||||
|
||||
command -v salt-lint >/dev/null ||
|
||||
{ printf >&2 "Missing program: salt-lint\n"; exit 1; }
|
||||
command -v git >/dev/null ||
|
||||
{ printf "Missing program: git\n" >&2; exit 1; }
|
||||
cd "$(git rev-parse --show-toplevel)" || exit 1
|
||||
|
||||
possible_conf="${PWD}/.salt-lint"
|
||||
conf=""
|
||||
test -f "${possible_conf}" && conf="-c ${possible_conf}"
|
||||
|
||||
find_tool="find"
|
||||
if command -v fd; then
|
||||
find_tool="fd"
|
||||
elif command -v fdfind >/dev/null; then
|
||||
find_tool="fdfind"
|
||||
fi
|
||||
|
||||
if test -n "${1-}"; then
|
||||
files=""
|
||||
for f in "$@"; do
|
||||
test -f "$f" || continue
|
||||
extension="$(echo "$f" | awk -F '.' '{print $NF}')"
|
||||
case "$extension" in
|
||||
top|sls) files="$files $f";;
|
||||
*) continue;;
|
||||
esac
|
||||
done
|
||||
test -n "$files" || exit 0
|
||||
exec salt-lint ${conf} ${files}
|
||||
fi
|
||||
|
||||
case "${find_tool}" in
|
||||
fd|fdfind) files="$(${find_tool} . minion.d/ --extension=conf) $(${find_tool} . salt/ --max-depth=2 --type=f --extension=sls --extension=top)";;
|
||||
find) files="$(find minion.d/ -type f -name "*.conf") $(find salt/* -maxdepth 2 -type f \( -name '*.sls' -o -name '*.top' \))";;
|
||||
esac
|
||||
|
||||
exec salt-lint ${conf} ${files}
|
19
scripts/setup.sh
Executable file
19
scripts/setup.sh
Executable file
|
@ -0,0 +1,19 @@
|
|||
#!/bin/sh
|
||||
|
||||
## SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. <ben.grande.b@gmail.com>
|
||||
##
|
||||
## SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
set -eu
|
||||
|
||||
test "$(hostname)" = "dom0" || { echo "Must be run from dom0" >&2; exit 1; }
|
||||
test "$(id -u)" = "0" || exec sudo "${0}"
|
||||
|
||||
group="qusal"
|
||||
file_roots="/srv/salt/${group}"
|
||||
|
||||
## Avoid having extra unwanted files.
|
||||
rm -rf "${file_roots}"
|
||||
cp -f minion.d/*.conf /etc/salt/minion.d/
|
||||
mkdir -p "${file_roots}"
|
||||
cp -r salt/* "${file_roots}"
|
70
scripts/shell-lint.sh
Executable file
70
scripts/shell-lint.sh
Executable file
|
@ -0,0 +1,70 @@
|
|||
#!/bin/sh
|
||||
|
||||
## SPDX-FileCopyrightText: 2018 Andreas Kusalananda <https://github.com/kusalaananda>
|
||||
## SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. <ben.grande.b@gmail.com>
|
||||
##
|
||||
## SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
## Credits: https://unix.stackexchange.com/a/483876
|
||||
|
||||
# shellcheck disable=SC2086
|
||||
set -eu
|
||||
|
||||
command -v shellcheck >/dev/null ||
|
||||
{ printf >&2 "Missing program: shellcheck\n"; exit 1; }
|
||||
command -v file >/dev/null ||
|
||||
{ printf >&2 "Missing program: file\n"; exit 1; }
|
||||
command -v git >/dev/null ||
|
||||
{ printf "Missing program: git\n" >&2; exit 1; }
|
||||
cd "$(git rev-parse --show-toplevel)" || exit 1
|
||||
|
||||
if command -v fd; then
|
||||
find_tool="fd"
|
||||
elif command -v fdfind >/dev/null; then
|
||||
find_tool="fdfind"
|
||||
fi
|
||||
|
||||
if test -n "${1-}"; then
|
||||
files=""
|
||||
sh_files=""
|
||||
for f in "$@"; do
|
||||
test -f "$f" || continue
|
||||
if test "${f##*/}" = "rc.local"; then
|
||||
sh_files="$sh_files $f"
|
||||
continue
|
||||
fi
|
||||
case $( file -bi "$f" ) in
|
||||
(*/x-shellscript*) files="$files $f";;
|
||||
esac
|
||||
done
|
||||
if test -n "$files" || test -n "$sh_files"; then
|
||||
exit 0
|
||||
fi
|
||||
test -z "$files" || shellcheck ${files}
|
||||
test -z "$sh_files" || shellcheck -s sh ${sh_files}
|
||||
exit
|
||||
fi
|
||||
|
||||
case "${find_tool}" in
|
||||
fd|fdfind)
|
||||
# shellcheck disable=2016,2215
|
||||
files="$(${find_tool} . scripts/ salt/ --hidden --exclude=zsh --type=f \
|
||||
--exec sh -c '
|
||||
case $( file -bi "$1" ) in (*/x-shellscript*)
|
||||
printf "%s\n" "$1";; esac' sh)"
|
||||
## No Shebang
|
||||
sh_files="$(${find_tool} rc.local salt/ --type=f)"
|
||||
;;
|
||||
find)
|
||||
files="$(find scripts/ salt/ -not \( -path "*/zsh" -prune \) -type f -exec sh -c '
|
||||
case $( file -bi "$1" ) in (*/x-shellscript*) exit 0;; esac
|
||||
exit 1' sh {} \; -print)"
|
||||
## No Shebang
|
||||
sh_files="$(find salt/ -type f -name "rc.local")"
|
||||
;;
|
||||
esac
|
||||
|
||||
files="$(echo "$files" | sort -u)"
|
||||
sh_files="$(echo "$sh_files" | sort -u)"
|
||||
shellcheck ${files}
|
||||
shellcheck -s sh ${sh_files}
|
67
scripts/spec-build.sh
Executable file
67
scripts/spec-build.sh
Executable file
|
@ -0,0 +1,67 @@
|
|||
#!/bin/sh
|
||||
|
||||
## SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. <ben.grande.b@gmail.com>
|
||||
##
|
||||
## SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
set -eu
|
||||
|
||||
usage(){
|
||||
printf '%s\n' "Usage: ${0##*/} PROJECT [release]" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
case "${1-}" in
|
||||
""|-*) usage;;
|
||||
esac
|
||||
|
||||
release=""
|
||||
case "${2-}" in
|
||||
release) release="1";;
|
||||
"") ;;
|
||||
*) usage;;
|
||||
esac
|
||||
|
||||
command -v dnf >/dev/null ||
|
||||
{ printf "Missing program: dnf\n" >&2; exit 1; }
|
||||
command -v rpmlint >/dev/null ||
|
||||
{ printf "Missing program: rpmlint\n" >&2; exit 1; }
|
||||
## command -v rpmdev-setuptree >/dev/null ||
|
||||
## { printf "Missing program: rpmdev-setuptree\n" >&2; exit 1; }
|
||||
command -v rpmbuild >/dev/null ||
|
||||
{ printf "Missing program: rpmbuild\n" >&2; exit 1; }
|
||||
command -v git >/dev/null ||
|
||||
{ printf "Missing program: git\n" >&2; exit 1; }
|
||||
cd "$(git rev-parse --show-toplevel)" || exit 1
|
||||
|
||||
project="${1}"
|
||||
spec_gen="./scripts/spec-gen.sh"
|
||||
spec_get="./scripts/spec-get.sh"
|
||||
group="$(${spec_get} "${project}" group)"
|
||||
spec="rpm_spec/${group}-${project}.spec"
|
||||
|
||||
"${spec_gen}" "${project}"
|
||||
rpmlint "${spec}"
|
||||
|
||||
if grep -q "^BuildRequires: " "${spec}"; then
|
||||
sudo dnf build-dep "${spec}"
|
||||
fi
|
||||
|
||||
if command -v rpmdev-setuptree >/dev/null; then
|
||||
rpmdev-setuptree
|
||||
else
|
||||
mkdir -p ~/rpmbuild/BUILD ~/rpmbuild/BUILDROOT ~/rpmbuild/RPMS
|
||||
mkdir -p ~/rpmbuild/SOURCES ~/rpmbuild/SPECS ~/rpmbuild/SRPMS
|
||||
fi
|
||||
|
||||
mkdir ~/rpmbuild/BUILD/"${group}-${project}"
|
||||
mkdir ~/rpmbuild/SOURCES/"${group}-${project}"
|
||||
|
||||
cp -r "salt/${project}"/* ~/rpmbuild/BUILD/"${group}-${project}"/
|
||||
cp -r "salt/${project}"/* ~/rpmbuild/SOURCES/"${group}-${project}"/
|
||||
|
||||
if test -n "${release}"; then
|
||||
rpmbuild -ba --sign "${spec}"
|
||||
else
|
||||
rpmbuild -ba "${spec}"
|
||||
fi
|
90
scripts/spec-gen.sh
Executable file
90
scripts/spec-gen.sh
Executable file
|
@ -0,0 +1,90 @@
|
|||
#!/bin/sh
|
||||
|
||||
## SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. <ben.grande.b@gmail.com>
|
||||
##
|
||||
## SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
set -eu
|
||||
|
||||
usage(){
|
||||
echo "Usage: ${0##*/} PROJECT [PROJECT ...]"
|
||||
}
|
||||
|
||||
# get_scriptlet scriptlet-action
|
||||
# [pre|post]-[install|upgrade], [pre|post]un-[uninstall|upgrade]
|
||||
## Get scriptlet command, else fail safe.
|
||||
get_scriptlet(){
|
||||
scriptlet="$1"
|
||||
sed -n "/^<\!-- pkg:begin:${scriptlet} -->$/,/^<\!-- pkg:end:${scriptlet} -->$/p" "${readme}" \
|
||||
| grep -v -e '^```\S*$' -e "^<\!-- " || echo "true"
|
||||
}
|
||||
|
||||
get_spec(){
|
||||
"${spec_get}" "${project}" "${1}"
|
||||
}
|
||||
|
||||
gen_spec(){
|
||||
project="${1}"
|
||||
|
||||
## Test if a standard option works without error.
|
||||
get_spec name >/dev/null
|
||||
|
||||
group="$(get_spec group)"
|
||||
template="rpm_spec/template/template.spec"
|
||||
target="rpm_spec/${group}-${project}.spec"
|
||||
|
||||
## Escape multiline strings for sed
|
||||
escaped_key(){
|
||||
echo "${1}" | sed ':a;N;$!ba;s/\n/\\n /g' | sed 's/\$/\\$/'
|
||||
}
|
||||
|
||||
readme="$(get_spec readme)"
|
||||
|
||||
pre_install="$(escaped_key "$(get_scriptlet pre-install)")"
|
||||
pre_upgrade="$(escaped_key "$(get_scriptlet pre-upgrade)")"
|
||||
post_install="$(escaped_key "$(get_scriptlet post-install)")"
|
||||
post_upgrade="$(escaped_key "$(get_scriptlet post-upgrade)")"
|
||||
preun_uninstall="$(escaped_key "$(get_scriptlet preun-uninstall)")"
|
||||
preun_upgrade="$(escaped_key "$(get_scriptlet preun-upgrade)")"
|
||||
postun_uninstall="$(escaped_key "$(get_scriptlet postun-uninstall)")"
|
||||
postun_upgrade="$(escaped_key "$(get_scriptlet postun-upgrade)")"
|
||||
|
||||
version="$(get_spec version)"
|
||||
changelog="$(get_spec changelog)"
|
||||
requires="$(get_spec requires)"
|
||||
|
||||
sed \
|
||||
-e "s/@PRE_INSTALL@/${pre_install}/" \
|
||||
-e "s/@PRE_UPGRADE@/${pre_upgrade}/" \
|
||||
-e "s/@POST_INSTALL@/${post_install}/" \
|
||||
-e "s/@POST_UPGRADE@/${post_upgrade}/" \
|
||||
-e "s/@PREUN_UNINSTALL@/${preun_uninstall}/" \
|
||||
-e "s/@PREUN_UPGRADE@/${preun_upgrade}/" \
|
||||
-e "s/@POSTUN_UNINSTALL@/${postun_uninstall}/" \
|
||||
-e "s/@POSTUN_UPGRADE@/${postun_upgrade}/" \
|
||||
-e "s/@VERSION@/${version}/" \
|
||||
-e "s/@PROJECT@/${project}/" \
|
||||
-e "/@CHANGELOG@/d" \
|
||||
"${template}" | tee "${target}" >/dev/null
|
||||
|
||||
requires_key=""
|
||||
for r in $(printf %s"${requires}" | tr " " "\n"); do
|
||||
requires_key="${requires_key}\nRequires: ${group}-${r}"
|
||||
done
|
||||
sed -i "s/@REQUIRES@/${requires_key}/" "${target}" >/dev/null
|
||||
echo "${changelog}" | tee -a "${target}" >/dev/null
|
||||
}
|
||||
|
||||
case "${1-}" in
|
||||
""|-h|--?help) usage; exit 1;;
|
||||
esac
|
||||
|
||||
command -v git >/dev/null ||
|
||||
{ printf "Missing program: git\n" >&2; exit 1; }
|
||||
cd "$(git rev-parse --show-toplevel)"
|
||||
|
||||
spec_get="./scripts/spec-get.sh"
|
||||
|
||||
for p in "$@"; do
|
||||
gen_spec "${p}"
|
||||
done
|
137
scripts/spec-get.sh
Executable file
137
scripts/spec-get.sh
Executable file
|
@ -0,0 +1,137 @@
|
|||
#!/bin/sh
|
||||
|
||||
## SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. <ben.grande.b@gmail.com>
|
||||
##
|
||||
## SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
# shellcheck disable=SC2034
|
||||
set -eu
|
||||
|
||||
usage(){
|
||||
names="$(find salt/ -maxdepth 1 -type d | cut -d "/" -f2 | tr "\n" " ")"
|
||||
echo "Usage: ${0##*/} <NAME> <KEY>"
|
||||
echo "Example: ${0##*/} qubes-builder description"
|
||||
echo "Names: ${names}"
|
||||
echo "Keys: ${keys}"
|
||||
}
|
||||
|
||||
block_max_chars(){
|
||||
char_key="${1}"
|
||||
char_value="${2}"
|
||||
less_than="${3}"
|
||||
if test "${#char_value}" -ge "${less_than}"; then
|
||||
echo "Error: ${char_key} is too long. Must be less than ${less_than} chars." >&2
|
||||
echo "Key contents: ${char_value}" >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
keys="name branch group file_roots requires vendor url version project project_dir changelog readme license_csv license description summary saltfiles"
|
||||
|
||||
case "${1-}" in
|
||||
"") usage; exit 1;;
|
||||
-h|--?help) usage; exit 0;;
|
||||
esac
|
||||
case "${2-}" in
|
||||
"") usage; exit 1;;
|
||||
esac
|
||||
|
||||
command -v reuse >/dev/null ||
|
||||
{ printf "Missing program: reuse\n" >&2; exit 1; }
|
||||
command -v git >/dev/null ||
|
||||
{ printf "Missing program: git\n" >&2; exit 1; }
|
||||
cd "$(git rev-parse --show-toplevel)" || exit 1
|
||||
|
||||
name="${1}"
|
||||
key="${2}"
|
||||
branch="$(git branch --show-current)"
|
||||
group="qusal"
|
||||
block_max_chars group "${group}" 70
|
||||
|
||||
file_roots="/srv/salt/${group}"
|
||||
vendor="Benjamin Grande"
|
||||
|
||||
url="https://github.com/ben-grande/qusal"
|
||||
version="1.0"
|
||||
|
||||
project="${group}-${name}"
|
||||
project_dir="salt/${name}"
|
||||
|
||||
if ! test -d "${project_dir}"; then
|
||||
echo "Project doesn't exist: ${project_dir}" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
readme="${project_dir}/README.md"
|
||||
if ! test -f "${readme}"; then
|
||||
echo "Project ${name} does not have README.md" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
license_csv="$(reuse --root "${project_dir}" lint |
|
||||
awk -F ':' '/^* Used licenses:/{print $2}' | tr -d " ")"
|
||||
license="$(echo "$license_csv" | sed "s/,/ AND /g")"
|
||||
#license="$(reuse --root "${project_dir}" lint |
|
||||
# awk -F ':' '/^* Used licenses:/{print $2}' | sed "s|, | AND |g")"
|
||||
|
||||
## The problem with %autochangelog is that it will print logs of all projects
|
||||
## and we separate a project per directory.
|
||||
## The disadvantage of the changelog below is that it doesn't differentiate
|
||||
## commits per package release.
|
||||
changelog="$(TZ=UTC0 git log -n 50 --format=format:"* %cd %an <%ae> - %h%n- %s%n%n" --date=format:"%a %b %d %Y" -- "${project_dir}" | sed -re "s/^- +- */- /;/^$/d")"
|
||||
|
||||
#block_max_chars license "${license}" 70
|
||||
description="$(sed -n '/^## Description/,/^## /p' "${readme}" |
|
||||
sed '1d;$d' | sed "1{/^$/d}")"
|
||||
summary="$(sed -n '3p' "${readme}")"
|
||||
block_max_chars summary "${summary}" 70
|
||||
|
||||
saltfiles="$(find "${project_dir}" -maxdepth 1 -name "*.sls")"
|
||||
# shellcheck disable=SC2086
|
||||
if test -n "${saltfiles}"; then
|
||||
requires="$(sed -n '/^include:$/,/^\s*$/p' ${saltfiles} | sed "/^\s*- \./d;/{/d" | grep "^\s*- " | cut -d "." -f1 | sort -u | sed "s/- //")"
|
||||
if grep -qrn "{%-\? from \('\|\"\)utils" ${saltfiles}; then
|
||||
if test -n "${requires}"; then
|
||||
requires="${requires} utils"
|
||||
else
|
||||
requires="utils"
|
||||
fi
|
||||
fi
|
||||
else
|
||||
requires=""
|
||||
fi
|
||||
requires_valid=""
|
||||
for r in $(printf %s"${requires}" | tr " " "\n"); do
|
||||
if ! test -d "salt/${r}"; then
|
||||
continue
|
||||
fi
|
||||
requires_valid="${requires_valid} ${r}"
|
||||
done
|
||||
requires="${requires_valid}"
|
||||
unset requires_valid
|
||||
|
||||
if test -z "${key}" || test "$(echo "${key}" | sed "s/ //g")" = ""; then
|
||||
echo "Key has no value: ${key}" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
case "${key}" in
|
||||
"") exit 1;;
|
||||
branch) echo "${branch}";;
|
||||
changelog) echo "${changelog}";;
|
||||
description) echo "${description}";;
|
||||
file_roots) echo "${file_roots}";;
|
||||
group) echo "${group}";;
|
||||
license_csv) echo "${license_csv}";;
|
||||
license) echo "${license}";;
|
||||
name) echo "${name}";;
|
||||
project) echo "${project}";;
|
||||
project_dir) echo "${project_dir}";;
|
||||
readme) echo "${readme}";;
|
||||
requires) echo "${requires}";;
|
||||
saltfiles) echo "${saltfiles}";;
|
||||
summary) echo "${summary}";;
|
||||
url) echo "${url}";;
|
||||
vendor) echo "${vendor}";;
|
||||
version) echo "${version}";;
|
||||
esac
|
42
scripts/toc-gen.sh
Executable file
42
scripts/toc-gen.sh
Executable file
|
@ -0,0 +1,42 @@
|
|||
#!/bin/sh
|
||||
|
||||
## SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. <ben.grande.b@gmail.com>
|
||||
##
|
||||
## SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
## Requires: https://github.com/mzlogin/vim-markdown-toc
|
||||
set -eu
|
||||
|
||||
usage(){
|
||||
echo "Usage: ${0##*/} <file> [file ...]"
|
||||
exit 1
|
||||
}
|
||||
|
||||
case "${1-}" in
|
||||
""|-h|--help) usage;;
|
||||
esac
|
||||
|
||||
## vim-markdown-toc deletes lines if they are folded, can't rely on its native
|
||||
## update on save.
|
||||
if ! vim -e -c 'setf markdown' -c 'if !exists(":GenTocGFM") | cq | endif' -c q
|
||||
then
|
||||
echo "Error: Vim Plugin mzlogin/vim-markdown-toc is not installed." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
for f in "$@"; do
|
||||
if ! test -f "$f"; then
|
||||
echo "Error: Not a regular file: $f" >&2
|
||||
exit 1
|
||||
fi
|
||||
if ! grep -q "^## Table of Contents$" "$f"; then
|
||||
echo "Could not find table of contents in file: $f, skipping" >&2
|
||||
continue
|
||||
fi
|
||||
## This is fragile, the table of contents should have at least one block
|
||||
## separated by an empty line before the nest heading, else it will delete
|
||||
## the rest of the file.
|
||||
vim -c 'norm zRgg' -c '/^## Table of Contents$' -c 'norm jd}k' -c ':GenTocGFM' -c 'norm ddgg' -c wq -- "${f}"
|
||||
echo "Updated TOC in file: $f"
|
||||
done
|
Loading…
Add table
Add a link
Reference in a new issue