Skip to content

Instantly share code, notes, and snippets.

@bgreenacre
Last active December 26, 2015 15:38
Show Gist options
  • Save bgreenacre/7173795 to your computer and use it in GitHub Desktop.
Save bgreenacre/7173795 to your computer and use it in GitHub Desktop.
This script syncs wordpress plugins and themes svn repositories to github git repositories using svn2git, git and the github api.
#!/bin/bash
##
# Name: wp-gitify
# Description: Turns the subversion repositories of wordpress
# plugins and themes into github read-only repositories.
# Author: Brian Greenacre <[email protected]>
# Requirements: git, svn, git-svn, svn2git, curl
##
# Credentials used for github api. <user>:<token>
github_credentials=""
github_org="wordpressgit"
# Maximum number of gitify jobs
max_jobs=10
# Directory where all repos are synced within
repo_dir='repos/'
mkdir -p "$repo_dir"
# Declare array to keep track of running jobs
declare -a running_jobs=()
# The urls to the top level svn repositories for plugins and themes
repos=( "http://plugins.svn.wordpress.org/" "http://themes.svn.wordpress.org/" )
# Gitify a wordpress plugin or theme from it's svn repository.
function gitify() {
this_repo="$repo_dir$2"
name=$(basename "$this_repo")
cd "$this_repo"
# Set github variables
github_repo_description="Read-only mirror of $1 using git-svn."
echo "$1" | grep -q "themes" &>/dev/null
is_theme=$?
echo "$1" | grep -q "plugins" &>/dev/null
is_plugin=$?
if [ is_plugin ]; then
github_repo_name="plugins/$name"
elif [ is_theme ]; then
github_repo_name="themes/$name"
fi
if [ ! -d ".git" ]; then
svn2git "$1" &>/dev/null
echo "Creating github repo for $name"
# Make call to github to create repo
github_api_result=$(curl -s -u "$github_credentials" \
-d "{\"name\": \"$github_repo_name\", \"description\": \"$github_repo_description\", \"has_wiki\": false, \"has_issues\": false, \"has_downloads\": true}" \
https://api.github.com/orgs/$github_org/repos)
# Find the ssh url from the api results.
ssh_url=$(echo "$github_api_result" | grep -Po '"ssh_url":.*?[^\\]",' | sed -e "s/^.\+: \"\([^\"]*\)\",\+/\1/")
if [ -n $ssh_url ]; then
# Add remote and push everything to github
git remote add origin "$ssh_url" &>/dev/null
git push origin --all &>/dev/null
git push origin --tags &>/dev/null
echo "Pushed to $github_repo_name github."
else
echo "Error creating github repo for $github_repo_name"
return 1
fi
else
git remote | grep "origin" &>/dev/null
if [ $? -eq 0 ]; then
echo "Repository exists with remote. Syncing remotes for $name."
# Repository exists and already has the github remote
# First let's make sure the first attempt and pushing
# refs to the remote finished from last time it was
# attempted.
git push origin --force --all &>/dev/null
git push origin --force --tags &>/dev/null
# Rebase from svn
svn2git "$1" --rebase &>/dev/null
# Push new refs to the remote
git push origin --all &>/dev/null
git push origin --tags &>/dev/null
else
echo "Repository exists without remote. Syncing remotes for $name."
# If there's no remote attached then the intial svn2git command
# was not completed. It's easiest to destroy and recreate it
# to avoid any corruption where using git fsck will just
# take up more time and probably not work entirely
cd ../
rm -rf "$this_repo"
mkdir -p "$this_repo"
cd "$this_repo"
svn2git "$1" &>/dev/null
echo "Creating github repo for $name"
# Make call to github to create repo
github_api_result=$(curl -s -u "$github_credentials" \
-d "{\"name\": \"$github_repo_name\", \"description\": \"$github_repo_description\", \"has_wiki\": false, \"has_issues\": false, \"has_downloads\": true}" \
https://api.github.com/orgs/$github_org/repos)
# Find the ssh url from the api results.
ssh_url=$(echo "$github_api_result" | grep -Po '"ssh_url":.*?[^\\]",' | sed -e "s/^.\+: \"\([^\"]*\)\",\+/\1/")
if [ -n $ssh_url ]; then
# Add remote and push everything to github
git remote add origin "$ssh_url" &>/dev/null
git push origin --all &>/dev/null
git push origin --tags &>/dev/null
echo "Pushed to $github_repo_name github."
else
echo "Error creating github repo for $github_repo_name"
return 1
fi
fi
fi
}
for url in $repos
do
# Get all repositories from top level url
packages=$(svn ls "$url")
# Loop through list and start the gitification
for package in $packages
do
echo "Syncing $package"
mkdir -p "$repo_dir$package"
# Gitify the svn repository
gitify "$url$package" "$package" &
# Add PID to jobs array to keep track of progress.
running_jobs=("${running_jobs[@]}" "$!")
if [ ${#running_jobs[@]} -ge $max_jobs ]; then
# While the jobs are running keep track of
# when the job ends to start the next gitification job.
while true
do
kill_loop=false
for job in $running_jobs
do
start_new_job=false
# Check the pid for the function call
kill -0 "$job" 2>/dev/null
[ $? -eq 0 ] || start_new_job=true
if $start_new_job ; then
# Remove the pid from the jobs array and break
# the while loop to start up the next gitification
# process for an svn repository
running_jobs=( ${running_jobs[@]/$job/} )
kill_loop=true
fi
done
if $kill_loop ; then
break
else
sleep 2
fi
done
fi
done
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment