Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 69 additions & 0 deletions bin/gh-prs-fix-all
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
#!/usr/bin/env bash
# gh-prs-fix-all — look at every open threatcrush-scan pull request, and fix the
# ones that are broken because of us.
#
# A real file on PATH rather than a shell function, and that is the whole point
# of it. The pit runs its aliases with `zsh -c <command>`, and `zsh -c` is a
# non-interactive shell: it does not read ~/.zshrc and it does not read
# ~/.zsh_aliases, so a function defined there is simply not there. The first
# version of this was a function and `/gh-prs-fix-all` in the pit answered
# `command not found` while the identical word worked when typed at a prompt.
# An executable works from all three — an interactive shell, `zsh -c`, and the
# pit — because none of them have to have sourced anything first.
#
# gh-prs-fix-all # fix ours, report theirs, leave theirs alone
# gh-prs-fix-all --dry-run # change nothing, just say what stands
# gh-prs-fix-all owner/name ... # only these
#
# The name says fix-all and it will not fix all, which is deliberate. Pushing
# the branch to a fork sets off whatever the upstream repo runs on push, so
# their test suite goes red against a commit that only added files under
# .github/. Those failures are reported and never touched. Failures in our own
# workflow that it does not recognise are printed rather than guessed at: a
# speculative commit pushed onto a stranger's review is worse than red, because
# red is at least honest.
set -euo pipefail

repo=${TCFEED_REPO:-$HOME/src/profullstack/threatcrush}
script="$repo/bin/tcfeed.ts"

if [ ! -f "$script" ]; then
printf 'gh-prs-fix-all: no script at %s\n' "$script" >&2
printf ' git -C %s pull # tcfeed check landed in #111\n' "$repo" >&2
printf ' TCFEED_REPO=/elsewhere # if the checkout moved\n' >&2
exit 1
fi

# Refuse a checkout that predates the subcommand, rather than handing it a word
# it does not know. tcfeed reads its first argument as a post count and falls
# back to 50 when it is not a number, so an older script answers `check` by
# fetching reddit and scanning ten strangers' repositories — a long, rate-
# limited, entirely wrong thing to do in response to "fix my pull requests".
if ! grep -q "argument === 'check'" "$script"; then
printf 'gh-prs-fix-all: %s has no `check` subcommand.\n' "$script" >&2
printf ' git -C %s pull # it is on master, this checkout is behind\n' "$repo" >&2
printf ' Without this guard the old script would read `check` as a post\n' >&2
printf ' count, fall back to 50, and go scan reddit instead.\n' >&2
exit 1
fi

# `check` without --fix reports and changes nothing; with it, it acts. Anything
# else on the command line is passed straight through, so naming repositories
# works the same as it does for tcfeed itself.
args=(check)
for arg in "$@"; do
case "$arg" in
--dry-run | -n) ;; # reporting is already the default without --fix
*) args+=("$arg") ;;
esac
done

case " $* " in
*" --dry-run "* | *" -n "*) ;;
*) args+=(--fix) ;;
esac

# Run from the repo so npx resolves tsx against its node_modules before reaching
# for the network. The script itself does not care where it is.
cd "$repo"
exec npx --yes tsx bin/tcfeed.ts "${args[@]}"
43 changes: 43 additions & 0 deletions bin/tcfeed
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#!/usr/bin/env bash
# tcfeed — read the newest posts on a subreddit, find the repositories they
# link, scan each one, and print a shortlist worth reading.
#
# tcfeed # the 50 newest posts
# tcfeed 100 # more of them
# tcfeed --forget # look at everything again next time
# tcfeed pr owner/name [--dry-run] # install the scan workflow
# tcfeed check [--fix] # how are the open requests doing
#
# An executable rather than the shell function this used to be, for the same
# reason gh-prs-fix-all is one: the moshcode pit runs its aliases with
# `zsh -c <command>`, and `zsh -c` is a non-interactive shell that reads
# neither ~/.zshrc nor ~/.zsh_aliases. A function defined there is simply not
# there, so `/alias tcfeed "tcfeed"` in the pit answered `command not found`
# while the identical word worked when typed at a prompt.
#
# Nothing should alias to this either. A function beats PATH, so a wrapper of
# the same name silently shadows this file and the two drift apart — which is
# exactly how the function version survived long enough to be confusing.
#
# Everything configurable lives in the header of the TypeScript this launches
# and is read from the environment by it, so exporting TCFEED_MIN_GAP,
# TCFEED_MAX, TCFEED_PAUSE, TCFEED_SUB, TCFEED_CACHE, TC_BIN and the rest works
# exactly as it did before.
#
# TCFEED_REPO where threatcrush is checked out, default below
set -euo pipefail

repo=${TCFEED_REPO:-$HOME/src/profullstack/threatcrush}
script="$repo/bin/tcfeed.ts"

if [ ! -f "$script" ]; then
printf 'tcfeed: no script at %s\n' "$script" >&2
printf ' git -C %s pull # it lives in the threatcrush repo\n' "$repo" >&2
printf ' TCFEED_REPO=/elsewhere # if the checkout moved\n' >&2
exit 1
fi

# Run from the repo so npx resolves tsx against its node_modules before reaching
# for the network. The script itself does not care where it is.
cd "$repo"
exec npx --yes tsx bin/tcfeed.ts "$@"