diff --git a/.markdownlint-cli2.yaml b/.markdownlint-cli2.yaml
index 35e5227..2782f6d 100644
--- a/.markdownlint-cli2.yaml
+++ b/.markdownlint-cli2.yaml
@@ -1,9 +1,10 @@
-# https://github.com/DavidAnson/markdownlint#rules--aliases
+# https://github.com/DavidAnson/markdownlint/blob/HEAD/doc/Rules.md
config:
- line-length: false
- no-duplicate-heading: false
- no-inline-html: false
- no-emphasis-as-heading: false
+ line-length: false # MD013
+ no-duplicate-heading: false # MD024
+ no-blanks-blockquote: false # MD028
+ no-inline-html: false # MD033
+ no-emphasis-as-heading: false # MD036
# https://github.com/DavidAnson/markdownlint-cli2#markdownlint-cli2jsonc
noBanner: true
diff --git a/tools/tidy.sh b/tools/tidy.sh
index aabf7b8..c7ba387 100755
--- a/tools/tidy.sh
+++ b/tools/tidy.sh
@@ -181,13 +181,26 @@ esac
check_install git
exclude_from_ls_files=()
+# - `find` lists symlinks. `! ( -name
-prune )` (.i.e., ignore ) are manually listed from .gitignore.
+# - `git submodule status` lists submodules. Use sed to remove the first character indicates status ( |+|-).
+# - `git ls-files --deleted` lists removed files.
while IFS=$'\n' read -r line; do exclude_from_ls_files+=("${line}"); done < <({
find . \! \( -name .git -prune \) \! \( -name target -prune \) \! \( -name .venv -prune \) \! \( -name tmp -prune \) -type l | cut -c3-
git submodule status | sed 's/^.//' | cut -d' ' -f2
git ls-files --deleted
} | LC_ALL=C sort -u)
+exclude_from_ls_files_no_symlink=()
+while IFS=$'\n' read -r line; do exclude_from_ls_files_no_symlink+=("${line}"); done < <({
+ git submodule status | sed 's/^.//' | cut -d' ' -f2
+ git ls-files --deleted
+} | LC_ALL=C sort -u)
ls_files() {
- comm -23 <(git ls-files "$@" | LC_ALL=C sort) <(printf '%s\n' ${exclude_from_ls_files[@]+"${exclude_from_ls_files[@]}"})
+ if [[ "${1:-}" == "--include-symlink" ]]; then
+ shift
+ comm -23 <(git ls-files "$@" | LC_ALL=C sort) <(printf '%s\n' ${exclude_from_ls_files_no_symlink[@]+"${exclude_from_ls_files_no_symlink[@]}"})
+ else
+ comm -23 <(git ls-files "$@" | LC_ALL=C sort) <(printf '%s\n' ${exclude_from_ls_files[@]+"${exclude_from_ls_files[@]}"})
+ fi
}
# Rust (if exists)
@@ -253,6 +266,7 @@ if [[ -n "$(ls_files '*.rs')" ]]; then
fi
exclude=''
has_public_crate=''
+ has_root_crate=''
for pkg in $(jq -c '. as $metadata | .workspace_members[] as $id | $metadata.packages[] | select(.id == $id)' <<<"${metadata}"); do
eval "$(jq -r '@sh "publish=\(.publish) manifest_path=\(.manifest_path)"' <<<"${pkg}")"
if [[ "$(tomlq -c '.lints' "${manifest_path}")" == "null" ]]; then
@@ -264,6 +278,7 @@ if [[ -n "$(ls_files '*.rs')" ]]; then
fi
has_public_crate=1
if [[ "${manifest_path}" == "${root_manifest}" ]]; then
+ has_root_crate=1
exclude=$(tomlq -r '.package.exclude[]' "${manifest_path}")
if ! grep -Eq '^/\.\*$' <<<"${exclude}"; then
error "top-level Cargo.toml of non-virtual workspace should have 'exclude' field with \"/.*\""
@@ -278,7 +293,7 @@ if [[ -n "$(ls_files '*.rs')" ]]; then
done
if [[ -n "${has_public_crate}" ]]; then
info "checking public crates don't contain executables and binaries"
- for p in $(ls_files); do
+ for p in $(ls_files --include-symlink); do
# Skip directories.
if [[ -d "${p}" ]]; then
continue
@@ -287,11 +302,18 @@ if [[ -n "$(ls_files '*.rs')" ]]; then
# TODO: fully respect exclude field in Cargo.toml.
case "${p}" in
.* | tools/* | target-specs/*) continue ;;
+ */*) ;;
+ *)
+ # If there is no crate at root, executables at the repository root directory if always okay.
+ if [[ -z "${has_root_crate}" ]]; then
+ continue
+ fi
+ ;;
esac
if [[ -x "${p}" ]]; then
executables+="${p}"$'\n'
fi
- # Use diff instead of file because file treats an empty file as a binary
+ # Use `diff` instead of `file` because `file` treats an empty file as a binary.
# https://unix.stackexchange.com/questions/275516/is-there-a-convenient-way-to-classify-files-as-binary-or-text#answer-402870
if { diff .gitattributes "${p}" || true; } | grep -Eq '^Binary file'; then
binaries+="${p}"$'\n'
@@ -392,7 +414,7 @@ if [[ -n "$(ls_files '*.md')" ]]; then
elif check_install npm; then
info "running \`npx -y markdownlint-cli2 \$(git ls-files '*.md')\`"
if ! npx -y markdownlint-cli2 $(ls_files '*.md'); then
- should_fail=1
+ error "check failed; please resolve the above markdownlint error(s)"
fi
fi
elif [[ -e .markdownlint-cli2.yaml ]]; then
@@ -529,7 +551,7 @@ if check_install shfmt; then
check_config .editorconfig
info "running \`shfmt -l -w \$(git ls-files '*.sh')\`"
if ! shfmt -l -w "${shell_files[@]}"; then
- should_fail=1
+ error "check failed; please resolve the shfmt error(s)"
fi
check_diff "${shell_files[@]}"
fi
@@ -539,14 +561,14 @@ elif check_install shellcheck; then
check_config .shellcheckrc
info "running \`shellcheck \$(git ls-files '*.sh')\`"
if ! shellcheck "${shell_files[@]}"; then
- should_fail=1
+ error "check failed; please resolve the above shellcheck error(s)"
fi
if [[ ${#docker_files[@]} -gt 0 ]]; then
# SC2154 doesn't seem to work on dockerfile.
# SC2250 may not correct on dockerfile because $v and ${v} is sometime different: https://github.com/moby/moby/issues/42863
info "running \`shellcheck --shell bash --exclude SC2154,SC2250 \$(git ls-files '*Dockerfile*')\`"
if ! shellcheck --shell bash --exclude SC2154,SC2250 "${docker_files[@]}"; then
- should_fail=1
+ error "check failed; please resolve the above shellcheck error(s)"
fi
fi
# Check scripts in other files.
@@ -588,7 +610,7 @@ EOF
color=always
fi
if ! shellcheck --color="${color}" --exclude SC2086,SC2096,SC2129 <(printf '%s\n' "${text}") | sed "s/\/dev\/fd\/[0-9][0-9]*/$(sed_rhs_escape "${display_path}")/g"; then
- should_fail=1
+ error "check failed; please resolve the above shellcheck error(s)"
fi
}
for workflow_path in ${workflows[@]+"${workflows[@]}"}; do
@@ -728,7 +750,11 @@ if [[ -f .cspell.json ]]; then
if [[ "${manifest_path}" != "Cargo.toml" ]] && [[ "$(tomlq -c '.workspace' "${manifest_path}")" == "null" ]]; then
continue
fi
- dependencies+="$(cargo metadata --format-version=1 --no-deps --manifest-path "${manifest_path}" | jq -r '. as $metadata | .workspace_members[] as $id | $metadata.packages[] | select(.id == $id) | .dependencies[].name')"$'\n'
+ m=$(cargo metadata --format-version=1 --no-deps --manifest-path "${manifest_path}" || true)
+ if [[ -z "${m}" ]]; then
+ continue # Ignore broken manifest
+ fi
+ dependencies+="$(jq -r '. as $metadata | .workspace_members[] as $id | $metadata.packages[] | select(.id == $id) | .dependencies[].name' <<<"${m}")"$'\n'
done
dependencies=$(LC_ALL=C sort -f -u <<<"${dependencies//[0-9_-]/$'\n'}")
fi