#!/bin/sh # Fails if `proto` depends on any workspace crate, or if any other crate depends on # a workspace crate other than `proto`. Every manifest section whose name contains # "dependencies" (including [dev-dependencies] and [build-dependencies]) is # inspected. A dependency name can appear as a plain key (`x = "1"`), a dotted key # (`x.workspace = true` or `x.path = ".."`) or a table header (`[dependencies.x]`); # the lines inside a table-form dependency are settings of that dependency, not # further dependencies. ROOT="${1:-.}" status=0 # Fail closed: there is nothing to check without a crates directory. if [ ! -d "$ROOT/crates" ]; then echo "check-crate-deps: $ROOT/crates is not a directory" >&2 exit 1 fi # 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 for crate in "$ROOT"/crates/*/; do [ -d "$crate" ] || continue crate_name=$(basename "$crate") [ -f "$crate/Cargo.toml" ] || continue # Emit one dependency name per line, from plain/dotted keys and table headers. keys=$(awk ' BEGIN { in_deps = 0; in_table = 0; depth = 0 } /^[ \t]*\[/ { hdr = $0 sub(/^[ \t]*\[/, "", hdr) sub(/[ \t]*\][ \t]*.*$/, "", hdr) if (hdr ~ /dependencies/) { n = split(hdr, parts, ".") if (parts[n] ~ /dependencies$/) { in_deps = 1; in_table = 0 } else { in_deps = 1; in_table = 1; print parts[n] } } else { in_deps = 0; in_table = 0 } depth = 0 next } in_table { next } in_deps { if (depth == 0) { t = $0 sub(/^[ \t]+/, "", t) if (match(t, /^[A-Za-z0-9][A-Za-z0-9_-]*(\.[A-Za-z0-9_-]+)*[ \t]*=/)) { name = t sub(/[ \t]*=.*/, "", name) sub(/\..*/, "", name) print name } } 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") for key in $keys; do hit=0 for w in $workspace; do if [ "$key" = "$w" ]; then hit=1; break; fi done if [ "$hit" -eq 1 ]; then if [ "$crate_name" = "proto" ]; then echo "check-crate-deps: $crate_name depends on workspace crate $key" >&2 status=1 elif [ "$key" != "proto" ]; then echo "check-crate-deps: $crate_name depends on workspace crate $key" >&2 status=1 fi fi done done exit $status