Skip to content

Instantly share code, notes, and snippets.

@andrelaszlo
Last active May 18, 2017 17:27
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save andrelaszlo/2e96027b531f6b177e73bef7ab064fbf to your computer and use it in GitHub Desktop.
Save andrelaszlo/2e96027b531f6b177e73bef7ab064fbf to your computer and use it in GitHub Desktop.
Hack to fix a broken url using the GitHub API
#!/usr/bin/env bash
source token.sh # should export the ACCESS_TOKEN and USER variables
PAGE=1 # Run once per page (manually for now)
PER_PAGE=100 # Max 100
function list_repos {
echo "Listing repos" > /dev/stderr
curl -s -H "Authorization: token $ACCESS_TOKEN" "https://api.github.com/search/code?page=$PAGE&per_page=$PER_PAGE&q=http://www.eecs.harvard.edu/~kirsch/pubs/bbbf/esa06.pdf" | \
jq --raw-output '.items[]["repository"] | select(.fork == false) | .full_name' | sort -u
}
function fork {
repo=$1
echo "Forking $1"
curl -s -H "Authorization: token $ACCESS_TOKEN" -XPOST "https://api.github.com/repos/$repo/forks" >> fork.log
}
function repo_name {
repo=$1
echo "$repo" | cut -f2 -d/
}
function clone {
repo=$1
fork=$USER/$(repo_name "$repo")
github="git@github.com:${fork}.git"
mkdir -p repos
(
cd repos
for retry in $(seq 6); do
if git clone --depth=1 "$github"; then
break
fi
# There is a window after a fork where clones fail, just wait it out
echo "Clone failed, retrying in 10 seconds"
sleep 10;
done
)
}
function fix_repo {
repo=$1
(
cd repos/$(repo_name "$repo") &&
git --no-pager grep -l --full-name http://www.eecs.harvard.edu/\~kirsch/pubs/bbbf/esa06.pdf | \
while read -r f; do
sed -i "s#http://www\.eecs\.harvard\.edu/~kirsch/pubs/bbbf/esa06\.pdf#https://www.eecs.harvard.edu/~michaelm/postscripts/tr-02-05.pdf#" "$f"
done &&
git add -Av &&
git commit -m "Fix broken url to \"Building a Better Bloom Filter\"" &&
git push -f
)
}
function reset_repo {
repo=$1
path=repos/$(repo_name "$repo")
echo "Resetting $1"
(
cd "$path" &&
git reset --hard
)
}
function undo_commit {
repo=$1
path=repos/$(repo_name "$repo")
echo "Reverting to origin: $path"
(
cd "$path" &&
git reset --hard "origin/$(git rev-parse --symbolic-full-name --abbrev-ref HEAD)"
)
}
function submit_pr {
repo=$1
path=repos/$(repo_name "$repo")
(
cd "$path"
branch=$(git rev-parse --symbolic-full-name --abbrev-ref HEAD)
echo "Using branch $branch"
curl -s -H "Authorization: token $ACCESS_TOKEN" -XPOST "https://api.github.com/repos/$repo/pulls" --data-binary \
'{"title": "Fix broken url to \"Better Bloom Filter\" paper", "body": "I noticed that this link was broken so I replaced it with a link to a copy provided by the other author", "head": "'$USER':'"$branch"'", "base": "'"$branch"'"}' >> prs.log
)
echo "$repo" >> done.txt
}
function wait_for_fork {
# Fork API is async
repo=$1
repo_name=$(repo_name "$repo")
while true; do
if curl -s -H "Authorization: token $ACCESS_TOKEN" "https://api.github.com/repos/${USER}/${repo_name}" | jq --raw-output '.' | grep "$repo_name" >/dev/null ; then
echo "$repo is forked"
break
else
echo "$repo not forked yet"
sleep 3;
fi
done
}
function delete_repo {
repo=$1
repo_name=$(repo_name "$repo")
fork=${USER}/${repo_name}
curl -s -H "Authorization: token ${ACCESS_TOKEN}" -XDELETE "https://api.github.com/repos/${fork}"
(
cd repos &&
rm -rf "$repo_name"
)
}
for repo in $(list_repos); do
if grep "$repo" done.txt >/dev/null; then
echo "Already done, skipping $repo"
continue
fi
echo "Doing $repo"
fork "$repo"
wait_for_fork "$repo"
clone "$repo"
fix_repo "$repo"
submit_pr "$repo"
delete_repo "$repo"
# Used for testing:
## reset_repo "$repo"
## undo_commit "$repo"
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment