diff options
author | Zach van Rijn <me@zv.io> | 2022-05-18 22:31:30 +0000 |
---|---|---|
committer | Zach van Rijn <me@zv.io> | 2022-05-21 09:24:25 -0500 |
commit | c1e964edbfda1e07d6648521f63dd4acd5b437e4 (patch) | |
tree | 574ba9e43323c5193e8b97023bd8148d7b891942 /scripts | |
parent | 82f6ae82470ae56ca21b65bb09f368c5635f68a6 (diff) | |
download | packages-c1e964edbfda1e07d6648521f63dd4acd5b437e4.tar.gz packages-c1e964edbfda1e07d6648521f63dd4acd5b437e4.tar.bz2 packages-c1e964edbfda1e07d6648521f63dd4acd5b437e4.tar.xz packages-c1e964edbfda1e07d6648521f63dd4acd5b437e4.zip |
scripts/depsort: implement package exclusion. fixes adelie-infra/autobuilder#16.
This is included in the 'packages.git' repository because it may be
useful to temporarily prevent packages from building in development
branches. The build plan is generated from this repository instead of
autobuilder in the first place, so putting it here makes sense.
Diffstat (limited to 'scripts')
-rwxr-xr-x | scripts/depsort | 116 |
1 files changed, 115 insertions, 1 deletions
diff --git a/scripts/depsort b/scripts/depsort index 953260238..2293d9aa4 100755 --- a/scripts/depsort +++ b/scripts/depsort @@ -1,3 +1,117 @@ #!/bin/sh -e -awk '{ for (f=1;f<=NF;f++) { print $(f),$1 } }' | "$(dirname $(readlink -f ${0}))"/tsort +HERE="$(dirname $(readlink -f ${0}))"; +LIST="${HERE}/../.exclude"; + +#--------------------------------------------------------------- +# overview + +## +# Usage: +# +# $ ./scripts/deplist system | ./scripts/depsort +# +# This script reads a list of packages (stdin) of the form: +# +# pkg1 dep1 dep2 ... +# pkg2 ... +# +# and computes a topological sort, then prints to stdout. +# +# If the file called '$LIST' exists, it will be used as a filter +# to exclude those packages, their dependencies, and transitive +# dependencies as well, from the build plan. +# +# Entries must be one per line of the form REPO/PACKAGE: +# +# user/rust +# +# It is possible to end up with a surprisingly small build plan +# if a more essential package is excluded, so this mechanism +# should only be used to temporarily avoid problematic packages +# or known package families e.g. "all java-related". + + +#--------------------------------------------------------------- +# supporting routines + +## +# Appends text to the end of each line of stdin, in this case it +# is to assist 'grep' later on. +# +# We strictly search for ending in space or end of line instead +# of with the flag '-F', which is string literal, to avoid any +# partial and undesirable matches, e.g. 'foo' in 'foo3'. +# +# This is a function because it is used multiple times and may +# need to be updated in the future. +# +suffix () +{ + sed -e 's@$@\\( \\|$\\)@g'; +} + + +#--------------------------------------------------------------- +# initialization + +## +# We need to create a few temporary files in order to support +# handling transitive dependencies because it is not possible to +# reuse 'foo' as in: 'tee >( ... > foo) | bar -f foo'. +# +data=$(mktemp); # stdin +user=$(mktemp); # processed '$LIST' +real=$(mktemp); # processed derivation of dependencies + +## +# Capture stdin because it needs to be split for filtering. +# This could in theory be done later, without 'cat', but +# it is much easier for others to follow when it's here. +# +cat > "${data}"; + + +#--------------------------------------------------------------- +# preprocessing + +## +# If there is no exclusion file, passthru. +# +if test -f "${LIST}"; then + + ## + # Preprocess user input '$LIST' to include a suffix that + # works better with 'grep'. Write to file for multi-line + # support. The '!' before ' grep' is to ignore a no-match + # error that will otherwise cause the script to exit early. + # + suffix < "${LIST}" > "${user}"; + ! grep -f "${user}" "${data}" \ + | awk '{print $1}' \ + | suffix \ + | grep / `# ensure all lines of form: REPO/PACKAGE` \ + > "${real}" \ + ; + exclude="grep -vf ${real} ${data}"; +else + exclude="cat ${data}"; +fi + +#--------------------------------------------------------------- +# filtering + +## +# Enumerate digraph nodes based on (possibly) filtered input. +# +# Pipe to 'tsort' for the final build plan. +# +${exclude} \ + | awk '{ for (f=1;f<=NF;f++) { print $(f),$1 } }' \ + | "${HERE}"/tsort \ + ; + +#--------------------------------------------------------------- +# cleanup + +rm -f "${data}" "${user}" "${real}"; |