diff options
33 files changed, 330 insertions, 95 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 5941e2ecdb..64d7542a5f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,29 @@ +## 1.9.4 (2015-04-13) + +Bugfixes: + + - fix regression in installing x86 and universal gems (#3565, @jdmundrawala) + - improve error when gems are missing (#3564, @sealocal) + +## 1.9.3 (2015-04-12) + +Bugfixes: + + - handle removal of `specs` from rubygems/rubygems@620910 (#3558, @indirect) + - install 'universal' gems on Windows (#3066, @jdmundrawala) + - stop passing --local during `rake install` task (#3236, @indirect) + - guard against all possible accidental public gem pushes (#3533, @indirect) + +## 1.9.2 (2015-03-30) + +Bugfixes: + + - ensure gem executables are executable (#3517, #3511, @indirect) + - fix warnings in Molinillo (#3516, @segiddins) + - ensure duplicate dependencies do not propagate (#3522, @segiddins) + - keep gems locked when updating another gem from the same source (#3520, @indirect) + - resolve race that could build gems without saved arguments (#3404, @indirect) + ## 1.9.1 (2015-03-21) Bugfixes: @@ -32,6 +58,13 @@ Features: - Molinillo resolver, shared with CocoaPods (@segiddins) - updated Thor to v0.19.1 (@segiddins) +## 1.8.6 (2015-03-30) + +Bugfixes: + + - keep gems locked when updating another gem from the same source (#3250, @indirect) + - resolve race that could build gems without saved arguments (#3404, @indirect) + ## 1.8.5 (2015-03-11) Bugfixes: diff --git a/bundler.gemspec b/bundler.gemspec index bd7e32e7c9..c9fafa59bd 100644 --- a/bundler.gemspec +++ b/bundler.gemspec @@ -16,10 +16,11 @@ Gem::Specification.new do |s| s.required_ruby_version = '>= 1.8.7' s.required_rubygems_version = '>= 1.3.6' - s.add_development_dependency 'mustache', '0.99.6' + s.add_development_dependency 'mustache', '0.99.6' s.add_development_dependency 'rdiscount', '~> 1.6' - s.add_development_dependency 'ronn', '~> 0.7.3' - s.add_development_dependency 'rspec', '~> 3.0' + s.add_development_dependency 'ronn', '~> 0.7.3' + s.add_development_dependency 'rspec', '~> 3.0' + s.add_development_dependency 'rake' s.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) } # we don't check in man pages, but we need to ship them because diff --git a/lib/bundler/cli/gem.rb b/lib/bundler/cli/gem.rb index a201c89910..f102dd50f9 100644 --- a/lib/bundler/cli/gem.rb +++ b/lib/bundler/cli/gem.rb @@ -54,6 +54,11 @@ module Bundler "bin/setup.tt" => "bin/setup" } + executables = %w[ + bin/console + bin/setup + ] + if ask_and_set(:coc, "Do you want to include a code of conduct in gems you generate?", "Codes of conduct can increase contributions to your project by contributors who " \ "prefer collaborative, safe spaces. You can read more about the code of conduct at " \ @@ -108,6 +113,12 @@ module Bundler thor.template("newgem/#{src}", target.join(dst), config) end + executables.each do |file| + path = target.join(file) + executable = (path.stat.mode | 0111) + path.chmod(executable) + end + Bundler.ui.info "Initializing git repo in #{target}" Dir.chdir(target) { `git init`; `git add .` } diff --git a/lib/bundler/definition.rb b/lib/bundler/definition.rb index 66d382168d..9643144427 100644 --- a/lib/bundler/definition.rb +++ b/lib/bundler/definition.rb @@ -284,7 +284,7 @@ module Bundler each do |spec| next if spec.name == 'bundler' out << spec.to_lock - end + end out << "\n" end @@ -577,8 +577,11 @@ module Bundler resolve end - def in_locked_deps?(dep, d) - d && dep.source == d.source + def in_locked_deps?(dep, locked_dep) + # Because the lockfile can't link a dep to a specific remote, we need to + # treat sources as equivalent anytime the locked dep has all the remotes + # that the Gemfile dep does. + locked_dep && locked_dep.source && dep.source && locked_dep.source.include?(dep.source) end def satisfies_locked_spec?(dep) diff --git a/lib/bundler/friendly_errors.rb b/lib/bundler/friendly_errors.rb index 4bd3e53381..2f24fc179e 100644 --- a/lib/bundler/friendly_errors.rb +++ b/lib/bundler/friendly_errors.rb @@ -73,7 +73,7 @@ module Bundler def self.issues_url(exception) 'https://github.com/bundler/bundler/search?q=' \ - "#{CGI.escape(exception.message)}&type=Issues" + "#{CGI.escape(exception.message.lines.first.chomp)}&type=Issues" end end diff --git a/lib/bundler/gem_helper.rb b/lib/bundler/gem_helper.rb index 6db31901e4..9aac3e0d75 100644 --- a/lib/bundler/gem_helper.rb +++ b/lib/bundler/gem_helper.rb @@ -44,6 +44,11 @@ module Bundler install_gem(built_gem_path) end + desc "Build and install #{name}-#{version}.gem into system gems without network access." + task 'install:local' => 'build' do + install_gem(built_gem_path, :local) + end + desc "Create tag #{version_tag} and build and push #{name}-#{version}.gem to Rubygems\n" \ "To prevent publishing in Rubygems use `gem_push=no rake release`" task 'release' => ['build', 'release:guard_clean', @@ -76,9 +81,9 @@ module Bundler File.join(base, 'pkg', file_name) end - def install_gem(built_gem_path=nil) + def install_gem(built_gem_path = nil, local = false) built_gem_path ||= build_gem - out, _ = sh_with_code("gem install '#{built_gem_path}' --local") + out, _ = sh_with_code("gem install '#{built_gem_path}'#{' --local' if local}") raise "Couldn't install gem, run `gem install #{built_gem_path}' for more detailed output" unless out[/Successfully installed/] Bundler.ui.confirm "#{name} (#{version}) installed." end diff --git a/lib/bundler/index.rb b/lib/bundler/index.rb index 8076c685e5..ea1edaca21 100644 --- a/lib/bundler/index.rb +++ b/lib/bundler/index.rb @@ -81,10 +81,6 @@ module Bundler end end - def source_types - sources.map{|s| s.class }.uniq - end - alias [] search def <<(spec) diff --git a/lib/bundler/installer.rb b/lib/bundler/installer.rb index 6cbdf3a6a9..7365b8f27e 100644 --- a/lib/bundler/installer.rb +++ b/lib/bundler/installer.rb @@ -98,20 +98,27 @@ module Bundler def install_gem_from_spec(spec, standalone = false, worker = 0, force = false) # Fetch the build settings, if there are any - settings = Bundler.settings["build.#{spec.name}"] - install_message = nil - post_install_message = nil - debug_message = nil - Bundler.rubygems.with_build_args [settings] do - install_message, post_install_message, debug_message = spec.source.install(spec, force) - if install_message.include? 'Installing' - Bundler.ui.confirm install_message - else - Bundler.ui.info install_message + settings = Bundler.settings["build.#{spec.name}"] + messages = nil + + if settings + # Build arguments are global, so this is mutexed + Bundler.rubygems.with_build_args [settings] do + messages = spec.source.install(spec, force) end - Bundler.ui.debug debug_message if debug_message - Bundler.ui.debug "#{worker}: #{spec.name} (#{spec.version}) from #{spec.loaded_from}" + else + messages = spec.source.install(spec, force) + end + + install_message, post_install_message, debug_message = *messages + + if install_message.include? 'Installing' + Bundler.ui.confirm install_message + else + Bundler.ui.info install_message end + Bundler.ui.debug debug_message if debug_message + Bundler.ui.debug "#{worker}: #{spec.name} (#{spec.version}) from #{spec.loaded_from}" if Bundler.settings[:bin] && standalone generate_standalone_bundler_executable_stubs(spec) diff --git a/lib/bundler/lazy_specification.rb b/lib/bundler/lazy_specification.rb index 16f46b8580..1119bdeed8 100644 --- a/lib/bundler/lazy_specification.rb +++ b/lib/bundler/lazy_specification.rb @@ -41,7 +41,7 @@ module Bundler out = " #{name} (#{version}-#{platform})\n" end - dependencies.sort_by {|d| d.to_s }.each do |dep| + dependencies.sort_by {|d| d.to_s }.uniq.each do |dep| next if dep.type == :development out << " #{dep.to_lock}\n" end diff --git a/lib/bundler/match_platform.rb b/lib/bundler/match_platform.rb index 757f2c6af4..e6a33ecbad 100644 --- a/lib/bundler/match_platform.rb +++ b/lib/bundler/match_platform.rb @@ -7,8 +7,7 @@ module Bundler def match_platform(p) Gem::Platform::RUBY == platform or platform.nil? or p == platform or - generic(Gem::Platform.new(platform)) == p or - platform === p + generic(Gem::Platform.new(platform)) === p end end end diff --git a/lib/bundler/resolver.rb b/lib/bundler/resolver.rb index df2c515cc5..5ec46acc82 100644 --- a/lib/bundler/resolver.rb +++ b/lib/bundler/resolver.rb @@ -323,12 +323,7 @@ module Bundler message << "Source does not contain any versions of '#{requirement}'" end else - message = "Could not find gem '#{requirement}' " - if @index.source_types.include?(Bundler::Source::Rubygems) - message << "in any of the gem sources listed in your Gemfile." - else - message << "in the gems available on this machine." - end + message = "Could not find gem '#{requirement}' in any of the gem sources listed in your Gemfile or installed on this machine." end raise GemNotFound, message end diff --git a/lib/bundler/rubygems_integration.rb b/lib/bundler/rubygems_integration.rb index 1cb9e72808..3c6c658299 100644 --- a/lib/bundler/rubygems_integration.rb +++ b/lib/bundler/rubygems_integration.rb @@ -161,12 +161,14 @@ module Bundler end def with_build_args(args) - old_args = self.build_args - begin - self.build_args = args - yield - ensure - self.build_args = old_args + ext_lock.synchronize do + old_args = self.build_args + begin + self.build_args = args + yield + ensure + self.build_args = old_args + end end end diff --git a/lib/bundler/runtime.rb b/lib/bundler/runtime.rb index f83cb30742..be61c2b15b 100644 --- a/lib/bundler/runtime.rb +++ b/lib/bundler/runtime.rb @@ -88,9 +88,6 @@ module Bundler raise if $1 != namespaced_file end end - rescue => e - Bundler.ui.debug e - Bundler.ui.warn "Unable to require #{required_file}. #{e.class}: #{e.message}." end end end diff --git a/lib/bundler/shared_helpers.rb b/lib/bundler/shared_helpers.rb index 0087f0786a..cd4ad71737 100644 --- a/lib/bundler/shared_helpers.rb +++ b/lib/bundler/shared_helpers.rb @@ -35,32 +35,27 @@ module Bundler end def default_bundle_dir - global_bundle_dir = File.join(Bundler.rubygems.user_home, ".bundle") bundle_dir = find_directory(".bundle") + return nil unless bundle_dir - if bundle_dir && bundle_dir != global_bundle_dir - Pathname.new(bundle_dir) - else - nil - end + global_bundle_dir = File.join(Bundler.rubygems.user_home, ".bundle") + return nil if bundle_dir == global_bundle_dir + + Pathname.new(bundle_dir) end def in_bundle? find_gemfile end - def chdir_monitor - Bundler.rubygems.ext_lock - end - def chdir(dir, &blk) - chdir_monitor.synchronize do + Bundler.rubygems.ext_lock.synchronize do Dir.chdir dir, &blk end end def pwd - chdir_monitor.synchronize do + Bundler.rubygems.ext_lock.synchronize do Dir.pwd end end diff --git a/lib/bundler/source.rb b/lib/bundler/source.rb index 213e98fb98..869931a1f0 100644 --- a/lib/bundler/source.rb +++ b/lib/bundler/source.rb @@ -27,5 +27,10 @@ module Bundler def can_lock?(spec) spec.source == self end + + def include?(other) + other == self + end + end end diff --git a/lib/bundler/source/rubygems.rb b/lib/bundler/source/rubygems.rb index a269a22133..66a0b72a06 100644 --- a/lib/bundler/source/rubygems.rb +++ b/lib/bundler/source/rubygems.rb @@ -38,11 +38,15 @@ module Bundler end def eql?(o) - o.is_a?(Rubygems) && remotes_equal?(o.remotes) + o.is_a?(Rubygems) && o.credless_remotes == credless_remotes end alias == eql? + def include?(o) + o.is_a?(Rubygems) && (o.credless_remotes - credless_remotes).empty? + end + def can_lock?(spec) spec.source.is_a?(Rubygems) end @@ -203,6 +207,10 @@ module Bundler protected + def credless_remotes + remotes.map(&method(:suppress_configured_credentials)) + end + def remotes_for_spec(spec) specs.search_all(spec.name).inject([]) do |uris, s| uris << s.remote if s.remote @@ -387,10 +395,6 @@ module Bundler spec.loaded_from && spec.loaded_from.include?("specifications/default/") end - def remotes_equal?(other_remotes) - remotes.map(&method(:suppress_configured_credentials)) == other_remotes.map(&method(:suppress_configured_credentials)) - end - end end end diff --git a/lib/bundler/templates/newgem/newgem.gemspec.tt b/lib/bundler/templates/newgem/newgem.gemspec.tt index 4749a9a70e..e630801026 100644 --- a/lib/bundler/templates/newgem/newgem.gemspec.tt +++ b/lib/bundler/templates/newgem/newgem.gemspec.tt @@ -16,6 +16,14 @@ Gem::Specification.new do |spec| spec.license = "MIT" <%- end -%> + # Prevent pushing this gem to RubyGems.org by setting 'allowed_push_host', or + # delete this section to allow pushing this gem to any host. + if spec.respond_to?(:metadata) + spec.metadata['allowed_push_host'] = "TODO: Set to 'http://mygemserver.com'" + else + raise "RubyGems 2.0 or newer is required to protect against public gem pushes." + end + spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) } spec.bindir = "exe" spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) } @@ -24,10 +32,6 @@ Gem::Specification.new do |spec| spec.extensions = ["ext/<%=config[:underscored_name]%>/extconf.rb"] <%- end -%> - if spec.respond_to?(:metadata) - spec.metadata['allowed_push_host'] = "TODO: Set to 'http://mygemserver.com' to prevent pushes to rubygems.org, or delete to allow pushes to any server." - end - spec.add_development_dependency "bundler", "~> <%= config[:bundler_version] %>" spec.add_development_dependency "rake", "~> 10.0" <%- if config[:ext] -%> diff --git a/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb b/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb index 4ee5708a56..7cde9fa5eb 100644 --- a/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb +++ b/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb @@ -61,7 +61,7 @@ module Bundler::Molinillo hash[name] = vertex.dup.tap { |v| v.graph = self } end end - @root_vertices = Hash[vertices.select { |n, _v| other.root_vertices[n] }] + @root_vertices = Hash[@vertices.select { |n, _v| other.root_vertices[n] }] @edges = other.edges.map do |edge| Edge.new( vertex_named(edge.origin.name), diff --git a/lib/bundler/vendor/molinillo/lib/molinillo/gem_metadata.rb b/lib/bundler/vendor/molinillo/lib/molinillo/gem_metadata.rb index 0736b89c3c..2cf1b60b12 100644 --- a/lib/bundler/vendor/molinillo/lib/molinillo/gem_metadata.rb +++ b/lib/bundler/vendor/molinillo/lib/molinillo/gem_metadata.rb @@ -1,3 +1,3 @@ module Bundler::Molinillo - VERSION = '0.2.1' + VERSION = '0.2.3' end diff --git a/lib/bundler/version.rb b/lib/bundler/version.rb index 1854799dcb..3dfc25db76 100644 --- a/lib/bundler/version.rb +++ b/lib/bundler/version.rb @@ -2,5 +2,5 @@ module Bundler # We're doing this because we might write tests that deal # with other versions of bundler and we are unsure how to # handle this better. - VERSION = "1.9.1" unless defined?(::Bundler::VERSION) + VERSION = "1.9.4" unless defined?(::Bundler::VERSION) end diff --git a/man/bundle-config.ronn b/man/bundle-config.ronn index 1a47fc150f..c0657c5ec7 100644 --- a/man/bundle-config.ronn +++ b/man/bundle-config.ronn @@ -106,9 +106,15 @@ learn more about their operation in [bundle install(1)][bundle-install]. * `ssl_client_cert` (`BUNDLE_SSL_CLIENT_CERT`): Path to a designated file containing a X.509 client certificate and key in PEM format. +* `cache_path` (`BUNDLE_CACHE_PATH`): The directory that bundler will place + cached gems in when running <code>bundle package</code>, and that bundler + will look in when installing gems. +* `disable_multisource` (`BUNDLE_DISABLE_MULTISOURCE`): When set, Gemfiles + containing multiple sources will produce errors instead of warnings. Use + `bundle config --delete disable_multisource` to unset. In general, you should set these settings per-application by using the applicable -flag to the [bundle install(1)][bundle-install] command. +flag to the [bundle install(1)][bundle-install] or [bundle package(1)][bundle-package] command. You can set them globally either via environment variables or `bundle config`, whichever is preferable for your setup. If you use both, environment variables diff --git a/man/bundle-install.ronn b/man/bundle-install.ronn index 117fd363ee..381b714ba9 100644 --- a/man/bundle-install.ronn +++ b/man/bundle-install.ronn @@ -8,10 +8,12 @@ bundle-install(1) -- Install the dependencies specified in your Gemfile [--full-index] [--gemfile=GEMFILE] [--jobs=NUMBER] - [--local] [--deployment] + [--local] + [--deployment] [--no-cache] [--no-prune] - [--path PATH] [--system] + [--path PATH] + [--system] [--quiet] [--retry=NUMBER] [--shebang] diff --git a/spec/bundler/bundler_spec.rb b/spec/bundler/bundler_spec.rb index f26183e073..fa226002cc 100644 --- a/spec/bundler/bundler_spec.rb +++ b/spec/bundler/bundler_spec.rb @@ -17,13 +17,11 @@ describe Bundler do end end - context "on Ruby 1.8", :ruby => "1.8" do - it "catches YAML syntax errors" do - expect { subject }.to raise_error(Bundler::GemspecError) - end + it "catches YAML syntax errors" do + expect { subject }.to raise_error(Bundler::GemspecError) end - context "on Ruby 1.9", :ruby => "1.9", :if => defined?(YAML::ENGINE) do + context "on Rubies with a settable YAML engine", :if => defined?(YAML::ENGINE) do context "with Syck as YAML::Engine" do it "raises a GemspecError after YAML load throws ArgumentError" do orig_yamler, YAML::ENGINE.yamler = YAML::ENGINE.yamler, 'syck' diff --git a/spec/bundler/friendly_errors_spec.rb b/spec/bundler/friendly_errors_spec.rb index 96c333a739..ee0667cb2f 100644 --- a/spec/bundler/friendly_errors_spec.rb +++ b/spec/bundler/friendly_errors_spec.rb @@ -10,4 +10,21 @@ describe Bundler, "friendly errors" do end }.to raise_error(SystemExit) end + + describe "#issues_url" do + it "generates a search URL for the exception message" do + exception = Exception.new("Exception message") + + expect(Bundler.issues_url(exception)).to eq("https://github.com/bundler/bundler/search?q=Exception+message&type=Issues") + end + + it "generates a search URL for only the first line of a multi-line exception message" do + exception = Exception.new(<<END) +First line of the exception message +Second line of the exception message +END + + expect(Bundler.issues_url(exception)).to eq("https://github.com/bundler/bundler/search?q=First+line+of+the+exception+message&type=Issues") + end + end end diff --git a/spec/bundler/gem_helper_spec.rb b/spec/bundler/gem_helper_spec.rb index 2b0f3d97aa..8cfacbac01 100644 --- a/spec/bundler/gem_helper_spec.rb +++ b/spec/bundler/gem_helper_spec.rb @@ -28,6 +28,15 @@ describe Bundler::GemHelper do end context "interpolates the name" do + before do + # Remove exception that prevents public pushes on older RubyGems versions + if Gem::Version.new(Gem::VERSION) < Gem::Version.new("2.0") + content = File.read(app_gemspec_path) + content.sub!(/raise "RubyGems 2\.0 or newer.*/, "") + File.open(app_gemspec_path, "w"){|f| f.write(content) } + end + end + it "when there is only one gemspec" do expect(subject.gemspec.name).to eq(app_name) end @@ -62,7 +71,7 @@ describe Bundler::GemHelper do let(:app_version) { "0.1.0" } let(:app_gem_dir) { app_path.join("pkg") } let(:app_gem_path) { app_gem_dir.join("#{app_name}-#{app_version}.gem") } - let(:app_gemspec_content) { File.read(app_gemspec_path) } + let(:app_gemspec_content) { remove_push_guard(File.read(app_gemspec_path)) } before(:each) do content = app_gemspec_content.gsub("TODO: ", "") @@ -70,6 +79,14 @@ describe Bundler::GemHelper do File.open(app_gemspec_path, "w") { |file| file << content } end + def remove_push_guard(gemspec_content) + # Remove exception that prevents public pushes on older RubyGems versions + if Gem::Version.new(Gem::VERSION) < Gem::Version.new("2.0") + gemspec_content.sub!(/raise "RubyGems 2\.0 or newer.*/, "") + end + gemspec_content + end + it "uses a shell UI for output" do expect(Bundler.ui).to be_a(Bundler::UI::Shell) end diff --git a/spec/commands/lock_spec.rb b/spec/commands/lock_spec.rb index 4545b8ce7f..07d92fb6cf 100644 --- a/spec/commands/lock_spec.rb +++ b/spec/commands/lock_spec.rb @@ -49,7 +49,7 @@ describe "bundle lock" do with_license BUNDLED WITH - 1.9.1 + #{Bundler::VERSION} L end @@ -84,7 +84,7 @@ describe "bundle lock" do it "does not fetch remote specs when using the --local option" do bundle "lock --update --local" - expect(out).to include("in the gems available on this machine.") + expect(out).to include("available on this machine.") end it "writes to a custom location using --lockfile" do diff --git a/spec/commands/newgem_spec.rb b/spec/commands/newgem_spec.rb index ef653d306d..b28a9f4f02 100644 --- a/spec/commands/newgem_spec.rb +++ b/spec/commands/newgem_spec.rb @@ -7,6 +7,15 @@ describe "bundle gem" do global_config "BUNDLE_GEM__MIT" => "false", "BUNDLE_GEM__TEST" => "false", "BUNDLE_GEM__COC" => "false" end + def remove_push_guard(gem_name) + # Remove exception that prevents public pushes on older RubyGems versions + if Gem::Version.new(Gem::VERSION) < Gem::Version.new("2.0") + path = "#{gem_name}/#{gem_name}.gemspec" + content = File.read(path).sub(/raise "RubyGems 2\.0 or newer.*/, "") + File.open(path, "w"){|f| f.write(content) } + end + end + before do @git_name = `git config --global user.name`.chomp `git config --global user.name "Bundler User"` @@ -48,7 +57,6 @@ describe "bundle gem" do bundle "gem newgem --bin" process_file(bundled_app('newgem', "newgem.gemspec")) do |line| - next line unless line =~ /TODO/ # Simulate replacing TODOs with real values case line when /spec\.metadata\['allowed_push_host'\]/, /spec\.homepage/ @@ -57,6 +65,9 @@ describe "bundle gem" do line.gsub(/\=.*$/, "= %q{A short summary of my new gem.}") when /spec\.description/ line.gsub(/\=.*$/, "= %q{A longer description of my new gem.}") + # Remove exception that prevents public pushes on older RubyGems versions + when /raise "RubyGems 2.0 or newer/ + line.gsub(/.*/, '') if Gem::Version.new(Gem::VERSION) < Gem::Version.new("2.0") else line end @@ -112,6 +123,7 @@ describe "bundle gem" do before do bundle "gem #{gem_name}" + remove_push_guard(gem_name) # reset gemspec cache for each test because of commit 3d4163a Bundler.clear_gemspec_cache end @@ -125,6 +137,11 @@ describe "bundle gem" do expect(bundled_app("test_gem/lib/test_gem.rb")).to exist expect(bundled_app("test_gem/lib/test_gem/version.rb")).to exist expect(bundled_app("test_gem/.gitignore")).to exist + + expect(bundled_app("test_gem/bin/setup")).to exist + expect(bundled_app("test_gem/bin/console")).to exist + expect(bundled_app("test_gem/bin/setup")).to be_executable + expect(bundled_app("test_gem/bin/console")).to be_executable end it "starts with version 0.1.0" do @@ -145,6 +162,7 @@ describe "bundle gem" do reset! in_app_root bundle "gem #{gem_name}" + remove_push_guard(gem_name) end it_should_behave_like "git config is absent" @@ -152,7 +170,7 @@ describe "bundle gem" do it "sets gemspec metadata['allowed_push_host']", :rubygems => "2.0" do expect(generated_gem.gemspec.metadata['allowed_push_host']). - to match("delete to allow pushes to any server") + to match(/mygemserver\.com/) end it "requires the version file" do @@ -318,6 +336,7 @@ describe "bundle gem" do before do bundle "gem #{gem_name} --mit" + remove_push_guard(gem_name) # reset gemspec cache for each test because of commit 3d4163a Bundler.clear_gemspec_cache end @@ -359,6 +378,7 @@ describe "bundle gem" do before do bundle "gem #{gem_name}" + remove_push_guard(gem_name) # reset gemspec cache for each test because of commit 3d4163a Bundler.clear_gemspec_cache end @@ -392,16 +412,12 @@ describe "bundle gem" do reset! in_app_root bundle "gem #{gem_name}" + remove_push_guard(gem_name) end it_should_behave_like "git config is absent" end - it "sets gemspec metadata['allowed_push_host']", :rubygems => "2.0" do - expect(generated_gem.gemspec.metadata['allowed_push_host']). - to match("delete to allow pushes to any server") - end - it "requires the version file" do expect(bundled_app("test-gem/lib/test/gem.rb").read).to match(/require "test\/gem\/version"/) end diff --git a/spec/install/gems/sources_spec.rb b/spec/install/gems/sources_spec.rb index cca00a914d..45e3a43e5d 100644 --- a/spec/install/gems/sources_spec.rb +++ b/spec/install/gems/sources_spec.rb @@ -319,4 +319,64 @@ describe "bundle install with gems on multiple sources" do should_be_installed("rack 1.0.0") end end + + context "when a single source contains multiple locked gems" do + before do + # 1. With these gems, + build_repo4 do + build_gem "foo", "0.1" + build_gem "bar", "0.1" + end + + # 2. Installing this gemfile will produce... + gemfile <<-G + source 'file://#{gem_repo1}' + gem 'rack' + gem 'foo', '~> 0.1', :source => 'file://#{gem_repo4}' + gem 'bar', '~> 0.1', :source => 'file://#{gem_repo4}' + G + + # 3. this lockfile. + lockfile <<-L + GEM + remote: file:/Users/andre/src/bundler/bundler/tmp/gems/remote1/ + remote: file:/Users/andre/src/bundler/bundler/tmp/gems/remote4/ + specs: + bar (0.1) + foo (0.1) + rack (1.0.0) + + PLATFORMS + ruby + + DEPENDENCIES + bar (~> 0.1)! + foo (~> 0.1)! + rack + L + + bundle "install --path ../gems/system" + + # 4. Then we add some new versions... + update_repo4 do + build_gem "foo", "0.2" + build_gem "bar", "0.3" + end + end + + it "allows them to be unlocked separately" do + # 5. and install this gemfile, updating only foo. + install_gemfile <<-G + source 'file://#{gem_repo1}' + gem 'rack' + gem 'foo', '~> 0.2', :source => 'file://#{gem_repo4}' + gem 'bar', '~> 0.1', :source => 'file://#{gem_repo4}' + G + + # 6. Which should update foo to 0.2, but not the (locked) bar 0.1 + should_be_installed("foo 0.2") + should_be_installed("bar 0.1") + end + end + end diff --git a/spec/install/post_bundle_message_spec.rb b/spec/install/post_bundle_message_spec.rb index 78133d9283..408e518894 100644 --- a/spec/install/post_bundle_message_spec.rb +++ b/spec/install/post_bundle_message_spec.rb @@ -81,6 +81,22 @@ describe "post bundle message" do expect(out).to include(bundle_complete_message) end end + + describe "with misspelled or non-existent gem name" do + before :each do + gemfile <<-G + source 'https://rubygems.org/' + gem "rails" + gem "misspelled-gem-name", :group => :development + G + end + + it "should report a helpufl error message" do + bundle :install + expect(out).to include("Fetching gem metadata from https://rubygems.org/") + expect(out).to include("Could not find gem 'misspelled-gem-name (>= 0) ruby' in any of the gem sources listed in your Gemfile or installed on this machine.") + end + end end describe "for second bundle install run" do diff --git a/spec/other/ext_spec.rb b/spec/other/ext_spec.rb index cbee163771..dca6c80a59 100644 --- a/spec/other/ext_spec.rb +++ b/spec/other/ext_spec.rb @@ -5,6 +5,14 @@ describe "Gem::Specification#match_platform" do darwin = gem "lol", "1.0", "platform_specific-1.0-x86-darwin-10" expect(darwin.match_platform(pl('java'))).to eq(false) end + + context "when platform is a string" do + it "matches when platform is a string" do + lazy_spec = Bundler::LazySpecification.new("lol", "1.0", "universal-mingw32") + expect(lazy_spec.match_platform(pl('x86-mingw32'))).to eq(true) + expect(lazy_spec.match_platform(pl('x64-mingw32'))).to eq(true) + end + end end describe "Bundler::GemHelpers#generic" do @@ -49,12 +57,12 @@ describe "Gem::SourceIndex#refresh!" do end it "does not explode when called", :if => rubygems_1_7 do - run "Gem.source_index.refresh!" - run "Gem::SourceIndex.new([]).refresh!" + run "Gem.source_index.refresh!", :expect_err => true + run "Gem::SourceIndex.new([]).refresh!", :expect_err => true end it "does not explode when called", :unless => rubygems_1_7 do - run "Gem.source_index.refresh!" - run "Gem::SourceIndex.from_gems_in([]).refresh!" + run "Gem.source_index.refresh!", :expect_err => true + run "Gem::SourceIndex.from_gems_in([]).refresh!", :expect_err => true end end diff --git a/spec/quality_spec.rb b/spec/quality_spec.rb index 79d3e0bd2a..b84e543670 100644 --- a/spec/quality_spec.rb +++ b/spec/quality_spec.rb @@ -97,7 +97,7 @@ describe "The library itself" do end end - expect(@err.split("\n").reject { |f| f =~ %r{(lib|\.)/bundler/vendor} }).to eq([]) + expect(@err.split("\n")).to eq([]) expect(@out).to eq("") end end diff --git a/spec/runtime/gem_tasks_spec.rb b/spec/runtime/gem_tasks_spec.rb new file mode 100644 index 0000000000..5124b05a3c --- /dev/null +++ b/spec/runtime/gem_tasks_spec.rb @@ -0,0 +1,35 @@ +require "spec_helper" + +describe "require 'bundler/gem_tasks'" do + before :each do + bundled_app("foo.gemspec").open("w") do |f| + f.write <<-GEMSPEC + Gem::Specification.new do |s| + s.name = "foo" + end + GEMSPEC + end + bundled_app("Rakefile").open("w") do |f| + f.write <<-RAKEFILE + $:.unshift("#{bundler_path}") + require "bundler/gem_tasks" + RAKEFILE + end + end + + it "includes the relevant tasks" do + with_gem_path_as(Spec::Path.base_system_gems.to_s) do + sys_exec "ruby -S rake -T" + end + + expect(err).to eq("") + expected_tasks = [ + "rake build", + "rake install", + "rake release", + ] + tasks = out.lines.to_a.map { |s| s.split('#').first.strip } + expect(tasks & expected_tasks).to eq(expected_tasks) + expect(exitstatus).to eq(0) if exitstatus + end +end diff --git a/spec/support/builders.rb b/spec/support/builders.rb index 5490a2b976..1a1c916779 100644 --- a/spec/support/builders.rb +++ b/spec/support/builders.rb @@ -260,12 +260,15 @@ module Spec FileUtils.rm_rf Dir[gem_repo3("prerelease*")] end - # A repo that has no pre-installed gems included. (The caller completely determines the contents with the block) - def build_repo4(&blk) + # A repo that has no pre-installed gems included. (The caller completely + # determines the contents with the block.) + def build_repo4 FileUtils.rm_rf gem_repo4 - build_repo(gem_repo4) do - yield if block_given? - end + build_repo(gem_repo4) { yield } + end + + def update_repo4 + update_repo(gem_repo4) { yield } end def update_repo2 |