Public part of my dotfiles.
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.

166 lines
4.8 KiB

  1. #!/usr/bin/env bash
  2. # Handles dotfiles
  3. # Yes there are tons of similar scipts yet I wanted no more nor less than what I needed
  4. # (sourceable)
  5. # Config
  6. if [ -z "$DOTHOME" ]; then
  7. DOTHOME="$HOME"
  8. fi
  9. if [ -z "$DOTREPO" ]; then
  10. DOTREPO="$HOME/.dotfiles"
  11. fi
  12. # Common functions
  13. # From http://stackoverflow.com/a/12498485
  14. function relativePath {
  15. # both $1 and $2 are absolute paths beginning with /
  16. # returns relative path to $2/$target from $1/$source
  17. source=$1
  18. target=$2
  19. common_part=$source # for now
  20. result="" # for now
  21. while [[ "${target#$common_part}" == "${target}" ]]; do
  22. # no match, means that candidate common part is not correct
  23. # go up one level (reduce common part)
  24. common_part="$(dirname $common_part)"
  25. # and record that we went back, with correct / handling
  26. if [[ -z $result ]]; then
  27. result=".."
  28. else
  29. result="../$result"
  30. fi
  31. done
  32. if [[ $common_part == "/" ]]; then
  33. # special case for root (no common path)
  34. result="$result/"
  35. fi
  36. # since we now have identified the common part,
  37. # compute the non-common part
  38. forward_part="${target#$common_part}"
  39. # and now stick all parts together
  40. if [[ -n $result ]] && [[ -n $forward_part ]]; then
  41. result="$result$forward_part"
  42. elif [[ -n $forward_part ]]; then
  43. # extra slash removal
  44. # result="${forward_part:1}" # Removes the . in the beginning...
  45. result="${forward_part#/}"
  46. fi
  47. echo "$result"
  48. }
  49. # Script common functions
  50. function _dotfiles-install-dir { # dir
  51. local dir
  52. local absSource
  53. local absTarget
  54. local relTarget
  55. dir="${1%/}"
  56. dir="${dir#/}"
  57. /bin/ls -A "$DOTREPO/$dir" | while read file; do
  58. if [[ -z "$dir" && $(echo $file | grep '^\(\.\|LICENSE\|README\)') ]]; then
  59. continue
  60. fi
  61. if [[ $(echo $file | grep '^.dfrecur$') ]]; then
  62. continue
  63. fi
  64. if [ -z "$dir" ]; then
  65. absSource="$DOTHOME/.$file"
  66. absTarget="$DOTREPO/$file"
  67. else
  68. absSource="$DOTHOME/.$dir/$file"
  69. absTarget="$DOTREPO/$dir/$file"
  70. fi
  71. relTarget="$(relativePath "$DOTHOME/$dir" "$absTarget")"
  72. recurIndicator="$absTarget/.dfrecur"
  73. if [[ -h "$absTarget" ]]; then
  74. if [ -e "$absSource" ]; then
  75. if [ -h "$absSource" ]; then
  76. cmd="cp --no-dereference --force $absTarget $absSource"
  77. if [ $DRY_RUN ]; then
  78. echo $cmd
  79. else
  80. yes | $cmd
  81. fi
  82. else
  83. echo "[ERROR] $absSource already exists, but is not a link"
  84. fi
  85. else
  86. cmd="cp --no-dereference --force $absTarget $absSource"
  87. if [ $DRY_RUN ]; then
  88. echo $cmd
  89. else
  90. yes | $cmd
  91. fi
  92. fi
  93. elif [[ -f "$absTarget" || ( -d $absTarget && ! -f $recurIndicator ) ]]; then
  94. if [ -e "$absSource" ]; then
  95. if [ -h "$absSource" ]; then
  96. cmd="ln --symbolic --no-dereference --force $relTarget $absSource"
  97. if [ $DRY_RUN ]; then
  98. echo $cmd
  99. else
  100. $cmd
  101. fi
  102. else
  103. echo "[ERROR] $absSource already exists, but is not a symbolic link"
  104. fi
  105. else
  106. cmd="ln --no-dereference --symbolic $relTarget $absSource"
  107. if [ $DRY_RUN ]; then
  108. echo $cmd
  109. else
  110. $cmd
  111. fi
  112. fi
  113. elif [[ -d "$absTarget" && -f $recurIndicator ]]; then
  114. if [ -e "$absSource" ]; then
  115. if [ -d "$absSource" ]; then
  116. # echo "Directory $absSource already exists"
  117. _dotfiles-install-dir $dir/$file
  118. else
  119. echo "[ERROR] $absSource already exists, but is not a directory"
  120. fi
  121. else
  122. cmd="mkdir $absSource"
  123. if [ $DRY_RUN ]; then
  124. echo $cmd
  125. else
  126. $cmd
  127. fi
  128. _dotfiles-install-dir $dir/$file
  129. fi
  130. else
  131. echo "[WARNING] Skipped $absTarget"
  132. fi
  133. done
  134. }
  135. # Script functions
  136. function dotfiles-install {
  137. _dotfiles-install-dir /
  138. }
  139. # TODO dotfiles-{link,unlink,clean,uninstall}
  140. # Link and Unlink should have a clever behavior regarding
  141. # recusive folders
  142. # Ex : linking config/i3 should make config recursible
  143. # Ex : linking config if some files in it are linked should unlink those