#!/bin/sh -e 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}";