Module GemManagement
In: merb-core/lib/merb-core/tasks/gem_management.rb

Methods

Included Modules

ColorfulMessages

Public Instance methods

[Source]

     # 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.

[Source]

     # 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

[Source]

     # 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.

[Source]

    # 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.

[Source]

     # 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 => […])

[Source]

     # 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

[Source]

     # 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

[Source]

     # 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

[Source]

     # 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

[Source]

     # 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

[Source]

     # 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

[Source]

     # 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.

[Source]

     # 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.

[Source]

     # 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

Private Instance methods

[Source]

     # 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

[Source]

     # 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

[Source]

     # File merb-core/lib/merb-core/tasks/gem_management.rb, line 361
361:   def update_source_index(dir)
362:     Gem.source_index.load_gems_in(File.join(dir, 'specifications'))
363:   end

[Validate]