sandbox.sh 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. #!/bin/bash
  2. # Load the configuration file
  3. FILE=.sandbox-config
  4. # Create the configuration file if it does not exist
  5. if ! test -f "$FILE"; then
  6. echo "No sandbox config exists."
  7. echo "What is the sandbox user? [wpdev]"
  8. read SANDBOX_USER
  9. SANDBOX_USER="${SANDBOX_USER:-wpdev}"
  10. echo "What is the sandbox location?"
  11. read SANDBOX_LOCATION
  12. [[ -z "$SANDBOX_LOCATION" ]] && { echo "Come back when you know where your sandbox is." ; exit 1; }
  13. echo "What is the themes folder on the sandbox? [/home/$SANDBOX_USER/public_html/wp-content/themes/pub]"
  14. read SANDBOX_PUBLIC_THEMES_FOLDER
  15. SANDBOX_PUBLIC_THEMES_FOLDER="${SANDBOX_PUBLIC_THEMES_FOLDER:-/home/$SANDBOX_USER/public_html/wp-content/themes/pub}"
  16. echo "Writing $FILE"
  17. /bin/cat <<EOM >$FILE
  18. SANDBOX_USER="$SANDBOX_USER"
  19. SANDBOX_LOCATION="$SANDBOX_LOCATION"
  20. SANDBOX_PUBLIC_THEMES_FOLDER="$SANDBOX_PUBLIC_THEMES_FOLDER"
  21. EOM
  22. fi
  23. source $FILE
  24. if [[ $1 == "clean" ]]; then
  25. ssh -T $SANDBOX_USER@$SANDBOX_LOCATION << EOF
  26. cd '$SANDBOX_PUBLIC_THEMES_FOLDER';
  27. svn revert -R .;
  28. svn cleanup --remove-unversioned;
  29. svn up;
  30. EOF
  31. elif [[ $1 == "pull" ]]; then
  32. cmd="rsync -av --no-p --no-times --exclude-from='.sandbox-ignore' --exclude=$ignore_string $SANDBOX_USER@$SANDBOX_LOCATION:$SANDBOX_PUBLIC_THEMES_FOLDER/ ./ "
  33. eval $cmd
  34. elif [[ $1 == "push" ]]; then
  35. if [[ $2 != '--ignore' ]]; then
  36. git remote update
  37. fi
  38. current_branch=$(git branch --show-current)
  39. hash1=$(git rev-parse origin/trunk)
  40. hash2=$(git merge-base origin/trunk ${current_branch})
  41. files_to_ignore=''
  42. if [ ! "${hash1}" = "${hash2}" ]; then
  43. if [[ $2 != '--force' && $2 != '--ignore' ]]; then
  44. echo "!! ----------------------------------------------------------- !!
  45. The branch you are pushing is not up-to-date with /trunk.
  46. This may result in out-of-date resources on your sandbox.
  47. How do you wish to proceed?
  48. 1 - Nevermind, I'll merge/rebase my branch first.
  49. (This option is the safest.)
  50. 2 - Go ahead, I know what I'm doing. I want the old files on my sandbox.
  51. (This is a good option if you are evaluating an old branch for breakage
  52. and want to have the sandbox reflect exactly the way it was back then.)
  53. 3 - IGNORE the files changed in /trunk since this branch diverged.
  54. (This is great during development so that you don't have to keep your
  55. branch completely up-to-date with /trunk and MIGHT be safe for pushing
  56. a build. Use at your own risk.)
  57. !! ----------------------------------------------------------- !!
  58. How do you wish to proceed? [1]"
  59. read sync_type
  60. fi
  61. if [[ $sync_type = "3" || $2 = '--ignore' ]]; then
  62. echo "building ignore list based on divergence"
  63. # These are the files that were changed in trunk since this branch diverged
  64. files_to_ignore=$(git diff ${hash2} origin/trunk --name-only)
  65. files_to_ignore=($files_to_ignore)
  66. # These are the files changed in THIS branch since it diverged
  67. # EVEN IF they changed in trunk we STILL want to include them in our sync
  68. committed_files_to_include=$(git diff ${hash2} ${current_branch} --name-only)
  69. committed_files_to_include=($committed_files_to_include)
  70. # Remove from the files_to_ignore collection anything found in committed_files_to_include
  71. for target in "${committed_files_to_include[@]}"; do
  72. for i in "${!files_to_ignore[@]}"; do
  73. if [[ ${files_to_ignore[i]} = $target ]]; then
  74. unset 'files_to_ignore[i]'
  75. fi
  76. done
  77. done
  78. # These are the changes we have made but haven't committed yet
  79. # EVEN IF they changed in trunk we STILL want to include them in our sync
  80. uncommitted_files_to_include=$(git diff HEAD --name-only)
  81. uncommitted_files_to_include=($uncommitted_files_to_include)
  82. # Remove from the files_to_ignore collection anything found in the uncommitted_files_to_include
  83. for target in "${uncommitted_files_to_include[@]}"; do
  84. for i in "${!files_to_ignore[@]}"; do
  85. if [[ ${files_to_ignore[i]} = $target ]]; then
  86. unset 'files_to_ignore[i]'
  87. fi
  88. done
  89. done
  90. # Build a string based on files_to_ignore to pass to rsync
  91. ignore_string=""
  92. for target in "${files_to_ignore[@]}"; do
  93. ignore_string="${ignore_string}${target}','"
  94. done
  95. ignore_string=${ignore_string::${#ignore_string}-2}
  96. ignore_string="{'$ignore_string}"
  97. elif [[ $sync_type = "2" || $2 = '--force' ]]; then
  98. echo "syncing to sandbox exactly what you have here"
  99. else
  100. echo "Exiting. Clean yourself up and come back later."
  101. exit 0;
  102. fi
  103. fi
  104. # Determine which files have been removed from the repository (or renamed) as of this head, within the past three months, according to git
  105. files_to_delete=$(git log --format=format:"" --name-only --since="last three months" -M100% --diff-filter=D HEAD)
  106. # Determine which files have been removed locally but not committed as a change
  107. uncommitted_files_to_delete=$(git diff HEAD --name-only --diff-filter=D)
  108. # Remove all of those files from the destination. (Note, if a file has since been re-added to the repo it will be uploaded in the next step)
  109. remove_command="ssh $SANDBOX_USER@$SANDBOX_LOCATION 'cd $SANDBOX_PUBLIC_THEMES_FOLDER && rm -f $files_to_delete $uncommitted_files_to_delete'"
  110. eval $remove_command;
  111. cmd="rsync -av --no-p --no-times --exclude-from='.sandbox-ignore' --exclude=$ignore_string ./ $SANDBOX_USER@$SANDBOX_LOCATION:$SANDBOX_PUBLIC_THEMES_FOLDER/"
  112. eval $cmd
  113. else
  114. echo 'No known command given. [clean, push]'
  115. fi