mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
509 lines
13 KiB
Ruby
509 lines
13 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
RSpec.describe "real source plugins" do
|
|
context "with a minimal source plugin" do
|
|
before do
|
|
build_repo2 do
|
|
build_plugin "bundler-source-mpath" do |s|
|
|
s.write "plugins.rb", <<-RUBY
|
|
require "bundler-source-mpath"
|
|
|
|
class MPath < Bundler::Plugin::API
|
|
source "mpath"
|
|
|
|
attr_reader :path
|
|
|
|
def initialize(opts)
|
|
super
|
|
|
|
@path = Pathname.new options["uri"]
|
|
end
|
|
|
|
def fetch_gemspec_files
|
|
@spec_files ||= begin
|
|
glob = "{,*,*/*}.gemspec"
|
|
if installed?
|
|
search_path = install_path
|
|
else
|
|
search_path = path
|
|
end
|
|
Dir["\#{search_path.to_s}/\#{glob}"]
|
|
end
|
|
end
|
|
|
|
def install(spec, opts)
|
|
mkdir_p(install_path.parent)
|
|
FileUtils.cp_r(path, install_path)
|
|
|
|
spec_path = install_path.join("\#{spec.full_name}.gemspec")
|
|
spec_path.open("wb") {|f| f.write spec.to_ruby }
|
|
spec.loaded_from = spec_path.to_s
|
|
|
|
post_install(spec)
|
|
|
|
nil
|
|
end
|
|
end
|
|
RUBY
|
|
end # build_plugin
|
|
end
|
|
|
|
build_lib "a-path-gem"
|
|
|
|
gemfile <<-G
|
|
source "#{file_uri_for(gem_repo2)}" # plugin source
|
|
source "#{lib_path("a-path-gem-1.0")}", :type => :mpath do
|
|
gem "a-path-gem"
|
|
end
|
|
G
|
|
end
|
|
|
|
it "installs" do
|
|
bundle "install"
|
|
|
|
expect(out).to include("Bundle complete!")
|
|
|
|
expect(the_bundle).to include_gems("a-path-gem 1.0")
|
|
end
|
|
|
|
it "writes to lock file", :bundler => "< 3" do
|
|
bundle "install"
|
|
|
|
lockfile_should_be <<-G
|
|
PLUGIN SOURCE
|
|
remote: #{lib_path("a-path-gem-1.0")}
|
|
type: mpath
|
|
specs:
|
|
a-path-gem (1.0)
|
|
|
|
GEM
|
|
remote: #{file_uri_for(gem_repo2)}/
|
|
specs:
|
|
|
|
PLATFORMS
|
|
#{generic_local_platform}
|
|
|
|
DEPENDENCIES
|
|
a-path-gem!
|
|
|
|
BUNDLED WITH
|
|
#{Bundler::VERSION}
|
|
G
|
|
end
|
|
|
|
it "writes to lock file", :bundler => "3" do
|
|
bundle "install"
|
|
|
|
lockfile_should_be <<-G
|
|
PLUGIN SOURCE
|
|
remote: #{lib_path("a-path-gem-1.0")}
|
|
type: mpath
|
|
specs:
|
|
a-path-gem (1.0)
|
|
|
|
GEM
|
|
remote: #{file_uri_for(gem_repo2)}/
|
|
specs:
|
|
|
|
PLATFORMS
|
|
#{lockfile_platforms}
|
|
|
|
DEPENDENCIES
|
|
a-path-gem!
|
|
|
|
BUNDLED WITH
|
|
#{Bundler::VERSION}
|
|
G
|
|
end
|
|
|
|
it "provides correct #full_gem_path" do
|
|
bundle "install"
|
|
run <<-RUBY
|
|
puts Bundler.rubygems.find_name('a-path-gem').first.full_gem_path
|
|
RUBY
|
|
expect(out).to eq(bundle("info a-path-gem --path"))
|
|
end
|
|
|
|
it "installs the gem executables" do
|
|
build_lib "gem_with_bin" do |s|
|
|
s.executables = ["foo"]
|
|
end
|
|
|
|
install_gemfile <<-G
|
|
source "#{file_uri_for(gem_repo2)}" # plugin source
|
|
source "#{lib_path("gem_with_bin-1.0")}", :type => :mpath do
|
|
gem "gem_with_bin"
|
|
end
|
|
G
|
|
|
|
bundle "exec foo"
|
|
expect(out).to eq("1.0")
|
|
end
|
|
|
|
describe "bundle cache/package" do
|
|
let(:uri_hash) { Digest(:SHA1).hexdigest(lib_path("a-path-gem-1.0").to_s) }
|
|
it "copies repository to vendor cache and uses it" do
|
|
bundle "install"
|
|
bundle "config set cache_all true"
|
|
bundle :cache
|
|
|
|
expect(bundled_app("vendor/cache/a-path-gem-1.0-#{uri_hash}")).to exist
|
|
expect(bundled_app("vendor/cache/a-path-gem-1.0-#{uri_hash}/.git")).not_to exist
|
|
expect(bundled_app("vendor/cache/a-path-gem-1.0-#{uri_hash}/.bundlecache")).to be_file
|
|
|
|
FileUtils.rm_rf lib_path("a-path-gem-1.0")
|
|
expect(the_bundle).to include_gems("a-path-gem 1.0")
|
|
end
|
|
|
|
it "copies repository to vendor cache and uses it even when installed with `path` configured" do
|
|
bundle "config --local path vendor/bundle"
|
|
bundle :install
|
|
bundle "config set cache_all true"
|
|
bundle :cache
|
|
|
|
expect(bundled_app("vendor/cache/a-path-gem-1.0-#{uri_hash}")).to exist
|
|
|
|
FileUtils.rm_rf lib_path("a-path-gem-1.0")
|
|
expect(the_bundle).to include_gems("a-path-gem 1.0")
|
|
end
|
|
|
|
it "bundler package copies repository to vendor cache" do
|
|
bundle "config --local path vendor/bundle"
|
|
bundle :install
|
|
bundle "config set cache_all true"
|
|
bundle :cache
|
|
|
|
expect(bundled_app("vendor/cache/a-path-gem-1.0-#{uri_hash}")).to exist
|
|
|
|
FileUtils.rm_rf lib_path("a-path-gem-1.0")
|
|
expect(the_bundle).to include_gems("a-path-gem 1.0")
|
|
end
|
|
end
|
|
|
|
context "with lockfile" do
|
|
before do
|
|
lockfile <<-G
|
|
PLUGIN SOURCE
|
|
remote: #{lib_path("a-path-gem-1.0")}
|
|
type: mpath
|
|
specs:
|
|
a-path-gem (1.0)
|
|
|
|
GEM
|
|
remote: #{file_uri_for(gem_repo2)}/
|
|
specs:
|
|
|
|
PLATFORMS
|
|
#{generic_local_platform}
|
|
|
|
DEPENDENCIES
|
|
a-path-gem!
|
|
|
|
BUNDLED WITH
|
|
#{Bundler::VERSION}
|
|
G
|
|
end
|
|
|
|
it "installs" do
|
|
bundle "install"
|
|
|
|
expect(the_bundle).to include_gems("a-path-gem 1.0")
|
|
end
|
|
end
|
|
end
|
|
|
|
context "with a more elaborate source plugin" do
|
|
before do
|
|
build_repo2 do
|
|
build_plugin "bundler-source-gitp" do |s|
|
|
s.write "plugins.rb", <<-RUBY
|
|
require "open3"
|
|
|
|
class SPlugin < Bundler::Plugin::API
|
|
source "gitp"
|
|
|
|
attr_reader :ref
|
|
|
|
def initialize(opts)
|
|
super
|
|
|
|
@ref = options["ref"] || options["branch"] || options["tag"] || "master"
|
|
@unlocked = false
|
|
end
|
|
|
|
def eql?(other)
|
|
other.is_a?(self.class) && uri == other.uri && ref == other.ref
|
|
end
|
|
|
|
alias_method :==, :eql?
|
|
|
|
def fetch_gemspec_files
|
|
@spec_files ||= begin
|
|
glob = "{,*,*/*}.gemspec"
|
|
if !cached?
|
|
cache_repo
|
|
end
|
|
|
|
if installed? && !@unlocked
|
|
path = install_path
|
|
else
|
|
path = cache_path
|
|
end
|
|
|
|
Dir["\#{path}/\#{glob}"]
|
|
end
|
|
end
|
|
|
|
def install(spec, opts)
|
|
mkdir_p(install_path.dirname)
|
|
rm_rf(install_path)
|
|
`git clone --no-checkout --quiet "\#{cache_path}" "\#{install_path}"`
|
|
Open3.capture2e("git reset --hard \#{revision}", :chdir => install_path)
|
|
|
|
spec_path = install_path.join("\#{spec.full_name}.gemspec")
|
|
spec_path.open("wb") {|f| f.write spec.to_ruby }
|
|
spec.loaded_from = spec_path.to_s
|
|
|
|
post_install(spec)
|
|
|
|
nil
|
|
end
|
|
|
|
def options_to_lock
|
|
opts = {"revision" => revision}
|
|
opts["ref"] = ref if ref != "master"
|
|
opts
|
|
end
|
|
|
|
def unlock!
|
|
@unlocked = true
|
|
@revision = latest_revision
|
|
end
|
|
|
|
def app_cache_dirname
|
|
"\#{base_name}-\#{shortref_for_path(revision)}"
|
|
end
|
|
|
|
private
|
|
|
|
def cache_path
|
|
@cache_path ||= cache_dir.join("gitp", base_name)
|
|
end
|
|
|
|
def cache_repo
|
|
`git clone --quiet \#{@options["uri"]} \#{cache_path}`
|
|
end
|
|
|
|
def cached?
|
|
File.directory?(cache_path)
|
|
end
|
|
|
|
def locked_revision
|
|
options["revision"]
|
|
end
|
|
|
|
def revision
|
|
@revision ||= locked_revision || latest_revision
|
|
end
|
|
|
|
def latest_revision
|
|
if !cached? || @unlocked
|
|
rm_rf(cache_path)
|
|
cache_repo
|
|
end
|
|
|
|
output, _status = Open3.capture2e("git rev-parse --verify \#{@ref}", :chdir => cache_path)
|
|
output.strip
|
|
end
|
|
|
|
def base_name
|
|
File.basename(uri.sub(%r{^(\w+://)?([^/:]+:)?(//\w*/)?(\w*/)*}, ""), ".git")
|
|
end
|
|
|
|
def shortref_for_path(ref)
|
|
ref[0..11]
|
|
end
|
|
|
|
def install_path
|
|
@install_path ||= begin
|
|
git_scope = "\#{base_name}-\#{shortref_for_path(revision)}"
|
|
|
|
path = gem_install_dir.join(git_scope)
|
|
|
|
if !path.exist? && requires_sudo?
|
|
user_bundle_path.join(ruby_scope).join(git_scope)
|
|
else
|
|
path
|
|
end
|
|
end
|
|
end
|
|
|
|
def installed?
|
|
File.directory?(install_path)
|
|
end
|
|
end
|
|
RUBY
|
|
end
|
|
end
|
|
|
|
build_git "ma-gitp-gem"
|
|
|
|
gemfile <<-G
|
|
source "#{file_uri_for(gem_repo2)}" # plugin source
|
|
source "#{file_uri_for(lib_path("ma-gitp-gem-1.0"))}", :type => :gitp do
|
|
gem "ma-gitp-gem"
|
|
end
|
|
G
|
|
end
|
|
|
|
it "handles the source option" do
|
|
bundle "install"
|
|
expect(out).to include("Bundle complete!")
|
|
expect(the_bundle).to include_gems("ma-gitp-gem 1.0")
|
|
end
|
|
|
|
it "writes to lock file", :bundler => "< 3" do
|
|
revision = revision_for(lib_path("ma-gitp-gem-1.0"))
|
|
bundle "install"
|
|
|
|
lockfile_should_be <<-G
|
|
PLUGIN SOURCE
|
|
remote: #{file_uri_for(lib_path("ma-gitp-gem-1.0"))}
|
|
type: gitp
|
|
revision: #{revision}
|
|
specs:
|
|
ma-gitp-gem (1.0)
|
|
|
|
GEM
|
|
remote: #{file_uri_for(gem_repo2)}/
|
|
specs:
|
|
|
|
PLATFORMS
|
|
#{generic_local_platform}
|
|
|
|
DEPENDENCIES
|
|
ma-gitp-gem!
|
|
|
|
BUNDLED WITH
|
|
#{Bundler::VERSION}
|
|
G
|
|
end
|
|
|
|
it "writes to lock file", :bundler => "3" do
|
|
revision = revision_for(lib_path("ma-gitp-gem-1.0"))
|
|
bundle "install"
|
|
|
|
lockfile_should_be <<-G
|
|
PLUGIN SOURCE
|
|
remote: #{file_uri_for(lib_path("ma-gitp-gem-1.0"))}
|
|
type: gitp
|
|
revision: #{revision}
|
|
specs:
|
|
ma-gitp-gem (1.0)
|
|
|
|
GEM
|
|
remote: #{file_uri_for(gem_repo2)}/
|
|
specs:
|
|
|
|
PLATFORMS
|
|
#{lockfile_platforms}
|
|
|
|
DEPENDENCIES
|
|
ma-gitp-gem!
|
|
|
|
BUNDLED WITH
|
|
#{Bundler::VERSION}
|
|
G
|
|
end
|
|
|
|
context "with lockfile" do
|
|
before do
|
|
revision = revision_for(lib_path("ma-gitp-gem-1.0"))
|
|
lockfile <<-G
|
|
PLUGIN SOURCE
|
|
remote: #{file_uri_for(lib_path("ma-gitp-gem-1.0"))}
|
|
type: gitp
|
|
revision: #{revision}
|
|
specs:
|
|
ma-gitp-gem (1.0)
|
|
|
|
GEM
|
|
remote: #{file_uri_for(gem_repo2)}/
|
|
specs:
|
|
|
|
PLATFORMS
|
|
#{generic_local_platform}
|
|
|
|
DEPENDENCIES
|
|
ma-gitp-gem!
|
|
|
|
BUNDLED WITH
|
|
#{Bundler::VERSION}
|
|
G
|
|
end
|
|
|
|
it "installs" do
|
|
bundle "install"
|
|
expect(the_bundle).to include_gems("ma-gitp-gem 1.0")
|
|
end
|
|
|
|
it "uses the locked ref" do
|
|
update_git "ma-gitp-gem"
|
|
bundle "install"
|
|
|
|
run <<-RUBY
|
|
require 'ma/gitp/gem'
|
|
puts "WIN" unless defined?(MAGITPGEM_PREV_REF)
|
|
RUBY
|
|
expect(out).to eq("WIN")
|
|
end
|
|
|
|
it "updates the deps on bundler update" do
|
|
update_git "ma-gitp-gem"
|
|
bundle "update ma-gitp-gem"
|
|
|
|
run <<-RUBY
|
|
require 'ma/gitp/gem'
|
|
puts "WIN" if defined?(MAGITPGEM_PREV_REF)
|
|
RUBY
|
|
expect(out).to eq("WIN")
|
|
end
|
|
|
|
it "updates the deps on change in gemfile" do
|
|
update_git "ma-gitp-gem", "1.1", :path => lib_path("ma-gitp-gem-1.0"), :gemspec => true
|
|
gemfile <<-G
|
|
source "#{file_uri_for(gem_repo2)}" # plugin source
|
|
source "#{file_uri_for(lib_path("ma-gitp-gem-1.0"))}", :type => :gitp do
|
|
gem "ma-gitp-gem", "1.1"
|
|
end
|
|
G
|
|
bundle "install"
|
|
|
|
expect(the_bundle).to include_gems("ma-gitp-gem 1.1")
|
|
end
|
|
end
|
|
|
|
describe "bundle cache with gitp" do
|
|
it "copies repository to vendor cache and uses it" do
|
|
git = build_git "foo"
|
|
ref = git.ref_for("master", 11)
|
|
|
|
install_gemfile <<-G
|
|
source "#{file_uri_for(gem_repo2)}" # plugin source
|
|
source '#{lib_path("foo-1.0")}', :type => :gitp do
|
|
gem "foo"
|
|
end
|
|
G
|
|
|
|
bundle "config set cache_all true"
|
|
bundle :cache
|
|
expect(bundled_app("vendor/cache/foo-1.0-#{ref}")).to exist
|
|
expect(bundled_app("vendor/cache/foo-1.0-#{ref}/.git")).not_to exist
|
|
expect(bundled_app("vendor/cache/foo-1.0-#{ref}/.bundlecache")).to be_file
|
|
|
|
FileUtils.rm_rf lib_path("foo-1.0")
|
|
expect(the_bundle).to include_gems "foo 1.0"
|
|
end
|
|
end
|
|
end
|
|
end
|