class Gem::Commands::InsturlCommand < Gem::Command def initialize super "insturl", "Install a gem from a URL" add_option("--git", "use `git clone' to fetch the URL") do |val, opt| options[:git] = true end add_option("--override", "install even if already exists") do |val, opt| options[:override] = true end end def description < 1 raise Gem::Exception.new("multiple gemspecs found") end gemspec = gemspecs[0] # load gemspec file spec = eval File.read(gemspec) name, version = spec.name, spec.version prevent_overriding(name, version) unless options[:override] # build and install build_gem gemspec install_gem "#{name}-#{version}.gem" end # Abort if the gem has already been installed. def prevent_overriding(name, version) find_gem_versions(name).each do |vsn| if vsn == version err = "#{name} #{version} has already been installed" raise Gem::Exception.new(err) end end end # Find installed versions of the gem. # Return a sequence of Gem::Version instances. def find_gem_versions(name) find_gem_specs(name).map{|spec| spec.version} end # Find installed versions of the gem. # Return a sequence of Gem::Specification instances. def find_gem_specs(name) if Gem::Specification.respond_to? :find_all_by_name Gem::Specification.find_all_by_name name elsif Gem.respond_to? :source_index and Gem.source_index.respond_to? :find_name Gem.source_index.find_name name else raise Gem::Exception.new("unsupported gem version") end end # Build a gem from a gemspec file. # e.g. gem-insturl.gemspec -> gem-insturl-0.1.0.gem def build_gem(gemspec_file) require 'rubygems/commands/build_command' Gem::Commands::BuildCommand.new.invoke gemspec_file end # Install a gem. # e.g. gem-insturl-0.1.0.gem def install_gem(gem_file) require 'rubygems/commands/install_command' Gem::Commands::InstallCommand.new.invoke gem_file end # Get specification of a gem file. # Return a Gem::Specification instance. def get_gem_spec(gem_file) begin require 'rubygems/format' Gem::Format.from_file_by_path(gem_file).spec rescue LoadError require 'rubygems/package' Gem::Package.new(gem_file).spec end end # List files in current directory. # Return an Array of String. def files_in_cwd Dir["*"].delete_if{|ent| !File.file?(ent)} end # List subdirectories in current directory. # Return an Array of String. def subdirs_in_cwd Dir["*"].delete_if{|ent| !File.directory?(ent)} end end # class Gem::Commands::InsturlCommand