module Bundler::Plugin::API::Source
def ==(other)
lockfile. To converge the sources, it is necessary that they match.
The sources objects are constructed from Gemfile as well as from
sources should compare on branch and tag but not on commit hash)
that are used to pin down the gem to specific version (e.g. Git
inferred from the options passed from Gemfile and not on attributes
The comparison shall take place only on the attribute that can be
This shall check if two source object represent the same source.
def ==(other) other.is_a?(self.class) && uri == other.uri end
def add_dependency_names(names)
Used by definition.
def add_dependency_names(names) @dependencies |= Array(names) end
def app_cache_dirname
Also this name is matched against the directories in cache for pruning
#cache is called.
Name of directory where plugin the is expected to cache the gems when
def app_cache_dirname base_name = File.basename(Bundler::URI.parse(uri).normalize.path) "#{base_name}-#{uri_hash}" end
def app_cache_path(custom_path = nil)
installed latter.
The full path where the plugin should cache the gem so that it can be
def app_cache_path(custom_path = nil) @app_cache_path ||= Bundler.app_cache(custom_path).join(app_cache_dirname) end
def cache(spec, custom_path = nil)
at sub paths of `cache_path` (from API). This can be though as caching
This cache is different from the internal caching that can be done
specs and install only from this cache when `cached!` is called.
This is stored with the app and source plugins should try to provide
alternative to remote)
be reinstalled from the cache without querying the remote (i.e. an
source can resolve to path provided by `app_cache_app`so that they can
This method is called while caching to save copy of the gems that the
def cache(spec, custom_path = nil) new_cache_path = app_cache_path(custom_path) FileUtils.rm_rf(new_cache_path) FileUtils.cp_r(install_path, new_cache_path) FileUtils.touch(app_cache_path.join(".bundlecache")) end
def cached!
When this is called, the source should try to fetch the specs and
Set internal representation to fetch the gems/specs from app cache.
def cached! end
def can_lock?(spec)
def can_lock?(spec) spec.source == self end
def double_check_for(*); end
- Private: -
def double_check_for(*); end
def fetch_gemspec_files
-
(Array
- paths of the gemspec files for gems that can)
def fetch_gemspec_files [] end
def gem_install_dir
def gem_install_dir Bundler.install_path end
def hash
docstring for `==` method, i.e. two methods equal by above comparison
When overriding `hash` please preserve the behaviour as mentioned in
def hash [self.class, uri].hash end
def include?(other)
def include?(other) other == self end
def initialize(opts)
def initialize(opts) @options = opts @dependency_names = [] @uri = opts["uri"] @type = opts["type"] @name = opts["name"] || "#{@type} at #{@uri}" end
def install(spec, opts)
-
(String)
- post installation message (if any)
def install(spec, opts) raise MalformattedPlugin, "Source plugins need to override the install method." end
def install_path
servers multiple gems, it's not of much use and the source should one
A default installation path to install a single gem. If the source
def install_path @install_path ||= begin base_name = File.basename(Bundler::URI.parse(uri).normalize.path) gem_install_dir.join("#{base_name}-#{uri_hash[0..11]}") end end
def installed?
def installed? File.directory?(install_path) end
def local!
When this is called, the source should try to fetch the specs and
Set internal representation to fetch the gems/specs locally.
def local! end
def options_to_lock
-
(Hash)
-
def options_to_lock {} end
def post_install(spec, disable_exts = false)
It also runs Gem hooks `pre_install`, `post_build` and `post_install`
gem at correct install location.
It should be called in `install` after the plugin is done placing the
plugins should set that.
It depends on `spec.loaded_from` to get full_gem_path. The source
provided.
It builds extensions, generates bins and installs them for the spec
def post_install(spec, disable_exts = false) opts = { :env_shebang => false, :disable_extensions => disable_exts } installer = Bundler::Source::Path::Installer.new(spec, opts) installer.post_install end
def remote!
When this is called, the source should try to fetch the specs and
Set internal representation to fetch the gems/specs from remote.
def remote! end
def root
spec's loaded_from path is expanded against this to get full_gem_path
It is used to obtain the full_gem_path.
def root Bundler.root end
def spec_names
Used by definition.
def spec_names specs.spec_names end
def specs
-
(Bundler::Index)
- index containing the specs
def specs files = fetch_gemspec_files Bundler::Index.build do |index| files.each do |file| next unless spec = Bundler.load_gemspec(file) Bundler.rubygems.set_installed_by_version(spec) spec.source = self Bundler.rubygems.validate(spec) index << spec end end end
def to_lock
and not override this.
Plugin should use `options_to_lock` to save information in lockfile
Saves type and remote and also calls to `options_to_lock`.
Generates the content to be entered into the lockfile.
def to_lock out = String.new("#{LockfileParser::PLUGIN}\n") out << " remote: #{@uri}\n" out << " type: #{@type}\n" options_to_lock.each do |opt, value| out << " #{opt}: #{value}\n" end out << " specs:\n" end
def to_s
def to_s "plugin source for #{@type} with uri #{@uri}" end
def unlock!
If the source plugin is loaded from lockfile or otherwise, it shall
This is called to update the spec and installation.
def unlock! end
def unmet_deps
Used by definition.
def unmet_deps specs.unmet_dependency_names end
def uri_hash
def uri_hash SharedHelpers.digest(:SHA1).hexdigest(uri) end