class BundlerSourceAwsS3::S3Source
Public Instance Methods
TODO What is bundler telling us if cached! is called?
# File plugins.rb, line 62 def cached! puts "[aws-s3] DEBUG: cached! called" end
Bundler plugin api, we need to install the gem for the given spec and then call post_install.
# File plugins.rb, line 12 def install(spec, opts) print_using_message "Using #{spec.name} #{spec.version} from #{self}" validate!(spec) package = package_for(spec) destination = install_path.join(spec.full_name) Bundler.mkdir_p(destination) package.extract_files(destination) File.open(spec.loaded_from, 'wb') { |f| f.write spec.to_ruby } post_install(spec) end
Bundler calls this to tell us fetching remote gems is okay.
# File plugins.rb, line 48 def remote! @remote = true end
# File plugins.rb, line 52 def remote? @remote ||= false end
Bundler plugin api, we need to return a Bundler::Index
# File plugins.rb, line 28 def specs # Only pull gems if bundler tells us to check remote pull if remote? # We haven't pulled any s3 gems if the directory doesn't exist, so we'll # give bundler an empty index. return Bundler::Index.new unless File.directory?(s3_gems_path) Bundler::Index.build do |index| packages.map(&:spec).each do |spec| spec.source = self spec.loaded_from = loaded_from_for(spec) Bundler.rubygems.validate(spec) index << spec end end end
# File plugins.rb, line 66 def to_s "aws-s3 plugin with uri #{uri}" end
TODO What is bundler telling us if unlock! is called?
# File plugins.rb, line 57 def unlock! puts "[aws-s3] DEBUG: unlock! called" end
Private Instance Methods
# File plugins.rb, line 136 def bucket URI.parse(uri).normalize.host end
This path is going to be under bundler's gem_install_dir and we'll then mirror the bucket/path directory structure from the source. This is where we want to place our gems. This directory can hold multiple installed gems.
# File plugins.rb, line 94 def install_path @install_path ||= gem_install_dir.join(bucket).join(path) end
We will use this value as the given spec's loaded_from. It should be the path of the installed gem's gemspec.
# File plugins.rb, line 85 def loaded_from_for(spec) destination = install_path.join(spec.full_name) destination.join("#{spec.full_name}.gemspec").to_s end
Find the Gem::Package for a given spec.
# File plugins.rb, line 128 def package_for(spec) packages.find { |package| package.spec.full_name == spec.full_name } end
Produces a list of Gem::Package for the s3 gems.
# File plugins.rb, line 120 def packages @packages ||= Dir.entries(s3_gems_path.join('gems')). map { |entry| s3_gems_path.join('gems').join(entry) }. select { |gem_path| File.file?(gem_path) }. map { |gem_path| Gem::Package.new(gem_path.to_s) } end
# File plugins.rb, line 140 def path # Remove the leading slash from the path. URI.parse(uri).normalize.path[1..-1] end
Pull s3 gems from the source and store them in .bundle/bundler-source-aws-s3/<bucket>/<path>. We will install, etc, from this directory.
# File plugins.rb, line 108 def pull # We only want to pull once in a single bundler run. return @pull if defined?(@pull) Bundler.mkdir_p(s3_gems_path) unless @pull = Open3.capture2(sync_cmd).last.success? raise "[aws-s3] #{sync_cmd.inspect} failed." end end
This is the path to the s3 gems for our source uri. We will pull the s3 gems into this directory.
# File plugins.rb, line 100 def s3_gems_path Bundler.user_bundle_path. join('bundler-source-aws-s3').join(bucket).join(path) end
# File plugins.rb, line 132 def sync_cmd "aws s3 sync --delete #{uri} #{s3_gems_path}" end
This is a guard against attempting to install a spec that doesn't match our requirements / expectations.
If we want to be more trusting, we could probably safely remove this method.
# File plugins.rb, line 77 def validate!(spec) unless spec.source == self && spec.loaded_from == loaded_from_for(spec) raise "[aws-s3] Error #{spec.full_name} spec is not valid" end end