Skip to content

run_one runs two recursive diffs over the same trees and only reads the first #129

Open

Description

@soarkit
  • Repository: pingdotgg/ts-rust
  • Target commit: 174f34ef377b7623ea48e1dacf35a8b90f5d9cee
  • File: scripts/goport/compare-emit.sh:86

Summary

run_one in scripts/goport/compare-emit.sh first runs diff -rq into diffq.txt (the file the MATCH/DIFF verdict reads) and then unconditionally runs diff -r over the same two output trees into diff.txt. diff.txt is never read by the verdict, so every project pays for a second full recursive comparison; the duplicate was left in when the quick -rq pass was added and the old detailed pass was not removed.

Affected code

scripts/goport/compare-emit.sh:

   78    rm -rf "${OUT:?}/$n"; mkdir -p "$OUT/$n"
   79    s=$(date +%s)
   80    (cd "$cwd" && timeout 1200 "$bin" -p "$cfg" --outDir "$OUT/$n/out" --pretty false $flags > "$OUT/$n/log" 2> "$OUT/$n/err"); e=$?
   81    t=$(( $(date +%s) - s ))
   82    # Guard: neither tool may write into the project. Report any new file.
   83    leaked=$(find "$cwd" -newer "$stamp" -type f -not -path '*/node_modules/*' 2>/dev/null | head -5)
   84    [ -n "$leaked" ] && echo "$n WROTE-INTO-PROJECT: $leaked"
   85    mkdir -p "$OC/$n/out" "$OUT/$n/out"
   86    diff -rq "$OC/$n/out" "$OUT/$n/out" > "$OUT/$n/diffq.txt" 2>&1
   87    diff -r "$OC/$n/out" "$OUT/$n/out" > "$OUT/$n/diff.txt" 2>&1
   88    no=$(find "$OC/$n/out" -type f | wc -l); ng=$(find "$OUT/$n/out" -type f | wc -l)
   89    nd=$(grep -c '^Files .* differ$' "$OUT/$n/diffq.txt"); nonly=$(grep -c '^Only in' "$OUT/$n/diffq.txt")
   90    if [ "$nd" -eq 0 ] && [ "$nonly" -eq 0 ] && { [ "$no" -gt 0 ] || { [ "$ng" -eq 0 ] && [ "$e" = "$(cat "$OC/$n/rc")" ] &&
   91      cmp -s "$OC/$n/log" "$OUT/$n/log"; }; }; then m=MATCH; else m=DIFF; fi
   92    echo "$n $m oracle=$no goport=$ng differ=$nd only=$nonly rc=$e oracle_rc=$(cat "$OC/$n/rc") ${t}s panics=$(grep -c panic "$OUT/$n/err") unported=$(grep -c '^unported' "$OUT/$n/err")"
   93  }
   94  export -f run_one; export OC OUT bin ORACLE
   95  printf '%s\n' "${projects[@]}" | grep -E "^($filter)" | xargs -d '\n' -P "${JOBS:-4}" -I{} bash -c 'run_one "$@"' _ {} | tee "$OUT/summary.txt"
   96  ! grep -q ' DIFF ' "$OUT/summary.txt"

Expected behavior

The emit comparator needs at most one recursive comparison of the two emitted trees per project to determine MATCH/DIFF and write the summary; the second full diff is not part of the documented output contract.

Actual behavior

In scripts/goport/compare-emit.sh:86-87, every project comparison performs two recursive diffs over the same oracle and goport output trees; only the diff -rq output is used by the verdict at line 90, so the subsequent unconditional diff -r repeats expensive comparison work beyond the required cardinality.

How to reproduce

Run compare-emit.sh on one project with a diff wrapper that logs invocations; two recursive diffs target the same directories.

Root cause

run_one in scripts/goport/compare-emit.sh first runs diff -rq into diffq.txt (the file the MATCH/DIFF verdict reads) and then unconditionally runs diff -r over the same two output trees into diff.txt. diff.txt is never read by the verdict, so every project pays for a second full recursive comparison; the duplicate was left in when the quick -rq pass was added and the old detailed pass was not removed.

Suggested fix

Remove the unconditional diff -r into diff.txt (or make it conditional on diff -rq reporting differences) so the verdict uses a single recursive comparison:

diff -rq "$OC/$p/out" "$OUT/$p/out" > "$OUT/$p/diffq.txt" || true
# drop the duplicate diff -r

Keep the detailed diff only when the quick pass found differences.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions