Skip to content

Commit

Permalink
Reject uninstalling a default gem
Browse files Browse the repository at this point in the history
Note: Gem::Specification#default_gem? is suitable name? Should it be
private?
  • Loading branch information
kou committed Nov 14, 2012
1 parent 60ddd38 commit b948b81
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 3 deletions.
10 changes: 9 additions & 1 deletion lib/rubygems/specification.rb
Expand Up @@ -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|
Expand All @@ -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

Expand Down Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions lib/rubygems/test_case.rb
Expand Up @@ -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")
Expand Down
16 changes: 14 additions & 2 deletions lib/rubygems/uninstaller.rb
Expand Up @@ -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

Expand Down
19 changes: 19 additions & 0 deletions test/rubygems/test_gem_commands_uninstall_command.rb
Expand Up @@ -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

0 comments on commit b948b81

Please sign in to comment.