#!/bin/bash
# Given a svn-url file one directory up, export the latest git commits to the specified SVN repo.
# Create a git release tag from the version specified in the plugin file.
# Author: Gustavo Bordoni (@bordoni)

set -e

cd $(dirname $0)/..

if [ ! -e svn-url ]; then
	echo "Error: Missing svn-url file" >&2
	exit 1
fi

force=
while getopts 'f' option; do
	case $option in
		f)
			force=1
			;;
	esac
done

if [ -n "$(git status -s -uno)" ] && [ -z "$force" ]; then
	git status
	echo "Error: Git state has modified or staged files. Commit or reset, or supply -f" >&2
	exit 1
fi

git_root=$(pwd)

current_branch=$(git rev-parse --abbrev-ref HEAD)
if [ $current_branch != 'master' ]; then
	git checkout master
fi

bin/generate-markdown-readme
git add readme.md
if [ -n "$(git status --porcelain readme.md)" ]; then
	echo "Please commit (--amend?) the updated readme.md"
	exit 1
fi

git pull origin master
git push origin master
svn_url=$(cat svn-url)
svn_repo_dir=/tmp/svn-$(basename $git_root)-$(md5 <<< $git_root | cut -c1-32)

for php in *.php; do
	if grep -q 'Plugin Name:' $php && grep -q 'Version:' $php; then
		plugin_version=$(cat $php | grep 'Version:' | sed 's/.*Version: *//')
	fi
done

if [ -z "$plugin_version" ]; then
	echo "Unable to find plugin version"
	exit 1
fi

if ! grep -q "$plugin_version" readme.txt; then
	echo "Please update readme.txt to include $plugin_version in changelog"
	exit 1
fi

if git show-ref --tags --quiet --verify -- "refs/tags/$plugin_version"; then
	has_tag=1
fi

if [ -n "$has_tag" ] && [ -z "$force" ]; then
	echo "Plugin version $plugin_version already tagged. Please bump version and try again, or supply -f"
	exit 1
fi

if [ -z "$has_tag" ]; then
	echo "Tagging plugin version $plugin_version"
	git tag "$plugin_version" master
	git push origin "$plugin_version"
else
	echo "Skipping plugin tag $plugin_version since already exists"
fi

if [ -e $svn_repo_dir ] && [ ! -e $svn_repo_dir/.svn ]; then
	rm -rf $svn_repo_dir
fi
if [ ! -e $svn_repo_dir ]; then
	svn checkout $svn_url $svn_repo_dir
	cd $svn_repo_dir
else
	cd $svn_repo_dir
	svn up
fi

cd $git_root

# rsync all cached files and their directories
cat <(
	git ls-files --cached --full-name $git_root \
	&
	git ls-files --cached --full-name $git_root | xargs -I {} dirname {} | sort | uniq
) | sort | rsync -avz --delete --delete-excluded --exclude='.git/' --exclude='node_modules/' --exclude='.sass-cache/' ./ $svn_repo_dir/trunk/

cd $svn_repo_dir/trunk

# move assets directory to proper location in SVN
if [ -d assets ]; then
	rsync -avz --delete ./assets/ ../assets/
	rm -r ./assets/
fi

# convert .gitignores to svn:ignore
for gitignore in $(find . -path ./.gitignore); do
	echo "Convert $gitignore to svn:global-ignores"
	svn propset svn:global-ignores -F $gitignore $(dirname $gitignore)
	svn rm --force $gitignore
done

cd $svn_repo_dir

# Delete any files from SVN that are no longer there
svn status . | grep "^\!" | sed 's/^\! *//g' | xargs svn rm

# Add everything left to commit
if [ -d assets ]; then
	svn add --force assets
fi
svn add --force trunk

# Do SVN commit
svn_commit_file=$svn_repo_dir/COMMIT_MSG
last_pushed_commit=$(svn log -l 1 | grep -E -o '^commit ([0-9a-f]{5,})' | head -n 1 | cut -c8-)

cd $git_root

git log -1 --format="Update to commit %h from $(git config --get remote.origin.url)" > $svn_commit_file
echo >> $svn_commit_file
echo 'Includes the following commit(s):' >> $svn_commit_file
echo >> $svn_commit_file

echo -n 'Obtaining last commit pushed to SVN...'
git_log_args='--pretty=short --name-status --color=never'
if [ -z "$last_pushed_commit" ]; then
	echo "none; starting from beginning"
	git log $git_log_args >> $svn_commit_file
else
	echo "$last_pushed_commit"
	git log $git_log_args $last_pushed_commit..HEAD >> $svn_commit_file
fi

cd $svn_repo_dir

svn commit -F $svn_commit_file
rm $svn_commit_file

# Restore branch
if [ $current_branch != 'master' ]; then
	git checkout $current_branch
fi
