summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThe Bundler Bot <bot@bundler.io>2017-04-11 23:33:20 +0000
committerThe Bundler Bot <bot@bundler.io>2017-04-11 23:33:20 +0000
commitfac4b7b519039199581b9d5eb62ed6ba31b247b3 (patch)
tree818f660062d7fd88782582382155cafec63ddfb6
parent9f3cac0d05a40ca37a865d7ada66bbe5f8b3427b (diff)
parentd7adcaa9e42973ee75f23f28280aed16e806c620 (diff)
downloadbundler-fac4b7b519039199581b9d5eb62ed6ba31b247b3.tar.gz
Auto merge of #5503 - denniss:ds-bundle-pristine, r=segiddins
Implementation of `bundle pristine` Initial implementation of bundle pristine Addressing: https://github.com/bundler/bundler/issues/4509 https://github.com/bundler/bundler-features/issues/5
-rw-r--r--lib/bundler/cli.rb6
-rw-r--r--lib/bundler/cli/pristine.rb31
-rw-r--r--lib/bundler/source/git.rb3
-rw-r--r--spec/commands/pristine_spec.rb96
4 files changed, 136 insertions, 0 deletions
diff --git a/lib/bundler/cli.rb b/lib/bundler/cli.rb
index 47c8bf22c1..9c49858e00 100644
--- a/lib/bundler/cli.rb
+++ b/lib/bundler/cli.rb
@@ -553,6 +553,12 @@ module Bundler
Issue.new.run
end
+ desc "pristine", "Restores installed gems to pristine condition from files located in the gem cache. Gem installed from a git repository will be issued `git checkout --force`."
+ def pristine
+ require "bundler/cli/pristine"
+ Pristine.new.run
+ end
+
if Bundler.feature_flag.plugins?
require "bundler/cli/plugin"
desc "plugin SUBCOMMAND ...ARGS", "manage the bundler plugins"
diff --git a/lib/bundler/cli/pristine.rb b/lib/bundler/cli/pristine.rb
new file mode 100644
index 0000000000..c7d8dcfdf5
--- /dev/null
+++ b/lib/bundler/cli/pristine.rb
@@ -0,0 +1,31 @@
+# frozen_string_literal: true
+require "bundler/cli/common"
+
+module Bundler
+ class CLI::Pristine
+ def run
+ ::Bundler.load.specs.each do |spec|
+ gem_name = "#{spec.name} (#{spec.version}#{spec.git_version})"
+ gem_name += " (#{spec.platform})" if !spec.platform.nil? && spec.platform != Gem::Platform::RUBY
+
+ case spec.source
+ when Source::Rubygems
+ cached_gem = spec.cache_file
+ unless File.exist?(cached_gem)
+ ::Bundler.ui.error("Failed to pristine #{gem_name}. Cached gem #{cached_gem} does not exist.")
+ next
+ end
+
+ FileUtils.rm_rf spec.full_gem_path
+ spec.source.install(spec, :force => true)
+ when Source::Git
+ git_source = spec.source
+ git_source.remote!
+ git_source.install(spec, :force => true)
+ else
+ ::Bundler.ui.warn("Cannot pristine #{gem_name}. Gem is sourced from local path.")
+ end
+ end
+ end
+ end
+end
diff --git a/lib/bundler/source/git.rb b/lib/bundler/source/git.rb
index f6efd588f9..62f38a3a8d 100644
--- a/lib/bundler/source/git.rb
+++ b/lib/bundler/source/git.rb
@@ -171,7 +171,10 @@ module Bundler
git_proxy.copy_to(install_path, submodules)
serialize_gemspecs_in(install_path)
@copied = true
+ elsif force
+ git_proxy.copy_to(install_path, submodules)
end
+
generate_bin_options = { :disable_extensions => !Bundler.rubygems.spec_missing_extensions?(spec), :build_args => options[:build_args] }
generate_bin(spec, generate_bin_options)
diff --git a/spec/commands/pristine_spec.rb b/spec/commands/pristine_spec.rb
new file mode 100644
index 0000000000..ff327e190b
--- /dev/null
+++ b/spec/commands/pristine_spec.rb
@@ -0,0 +1,96 @@
+# frozen_string_literal: true
+require "spec_helper"
+require "fileutils"
+
+RSpec.describe "bundle pristine" do
+ before :each do
+ build_lib "baz", :path => bundled_app do |s|
+ s.version = "1.0.0"
+ s.add_development_dependency "baz-dev", "=1.0.0"
+ end
+
+ build_repo2 do
+ build_gem "weakling"
+ build_gem "baz-dev", "1.0.0"
+ build_git "foo", :path => lib_path("foo")
+ build_lib "bar", :path => lib_path("bar")
+ end
+
+ install_gemfile! <<-G
+ source "file://#{gem_repo2}"
+ gem "weakling"
+ gem "foo", :git => "#{lib_path("foo")}"
+ gem "bar", :path => "#{lib_path("bar")}"
+
+ gemspec
+ G
+
+ bundle "install"
+ end
+
+ context "when sourced from Rubygems" do
+ it "reverts using cached .gem file" do
+ spec = Bundler.definition.specs["weakling"].first
+ changes_txt = Pathname.new(spec.full_gem_path).join("lib/changes.txt")
+
+ FileUtils.touch(changes_txt)
+ expect(changes_txt).to be_file
+
+ bundle "pristine"
+ expect(changes_txt).to_not be_file
+ end
+ end
+
+ context "when sourced from git repo" do
+ it "reverts by resetting to current revision`" do
+ spec = Bundler.definition.specs["foo"].first
+ changed_file = Pathname.new(spec.full_gem_path).join("lib/foo.rb")
+ diff = "#Pristine spec changes"
+
+ File.open(changed_file, "a") {|f| f.puts "#Pristine spec changes" }
+ expect(File.read(changed_file)).to include(diff)
+
+ bundle "pristine"
+ expect(File.read(changed_file)).to_not include(diff)
+ end
+ end
+
+ context "when sourced from gemspec" do
+ it "displays warning and ignores changes when sourced from gemspec" do
+ spec = Bundler.definition.specs["baz"].first
+ changed_file = Pathname.new(spec.full_gem_path).join("lib/baz.rb")
+ diff = "#Pristine spec changes"
+
+ File.open(changed_file, "a") {|f| f.puts "#Pristine spec changes" }
+ expect(File.read(changed_file)).to include(diff)
+
+ bundle "pristine"
+ expect(File.read(changed_file)).to include(diff)
+ expect(out).to include("Cannot pristine #{spec.name} (#{spec.version}#{spec.git_version}). Gem is sourced from local path.")
+ end
+
+ it "reinstall gemspec dependency" do
+ spec = Bundler.definition.specs["baz-dev"].first
+ changed_file = Pathname.new(spec.full_gem_path).join("lib/baz-dev.rb")
+ diff = "#Pristine spec changes"
+
+ File.open(changed_file, "a") {|f| f.puts "#Pristine spec changes" }
+ expect(File.read(changed_file)).to include(diff)
+
+ bundle "pristine"
+ expect(File.read(changed_file)).to_not include(diff)
+ end
+ end
+
+ context "when sourced from path" do
+ it "displays warning and ignores changes when sourced from local path" do
+ spec = Bundler.definition.specs["bar"].first
+ changes_txt = Pathname.new(spec.full_gem_path).join("lib/changes.txt")
+ FileUtils.touch(changes_txt)
+ expect(changes_txt).to be_file
+ bundle "pristine"
+ expect(out).to include("Cannot pristine #{spec.name} (#{spec.version}#{spec.git_version}). Gem is sourced from local path.")
+ expect(changes_txt).to be_file
+ end
+ end
+end