#!/usr/bin/env bash rubygems_remove() { \typeset rubygems_path __ruby entry rvm_log "Removing old Rubygems files..." case "$rvm_ruby_string" in (rbx-*) __ruby="['prefix']" ;; (*) __ruby=".values_at('sitelibdir','vendorlibdir').detect{ |path| File.directory?(File.join(path.to_s, 'rubygems')) }.to_s" ;; esac rubygems_path="$(${1:-ruby} -rrbconfig -e "puts ::Kernel.const_get('RbConfig')::CONFIG${ruby__}")" # Remove common files installed by ruby gems. entries=( "${rubygems_path}/ubygems.rb" "${rubygems_path}/gauntlet_rubygems.rb" "${rubygems_path}/rbconfig/" ) for entry in "${entries[@]}" "${rubygems_path}/rubygems"* do __rvm_rm_rf "$entry" done } can_switch_rubygems() { case "$rvm_ruby_string" in maglev*) return 1 ;; *) return 0 ;; esac } make_sure_jruby_can_work_with_rubygems() { case "$rvm_ruby_string" in jruby-head*) true ;; jruby*) __rvm_version_compare "$rvm_ruby_version" -ge 1.7.1 || return 1 ;; *) return 0 # do not care about other rubies ;; esac case "${rvm_rubygems_version}" in head|master) true ;; *) __rvm_version_compare "$rvm_rubygems_version" -ge 2.0.0 || return 1 ;; esac } rubygems_fatal_error() { rvm_error "$1" exit ${2:-1} } rubygems_version_list() { __rvm_curl -sS https://rubygems.org/api/v1/versions/rubygems-update.json | __rvm_awk -v RS=',' -v FS='"' '$2=="number"{print $4}' | __rvm_version_sort | __rvm_grep '^[[:digit:]\.]*$' } rubygems_current_rubygems_version() { "${rvm_ruby_binary}" -rrubygems -e 'puts(Gem::VERSION)' 2>/dev/null } rubygems_master_sha() { __rvm_curl -s "https://api.github.com/repos/rubygems/rubygems/commits?page=last&per_page=1" | __rvm_sed -n '/^ "sha":/ {s/^.*".*": "\(.*\)".*$/\1/;p;}' } bundler_rubygems_master_sha() { __rvm_curl -s "https://api.github.com/repos/rubygems/rubygems/contents/bundler" | __rvm_sed -n '/^ "sha":/ {s/^.*".*": "\(.*\)".*$/\1/;p;}' } rubygems_select_current() { case "$version" in latest|current) version="$(__rvm_db "${rvm_ruby_string//-/_}_rubygems_version")" version="${version:-"$(__rvm_db "${rvm_ruby_interpreter}_${rvm_ruby_version}_rubygems_version")"}" if (( ${rvm_head_flag:-0} == 1 )) && [[ -z "${version:-}" ]] then version="$(__rvm_db "${rvm_ruby_interpreter}_head_rubygems_version")" fi version="${version:-"$(__rvm_db "${rvm_ruby_interpreter}_rubygems_version")"}" version="${version:-"$(__rvm_db "rubygems_version")"}" ;; esac } rubygems_select_latest() { case "$version" in latest-*) version="${version#latest-}" version="$(rubygems_version_list | __rvm_grep "^${version}\." | __rvm_tail -n 1 )" version="${version}" ;; esac } rubygems_select_version_url() { case "${version:-missing}" in ignore|none) rvm_rubygems_version="$version" ;; head|master) \typeset sha sha="$(rubygems_master_sha)" rvm_rubygems_version="$version" rvm_gem_package_name="rubygems-${sha}" rvm_gem_url="https://github.com/rubygems/rubygems/archive/${sha}.tar.gz" __bundler_sha="$(bundler_rubygems_master_sha)" __bundler_package_name="bundler-${__bundler_sha}" __bundler_url="https://github.com/bundler/bundler/archive/${__bundler_sha}.tar.gz" export rvm_verify_downloads_flag=1 ;; v*) rvm_rubygems_version="$version" rvm_gem_package_name="rubygems-${version#v}" rvm_gem_url="https://github.com/rubygems/rubygems/archive/$version.tar.gz" export rvm_verify_downloads_flag=1 ;; missing) rvm_error "There was an error while trying to resolve rubygems version for '$1'. \nHalting the installation." return 4 ;; *) rvm_rubygems_version="$version" rvm_gem_package_name="rubygems-${rvm_rubygems_version}" rvm_rubygems_url=$(__rvm_db "rubygems_url") rvm_gem_url="${rvm_rubygems_url}/${rvm_gem_package_name}.tgz" ;; esac } rubygems_select_version() { rubygems_select_current "$1" && rubygems_select_latest "$1" && rubygems_select_version_url "$1" || return $? } __rvm_warn_on_rubyopt() { if [[ -n "${RUBYOPT:-""}" ]]; then rvm_warn \ "Please note: You have the RUBYOPT environment variable set and this \ may interfere with normal rvm operations. We sugges unsetting it." return 1 else return 0 fi } rubygems_setup() { export version="$1" \typeset __bundler_sha __bundler_package_name __bundler_url rvm_debug "rubygems_setup version:${version} rvm_ruby_string:${rvm_ruby_string} rvm_ruby_home:${rvm_ruby_home} rvm_ruby_binary:${rvm_ruby_binary}" case "${version:-missing}" in ignore|none) rvm_debug "Skipping installing rubygems." return 0 ;; esac can_switch_rubygems || rubygems_fatal_error "RVM can not install rubygems for maglev and older jruby, select other ruby and try again." $? __rvm_warn_on_rubyopt true ${rvm_ruby_selected_flag:=0} unset RUBYOPT (( rvm_ruby_selected_flag == 0 )) || __rvm_select rubygems_select_version "$version" || return $? rvm_debug "rubygems_setup_rubygems version:${rvm_rubygems_version} rvm_gem_package_name:${rvm_gem_package_name} rvm_gem_url:${rvm_gem_url}" rvm_debug "rubygems_setup_bundler sha:${__bundler_sha} __bundler_package_name:${__bundler_package_name} __bundler_url:${__bundler_url}" if [[ "${rvm_force_flag:-0}" -eq 1 ]] then true # just let us continue with installation else \typeset __current_rubygems_version="$( rubygems_current_rubygems_version )" if __rvm_version_compare "${__current_rubygems_version}" -eq "$version" then rvm_log "Rubygems $version already available in installed ruby, skipping installation, use --force to reinstall." return 0 elif __rvm_version_compare "${__current_rubygems_version}" -gt "$version" then rvm_log "Installed rubygems ${__current_rubygems_version} is newer than $version provided with installed ruby, skipping installation, use --force to force installation." return 0 fi fi make_sure_jruby_can_work_with_rubygems || rubygems_fatal_error "RVM can not install rubygems for older jruby, select other ruby and try again." $? # always cleanup! [[ -d "${rvm_src_path}/$rvm_gem_package_name" ]] || __rvm_rm_rf "${rvm_src_path}/$rvm_gem_package_name" rvm_log "$rvm_ruby_string - #downloading $rvm_gem_package_name" "$rvm_scripts_path/fetch" "$rvm_gem_url" "${rvm_gem_package_name}.tgz" || rubygems_fatal_error "There has been an error while trying to fetch rubygems. \nHalting the installation." $? if [[ -n "${__bundler_sha:-}" ]] then rvm_log "$rvm_ruby_string - #downloading $__bundler_package_name" "$rvm_scripts_path/fetch" "$__bundler_url" "${__bundler_package_name}.tgz" || rubygems_fatal_error "There has been an error while trying to fetch bundler. \nHalting the installation." $? fi __rvm_log_command "rubygems.extract" "$rvm_ruby_string - #extracting $rvm_gem_package_name" \ __rvm_package_extract "${rvm_archives_path}/$rvm_gem_package_name.tgz" "${rvm_src_path}" || rubygems_fatal_error "There has been an error while trying to extract rubygems. \nHalting the installation." $? if [[ -n "${__bundler_sha:-}" ]] then __rvm_log_command "rubygems.bundler.extract" "$rvm_ruby_string - #extracting $__bundler_package_name" \ __rvm_package_extract "${rvm_archives_path}/$__bundler_package_name.tgz" "${rvm_src_path}" "*/spec/*" || rubygems_fatal_error "There has been an error while trying to extract bundler. \nHalting the installation." $? \rm -rf "${rvm_src_path}/$rvm_gem_package_name/bundler" && ln -nfs "${rvm_src_path}/$__bundler_package_name/" "${rvm_src_path}/$rvm_gem_package_name/bundler" || rubygems_fatal_error "There has been an error while linking bundler. \nHalting the installation." $? fi __rvm_log_command "rubygems.remove" "$rvm_ruby_string - #removing old rubygems" rubygems_remove "${rvm_ruby_binary}" __rvm_cd "${rvm_src_path}/$rvm_gem_package_name" \typeset -a __command __command=( GEM_HOME="$rvm_gems_path/${rvm_ruby_string}@global" GEM_PATH="" "${rvm_ruby_binary}" -d "${rvm_src_path}/$rvm_gem_package_name/setup.rb" ) if [[ ${rvm_debug_flag:-0} == 1 || ${rvm_trace_flag:-0} == 1 ]] then __command+=( --verbose ) fi if (( ${rvm_docs_flag:-0} == 0 )) then if __rvm_version_compare "$version" -ge 2.2 then __command+=( --no-document ) else __command+=( --no-ri --no-rdoc ) fi fi __setup_lang_fallback __rvm_log_command "rubygems.install" \ "$rvm_ruby_string - #installing $rvm_gem_package_name" \ "${__command[@]}" || return $? [[ -e "$rvm_ruby_home/bin/gem" ]] || { \typeset program_suffix program_suffix="$( __rvm_ruby_config_get configure_args "${rvm_ruby_binary}" )" case "${program_suffix:-}" in (*--program-suffix=*) program_suffix="${program_suffix#*--program-suffix=}" program_suffix="${program_suffix%%[\' ]*}" __rvm_log_command "link.gem" "$rvm_ruby_string - #linking gem${program_suffix} -> gem" \ ln -s "$rvm_ruby_home/bin/gem${program_suffix}" "$rvm_ruby_home/bin/gem" ;; esac } true # for osx } rubygems_validate_gemfile_extract() ( \command \mkdir -p "$2/gem" && \command \tar -C "$2" -xf "$1" --touch && \command \cd "$2" && \command \gzip -d "metadata.gz" && \command \tar -C gem -xzf "data.tar.gz" --touch && \command \rm "data.tar.gz" || { \typeset ret=$? rvm_error "Error extracting '$1' to '$2'." \command \rm -rf "${rvm_tmp_path}/rg$$" return $ret } ) # Adapted from: https://gist.github.com/4678778 rubygems_validate_gemfile() ( gem_file="$1" downloaded_file="${gem_file##*/}" gem__url="${2:-https://d2chzxaqi4y7f8.cloudfront.net/gems/$downloaded_file}" dir_local_copy="${downloaded_file%.gem}--local" dir_remote_copy="${downloaded_file%.gem}-remote" mkdir -p "${rvm_tmp_path}/rg$$" cd "${rvm_tmp_path}/rg$$" __rvm_curl "$gem__url" -o "$downloaded_file" && [[ -f "$downloaded_file" ]] || { \typeset ret=$? rvm_error "Could not download '$gem__url'." \command \rm -rf "${rvm_tmp_path}/rg$$" return $ret } rubygems_validate_gemfile_extract "$gem_file" "$dir_local_copy" || return $? rubygems_validate_gemfile_extract "$downloaded_file" "$dir_remote_copy" || return $? # compare diff -ru "$dir_local_copy" "$dir_remote_copy" # cleanup \command \rm -rf "${rvm_tmp_path}/rg$$" ) rubygems_validate_list_gemdirs() { for gemdir in "$@" do __rvm_readlink_deep gemdir echo "${gemdir}" done | sort -u } # Adapted from: https://gist.github.com/4678189 rubygems_validate() { __rvm_which openssl > /dev/null || rubygems_fatal_error "'openssl' was not found, please install it." \typeset gemdir gemfile url gem loc rem log \typeset -a gemdirs rvm_log "Validating RubyGems... This will take a while..." __rvm_read_lines gemdirs <( rubygems_validate_list_gemdirs "$@" ) (( ${#gemdirs[@]} )) || __rvm_read_lines gemdirs <( rubygems_validate_list_gemdirs "$rvm_gems_path"/*/cache ) for gemdir in "${gemdirs[@]}" do for gem in "$gemdir"/*.gem do gemfile="${gem##*/}" url="https://d2chzxaqi4y7f8.cloudfront.net/gems/$gemfile" printf "%b" "${rvm_notify_clr}${gem}${rvm_reset_clr}" loc=$(openssl md5 $gem |cut -d" " -f2) rem=$(__rvm_curl -3 -s -D - -X HEAD -H 'Connection:close' "$url" | __rvm_grep 'ETag' | cut -d'"' -f2) [[ $loc == $rem ]] || { printf "%b" " " log="${rvm_log_path}/$gemfile.diff" rubygems_validate_gemfile "$gem" "$url" > "$log" printf "%b" "${rvm_error_clr}mismatch, local: $loc, remote: $rem${rvm_reset_clr}, differences recorded in '$log'" } printf "%b" ", " done done rvm_log "\nDone verifying gems." }