class Bundler::Source::Path
def self.from_lock(options)
def self.from_lock(options) new(options.merge("path" => options.delete("remote"))) end
def cache(spec)
def cache(spec) unless path.to_s.index(Bundler.root.to_s) == 0 Bundler.ui.warn " * #{spec.name} at `#{path}` will not be cached." end end
def cached!
def cached! @allow_cached = true end
def eql?(o)
def eql?(o) Path === o && path == o.path && name == o.name && version == o.version end
def generate_bin(spec)
def generate_bin(spec) gem_dir = Pathname.new(spec.full_gem_path) # Some gem authors put absolute paths in their gemspec # and we have to save them from themselves spec.files = spec.files.map do |p| next if File.directory?(p) begin Pathname.new(p).relative_path_from(gem_dir).to_s rescue ArgumentError p end end.compact gem_file = Dir.chdir(gem_dir){ Gem::Builder.new(spec).build } installer = Gem::Installer.new File.join(gem_dir, gem_file), :bin_dir => "#{Gem.dir}/bin", :wrappers => true, :env_shebang => false, :format_executable => false installer.instance_eval { @gem_dir = gem_dir } installer.build_extensions installer.generate_bin rescue Gem::InvalidSpecificationException => e Bundler.ui.warn "\n#{spec.name} at #{spec.full_gem_path} did not have a valid gemspec.\n" \ "This prevents bundler from installing bins or native extensions, but " \ "that may not affect its functionality." if !spec.extensions.empty? && !spec.email.empty? Bundler.ui.warn "If you need to use this package without installing it from a gem " \ "repository, please contact #{spec.email} and ask them " \ "to modify their .gemspec so it can work with `gem build`." end Bundler.ui.warn "The validation message from Rubygems was:\n #{e.message}" ensure Dir.chdir(gem_dir){ FileUtils.rm_rf(gem_file) if gem_file && File.exist?(gem_file) } end
def hash
def hash self.class.hash end
def initialize(options)
def initialize(options) @options = options @glob = options["glob"] || DEFAULT_GLOB @allow_cached = false @allow_remote = false if options["path"] @path = Pathname.new(options["path"]).expand_path(Bundler.root) end @name = options["name"] @version = options["version"] end
def install(spec)
def install(spec) Bundler.ui.info "Using #{spec.name} (#{spec.version}) from #{to_s} " # Let's be honest, when we're working from a path, we can't # really expect native extensions to work because the whole point # is to just be able to modify what's in that path and go. So, let's # not put ourselves through the pain of actually trying to generate # the full gem. Installer.new(spec).generate_bin end
def load_spec_files
def load_spec_files index = Index.new if File.directory?(path) Dir["#{path}/#{@glob}"].each do |file| file = Pathname.new(file) # Eval the gemspec from its parent directory spec = Dir.chdir(file.dirname) do begin Gem::Specification.from_yaml(file.basename) # Raises ArgumentError if the file is not valid YAML rescue ArgumentError, Gem::EndOfYAMLException, Gem::Exception begin eval(File.read(file.basename), TOPLEVEL_BINDING, file.expand_path.to_s) rescue LoadError raise GemspecError, "There was a LoadError while evaluating #{file.basename}.\n" + "Does it try to require a relative path? That doesn't work in Ruby 1.9." end end end if spec spec.loaded_from = file.to_s spec.source = self index << spec end end if index.empty? && @name && @version index << Gem::Specification.new do |s| s.name = @name s.source = self s.version = Gem::Version.new(@version) s.platform = Gem::Platform::RUBY s.summary = "Fake gemspec for #{@name}" s.relative_loaded_from = "#{@name}.gemspec" if path.join("bin").exist? binaries = path.join("bin").children.map{|c| c.basename.to_s } s.executables = binaries end end end else raise PathError, "The path `#{path}` does not exist." end index end
def local_specs
def local_specs @local_specs ||= load_spec_files end
def name
def name File.basename(@path.to_s) end
def relative_path
def relative_path if path.to_s.include?(Bundler.root.to_s) return path.relative_path_from(Bundler.root) end path end
def remote!
def remote! @allow_remote = true end
def to_lock
def to_lock out = "PATH\n" out << " remote: #{relative_path}\n" out << " glob: #{@glob}\n" unless @glob == DEFAULT_GLOB out << " specs:\n" end
def to_s
def to_s "source at #{@path}" end