diff -uNr a/vtools/Makefile b/vtools/Makefile --- a/vtools/Makefile 85500ed7a489bcd8d604fd29696a630d9b43a7422bb23f393c77c5029f34a729316a0a19e5bd4ec591e06f4b9fb170e119739e3d6ac8f20bf11c613c5c7c116b +++ b/vtools/Makefile 67cefb8f1983138b975a6ec3402c6718e3fa8855201d2c41f4f4cd68284a21fc853cc56ce1d03b61a1d93df3ddcde48979b1a7ede00d077e31f39bd647daf1ed @@ -5,6 +5,10 @@ vpatch: gprbuild -Pvpatch.gpr +vflow: + gprbuild -Pvflow.gpr + clean: gprclean -Pvdiff.gpr gprclean -Pvpatch.gpr + gprclean -Pvflow.gpr diff -uNr a/vtools/manifest b/vtools/manifest --- a/vtools/manifest 35a57f6c4eaad4c3084874e6f97aceba39d8b54879b41a1498988fc45015bc618e72400887accc694e164f9704ecb33a8db29c6d135ea9880ec1345402eafda9 +++ b/vtools/manifest 47bb2feba0952de6c08f9f9c644500bf867571c2c5058c70475811c6de72fa3f8297ca90155e12da32901569d9da2d8e4d084635e72cc85c0902f1aaf7753929 @@ -16,3 +16,4 @@ 617378 bvt vtools_vsh_utils_one_binary Merge all v.sh Ada utilities into one. 617638 bvt vtools_vsh_ada_vfilter Add an implementation of vfilter in Ada. 619714 bvt vtools_vsh_shellcheck A round of shellcheck on the v.sh source. +620790 bvt vtools_ascii_visualization Add "vtree" command, work towards pipeable output. diff -uNr a/vtools/src/vflow.adb b/vtools/src/vflow.adb --- a/vtools/src/vflow.adb 400069490b8212c36d75f27a9935f5017ad6bdb49c9f520293082a4dcc4a1e902fe3733cf34c4356c8a0c315905b8534236ad9b1557a32ec501742693f644514 +++ b/vtools/src/vflow.adb e6faf838d6886b05028f7483b7ff738584217d570a2a894fbe91380614a576f25952120f7fa5c1dff3bd6b16e53364cb5859ed2407412ab121c1c76d0826044c @@ -366,6 +366,8 @@ for I in Vpatch_Order'Range loop if Selected_Vpatches(Vpatch_Order(I)) then Put_Line("P " & Integer'Image(Vpatch_Order(I))); + else + Put_Line("p " & Integer'Image(Vpatch_Order(I))); end if; end loop; end Print_Flow_Or_Conflicts; diff -uNr a/vtools/v.sh b/vtools/v.sh --- a/vtools/v.sh 535fd4d5c7268d52140490ddb24d4ada36a3269b5d285c98da2db542b6c0fe52a844e6c273fcb1ee9d6c45c04e2fdb82e48285e4e970485da5daa86c6c578e8e +++ b/vtools/v.sh ba8feba74997e15453711dd8c414240605d87674dabd3feac0fdba6a97cb2beefbf0ef03b28b02d4b1d9ae251c58c9400b02f6359c1a3d76ad351e31c6f4caae @@ -2,6 +2,8 @@ set -e +allkeyword="all" + vgpgdir="" vpatches="" filtered="" @@ -18,13 +20,14 @@ v descendants patch -- list patch descendants v origin hash -- find patch that introduced the hash v press directory leaves -- press all patches up to head +v vtree leaves -- print the vtree structure for a press EOF exit 0 } checkdir() { if [ ! -d "$1" ]; then - echo "$1 directory not found" + >&2 echo "$1 directory not found" kill -TERM 0 fi } @@ -47,13 +50,20 @@ if [ ! -z "$vgpgdir" ]; then rm -rf "$vgpgdir" fi - exit 0 + exit "$1" +} +exit_success() { + cleanup 0 } -trap cleanup TERM INT + +fail() { + cleanup 1 +} +trap fail TERM INT exit_msg() { - echo "$1" - cleanup + >&2 echo "$1" + cleanup 1 } verify() { @@ -105,7 +115,8 @@ vpatchnos() { awk -v VF="$vpatches" ' -FILENAME==VF {a[$1]=$2} FILENAME=="-" {print a[$1]}' "$vpatches" - +FILENAME==VF {a[$1]=$2} +FILENAME=="-" {if (!($1 in a)) {print "not found:",$1} else {print a[$1]}}' "$vpatches" - } vpatchnames() { @@ -114,12 +125,15 @@ } vpatchflow() { - [ -z "$*" ] && exit_msg "No leaves selected." filterall | internall >"$filtered" - if [ "$*" = "-" ]; then + if [ "$*" = "$allkeyword" ] || [ -z "$*" ]; then echo "S" >"$selfile" else - echo $* | tr ' ' '\n' | vpatchnos | sed -e 's/^/s /g' - >"$selfile" + echo $* | tr ' ' '\n' | vpatchnos >"$selfile" + if >&2 grep "not found:" "$selfile"; then + fail + fi + sed -i -e 's/^/s /g' "$selfile" fi cat "$filtered" "$selfile" | \ vflow $(wc -l <"$filtered") $(wc -l <"$vpatches") >"$topo" @@ -133,17 +147,17 @@ END {if (err != 0) exit err; if (ok != 1) exit 3; exit 0;}' <"$topo" exitcode="$?" if [ "$exitcode" -eq "1" ]; then - printf "\nConflicting leaves selected:\n" - awk '$1 == "C" {print $2}' < "$topo" | vpatchnames | sort | uniq - cleanup + >&2 printf "\nConflicting leaves selected:\n" + >&2 awk '$1 == "C" {print $2}' < "$topo" | vpatchnames | sort | uniq + fail elif [ "$exitcode" -eq "2" ]; then - printf "\nConflicting leaves selected:\n" - awk '{print $2}' < "$topo" | vpatchnames - cleanup + >&2 printf "\nConflicting leaves selected:\n" + >&2 awk '{print $2}' < "$topo" | vpatchnames + fail elif [ "$exitcode" -eq "3" ]; then - echo "Unknown error. Investigate in $vgpgdir:" - cat "$topo" - exit 0 # no cleanup + >&2 echo "Unknown error. Investigate in $vgpgdir:" + >&2 cat "$topo" + exit 1 # no cleanup fi } @@ -153,14 +167,14 @@ if [ "$1" = "wot" ]; then gpg --homedir "$vgpgdir" --logger-fd 1 --batch --keyid-format=long -k - cleanup + exit_success fi verifyall if [ "$1" = "patches" ]; then cat "$vgpgdir"/signers.txt - cleanup + exit_success fi if [ "$1" = "graph" ]; then @@ -170,7 +184,7 @@ svgfile="$1" shift - vpatchflow - + vpatchflow cat >"$dotfile" <> "$dotfile" dot -Tsvg "$dotfile" -o "$svgfile" # dot -Tcmapx $dotfile -o $svgfile.html-map - cleanup + exit_success fi if [ "$1" = "antecedents" ]; then @@ -190,13 +204,14 @@ vpatch="$1" shift - vpatchflow - + vpatchflow vno=$(awk -v V="$vpatch" '$1==V {print $2}' < "$vpatches") + [ -z "$vno" ] && exit_msg "not found: $vpatch" awk -v N="$vno" ' ($1 == "I" || $1 == "d" ) && $2 == N {a[$3]=1} ($1 == "P") {if ($2 in a) {print $2}} ' "$topo" | vpatchnames - cleanup + exit_success fi if [ "$1" = "descendants" ]; then @@ -204,13 +219,14 @@ vpatch="$1" shift - vpatchflow - + vpatchflow vno=$(awk -v V="$vpatch" '$1==V {print $2}' < "$vpatches") + [ -z "$vno" ] && exit_msg "not found: $vpatch" awk -v N="$vno" ' ($1 == "I" || $1 == "d" ) && $3 == N {a[$2]=1} ($1 == "P") {if ($2 in a) {print $2}} ' "$topo" | vpatchnames - cleanup + exit_success fi if [ "$1" = "origin" ]; then @@ -220,24 +236,24 @@ filterall >"$filtered" awk -v hash="$hash" '$5 == hash {print $1}' <"$filtered" | vpatchnames - cleanup + exit_success fi; if [ "$1" = "flow" ]; then shift vpatchflow $* + vpatchflowerr - echo "Press order:" awk '$1 == "P" {print $2}' < "$topo" | vpatchnames - vpatchflowerr - cleanup + exit_success fi if [ "$1" = "press" ]; then shift dir="$1" + [ -z "$dir" ] && exit_msg "Provide press directory" shift [ -d "$dir" ] && exit_msg "Directory $dir already exists" @@ -249,12 +265,28 @@ awk '$1 == "P" {print $2}' < "$topo" | vpatchnames | while read i; do i=$(readlink -f "$i") cd "$dir" - vpatch <"$i" >/dev/null + vpatch <"$i" cd - >/dev/null done - cleanup + exit_success +fi + +if [ "$1" = "vtree" ]; then + shift + + vpatchflow "$@" + awk -v VF="$vpatches" ' +function repeat(s,n) {i=0; while (i++ < n) {printf("%s",s);}} +FILENAME==VF {n[$2]=$1} +FILENAME=="-" && ($1 == "I" || $1 == "d" ) {a[$2]++;b[$3]=1;} +FILENAME=="-" && ($1 == "P" || $1 == "p") { + if (!($2 in a)) {a[$2]=0}; + repeat(" ", a[$2]); + printf("%s%s%s\n",n[$2], ($2 in b) ? "" : " (*)", ($1 == "P") ? " +" : "" ); +}' "$vpatches" - <"$topo" + exit_success fi -echo "Unknown command: $1" -cleanup +>&2 echo "Unknown command: $1" +fail