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