#!/bin/sh # Fails if a key in [workspace.dependencies] of ROOT/Cargo.toml that is not a # workspace crate has no table row starting `| `name` |` in ROOT/docs/dependencies.md. # Also fails if any dependency line in any ROOT/crates/*/Cargo.toml lacks # `workspace = true`. ROOT="${1:-.}" status=0 # Workspace crate names: directories under ROOT/crates that contain a Cargo.toml. workspace="" for d in "$ROOT"/crates/*/; do [ -d "$d" ] || continue [ -f "$d/Cargo.toml" ] || continue workspace="$workspace $(basename "$d")" done root_toml="$ROOT/Cargo.toml" docs="$ROOT/docs/dependencies.md" # Extract dependency keys from every [dependencies*]-ish section. dep_keys=$(awk ' BEGIN { in_deps = 0; depth = 0 } /^\[/ { sec = $0 sub(/^\[[ \t]*/, "", sec) sub(/[ \t]*\][ \t]*.*$/, "", sec) in_deps = (sec ~ /dependencies/) depth = 0 next } in_deps { if (depth == 0) { t = $0 sub(/^[ \t]+/, "", t) if (t ~ /^[A-Za-z0-9][A-Za-z0-9_-]*(\.workspace)?[ \t]*=/) { if (match(t, /[A-Za-z0-9][A-Za-z0-9_-]*/)) { k = substr(t, RSTART, RLENGTH) if (RSTART == 1) print k } } } s = $0 while (match(s, /[{}]/)) { c = substr(s, RSTART, 1) if (c == "{") depth++ else if (depth > 0) depth-- s = substr(s, RSTART + 1) } } ' "$root_toml" 2>/dev/null) # Part 1: non-workspace-crate workspace dependencies must have a docs table row. for key in $dep_keys; do hit=0 for w in $workspace; do if [ "$key" = "$w" ]; then hit=1; break; fi done if [ "$hit" -eq 0 ]; then if ! awk -v k="$key" 'index($0, "| `" k "` |") == 1 { found = 1; exit } END { exit !found }' "$docs" 2>/dev/null; then echo "check-dep-docs: $key has no row in $docs" >&2 status=1 fi fi done # Part 2: every dependency line in a crate manifest must contain `workspace = true`. for crate in "$ROOT"/crates/*/; do [ -d "$crate" ] || continue crate_name=$(basename "$crate") [ -f "$crate/Cargo.toml" ] || continue bad=$(awk ' BEGIN { in_deps = 0; depth = 0 } /^\[/ { sec = $0 sub(/^\[[ \t]*/, "", sec) sub(/[ \t]*\][ \t]*.*$/, "", sec) in_deps = (sec ~ /dependencies/) depth = 0 next } in_deps { if (depth == 0) { t = $0 sub(/^[ \t]+/, "", t) if (t ~ /^[A-Za-z0-9][A-Za-z0-9_-]*(\.workspace)?[ \t]*=/) { print $0 } } s = $0 while (match(s, /[{}]/)) { c = substr(s, RSTART, 1) if (c == "{") depth++ else if (depth > 0) depth-- s = substr(s, RSTART + 1) } } ' "$crate/Cargo.toml" 2>/dev/null | grep -v 'workspace = true') if [ -n "$bad" ]; then echo "$bad" | while read -r line; do [ -n "$line" ] && echo "check-dep-docs: $crate_name declares a dependency without workspace = true: $line" >&2 done status=1 fi done exit $status