Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
136 changes: 136 additions & 0 deletions lib/rubygems/resources.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
##
# Track Internet resources related to a gem.

class Gem::Resources
include Enumerable

##
# Valid URL (TODO: improve)

URL = /^(http|https|ftp|mailto)\:\/\/.*?$/

##
# Specail accessor stores values in a hash and can also handle hash
# key +aliases+.

def self.attr_accessor(name, *aliases)
list = ([name] + aliases).map{ |k| k.to_sym }
list.each do |label|
#list << list.shift until list.first == name
define_method(label) do
key = list.find{ |k| @table[k] } || label
@table[key]
end
define_method("#{label}=") do |url|
raise ArgumentError unless URL =~ url
key = list.find{ |k| @table[k] } || label
@table[key] = url
end
end
end

##
# Create new Resources instance. A Hash of <code>label => url</code>
# can be passed as +resources+.

def initialize(resources={})
@table = {}
resources.each do |label,url|
add_resource(label, url)
end
end

##
# Add a new resource.

def add_resource(label, url)
__send__("#{label}=", url)
end

##
# Convert Resource to a Hash.

def to_h
@table.inject({}) do |h,(k,v)|
h[k.to_s] = v; h
end
end

##
# Project homepage.

attr_accessor :home, :homepage

##
# Source code browser.

attr_accessor :code, :source, :source_code

##
# Issue tracker.

attr_accessor :bugs, :bug_tracker, :issues, :issue_tracker

##
# Mialing list.

attr_accessor :mail, :mailing_list

##
# Documentation.

attr_accessor :docs, :documentation

##
# Wiki pages.

attr_accessor :wiki

##
# Support arbitrary resource labels.

def method_missing(label, *args)
case label.to_s
when /=$/
url = args.first
raise ArgumentError unless URL =~ url
label = label.to_s.chomp('=').to_sym
@table[label] = url
else
@table[label]
end
end

##
# A resources's hash is the hash of the underlying table.

def hash # :nodoc:
@table.hash
end

##
# Equality.

def ==(other)
self.class == other.class and @table == other.table
end

##
# Iterate over each label, url pair.

def each(&block)
@table.each(&block)
end

##
# Returns the number of reources.

def size
@table.size
end

protected

attr :table

end
35 changes: 34 additions & 1 deletion lib/rubygems/specification.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
require 'rubygems/version'
require 'rubygems/requirement'
require 'rubygems/platform'
require 'rubygems/resources'

# :stopdoc:
class Date; end # for ruby_code if date.rb wasn't required
Expand Down Expand Up @@ -278,7 +279,8 @@ def _dump(limit)
@homepage,
@has_rdoc,
@new_platform,
@licenses
@licenses,
@resources
]
end

Expand Down Expand Up @@ -324,6 +326,7 @@ def self._load(str)
spec.instance_variable_set :@new_platform, array[16]
spec.instance_variable_set :@platform, array[16].to_s
spec.instance_variable_set :@license, array[17]
spec.instance_variable_set :@resources, array[18]
spec.instance_variable_set :@loaded, false

spec
Expand Down Expand Up @@ -764,6 +767,7 @@ def to_ruby

handled = [
:dependencies,
:resources,
:name,
:platform,
:required_rubygems_version,
Expand All @@ -782,6 +786,14 @@ def to_ruby
end
end

result << nil

unless resources.empty? then
resources.each do |k,v|
result << " s.add_resource(#{k.inspect}, #{v.inspect})"
end
end

result << nil
result << " if s.respond_to? :specification_version then"
result << " s.specification_version = #{specification_version}"
Expand Down Expand Up @@ -1039,6 +1051,15 @@ def add_dependency_with_type(dependency, type, *requirements)

private :add_dependency_with_type

##
# Adds a resource to the gem with given +label+ and +url+.
# Some labels are synonymous with others, e.g. +mail+ with
# +mailing_list+. See Resources class for details.

def add_resource(label, url)
resources.add_resource(label, url)
end

##
# Finds all gems that satisfy +dep+

Expand All @@ -1065,6 +1086,7 @@ def ruby_code(obj)
when true, false, nil then obj.inspect
when Gem::Platform then "Gem::Platform.new(#{obj.to_a.inspect})"
when Gem::Requirement then "Gem::Requirement.new(#{obj.to_s.inspect})"
when Gem::Resources then "Gem::Resources.new(#{obj.to_h.inspect})"
else raise Gem::Exception, "ruby_code case not handled: #{obj.class}"
end
end
Expand Down Expand Up @@ -1349,6 +1371,17 @@ def ruby_code(obj)

read_only :dependencies

##
# :attr_reader: resources
#
# Resources instance which stores a mapping of label to URL.
#
# Use #resource or #add_resource to add a resource to a gem.

attribute :resources, Gem::Resources.new

read_only :resources

# :section: Aliased gemspec attributes

##
Expand Down
44 changes: 44 additions & 0 deletions test/test_gem_resources.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
require File.expand_path('../gemutilities', __FILE__)
require 'rubygems/resources'

class TestGemSpecification < RubyGemTestCase

def test_resource_new_empty
Gem::Resources.new
end

def test_resource_new_with_entries
Gem::Resources.new(:wiki=>'http://someplace.org')
end

def test_add_resource
r = Gem::Resources.new
r.add_resource('home', 'http://someplace.org')
assert_equal 'http://someplace.org', r.home
assert_equal 'http://someplace.org', r.homepage
end

def test_add_arbitrary_resource
r = Gem::Resources.new
r.add_resource('foo', 'http://someplace.org')
assert_equal 'http://someplace.org', r.foo
end

def test_to_h
r = Gem::Resources.new
r.add_resource('home', 'http://somehome.org')
r.add_resource(:wiki, 'http://somewiki.org')
h = {'home'=>'http://somehome.org',
'wiki'=>'http://somewiki.org'}
assert_equal h, r.to_h
end

def test_aliases
r = Gem::Resources.new
r.add_resource('home', 'http://somehome.org')
assert_equal r.homepage, 'http://somehome.org'
r.add_resource('homepage', 'http://someother.org')
assert_equal r.home, 'http://someother.org'
end

end
12 changes: 12 additions & 0 deletions test/test_gem_specification.rb
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ def setup
s.add_dependency 'jabber4r', '> 0.0.0'
s.add_dependency 'pqa', ['> 0.4', '<= 0.6']

s.add_resource 'wiki', 'http://somewiki.org'

s.mark_version
s.files = %w[lib/code.rb]
end
Expand Down Expand Up @@ -95,6 +97,7 @@ def test_self_attribute_names
required_ruby_version
required_rubygems_version
requirements
resources
rubyforge_project
rubygems_version
signing_key
Expand Down Expand Up @@ -365,6 +368,11 @@ def test_dependencies
assert_equal [rake, jabber, pqa], @a1.dependencies
end

def test_resources
r = Gem::Resources.new 'wiki' => 'http://somewiki.org'
assert_equal r, @a1.resources
end

def test_dependencies_scoped_by_type
gem = quick_gem "awesome", "1.0" do |awesome|
awesome.add_runtime_dependency "bonobo", []
Expand Down Expand Up @@ -776,6 +784,8 @@ def test_to_ruby
s.rubygems_version = %q{#{Gem::VERSION}}
s.summary = %q{this is a summary}

s.add_resource(:wiki, "http://somewiki.org")

if s.respond_to? :specification_version then
s.specification_version = #{Gem::Specification::CURRENT_SPECIFICATION_VERSION}

Expand Down Expand Up @@ -830,6 +840,8 @@ def test_to_ruby_fancy
s.summary = %q{this is a summary}
s.test_files = [\"test/suite.rb\"]

s.add_resource(:wiki, "http://somewiki.org")

if s.respond_to? :specification_version then
s.specification_version = 3

Expand Down