migrate 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  1. #!/usr/bin/env bash
  2. unset GREP_OPTIONS
  3. source "$rvm_scripts_path/base"
  4. usage()
  5. {
  6. printf "%b" "
  7. Usage:
  8. rvm migrate {source-ruby} {destination-ruby} [--force]
  9. Description:
  10. Moves all gemsets from {source-ruby} ruby to {destination-ruby}.
  11. " >&2
  12. }
  13. confirm()
  14. {
  15. if (( ${rvm_force_flag:-0} > 0 ))
  16. then return 0
  17. fi
  18. \typeset confirmation_response
  19. printf "%b" "$1 (Y/n): "
  20. read -r confirmation_response
  21. [[ -z "$confirmation_response" ]] ||
  22. echo "$confirmation_response" | __rvm_grep -i '^y' >/dev/null 2>&1
  23. }
  24. die_with_error()
  25. {
  26. rvm_error "$1"
  27. exit "${2:-1}"
  28. }
  29. expand_ruby_name()
  30. {
  31. "$rvm_scripts_path/tools" strings "$1" | __rvm_awk -F"${rvm_gemset_separator:-"@"}" '{print $1}'
  32. }
  33. migrate_rubies()
  34. {
  35. \typeset -a origin_gemsets alias_pairs
  36. \typeset origin_gemset destination_gemset gemset_name migrate_ruby_name \
  37. migrate_alias_name migrate_new_alias_name binaries origin_wrappers_path \
  38. full_bin_path expanded_symlink linked_binary_name new_wrapper_destination
  39. expanded_source="$(expand_ruby_name "$source_ruby")"
  40. expanded_destination="$(expand_ruby_name "$destination_ruby")"
  41. migrate_rubies_checks &&
  42. migrate_rubies_gemsets &&
  43. migrate_rubies_aliases &&
  44. migrate_rubies_summary ||
  45. return $?
  46. }
  47. migrate_rubies_checks()
  48. {
  49. if
  50. [[ -z "$expanded_source" ]]
  51. then
  52. die_with_error "Could not expand source ruby '$source_ruby'"
  53. elif
  54. [[ -z "$expanded_destination" ]]
  55. then
  56. die_with_error "Could not expand destination ruby '$destination_ruby'"
  57. elif
  58. [[ "$expanded_destination" == "$expanded_source" ]]
  59. then
  60. die_with_error "Source and Destination Ruby are the same ($expanded_destination)"
  61. elif
  62. [[ ! -d "$rvm_rubies_path/$expanded_source" ]]
  63. then
  64. die_with_error "Ruby '$expanded_source' is not installed - please install it first."
  65. elif
  66. [[ ! -d "$rvm_rubies_path/$expanded_destination" ]]
  67. then
  68. die_with_error "Ruby '$expanded_destination' is not installed - please install it first."
  69. fi
  70. migrate_rubies_checks_required_space
  71. }
  72. migrate_rubies_checks_required_space()
  73. {
  74. \typeset __used_space __free_space
  75. __rvm_calculate_space_free "${rvm_gems_path}"
  76. __rvm_calculate_space_used "$rvm_gems_path/$expanded_source"{,@*}
  77. if
  78. (( __used_space > __free_space ))
  79. then
  80. die_with_error "Not enough space (${__free_space}MB) to copy gemsets (${__used_space}MB)."
  81. elif
  82. (( __used_space*12 > __free_space*10 )) # 20% check
  83. then
  84. rvm_warn "You are running low on disk space ${__free_space}MB, required ${__used_space}MB."
  85. else
  86. rvm_log "Free disk space ${__free_space}MB, required ${__used_space}MB."
  87. fi
  88. }
  89. migrate_rubies_gemset_calculate_destination()
  90. {
  91. destination_gemset="$expanded_destination"
  92. case "$origin_gemset" in
  93. (*${rvm_gemset_separator:-@}*)
  94. gemset_name="${origin_gemset/*${rvm_gemset_separator:-"@"}/}"
  95. destination_gemset="${destination_gemset}${rvm_gemset_separator:-"@"}${gemset_name}"
  96. ;;
  97. (*)
  98. gemset_name="default"
  99. ;;
  100. esac
  101. }
  102. migrate_rubies_gemsets_run_each_ask()
  103. {
  104. case "$__action" in
  105. (copy)
  106. echo "Moving gems from $* to $expanded_destination?"
  107. ;;
  108. (merge)
  109. confirm "Are you sure you wish to Merge gems from $* to $expanded_destination" || return 1
  110. ;;
  111. (overwrite)
  112. echo "Are you sure you wish to MOVE gems from $* to $expanded_destination?"
  113. confirm "This will overwrite existing gems in $expanded_destination and remove them from $expanded_source" || return 1
  114. ;;
  115. (*)
  116. rvm_error "Unknown action($__action) for migrate_rubies_gemsets_run_each"
  117. return 204
  118. esac
  119. }
  120. migrate_rubies_gemset_clean_destination()
  121. {
  122. case "$__action" in
  123. (overwrite)
  124. __rvm_log_command "remove.gemset.$gemset_name" "Removing $destination_gemset" \
  125. \command \rm -rfv "${rvm_gems_path:-"$rvm_path/gems"}/$destination_gemset"/* ||
  126. return $?
  127. ;;
  128. esac
  129. }
  130. __migrate_gemset()
  131. {
  132. \command \mkdir -p "${rvm_gems_path:-"$rvm_path/gems"}/$destination_gemset"/ &&
  133. \command \mv -v "${rvm_gems_path:-"$rvm_path/gems"}/$1"/* "${rvm_gems_path:-"$rvm_path/gems"}/$2"/ &&
  134. gemset_reset_env "$2"
  135. }
  136. __merge_gemset()
  137. (
  138. \typeset __file
  139. \typeset -a __files
  140. __files=()
  141. cd "${rvm_gems_path:-"$rvm_path/gems"}/$1"/
  142. __rvm_read_lines __files <(
  143. __rvm_find . -type d
  144. )
  145. for __file in "${__files[@]}"
  146. do
  147. mkdir -p "${rvm_gems_path:-"$rvm_path/gems"}/$2/${__file#./}"
  148. done
  149. __files=()
  150. __rvm_read_lines __files <(
  151. __rvm_find . -type f
  152. )
  153. for __file in "${__files[@]}"
  154. do
  155. \command \mv -v "${__file}" "${rvm_gems_path:-"$rvm_path/gems"}/$2/${__file#./}"
  156. done
  157. rm -rf "${rvm_gems_path:-"$rvm_path/gems"}/$1"/
  158. cd ..
  159. gemset_reset_env "$2"
  160. )
  161. migrate_rubies_gemsets_run_migration()
  162. {
  163. case "$__action" in
  164. (copy|overwrite)
  165. __rvm_log_command "migrate.gemset.$gemset_name" "Moving $origin_gemset to $destination_gemset" \
  166. __migrate_gemset "$origin_gemset" "$destination_gemset" ||
  167. return $?
  168. ;;
  169. (merge)
  170. __rvm_log_command "merge.gemset.$gemset_name" "Merging $origin_gemset to $destination_gemset" \
  171. __merge_gemset "$origin_gemset" "$destination_gemset" ||
  172. return $?
  173. ;;
  174. esac
  175. }
  176. migrate_rubies_gemsets_run_each()
  177. {
  178. \typeset __action=$1
  179. shift
  180. migrate_rubies_gemsets_run_each_ask "$@" || return $?
  181. for origin_gemset in "$@"
  182. do
  183. migrate_rubies_gemset_calculate_destination
  184. migrate_rubies_gemset_clean_destination
  185. migrate_rubies_gemsets_run_migration
  186. __rvm_gemset_pristine "$destination_gemset"
  187. done
  188. }
  189. migrate_rubies_gemset_partition()
  190. {
  191. if
  192. [[ ! -d "${rvm_gems_path:-"$rvm_path/gems"}/$destination_gemset" ]]
  193. then
  194. __list_new+=( "$origin_gemset" )
  195. elif
  196. [[ "$gemset_name" == "global" ]]
  197. then
  198. __list_global+=( "$origin_gemset" )
  199. elif
  200. [[ "$gemset_name" == "default" ]]
  201. then
  202. __list_default+=( "$origin_gemset" )
  203. else
  204. __list_existing+=( "$origin_gemset" )
  205. fi
  206. }
  207. migrate_rubies_gemsets_run()
  208. {
  209. if [[ -n "${__list_global[*]}" ]]
  210. then migrate_rubies_gemsets_run_each overwrite "${__list_global[@]}"
  211. fi
  212. if [[ -n "${__list_default[*]}" ]]
  213. then migrate_rubies_gemsets_run_each merge "${__list_default[@]}"
  214. fi
  215. if [[ -n "${__list_existing[*]}" ]]
  216. then migrate_rubies_gemsets_run_each overwrite "${__list_existing[@]}"
  217. fi
  218. if [[ -n "${__list_new[*]}" ]]
  219. then migrate_rubies_gemsets_run_each copy "${__list_new[@]}"
  220. fi
  221. }
  222. migrate_rubies_gemsets()
  223. {
  224. \typeset origin_gemsets __list_global __list_default __list_existing __list_new
  225. __list_global=()
  226. __list_default=()
  227. __list_existing=()
  228. __list_new=()
  229. __rvm_read_lines origin_gemsets <(
  230. __rvm_list_gemset_strings | __rvm_grep -E "^$expanded_source(@.*)?$"
  231. )
  232. for origin_gemset in "${origin_gemsets[@]}"
  233. do
  234. migrate_rubies_gemset_calculate_destination
  235. migrate_rubies_gemset_partition
  236. done
  237. rvm_debug "__list_global= ${__list_global[*]};"
  238. rvm_debug "__list_default= ${__list_default[*]};"
  239. rvm_debug "__list_existing=${__list_existing[*]};"
  240. rvm_debug "__list_new= ${__list_new[*]};"
  241. migrate_rubies_gemsets_run
  242. }
  243. migrate_rubies_alias()
  244. {
  245. "$rvm_scripts_path/alias" delete "$migrate_alias_name"
  246. "$rvm_scripts_path/alias" create "$migrate_alias_name" "$migrate_new_alias_name"
  247. }
  248. migrate_rubies_aliases()
  249. {
  250. __rvm_read_lines alias_pairs < "$rvm_path/config/alias"
  251. aliases=()
  252. for alias_pair in "${alias_pairs[@]}"
  253. do
  254. migrate_alias_name="${alias_pair/=*/}"
  255. migrate_ruby_name="${alias_pair/*=/}"
  256. if
  257. [[ "$migrate_ruby_name" == "$expanded_source" ||
  258. "$migrate_ruby_name" == "${expanded_source}${rvm_gemset_separator:-"@"}"*
  259. ]]
  260. then
  261. migrate_new_alias_name="${migrate_ruby_name/$expanded_source/$expanded_destination}"
  262. aliases+=( "$migrate_alias_name=$migrate_new_alias_name" )
  263. fi
  264. done
  265. if
  266. (( ${#aliases[@]} )) &&
  267. confirm 'Do you wish to move over aliases?'
  268. then
  269. for alias_pair in "${aliases[@]}"
  270. do
  271. migrate_alias_name="${alias_pair%%=*}"
  272. migrate_new_alias_name="${alias_pair#*=}"
  273. __rvm_log_command "migrate.alias.$migrate_alias_name" \
  274. "Updating alias $migrate_alias_name to point to $migrate_new_alias_name" \
  275. migrate_rubies_alias
  276. done
  277. fi
  278. true
  279. }
  280. migrate_rubies_summary()
  281. {
  282. if confirm "Do you also wish to completely remove $expanded_source (inc. archive)?"
  283. then __rvm_log_command "rvm.remove" "Removing $expanded_source" __rvm_run_wrapper manage remove "$expanded_source" --archive --gems
  284. fi
  285. echo "Successfully migrated $expanded_source to $expanded_destination"
  286. }
  287. source_ruby="$1"
  288. destination_ruby="$2"
  289. if
  290. [[ -z "$source_ruby" || -z "$destination_ruby" ]]
  291. then
  292. usage
  293. exit 1
  294. fi
  295. migrate_rubies