diff options
author | Jari Vetoniemi <jari.vetoniemi@indooratlas.com> | 2020-03-16 18:49:26 +0900 |
---|---|---|
committer | Jari Vetoniemi <jari.vetoniemi@indooratlas.com> | 2020-03-30 00:39:06 +0900 |
commit | fcbf63e62c627deae76c1b8cb8c0876c536ed811 (patch) | |
tree | 64cb17de3f41a2b6fef2368028fbd00349946994 /jni/ruby/lib/rubygems/commands/install_command.rb |
Fresh start
Diffstat (limited to 'jni/ruby/lib/rubygems/commands/install_command.rb')
-rw-r--r-- | jni/ruby/lib/rubygems/commands/install_command.rb | 347 |
1 files changed, 347 insertions, 0 deletions
diff --git a/jni/ruby/lib/rubygems/commands/install_command.rb b/jni/ruby/lib/rubygems/commands/install_command.rb new file mode 100644 index 0000000..1bf5928 --- /dev/null +++ b/jni/ruby/lib/rubygems/commands/install_command.rb @@ -0,0 +1,347 @@ +require 'rubygems/command' +require 'rubygems/install_update_options' +require 'rubygems/dependency_installer' +require 'rubygems/local_remote_options' +require 'rubygems/validator' +require 'rubygems/version_option' + +## +# Gem installer command line tool +# +# See `gem help install` + +class Gem::Commands::InstallCommand < Gem::Command + + attr_reader :installed_specs # :nodoc: + + include Gem::VersionOption + include Gem::LocalRemoteOptions + include Gem::InstallUpdateOptions + + def initialize + defaults = Gem::DependencyInstaller::DEFAULT_OPTIONS.merge({ + :format_executable => false, + :lock => true, + :suggest_alternate => true, + :version => Gem::Requirement.default, + :without_groups => [], + }) + + super 'install', 'Install a gem into the local repository', defaults + + add_install_update_options + add_local_remote_options + add_platform_option + add_version_option + add_prerelease_option "to be installed. (Only for listed gems)" + + add_option(:"Install/Update", '-g', '--file [FILE]', + 'Read from a gem dependencies API file and', + 'install the listed gems') do |v,o| + v = Gem::GEM_DEP_FILES.find do |file| + File.exist? file + end unless v + + unless v then + message = v ? v : "(tried #{Gem::GEM_DEP_FILES.join ', '})" + + raise OptionParser::InvalidArgument, + "cannot find gem dependencies file #{message}" + end + + o[:gemdeps] = v + end + + add_option(:"Install/Update", '--without GROUPS', Array, + 'Omit the named groups (comma separated)', + 'when installing from a gem dependencies', + 'file') do |v,o| + o[:without_groups].concat v.map { |without| without.intern } + end + + add_option(:"Install/Update", '--default', + 'Add the gem\'s full specification to', + 'specifications/default and extract only its bin') do |v,o| + o[:install_as_default] = v + end + + add_option(:"Install/Update", '--explain', + 'Rather than install the gems, indicate which would', + 'be installed') do |v,o| + o[:explain] = v + end + + add_option(:"Install/Update", '--[no-]lock', + 'Create a lock file (when used with -g/--file)') do |v,o| + o[:lock] = v + end + + add_option(:"Install/Update", '--[no-]suggestions', + 'Suggest alternates when gems are not found') do |v,o| + o[:suggest_alternate] = v + end + + @installed_specs = [] + end + + def arguments # :nodoc: + "GEMNAME name of gem to install" + end + + def defaults_str # :nodoc: + "--both --version '#{Gem::Requirement.default}' --document --no-force\n" + + "--install-dir #{Gem.dir} --lock" + end + + def description # :nodoc: + <<-EOF +The install command installs local or remote gem into a gem repository. + +For gems with executables ruby installs a wrapper file into the executable +directory by default. This can be overridden with the --no-wrappers option. +The wrapper allows you to choose among alternate gem versions using _version_. + +For example `rake _0.7.3_ --version` will run rake version 0.7.3 if a newer +version is also installed. + +Gem Dependency Files +==================== + +RubyGems can install a consistent set of gems across multiple environments +using `gem install -g` when a gem dependencies file (gem.deps.rb, Gemfile or +Isolate) is present. If no explicit file is given RubyGems attempts to find +one in the current directory. + +When the RUBYGEMS_GEMDEPS environment variable is set to a gem dependencies +file the gems from that file will be activated at startup time. Set it to a +specific filename or to "-" to have RubyGems automatically discover the gem +dependencies file by walking up from the current directory. + +NOTE: Enabling automatic discovery on multiuser systems can lead to +execution of arbitrary code when used from directories outside your control. + +Extension Install Failures +========================== + +If an extension fails to compile during gem installation the gem +specification is not written out, but the gem remains unpacked in the +repository. You may need to specify the path to the library's headers and +libraries to continue. You can do this by adding a -- between RubyGems' +options and the extension's build options: + + $ gem install some_extension_gem + [build fails] + Gem files will remain installed in \\ + /path/to/gems/some_extension_gem-1.0 for inspection. + Results logged to /path/to/gems/some_extension_gem-1.0/gem_make.out + $ gem install some_extension_gem -- --with-extension-lib=/path/to/lib + [build succeeds] + $ gem list some_extension_gem + + *** LOCAL GEMS *** + + some_extension_gem (1.0) + $ + +If you correct the compilation errors by editing the gem files you will need +to write the specification by hand. For example: + + $ gem install some_extension_gem + [build fails] + Gem files will remain installed in \\ + /path/to/gems/some_extension_gem-1.0 for inspection. + Results logged to /path/to/gems/some_extension_gem-1.0/gem_make.out + $ [cd /path/to/gems/some_extension_gem-1.0] + $ [edit files or what-have-you and run make] + $ gem spec ../../cache/some_extension_gem-1.0.gem --ruby > \\ + ../../specifications/some_extension_gem-1.0.gemspec + $ gem list some_extension_gem + + *** LOCAL GEMS *** + + some_extension_gem (1.0) + $ + + EOF + end + + def usage # :nodoc: + "#{program_name} GEMNAME [GEMNAME ...] [options] -- --build-flags" + end + + def check_install_dir # :nodoc: + if options[:install_dir] and options[:user_install] then + alert_error "Use --install-dir or --user-install but not both" + terminate_interaction 1 + end + end + + def check_version # :nodoc: + if options[:version] != Gem::Requirement.default and + get_all_gem_names.size > 1 then + alert_error "Can't use --version w/ multiple gems. Use name:ver instead." + terminate_interaction 1 + end + end + + def execute + if options.include? :gemdeps then + install_from_gemdeps + return # not reached + end + + @installed_specs = [] + + ENV.delete 'GEM_PATH' if options[:install_dir].nil? and RUBY_VERSION > '1.9' + + check_install_dir + check_version + + load_hooks + + exit_code = install_gems + + show_installed + + terminate_interaction exit_code + end + + def install_from_gemdeps # :nodoc: + require 'rubygems/request_set' + rs = Gem::RequestSet.new + + specs = rs.install_from_gemdeps options do |req, inst| + s = req.full_spec + + if inst + say "Installing #{s.name} (#{s.version})" + else + say "Using #{s.name} (#{s.version})" + end + end + + @installed_specs = specs + + terminate_interaction + end + + def install_gem name, version # :nodoc: + return if options[:conservative] and + not Gem::Dependency.new(name, version).matching_specs.empty? + + req = Gem::Requirement.create(version) + + if options[:ignore_dependencies] then + install_gem_without_dependencies name, req + else + inst = Gem::DependencyInstaller.new options + request_set = inst.resolve_dependencies name, req + + if options[:explain] + puts "Gems to install:" + + request_set.sorted_requests.each do |s| + puts " #{s.full_name}" + end + + return + else + @installed_specs.concat request_set.install options + end + + show_install_errors inst.errors + end + end + + def install_gem_without_dependencies name, req # :nodoc: + gem = nil + + if local? then + if name =~ /\.gem$/ and File.file? name then + source = Gem::Source::SpecificFile.new name + spec = source.spec + else + source = Gem::Source::Local.new + spec = source.find_gem name, req + end + gem = source.download spec if spec + end + + if remote? and not gem then + dependency = Gem::Dependency.new name, req + dependency.prerelease = options[:prerelease] + + fetcher = Gem::RemoteFetcher.fetcher + gem = fetcher.download_to_cache dependency + end + + inst = Gem::Installer.new gem, options + inst.install + + require 'rubygems/dependency_installer' + dinst = Gem::DependencyInstaller.new options + dinst.installed_gems.replace [inst.spec] + + Gem.done_installing_hooks.each do |hook| + hook.call dinst, [inst.spec] + end unless Gem.done_installing_hooks.empty? + + @installed_specs.push(inst.spec) + end + + def install_gems # :nodoc: + exit_code = 0 + + get_all_gem_names_and_versions.each do |gem_name, gem_version| + gem_version ||= options[:version] + + begin + install_gem gem_name, gem_version + rescue Gem::InstallError => e + alert_error "Error installing #{gem_name}:\n\t#{e.message}" + exit_code |= 1 + rescue Gem::GemNotFoundException, Gem::UnsatisfiableDependencyError => e + domain = options[:domain] + domain = :local unless options[:suggest_alternate] + show_lookup_failure e.name, e.version, e.errors, domain + + exit_code |= 2 + end + end + + exit_code + end + + ## + # Loads post-install hooks + + def load_hooks # :nodoc: + if options[:install_as_default] + require 'rubygems/install_default_message' + else + require 'rubygems/install_message' + end + require 'rubygems/rdoc' + end + + def show_install_errors errors # :nodoc: + return unless errors + + errors.each do |x| + return unless Gem::SourceFetchProblem === x + + msg = "Unable to pull data from '#{x.source.uri}': #{x.error.message}" + + alert_warning msg + end + end + + def show_installed # :nodoc: + return if @installed_specs.empty? + + gems = @installed_specs.length == 1 ? 'gem' : 'gems' + say "#{@installed_specs.length} #{gems} installed" + end + +end + |