1require 'rubygems/command' 2require 'rubygems/install_update_options' 3require 'rubygems/dependency_installer' 4require 'rubygems/local_remote_options' 5require 'rubygems/validator' 6require 'rubygems/version_option' 7require 'rubygems/install_message' # must come before rdoc for messaging 8require 'rubygems/rdoc' 9 10## 11# Gem installer command line tool 12# 13# See `gem help install` 14 15class Gem::Commands::InstallCommand < Gem::Command 16 17 attr_reader :installed_specs # :nodoc: 18 19 include Gem::VersionOption 20 include Gem::LocalRemoteOptions 21 include Gem::InstallUpdateOptions 22 23 def initialize 24 defaults = Gem::DependencyInstaller::DEFAULT_OPTIONS.merge({ 25 :format_executable => false, 26 :version => Gem::Requirement.default, 27 }) 28 29 super 'install', 'Install a gem into the local repository', defaults 30 31 add_install_update_options 32 add_local_remote_options 33 add_platform_option 34 add_version_option 35 add_prerelease_option "to be installed. (Only for listed gems)" 36 37 add_option(:"Install/Update", '-g', '--file FILE', 38 'Read from a gem dependencies API file and', 39 'install the listed gems') do |v,o| 40 o[:gemdeps] = v 41 end 42 43 @installed_specs = nil 44 end 45 46 def arguments # :nodoc: 47 "GEMNAME name of gem to install" 48 end 49 50 def defaults_str # :nodoc: 51 "--both --version '#{Gem::Requirement.default}' --document --no-force\n" + 52 "--install-dir #{Gem.dir}" 53 end 54 55 def description # :nodoc: 56 <<-EOF 57The install command installs local or remote gem into a gem repository. 58 59For gems with executables ruby installs a wrapper file into the executable 60directory by default. This can be overridden with the --no-wrappers option. 61The wrapper allows you to choose among alternate gem versions using _version_. 62 63For example `rake _0.7.3_ --version` will run rake version 0.7.3 if a newer 64version is also installed. 65 66If an extension fails to compile during gem installation the gem 67specification is not written out, but the gem remains unpacked in the 68repository. You may need to specify the path to the library's headers and 69libraries to continue. You can do this by adding a -- between RubyGems' 70options and the extension's build options: 71 72 $ gem install some_extension_gem 73 [build fails] 74 Gem files will remain installed in \\ 75 /path/to/gems/some_extension_gem-1.0 for inspection. 76 Results logged to /path/to/gems/some_extension_gem-1.0/gem_make.out 77 $ gem install some_extension_gem -- --with-extension-lib=/path/to/lib 78 [build succeeds] 79 $ gem list some_extension_gem 80 81 *** LOCAL GEMS *** 82 83 some_extension_gem (1.0) 84 $ 85 86If you correct the compilation errors by editing the gem files you will need 87to write the specification by hand. For example: 88 89 $ gem install some_extension_gem 90 [build fails] 91 Gem files will remain installed in \\ 92 /path/to/gems/some_extension_gem-1.0 for inspection. 93 Results logged to /path/to/gems/some_extension_gem-1.0/gem_make.out 94 $ [cd /path/to/gems/some_extension_gem-1.0] 95 $ [edit files or what-have-you and run make] 96 $ gem spec ../../cache/some_extension_gem-1.0.gem --ruby > \\ 97 ../../specifications/some_extension_gem-1.0.gemspec 98 $ gem list some_extension_gem 99 100 *** LOCAL GEMS *** 101 102 some_extension_gem (1.0) 103 $ 104 105 EOF 106 end 107 108 def usage # :nodoc: 109 "#{program_name} GEMNAME [GEMNAME ...] [options] -- --build-flags" 110 end 111 112 def install_from_gemdeps(gf) 113 require 'rubygems/request_set' 114 rs = Gem::RequestSet.new 115 rs.load_gemdeps gf 116 117 rs.resolve 118 119 specs = rs.install options do |req, inst| 120 s = req.full_spec 121 122 if inst 123 say "Installing #{s.name} (#{s.version})" 124 else 125 say "Using #{s.name} (#{s.version})" 126 end 127 end 128 129 @installed_specs = specs 130 131 raise Gem::SystemExitException, 0 132 end 133 134 def execute 135 if gf = options[:gemdeps] then 136 install_from_gemdeps gf 137 return 138 end 139 140 @installed_specs = [] 141 142 ENV.delete 'GEM_PATH' if options[:install_dir].nil? and RUBY_VERSION > '1.9' 143 144 if options[:install_dir] and options[:user_install] 145 alert_error "Use --install-dir or --user-install but not both" 146 terminate_interaction 1 147 end 148 149 exit_code = 0 150 151 if options[:version] != Gem::Requirement.default && 152 get_all_gem_names.size > 1 then 153 alert_error "Can't use --version w/ multiple gems. Use name:ver instead." 154 terminate_interaction 1 155 end 156 157 158 get_all_gem_names_and_versions.each do |gem_name, gem_version| 159 gem_version ||= options[:version] 160 161 begin 162 next if options[:conservative] and 163 not Gem::Dependency.new(gem_name, gem_version).matching_specs.empty? 164 165 inst = Gem::DependencyInstaller.new options 166 inst.install gem_name, Gem::Requirement.create(gem_version) 167 168 @installed_specs.push(*inst.installed_gems) 169 170 next unless errs = inst.errors 171 172 errs.each do |x| 173 next unless Gem::SourceFetchProblem === x 174 175 msg = "Unable to pull data from '#{x.source.uri}': #{x.error.message}" 176 177 alert_warning msg 178 end 179 rescue Gem::InstallError => e 180 alert_error "Error installing #{gem_name}:\n\t#{e.message}" 181 exit_code |= 1 182 rescue Gem::GemNotFoundException => e 183 show_lookup_failure e.name, e.version, e.errors, options[:domain] 184 185 exit_code |= 2 186 end 187 end 188 189 unless @installed_specs.empty? then 190 gems = @installed_specs.length == 1 ? 'gem' : 'gems' 191 say "#{@installed_specs.length} #{gems} installed" 192 end 193 194 raise Gem::SystemExitException, exit_code 195 end 196 197end 198 199