#!/usr/bin/env bash unset GREP_OPTIONS source "$rvm_scripts_path/base" usage() { printf "%b" " Usage: rvm migrate {source-ruby} {destination-ruby} [--force] Description: Moves all gemsets from {source-ruby} ruby to {destination-ruby}. " >&2 } confirm() { if (( ${rvm_force_flag:-0} > 0 )) then return 0 fi \typeset confirmation_response printf "%b" "$1 (Y/n): " read -r confirmation_response [[ -z "$confirmation_response" ]] || echo "$confirmation_response" | __rvm_grep -i '^y' >/dev/null 2>&1 } die_with_error() { rvm_error "$1" exit "${2:-1}" } expand_ruby_name() { "$rvm_scripts_path/tools" strings "$1" | __rvm_awk -F"${rvm_gemset_separator:-"@"}" '{print $1}' } migrate_rubies() { \typeset -a origin_gemsets alias_pairs \typeset origin_gemset destination_gemset gemset_name migrate_ruby_name \ migrate_alias_name migrate_new_alias_name binaries origin_wrappers_path \ full_bin_path expanded_symlink linked_binary_name new_wrapper_destination expanded_source="$(expand_ruby_name "$source_ruby")" expanded_destination="$(expand_ruby_name "$destination_ruby")" migrate_rubies_checks && migrate_rubies_gemsets && migrate_rubies_aliases && migrate_rubies_summary || return $? } migrate_rubies_checks() { if [[ -z "$expanded_source" ]] then die_with_error "Could not expand source ruby '$source_ruby'" elif [[ -z "$expanded_destination" ]] then die_with_error "Could not expand destination ruby '$destination_ruby'" elif [[ "$expanded_destination" == "$expanded_source" ]] then die_with_error "Source and Destination Ruby are the same ($expanded_destination)" elif [[ ! -d "$rvm_rubies_path/$expanded_source" ]] then die_with_error "Ruby '$expanded_source' is not installed - please install it first." elif [[ ! -d "$rvm_rubies_path/$expanded_destination" ]] then die_with_error "Ruby '$expanded_destination' is not installed - please install it first." fi migrate_rubies_checks_required_space } migrate_rubies_checks_required_space() { \typeset __used_space __free_space __rvm_calculate_space_free "${rvm_gems_path}" __rvm_calculate_space_used "$rvm_gems_path/$expanded_source"{,@*} if (( __used_space > __free_space )) then die_with_error "Not enough space (${__free_space}MB) to copy gemsets (${__used_space}MB)." elif (( __used_space*12 > __free_space*10 )) # 20% check then rvm_warn "You are running low on disk space ${__free_space}MB, required ${__used_space}MB." else rvm_log "Free disk space ${__free_space}MB, required ${__used_space}MB." fi } migrate_rubies_gemset_calculate_destination() { destination_gemset="$expanded_destination" case "$origin_gemset" in (*${rvm_gemset_separator:-@}*) gemset_name="${origin_gemset/*${rvm_gemset_separator:-"@"}/}" destination_gemset="${destination_gemset}${rvm_gemset_separator:-"@"}${gemset_name}" ;; (*) gemset_name="default" ;; esac } migrate_rubies_gemsets_run_each_ask() { case "$__action" in (copy) echo "Moving gems from $* to $expanded_destination?" ;; (merge) confirm "Are you sure you wish to Merge gems from $* to $expanded_destination" || return 1 ;; (overwrite) echo "Are you sure you wish to MOVE gems from $* to $expanded_destination?" confirm "This will overwrite existing gems in $expanded_destination and remove them from $expanded_source" || return 1 ;; (*) rvm_error "Unknown action($__action) for migrate_rubies_gemsets_run_each" return 204 esac } migrate_rubies_gemset_clean_destination() { case "$__action" in (overwrite) __rvm_log_command "remove.gemset.$gemset_name" "Removing $destination_gemset" \ \command \rm -rfv "${rvm_gems_path:-"$rvm_path/gems"}/$destination_gemset"/* || return $? ;; esac } __migrate_gemset() { \command \mkdir -p "${rvm_gems_path:-"$rvm_path/gems"}/$destination_gemset"/ && \command \mv -v "${rvm_gems_path:-"$rvm_path/gems"}/$1"/* "${rvm_gems_path:-"$rvm_path/gems"}/$2"/ && gemset_reset_env "$2" } __merge_gemset() ( \typeset __file \typeset -a __files __files=() cd "${rvm_gems_path:-"$rvm_path/gems"}/$1"/ __rvm_read_lines __files <( __rvm_find . -type d ) for __file in "${__files[@]}" do mkdir -p "${rvm_gems_path:-"$rvm_path/gems"}/$2/${__file#./}" done __files=() __rvm_read_lines __files <( __rvm_find . -type f ) for __file in "${__files[@]}" do \command \mv -v "${__file}" "${rvm_gems_path:-"$rvm_path/gems"}/$2/${__file#./}" done rm -rf "${rvm_gems_path:-"$rvm_path/gems"}/$1"/ cd .. gemset_reset_env "$2" ) migrate_rubies_gemsets_run_migration() { case "$__action" in (copy|overwrite) __rvm_log_command "migrate.gemset.$gemset_name" "Moving $origin_gemset to $destination_gemset" \ __migrate_gemset "$origin_gemset" "$destination_gemset" || return $? ;; (merge) __rvm_log_command "merge.gemset.$gemset_name" "Merging $origin_gemset to $destination_gemset" \ __merge_gemset "$origin_gemset" "$destination_gemset" || return $? ;; esac } migrate_rubies_gemsets_run_each() { \typeset __action=$1 shift migrate_rubies_gemsets_run_each_ask "$@" || return $? for origin_gemset in "$@" do migrate_rubies_gemset_calculate_destination migrate_rubies_gemset_clean_destination migrate_rubies_gemsets_run_migration __rvm_gemset_pristine "$destination_gemset" done } migrate_rubies_gemset_partition() { if [[ ! -d "${rvm_gems_path:-"$rvm_path/gems"}/$destination_gemset" ]] then __list_new+=( "$origin_gemset" ) elif [[ "$gemset_name" == "global" ]] then __list_global+=( "$origin_gemset" ) elif [[ "$gemset_name" == "default" ]] then __list_default+=( "$origin_gemset" ) else __list_existing+=( "$origin_gemset" ) fi } migrate_rubies_gemsets_run() { if [[ -n "${__list_global[*]}" ]] then migrate_rubies_gemsets_run_each overwrite "${__list_global[@]}" fi if [[ -n "${__list_default[*]}" ]] then migrate_rubies_gemsets_run_each merge "${__list_default[@]}" fi if [[ -n "${__list_existing[*]}" ]] then migrate_rubies_gemsets_run_each overwrite "${__list_existing[@]}" fi if [[ -n "${__list_new[*]}" ]] then migrate_rubies_gemsets_run_each copy "${__list_new[@]}" fi } migrate_rubies_gemsets() { \typeset origin_gemsets __list_global __list_default __list_existing __list_new __list_global=() __list_default=() __list_existing=() __list_new=() __rvm_read_lines origin_gemsets <( __rvm_list_gemset_strings | __rvm_grep -E "^$expanded_source(@.*)?$" ) for origin_gemset in "${origin_gemsets[@]}" do migrate_rubies_gemset_calculate_destination migrate_rubies_gemset_partition done rvm_debug "__list_global= ${__list_global[*]};" rvm_debug "__list_default= ${__list_default[*]};" rvm_debug "__list_existing=${__list_existing[*]};" rvm_debug "__list_new= ${__list_new[*]};" migrate_rubies_gemsets_run } migrate_rubies_alias() { "$rvm_scripts_path/alias" delete "$migrate_alias_name" "$rvm_scripts_path/alias" create "$migrate_alias_name" "$migrate_new_alias_name" } migrate_rubies_aliases() { __rvm_read_lines alias_pairs < "$rvm_path/config/alias" aliases=() for alias_pair in "${alias_pairs[@]}" do migrate_alias_name="${alias_pair/=*/}" migrate_ruby_name="${alias_pair/*=/}" if [[ "$migrate_ruby_name" == "$expanded_source" || "$migrate_ruby_name" == "${expanded_source}${rvm_gemset_separator:-"@"}"* ]] then migrate_new_alias_name="${migrate_ruby_name/$expanded_source/$expanded_destination}" aliases+=( "$migrate_alias_name=$migrate_new_alias_name" ) fi done if (( ${#aliases[@]} )) && confirm 'Do you wish to move over aliases?' then for alias_pair in "${aliases[@]}" do migrate_alias_name="${alias_pair%%=*}" migrate_new_alias_name="${alias_pair#*=}" __rvm_log_command "migrate.alias.$migrate_alias_name" \ "Updating alias $migrate_alias_name to point to $migrate_new_alias_name" \ migrate_rubies_alias done fi true } migrate_rubies_summary() { if confirm "Do you also wish to completely remove $expanded_source (inc. archive)?" then __rvm_log_command "rvm.remove" "Removing $expanded_source" __rvm_run_wrapper manage remove "$expanded_source" --archive --gems fi echo "Successfully migrated $expanded_source to $expanded_destination" } source_ruby="$1" destination_ruby="$2" if [[ -z "$source_ruby" || -z "$destination_ruby" ]] then usage exit 1 fi migrate_rubies