You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

218 lines
6.5 KiB

  1. #!/usr/bin/env bash
  2. #
  3. # A script to convert the local system to use my dotfiles my local dotfiles over
  4. # the provided ones already on the system. This script will backup any of the
  5. # existing dot files, before linking to the ones in this repository.
  6. #
  7. # This script must be able to operate cleanly on an already bootstraped environment
  8. # so as to update the system cleanly to new versions of the dotfiles repository.
  9. #
  10. # Helper Functions
  11. # Make a backup of the existing file if it exists
  12. # Then link to our supplied dotfile
  13. link() {
  14. # Only make a backup if an existing file is there and is not a link
  15. if [ -f "$1/$2" ] && [ ! -L "$1/$2" ]; then
  16. cp "$1/$2" "$1/$2.old"
  17. echo "Backed up original $2 to $1/$2.old"
  18. fi
  19. ln -sf "$3" "$1/$2"
  20. }
  21. copy() {
  22. # Only make a backup if an existing directory is there and is not a link
  23. if [ -f "$1/$2" ] || [ -L "$1/$2" ]; then
  24. # Allow passing true as third param to do backups
  25. backup=true
  26. if [ ! -z "$4" ]; then
  27. backup=$4
  28. fi
  29. overwrite=false
  30. if [ ! -z "$5" ]; then
  31. overwrite=$5
  32. fi
  33. if $backup; then
  34. mv "$1/$2" "$1/$2.old"
  35. echo "Backed up original $2 to $1/$2.old"
  36. else
  37. if $overwrite; then
  38. rm -r "$1/$2"
  39. echo "removed original $2"
  40. fi
  41. fi
  42. fi
  43. # Should probably only do this is the source is newer
  44. # Remove the old and copy the new
  45. if $overwrite; then
  46. cp -r "$3" "$1/$2"
  47. fi
  48. }
  49. link_dir() {
  50. # Only make a backup if an existing directory is there and is not a link
  51. if [ -d "$1/$2" ] && [ ! -L "$1/$2" ]; then
  52. mv "$1/$2" "$1/$2.old"
  53. echo "Backed up original $2 to $1/$2.old"
  54. fi
  55. # Don't overwrite links
  56. if [ ! -L "$1/$2" ]; then
  57. echo "ln -sf $3 $1/$2"
  58. ln -sf "$3" "$1/$2"
  59. fi
  60. }
  61. copy_dir() {
  62. # Only make a backup if an existing directory is there and is not a link
  63. if [ -d "$1/$2" ] || [ -L "$1/$2" ]; then
  64. # Allow passing true as third param to do backups
  65. backup=true
  66. if [ ! -z "$3" ]; then
  67. backup=$4
  68. fi
  69. if $backup; then
  70. mv "$1/$2" "$1/$2.old"
  71. echo "Backed up original $2 to $1/$2.old"
  72. else
  73. rm -r "$1/$2"
  74. echo "removed original $2"
  75. fi
  76. fi
  77. # Should probably only do this is the source is newer
  78. # Remove the old and copy the new
  79. cp -r "$3" "$1/$2"
  80. }
  81. # Escape the path so we can use it in sed
  82. escape_path() {
  83. local safe="$(echo $1 | sed 's/\//\\\//g')"
  84. echo $safe
  85. }
  86. # Clone a git repository into a location
  87. clone_git_repo() {
  88. local target=$1
  89. local repo=$2
  90. if [ ! -d "$target" ]; then
  91. mkdir -p "$target"
  92. echo "Cloning [$repo] into [$target]"
  93. git clone "$repo" "$target"
  94. else
  95. # Update the repo otherwise
  96. echo "Updating [$repo]"
  97. cur_dir=$PWD
  98. cd "$target"
  99. git checkout .
  100. git pull
  101. cd $cur_dir
  102. fi
  103. }
  104. set -x
  105. set -e
  106. # Need to get the source for the script
  107. SOURCE="${BASH_SOURCE[0]}"
  108. while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
  109. TARGET="$(readlink "$SOURCE")"
  110. if [[ $TARGET == /* ]]; then
  111. echo "SOURCE '$SOURCE' is an absolute symlink to '$TARGET'"
  112. SOURCE="$TARGET"
  113. else
  114. DIR="$( dirname "$SOURCE" )"
  115. echo "SOURCE '$SOURCE' is a relative symlink to '$TARGET' (relative to '$DIR')"
  116. SOURCE="$DIR/$TARGET" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
  117. fi
  118. done
  119. echo "SOURCE is '$SOURCE'"
  120. RDIR="$( dirname "$SOURCE" )"
  121. DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
  122. if [ "$DIR" != "$RDIR" ]; then
  123. echo "DIR '$RDIR' resolves to '$DIR'"
  124. fi
  125. echo "DIR is '$DIR'"
  126. # Step into the directory where thes script is
  127. cd $DIR
  128. # Store the path to the root directory and the reference home directory
  129. GIT_DIR="$(echo `git rev-parse --show-toplevel`)"
  130. cd $GIT_DIR
  131. # Home directory in the git directory
  132. DOTFILES_DIR="$GIT_DIR"
  133. DOTFILES_HOME="$DOTFILES_DIR/home"
  134. # Configure .vimrc
  135. link "$HOME" ".vimrc" "$DOTFILES_HOME/.vimrc"
  136. # Download pathogen if it doesn't exist already
  137. VIM_AUTOLOAD=$HOME/.vim/autoload
  138. mkdir -p $VIM_AUTOLOAD
  139. if [ ! -f "$VIM_AUTOLOAD/pathogen.vim" ]; then
  140. curl -LSso $VIM_AUTOLOAD/pathogen.vim https://tpo.pe/pathogen.vim
  141. fi
  142. # Configure Pathogen Plugins
  143. VIM_BUNDLE=$HOME/.vim/bundle
  144. # Make the bundle directory and it's parents if they don't exist
  145. mkdir -p $VIM_BUNDLE
  146. # A list of vim plugins that are submodules
  147. plugins=($(ls -d $DOTFILES_HOME/.vim/bundle/* | tr -s ' '))
  148. #echo "${plugins[@]}"
  149. # Loop through all of the plugins and install them as links in the bundle directory
  150. for plugin in ${plugins[@]}; do
  151. parts=($(echo "$plugin" | tr '/' ' '))
  152. plugin_name=${parts[-1]}
  153. #echo "$VIM_BUNDLE $plugin_name $plugin"
  154. copy_dir $VIM_BUNDLE $plugin_name $plugin false
  155. done
  156. # Configure .gitconfig
  157. link "$HOME" ".gitconfig" "$DOTFILES_HOME/.gitconfig"
  158. # Configure .zshrc
  159. link "$HOME" ".zshrc" "$DOTFILES_HOME/.zshrc"
  160. clone_git_repo $HOME/.tmux/plugins/tpm https://github.com/tmux-plugins/tpm.git
  161. clone_git_repo $HOME/.tmux/plugins/tmux-sensible https://github.com/tmux-plugins/tmux-sensible.git
  162. clone_git_repo $HOME/.tmux/plugins/tmux-resurrect https://github.com/tmux-plugins/tmux-resurrect.git
  163. # Configure .tmux.conf
  164. link "$HOME" ".tmux.conf" "$DOTFILES_HOME/.tmux.conf"
  165. # Copy example ssh config
  166. copy "$HOME" ".ssh/config" "$DOTFILES_HOME/.ssh/config" false false
  167. cd $GIT_DIR
  168. # Create an auto updater for the dotfiles
  169. SOURCE_MD5="$(md5sum scripts/.update_dotfiles.sh | tr -s ' ' | cut -d ' ' -f 1)"
  170. WRITE_NEW_UPDATER=false
  171. # If it doesn't exist, we need to create it
  172. if [ ! -f "$HOME/.update_dotfiles.sh" ]; then
  173. WRITE_NEW_UPDATER=true
  174. else
  175. # Now we need to check if the md5's don't match
  176. CURRENT_MD5="$(cat $HOME/.update_dotfiles.sh | tail -n 1 | tr -s ' ' | cut -d ' ' -f 2)"
  177. # No hash, we need to update the file
  178. if [ -z "$CURRENT_MD5" ]; then
  179. WRITE_NEW_UPDATER=true
  180. else
  181. # need to compare the hashes, if they don't match we need to update
  182. if [ "$CURRENT_MD5" != "$SOURCE_MD5" ]; then
  183. WRITE_NEW_UPDATER=true
  184. fi
  185. fi
  186. fi
  187. if $WRITE_NEW_UPDATER; then
  188. SAFE_PATH="$(escape_path $GIT_DIR)"
  189. cat "scripts/.update_dotfiles.sh" | sed "s/@GIT_DIR@/$SAFE_PATH/" > $HOME/.update_dotfiles.sh
  190. echo "# $SOURCE_MD5" >> $HOME/.update_dotfiles.sh
  191. chmod +x $HOME/.update_dotfiles.sh
  192. fi