| 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