Skip to content

Instantly share code, notes, and snippets.

@mcsf
Last active July 30, 2023 11:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mcsf/58a563b4065c0a20e118c950e1f22d9c to your computer and use it in GitHub Desktop.
Save mcsf/58a563b4065c0a20e118c950e1f22d9c to your computer and use it in GitHub Desktop.
Find circular dependencies in Gutenberg packages
#!/bin/sh
# Alternative implementation with JQ instead of AWK
find packages -depth 2 -name 'package.json' -print0 \
| xargs -0 jq -r '
.dependencies // {}
| keys[]
| select(contains("@wordpress/"))
| sub("@wordpress/"; "")
| [
(input_filename
| sub("packages/"; "")
| sub("/package.json"; "")),
. ]
| join("\t")' \
| tsort 2>&1 >/dev/null
# Using JQ is more correct, but AWK was so much quicker and more pleasant to
# use, not to mention universal. It's almost like cheating.
BEGIN {
FS = "\""
}
$2 ~ "^@wordpress/" {
print strip(FILENAME), strip($2)
}
function strip(s) {
sub("packages/", "", s)
sub("/package.json", "", s)
sub("@wordpress/", "", s)
return s
}
#!/bin/sh
# Run all our package.json files through deps.awk, which extracts their
# @wordpress-namespaced dependencies and produces a graph where each line is an
# edge from a package to its dependency. For example:
#
# annotations data
# annotations hooks
# annotations i18n
# annotations rich-text
#
# Then feed this to tsort. Since we only care about spotting cycles, we ignore
# its stdout and only grab its stderr.
find packages -depth 2 -name 'package.json' -print0 \
| xargs -0 awk -f deps.awk \
| tsort 2>&1 >/dev/null
# For example, adding `block-editor` as a dependency of `components` results in
# tsort reporting two cycles as follows:
#
# tsort: cycle in data
# tsort: components
# tsort: block-editor
# tsort: preferences
# tsort: cycle in data
# tsort: block-editor
# tsort: components
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment