Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Reject uninstalling a default gem

Note: Gem::Specification#default_gem? is suitable name? Should it be
private?
  • Loading branch information...
commit b948b8188dd59c40105f5a9f3a89e98f52b47029 1 parent 60ddd38
Kouhei Sutou authored
10 lib/rubygems/specification.rb
View
@@ -612,6 +612,10 @@ def test_files= files
attr_accessor :specification_version
class << self
+ def default_specifications_dir
+ File.join(Gem.default_dir, "specifications", "default")
+ end
+
private
def each_spec(search_dirs) # :nodoc:
search_dirs.each { |dir|
@@ -625,7 +629,7 @@ def each_spec(search_dirs) # :nodoc:
end
def each_default(&block) # :nodoc:
- each_spec([File.join(Gem.default_dir, "specifications", "default")],
+ each_spec([default_specifications_dir],
&block)
end
@@ -2508,6 +2512,10 @@ def reset_nil_attributes_to_default
instance_variable_set "@#{attribute}", value
end
+
+ def default_gem?
+ loaded_from &&
+ File.dirname(loaded_from) == self.class.default_specifications_dir
end
extend Gem::Deprecate
1  lib/rubygems/test_case.rb
View
@@ -516,6 +516,7 @@ def new_spec name, version, deps = nil, *files
def new_default_spec(name, version, deps = nil, *files)
spec = new_spec(name, version, deps)
+ spec.loaded_from = File.join(@default_spec_dir, spec.spec_name)
spec.files = files
lib_dir = File.join(@tempdir, "default_gems", "lib")
16 lib/rubygems/uninstaller.rb
View
@@ -74,14 +74,26 @@ def initialize(gem, options = {})
def uninstall
list = Gem::Specification.find_all_by_name(@gem, @version)
+ default_specs, list = list.partition do |spec|
+ spec.default_gem?
+ end
+
list, other_repo_specs = list.partition do |spec|
@gem_home == spec.base_dir or
(@user_install and spec.base_dir == Gem.user_dir)
end
if list.empty? then
- raise Gem::InstallError, "gem #{@gem.inspect} is not installed" if
- other_repo_specs.empty?
+ if other_repo_specs.empty?
+ if default_specs.empty?
+ raise Gem::InstallError, "gem #{@gem.inspect} is not installed"
+ else
+ message =
+ "gem #{@gem.inspect} cannot be uninstalled " +
+ "because it is a default gem"
+ raise Gem::InstallError, message
+ end
+ end
other_repos = other_repo_specs.map { |spec| spec.base_dir }.uniq
19 test/rubygems/test_gem_commands_uninstall_command.rb
View
@@ -174,5 +174,24 @@ def test_execute_with_force_ignores_dependencies
assert Gem::Specification.find_all_by_name('dep_x').length > 0
assert Gem::Specification.find_all_by_name('x').length == 0
end
+
+ def test_execute_default_gem
+ default_gem_spec = new_default_spec("default", "2.0.0.0",
+ nil, "default/gem.rb")
+ install_default_specs(default_gem_spec)
+
+ ui = Gem::MockGemUi.new
+
+ @cmd.options[:args] = %w[default]
+ @cmd.options[:executables] = true
+
+ use_ui ui do
+ e = assert_raises Gem::InstallError do
+ @cmd.execute
+ end
+ assert_equal "gem \"default\" cannot be uninstalled because it is a default gem",
+ e.message
+ end
+ end
end
Please sign in to comment.
Something went wrong with that request. Please try again.