Module: GemManagement
- Includes:
- ColorfulMessages
- Included in:
- Merb::RakeHelper
- Defined in:
- lib/merb-core/tasks/gem_management.rb
Instance Method Summary collapse
- #clobber(source_dir) ⇒ Object
-
#ensure_bin_wrapper_for(gem_dir, bin_dir, *gems) ⇒ Object
Create a modified executable wrapper in the specified bin directory.
- #ensure_bin_wrapper_for_installed_gems(gemspecs, options) ⇒ Object
-
#install_gem(gem, options = {}) ⇒ Object
Install a gem - looks remotely and local gem cache; won’t process rdoc or ri options.
-
#install_gem_from_cache(gem, options = {}) ⇒ Object
Install a gem - looks in the system’s gem cache instead of remotely; won’t process rdoc or ri options.
-
#install_gem_from_source(source_dir, *args) ⇒ Object
Install a gem from source - builds and packages it first then installs.
- #install_pkg(gem_pkg, opts = {}) ⇒ Object
- #package(source_dir, clobber = true) ⇒ Object
- #package_all(source_dir, skip = [], packages = []) ⇒ Object
-
#partition_dependencies(dependencies, gem_dir) ⇒ Object
Partition gems into system, local and missing gems.
- #rake(cmd) ⇒ Object
- #thor(cmd) ⇒ Object
-
#uninstall_gem(gem, options = {}) ⇒ Object
Uninstall a gem.
-
#which(executable) ⇒ Object
Use the local bin/* executables if available.
Methods included from ColorfulMessages
#error, #info, #note, #success, #warning
Instance Method Details
#clobber(source_dir) ⇒ Object
199 200 201 202 203 |
# File 'lib/merb-core/tasks/gem_management.rb', line 199 def clobber(source_dir) Dir.chdir(source_dir) do system "#{Gem.ruby} -S rake -s clobber" unless File.exists?('Thorfile') end end |
#ensure_bin_wrapper_for(gem_dir, bin_dir, *gems) ⇒ Object
Create a modified executable wrapper in the specified bin directory.
280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 |
# File 'lib/merb-core/tasks/gem_management.rb', line 280 def ensure_bin_wrapper_for(gem_dir, bin_dir, *gems) = gems.last.is_a?(Hash) ? gems.last : {} [:no_minigems] ||= [] if bin_dir && File.directory?(bin_dir) gems.each do |gem| if gemspec_path = Dir[File.join(gem_dir, 'specifications', "#{gem}-*.gemspec")].last spec = Gem::Specification.load(gemspec_path) enable_minigems = ![:no_minigems].include?(spec.name) spec.executables.each do |exec| executable = File.join(bin_dir, exec) "Writing executable wrapper #{executable}" File.open(executable, 'w', 0755) do |f| f.write(executable_wrapper(spec, exec, enable_minigems)) end end end end end end |
#ensure_bin_wrapper_for_installed_gems(gemspecs, options) ⇒ Object
300 301 302 303 304 305 |
# File 'lib/merb-core/tasks/gem_management.rb', line 300 def ensure_bin_wrapper_for_installed_gems(gemspecs, ) if [:install_dir] && [:bin_dir] gems = gemspecs.map { |spec| spec.name } ensure_bin_wrapper_for([:install_dir], [:bin_dir], *gems) end end |
#install_gem(gem, options = {}) ⇒ Object
Install a gem - looks remotely and local gem cache; won’t process rdoc or ri options.
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
# File 'lib/merb-core/tasks/gem_management.rb', line 46 def install_gem(gem, = {}) refresh = .delete(:refresh) || [] from_cache = (.key?(:cache) && .delete(:cache)) if from_cache install_gem_from_cache(gem, ) else version = .delete(:version) Gem.configuration.update_sources = false # Limit source index to install dir update_source_index([:install_dir]) if [:install_dir] installer = Gem::DependencyInstaller.new(.merge(:user_install => false)) # Force-refresh certain gems by excluding them from the current index if ![:ignore_dependencies] && refresh.respond_to?(:include?) && !refresh.empty? source_index = installer.instance_variable_get(:@source_index) source_index.gems.each do |name, spec| source_index.gems.delete(name) if refresh.include?(spec.name) end end exception = nil begin installer.install gem, version rescue Gem::InstallError => e exception = e rescue Gem::GemNotFoundException => e if from_cache && gem_file = find_gem_in_cache(gem, version) puts "Located #{gem} in gem cache..." installer.install gem_file else exception = e end rescue => e exception = e end if installer.installed_gems.empty? && exception error "Failed to install gem '#{gem} (#{version || 'any version'})' (#{exception.})" end ensure_bin_wrapper_for_installed_gems(installer.installed_gems, ) installer.installed_gems.each do |spec| success "Successfully installed #{spec.full_name}" end return !installer.installed_gems.empty? end end |
#install_gem_from_cache(gem, options = {}) ⇒ Object
Install a gem - looks in the system’s gem cache instead of remotely; won’t process rdoc or ri options.
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 |
# File 'lib/merb-core/tasks/gem_management.rb', line 96 def install_gem_from_cache(gem, = {}) version = .delete(:version) Gem.configuration.update_sources = false installer = Gem::DependencyInstaller.new(.merge(:user_install => false)) exception = nil begin if gem_file = find_gem_in_cache(gem, version) puts "Located #{gem} in gem cache..." installer.install gem_file else raise Gem::InstallError, "Unknown gem #{gem}" end rescue Gem::InstallError => e exception = e end if installer.installed_gems.empty? && exception error "Failed to install gem '#{gem}' (#{e.})" end ensure_bin_wrapper_for_installed_gems(installer.installed_gems, ) installer.installed_gems.each do |spec| success "Successfully installed #{spec.full_name}" end end |
#install_gem_from_source(source_dir, *args) ⇒ Object
Install a gem from source - builds and packages it first then installs.
Examples: install_gem_from_source(source_dir, :install_dir => …) install_gem_from_source(source_dir, gem_name) install_gem_from_source(source_dir, :skip => […])
126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 |
# File 'lib/merb-core/tasks/gem_management.rb', line 126 def install_gem_from_source(source_dir, *args) installed_gems = [] opts = args.last.is_a?(Hash) ? args.pop : {} Dir.chdir(source_dir) do gem_name = args[0] || File.basename(source_dir) gem_pkg_dir = File.join(source_dir, 'pkg') gem_pkg_glob = File.join(gem_pkg_dir, "#{gem_name}-*.gem") skip_gems = opts.delete(:skip) || [] # Cleanup what's already there clobber(source_dir) FileUtils.mkdir_p(gem_pkg_dir) unless File.directory?(gem_pkg_dir) # Recursively process all gem packages within the source dir skip_gems << gem_name packages = package_all(source_dir, skip_gems) if packages.length == 1 # The are no subpackages for the main package refresh = [gem_name] else # Gather all packages into the top-level pkg directory packages.each do |pkg| FileUtils.copy_entry(pkg, File.join(gem_pkg_dir, File.basename(pkg))) end # Finally package the main gem - without clobbering the already copied pkgs package(source_dir, false) # Gather subgems to refresh during installation of the main gem refresh = packages.map do |pkg| File.basename(pkg, '.gem')[/^(.*?)-([\d\.]+)$/, 1] rescue nil end.compact # Install subgems explicitly even if ignore_dependencies is set if opts[:ignore_dependencies] refresh.each do |name| gem_pkg = Dir[File.join(gem_pkg_dir, "#{name}-*.gem")][0] install_pkg(gem_pkg, opts) end end end ensure_bin_wrapper_for(opts[:install_dir], opts[:bin_dir], *installed_gems) # Finally install the main gem if install_pkg(Dir[gem_pkg_glob][0], opts.merge(:refresh => refresh)) installed_gems = refresh else installed_gems = [] end end installed_gems end |
#install_pkg(gem_pkg, opts = {}) ⇒ Object
181 182 183 184 185 186 187 188 |
# File 'lib/merb-core/tasks/gem_management.rb', line 181 def install_pkg(gem_pkg, opts = {}) if (gem_pkg && File.exists?(gem_pkg)) # Needs to be executed from the directory that contains all packages Dir.chdir(File.dirname(gem_pkg)) { install_gem(gem_pkg, opts) } else false end end |
#package(source_dir, clobber = true) ⇒ Object
205 206 207 208 209 210 211 212 213 214 215 |
# File 'lib/merb-core/tasks/gem_management.rb', line 205 def package(source_dir, clobber = true) Dir.chdir(source_dir) do if File.exists?('Thorfile') thor ":package" elsif File.exists?('Rakefile') rake "clobber" if clobber rake "package" end end Dir[File.join(source_dir, 'pkg/*.gem')] end |
#package_all(source_dir, skip = [], packages = []) ⇒ Object
217 218 219 220 221 222 223 224 225 226 |
# File 'lib/merb-core/tasks/gem_management.rb', line 217 def package_all(source_dir, skip = [], packages = []) if Dir[File.join(source_dir, '{Rakefile,Thorfile}')][0] name = File.basename(source_dir) Dir[File.join(source_dir, '*', '{Rakefile,Thorfile}')].each do |taskfile| package_all(File.dirname(taskfile), skip, packages) end packages.push(*package(source_dir)) unless skip.include?(name) end packages.uniq end |
#partition_dependencies(dependencies, gem_dir) ⇒ Object
Partition gems into system, local and missing gems
248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 |
# File 'lib/merb-core/tasks/gem_management.rb', line 248 def partition_dependencies(dependencies, gem_dir) system_specs, local_specs, missing_deps = [], [], [] if gem_dir && File.directory?(gem_dir) gem_dir = File.(gem_dir) ::Gem.clear_paths; ::Gem.path.unshift(gem_dir) ::Gem.source_index.refresh! dependencies.each do |dep| gemspecs = ::Gem.source_index.search(dep) local = gemspecs.reverse.find { |s| s.loaded_from.index(gem_dir) == 0 } if local local_specs << local elsif gemspecs.last system_specs << gemspecs.last else missing_deps << dep end end ::Gem.clear_paths else dependencies.each do |dep| gemspecs = ::Gem.source_index.search(dep) if gemspecs.last system_specs << gemspecs.last else missing_deps << dep end end end [system_specs, local_specs, missing_deps] end |
#rake(cmd) ⇒ Object
228 229 230 231 |
# File 'lib/merb-core/tasks/gem_management.rb', line 228 def rake(cmd) cmd << " >/dev/null" if $SILENT && !Gem.win_platform? system "#{Gem.ruby} -S #{which('rake')} -s #{cmd} >/dev/null" end |
#thor(cmd) ⇒ Object
233 234 235 236 |
# File 'lib/merb-core/tasks/gem_management.rb', line 233 def thor(cmd) cmd << " >/dev/null" if $SILENT && !Gem.win_platform? system "#{Gem.ruby} -S #{which('thor')} #{cmd}" end |
#uninstall_gem(gem, options = {}) ⇒ Object
Uninstall a gem.
191 192 193 194 195 196 197 |
# File 'lib/merb-core/tasks/gem_management.rb', line 191 def uninstall_gem(gem, = {}) if [:version] && ![:version].is_a?(Gem::Requirement) [:version] = Gem::Requirement.new ["= #{[:version]}"] end update_source_index([:install_dir]) if [:install_dir] Gem::Uninstaller.new(gem, ).uninstall rescue nil end |
#which(executable) ⇒ Object
Use the local bin/* executables if available.
239 240 241 242 243 244 245 |
# File 'lib/merb-core/tasks/gem_management.rb', line 239 def which(executable) if File.executable?(exec = File.join(Dir.pwd, 'bin', executable)) exec else executable end end |