modfiles.sh 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. #!/usr/bin/env bash
  2. set -euo pipefail
  3. # modfiles.sh: snapshot or restore the set of dirty go.mod / go.sum files.
  4. #
  5. # Used by the `test` Makefile target to undo the cross-submodule churn that
  6. # `go work sync` introduces. The snapshot subcommand records which go.mod /
  7. # go.sum files were ALREADY modified before the test run; the restore
  8. # subcommand reverts any go.mod / go.sum files that became dirty during the
  9. # run but were not in the snapshot, leaving the developer's intentional
  10. # changes alone.
  11. #
  12. # Usage:
  13. # hack/modfiles.sh snapshot <snapshot-file>
  14. # hack/modfiles.sh restore <snapshot-file>
  15. #
  16. # Both subcommands are no-ops when run outside a git checkout.
  17. cmd="${1:-}"
  18. snap="${2:-}"
  19. if [[ -z "$cmd" || -z "$snap" ]]; then
  20. echo "Usage: $0 {snapshot|restore} <snapshot-file>" >&2
  21. exit 2
  22. fi
  23. # Print every dirty path (including renames and untracked) whose basename is
  24. # go.mod or go.sum, one per line, sorted and unique. Tolerates non-git
  25. # checkouts by swallowing git's error and emitting nothing.
  26. list_dirty_modfiles() {
  27. { git status --porcelain 2>/dev/null || true; } \
  28. | awk '{print $NF}' \
  29. | awk '$0 ~ /(^|\/)(go\.mod|go\.sum)$/' \
  30. | sort -u
  31. }
  32. case "$cmd" in
  33. snapshot)
  34. list_dirty_modfiles > "$snap"
  35. ;;
  36. restore)
  37. [[ -f "$snap" ]] || exit 0
  38. post=$(list_dirty_modfiles)
  39. if [[ -n "$post" ]]; then
  40. to_restore=$(printf '%s\n' "$post" | grep -Fxvf "$snap" || true)
  41. if [[ -n "$to_restore" ]]; then
  42. printf '%s\n' "$to_restore" | xargs git checkout --
  43. fi
  44. fi
  45. rm -f "$snap"
  46. ;;
  47. *)
  48. echo "Unknown command: $cmd" >&2
  49. exit 2
  50. ;;
  51. esac