rubygems-update 0.8.6 → 0.8.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of rubygems-update might be problematic. Click here for more details.

Files changed (42) hide show
  1. data/ChangeLog +134 -0
  2. data/Rakefile +41 -17
  3. data/bin/gemwhich +61 -0
  4. data/examples/application/an-app.gemspec +1 -0
  5. data/lib/gemconfigure.rb +18 -0
  6. data/lib/rubygems.rb +65 -47
  7. data/lib/rubygems/cmd_manager.rb +3 -1
  8. data/lib/rubygems/command.rb +4 -0
  9. data/lib/rubygems/config_file.rb +2 -6
  10. data/lib/rubygems/custom_require.rb +2 -2
  11. data/lib/rubygems/dependency_list.rb +131 -0
  12. data/lib/rubygems/deployment.rb +265 -0
  13. data/lib/rubygems/doc_manager.rb +1 -0
  14. data/lib/rubygems/gem_commands.rb +216 -15
  15. data/lib/rubygems/installer.rb +111 -286
  16. data/lib/rubygems/remote_installer.rb +16 -6
  17. data/lib/rubygems/rubygems_version.rb +1 -1
  18. data/lib/rubygems/source_index.rb +11 -5
  19. data/lib/rubygems/specification.rb +5 -0
  20. data/lib/rubygems/version.rb +146 -129
  21. data/test/test_configfile.rb +1 -1
  22. data/test/test_dependency_list.rb +163 -0
  23. data/test/test_deployment.rb +93 -0
  24. data/test/test_remote_fetcher.rb +38 -36
  25. metadata +23 -47
  26. data/test/data/a-0.0.1.gem +0 -0
  27. data/test/data/a-0.0.2.gem +0 -0
  28. data/test/data/b-0.0.2.gem +0 -0
  29. data/test/data/c-1.2.gem +0 -0
  30. data/test/data/gemhome/cache/a-0.0.1.gem +0 -0
  31. data/test/data/gemhome/cache/a-0.0.2.gem +0 -0
  32. data/test/data/gemhome/cache/b-0.0.2.gem +0 -0
  33. data/test/data/gemhome/cache/c-1.2.gem +0 -0
  34. data/test/data/gemhome/gems/a-0.0.1/lib/code.rb +0 -1
  35. data/test/data/gemhome/gems/a-0.0.2/lib/code.rb +0 -1
  36. data/test/data/gemhome/gems/b-0.0.2/lib/code.rb +0 -1
  37. data/test/data/gemhome/gems/c-1.2/lib/code.rb +0 -1
  38. data/test/data/gemhome/specifications/a-0.0.1.gemspec +0 -8
  39. data/test/data/gemhome/specifications/a-0.0.2.gemspec +0 -8
  40. data/test/data/gemhome/specifications/b-0.0.2.gemspec +0 -8
  41. data/test/data/gemhome/specifications/c-1.2.gemspec +0 -8
  42. data/test/data/one/one-0.0.1.gem +0 -0
@@ -16,7 +16,7 @@ module Gem
16
16
  # Initialize a remote fetcher using the source URI (and possible
17
17
  # proxy information).
18
18
  def initialize(source_uri, proxy)
19
- @uri = source_uri
19
+ @uri = normalize_uri(source_uri)
20
20
  @http_proxy = proxy
21
21
  if @http_proxy == true
22
22
  @http_proxy = ENV['http_proxy'] || ENV['HTTP_PROXY']
@@ -61,6 +61,11 @@ module Gem
61
61
 
62
62
  private
63
63
 
64
+ # Normalize the URI by adding "http://" if it is missing.
65
+ def normalize_uri(uri)
66
+ (uri =~ /^(https?|ftp):/) ? uri : "http://#{uri}"
67
+ end
68
+
64
69
  # Connect to the source host/port, using a proxy if needed.
65
70
  def connect_to(host, port)
66
71
  if @http_proxy
@@ -169,7 +174,7 @@ module Gem
169
174
  # Write data to the proper cache.
170
175
  def write_cache
171
176
  data = cache_data
172
- open(writable_file, "w") do |f|
177
+ open(writable_file, "wb") do |f|
173
178
  f.puts Marshal.dump(data)
174
179
  end
175
180
  end
@@ -207,7 +212,7 @@ module Gem
207
212
  def read_cache
208
213
  @cache_file = select_cache_file
209
214
  begin
210
- open(@cache_file) { |f| load_local_cache(f) } || {}
215
+ open(@cache_file, "rb") { |f| load_local_cache(f) } || {}
211
216
  rescue StandardError => ex
212
217
  {}
213
218
  end
@@ -457,7 +462,10 @@ module Gem
457
462
  to_install = []
458
463
  dependencies.each do |dependency|
459
464
  begin
460
- require_gem(dependency.name, *dependency.requirement_list)
465
+ require_gem_with_options(
466
+ dependency.name,
467
+ dependency.requirement_list,
468
+ :auto_require=>false)
461
469
  rescue LoadError => e
462
470
  to_install.push dependency
463
471
  end
@@ -472,9 +480,11 @@ module Gem
472
480
  # way to do things (e.g. if a package fails to download, we
473
481
  # shouldn't install anything).
474
482
  def install_dependencies(dependencies, force, install_dir)
483
+ return if @options[:ignore_dependencies]
475
484
  installed_gems = []
476
485
  dependencies.each do |dependency|
477
- if ask_yes_no("Install required dependency #{dependency.name}?", true)
486
+ if @options[:include_dependencies] ||
487
+ ask_yes_no("Install required dependency #{dependency.name}?", true)
478
488
  remote_installer = RemoteInstaller.new(@options)
479
489
  installed_gems << remote_installer.install(
480
490
  dependency.name,
@@ -503,7 +513,7 @@ module Gem
503
513
  end
504
514
 
505
515
  def new_installer(gem)
506
- return Installer.new(gem)
516
+ return Installer.new(gem, @options)
507
517
  end
508
518
  end
509
519
 
@@ -2,5 +2,5 @@
2
2
  # This file is auto-generated by build scripts.
3
3
  # See: rake update_version
4
4
  module Gem
5
- RubyGemsVersion = '0.8.6'
5
+ RubyGemsVersion = '0.8.8'
6
6
  end
@@ -89,10 +89,16 @@ module Gem
89
89
 
90
90
  def_delegators :@gems, :size, :length
91
91
 
92
- # Search for a gem by name and optional version
92
+ # Find a gem by an exact match on the short name.
93
+ def find_name(gem_name, version_requirement=Version::Requirement.new(">= 0"))
94
+ search(/^#{gem_name}$/, version_requirement)
95
+ end
96
+
97
+ # Search for a gem by short name pattern and optional version
93
98
  #
94
99
  # gem_name::
95
- # [String] the (short) name of the gem
100
+ # [String] a partial for the (short) name of the gem, or
101
+ # [Regex] a pattern to match against the short name
96
102
  # version_requirement::
97
103
  # [String | default=Version::Requirement.new(">= 0")] version to
98
104
  # find
@@ -100,13 +106,13 @@ module Gem
100
106
  # [Array] list of Gem::Specification objects in sorted (version)
101
107
  # order. Empty if not found.
102
108
  #
103
- def search(gem_name, version_requirement=Version::Requirement.new(">= 0"))
109
+ def search(gem_pattern, version_requirement=Version::Requirement.new(">= 0"))
104
110
  #FIXME - remove duplication between this and RemoteInstaller.search
105
- gem_name = /#{ gem_name }/i if String === gem_name
111
+ gem_pattern = /#{ gem_pattern }/i if String === gem_pattern
106
112
  version_requirement = Gem::Version::Requirement.create(version_requirement)
107
113
  result = []
108
114
  @gems.each do |full_spec_name, spec|
109
- next unless spec.name =~ gem_name
115
+ next unless spec.name =~ gem_pattern
110
116
  result << spec if version_requirement.satisfied_by?(spec.version)
111
117
  end
112
118
  result = result.sort
@@ -559,6 +559,11 @@ module Gem
559
559
  # ------------------------- Dependency methods.
560
560
 
561
561
  ##
562
+ # Return a list of all gems that have a dependency on this
563
+ # gemspec. The list is structured with entries that conform to:
564
+ #
565
+ # [depending_gem, dependency, [list_of_gems_that_satisfy_dependency]]
566
+ #
562
567
  # return:: [Array] [[dependent_gem, dependency, [list_of_satisfiers]]]
563
568
  #
564
569
  def dependent_gems
@@ -1,6 +1,6 @@
1
1
  module Gem
2
2
 
3
- ##
3
+ ####################################################################
4
4
  # The Dependency class holds a Gem name and Version::Requirement
5
5
  #
6
6
  class Dependency
@@ -50,16 +50,22 @@ module Gem
50
50
  end
51
51
  end
52
52
 
53
- ##
53
+ ####################################################################
54
54
  # The Version class processes string versions into comparable values
55
55
  #
56
56
  class Version
57
57
  include Comparable
58
58
 
59
+ # The originating definition of Requirement is left nested in
60
+ # Version for compatibility. The full definition is given in
61
+ # Gem::Requirement.
62
+ class Requirement
63
+ end
64
+
59
65
  attr_accessor :version
60
-
66
+
61
67
  NUM_RE = /\s*(\d+(\.\d+)*)*\s*/
62
-
68
+
63
69
  ##
64
70
  # Checks if version string is valid format
65
71
  #
@@ -147,137 +153,148 @@ module Gem
147
153
  self.class.new(ints.join("."))
148
154
  end
149
155
 
156
+ end
157
+
158
+ # Class Requirement's original definition is nested in Version.
159
+ # Although an probably inappropriate place, current gems specs
160
+ # reference the nested class name explicitly. To remain compatible
161
+ # with old software loading gemspecs, we leave the original
162
+ # definition in Version, but define an alias Gem::Requirement for
163
+ # use everywhere else.
164
+ Requirement = ::Gem::Version::Requirement
165
+
166
+ ##################################################################
167
+ # Requirement version includes a prefaced comparator in addition
168
+ # to a version number.
169
+ #
170
+ # A Requirement object can actually contain multiple, er,
171
+ # requirements, as in (> 1.2, < 2.0).
172
+ #
173
+ class Requirement
174
+ include Comparable
175
+
176
+ OPS = {
177
+ "=" => lambda { |v, r| v == r },
178
+ "!=" => lambda { |v, r| v != r },
179
+ ">" => lambda { |v, r| v > r },
180
+ "<" => lambda { |v, r| v < r },
181
+ ">=" => lambda { |v, r| v >= r },
182
+ "<=" => lambda { |v, r| v <= r },
183
+ "~>" => lambda { |v, r| v >= r && v < r.bump }
184
+ }
185
+
186
+ OP_RE = Regexp.new(OPS.keys.collect{|k| Regexp.quote(k)}.join("|"))
187
+ REQ_RE = /\s*(#{OP_RE})\s*/
188
+
150
189
  ##
151
- # Requirement version includes a prefaced comparator in addition
152
- # to a version number.
190
+ # Factory method to create a Version::Requirement object. Input may be a
191
+ # Version, a String, or nil. Intended to simplify client code.
153
192
  #
154
- # A Requirement object can actually contain multiple, er, requirements, as
155
- # in (> 1.2, < 2.0).
193
+ # If the input is "weird", the default version requirement is returned.
156
194
  #
157
- class Requirement
158
- include Comparable
159
-
160
- OPS = {
161
- "=" => lambda { |v, r| v == r },
162
- "!=" => lambda { |v, r| v != r },
163
- ">" => lambda { |v, r| v > r },
164
- "<" => lambda { |v, r| v < r },
165
- ">=" => lambda { |v, r| v >= r },
166
- "<=" => lambda { |v, r| v <= r },
167
- "~>" => lambda { |v, r| v >= r && v < r.bump }
168
- }
169
-
170
- OP_RE = Regexp.new(OPS.keys.collect{|k| Regexp.quote(k)}.join("|"))
171
- REQ_RE = /\s*(#{OP_RE})\s*/
172
-
173
- ##
174
- # Factory method to create a Version::Requirement object. Input may be a
175
- # Version, a String, or nil. Intended to simplify client code.
176
- #
177
- # If the input is "weird", the default version requirement is returned.
178
- #
179
- def self.create(input)
180
- if input.kind_of?(Requirement)
181
- return input
182
- elsif input.kind_of?(Array)
183
- return self.new(input)
184
- elsif input.respond_to? :to_str
185
- return self.new([input.to_str])
186
- else
187
- return self.default
188
- end
189
- end
190
-
191
- ##
192
- # A default "version requirement" can surely _only_ be '> 0'.
193
- #
194
- def self.default
195
- self.new(['> 0.0.0'])
196
- end
197
-
198
- ##
199
- # Constructs a version requirement instance
200
- #
201
- # str:: [String Array] the version requirement string (e.g. ["> 1.23"])
202
- #
203
- def initialize(reqs)
204
- @requirements = reqs.collect do |rq|
205
- op, version_string = parse(rq)
206
- [op, Version.new(version_string)]
207
- end
208
- @version = nil # Avoid warnings.
209
- end
210
-
211
- ##
212
- # Overrides to check for comparator
213
- #
214
- # str:: [String] the version requirement string
215
- # return:: [Boolean] true if the string format is correct, otherwise false
216
- #
217
- def correct?(str)
218
- /^#{REQ_RE}#{NUM_RE}$/.match(str)
219
- end
220
-
221
- def to_s
222
- as_list.join(", ")
223
- end
224
-
225
- def as_list
226
- normalize
227
- @requirements.collect { |req|
228
- "#{req[0]} #{req[1]}"
229
- }
230
- end
231
-
232
- def normalize
233
- return if @version.nil?
234
- @requirements = [parse(@version)]
235
- @nums = nil
236
- @version = nil
237
- @op = nil
238
- end
239
-
240
- ##
241
- # Is the requirement satifised by +version+.
242
- #
243
- # version:: [Gem::Version] the version to compare against
244
- # return:: [Boolean] true if this requirement is satisfied by
245
- # the version, otherwise false
246
- #
247
- def satisfied_by?(version)
248
- normalize
249
- @requirements.all? { |op, rv| satisfy?(op, version, rv) }
250
- end
251
-
252
- private
253
-
254
- ##
255
- # Is "version op required_version" satisfied?
256
- #
257
- def satisfy?(op, version, required_version)
258
- OPS[op].call(version, required_version)
195
+ def self.create(input)
196
+ if input.kind_of?(Requirement)
197
+ return input
198
+ elsif input.kind_of?(Array)
199
+ return self.new(input)
200
+ elsif input.respond_to? :to_str
201
+ return self.new([input.to_str])
202
+ else
203
+ return self.default
259
204
  end
260
-
261
- ##
262
- # Parse the version requirement string. Return the operator and
263
- # version strings.
264
- #
265
- def parse(str)
266
- if md = /^\s*(#{OP_RE})\s*([0-9.]+)\s*$/.match(str)
267
- [md[1], md[2]]
268
- elsif md = /^\s*([0-9.]+)\s*$/.match(str)
269
- ["=", md[1]]
270
- elsif md = /^\s*(#{OP_RE})\s*$/.match(str)
271
- [md[1], "0"]
272
- else
273
- fail ArgumentError, "Illformed requirement [#{str}]"
274
- end
205
+ end
206
+
207
+ ##
208
+ # A default "version requirement" can surely _only_ be '> 0'.
209
+ #
210
+ def self.default
211
+ self.new(['> 0.0.0'])
212
+ end
213
+
214
+ ##
215
+ # Constructs a version requirement instance
216
+ #
217
+ # str:: [String Array] the version requirement string (e.g. ["> 1.23"])
218
+ #
219
+ def initialize(reqs)
220
+ @requirements = reqs.collect do |rq|
221
+ op, version_string = parse(rq)
222
+ [op, Version.new(version_string)]
275
223
  end
276
-
277
- def <=>(other)
278
- to_s <=> other.to_s
224
+ @version = nil # Avoid warnings.
225
+ end
226
+
227
+ ##
228
+ # Overrides to check for comparator
229
+ #
230
+ # str:: [String] the version requirement string
231
+ # return:: [Boolean] true if the string format is correct, otherwise false
232
+ #
233
+ # NOTE: Commented out because I don't think it is used.
234
+ # def correct?(str)
235
+ # /^#{REQ_RE}#{NUM_RE}$/.match(str)
236
+ # end
237
+
238
+ def to_s
239
+ as_list.join(", ")
240
+ end
241
+
242
+ def as_list
243
+ normalize
244
+ @requirements.collect { |req|
245
+ "#{req[0]} #{req[1]}"
246
+ }
247
+ end
248
+
249
+ def normalize
250
+ return if @version.nil?
251
+ @requirements = [parse(@version)]
252
+ @nums = nil
253
+ @version = nil
254
+ @op = nil
255
+ end
256
+
257
+ ##
258
+ # Is the requirement satifised by +version+.
259
+ #
260
+ # version:: [Gem::Version] the version to compare against
261
+ # return:: [Boolean] true if this requirement is satisfied by
262
+ # the version, otherwise false
263
+ #
264
+ def satisfied_by?(version)
265
+ normalize
266
+ @requirements.all? { |op, rv| satisfy?(op, version, rv) }
267
+ end
268
+
269
+ private
270
+
271
+ ##
272
+ # Is "version op required_version" satisfied?
273
+ #
274
+ def satisfy?(op, version, required_version)
275
+ OPS[op].call(version, required_version)
276
+ end
277
+
278
+ ##
279
+ # Parse the version requirement string. Return the operator and
280
+ # version strings.
281
+ #
282
+ def parse(str)
283
+ if md = /^\s*(#{OP_RE})\s*([0-9.]+)\s*$/.match(str)
284
+ [md[1], md[2]]
285
+ elsif md = /^\s*([0-9.]+)\s*$/.match(str)
286
+ ["=", md[1]]
287
+ elsif md = /^\s*(#{OP_RE})\s*$/.match(str)
288
+ [md[1], "0"]
289
+ else
290
+ fail ArgumentError, "Illformed requirement [#{str}]"
279
291
  end
280
-
281
292
  end
293
+
294
+ def <=>(other)
295
+ to_s <=> other.to_s
296
+ end
297
+
282
298
  end
299
+
283
300
  end
@@ -10,7 +10,7 @@ class TestArgPreprocessor < Test::Unit::TestCase
10
10
  def test_create
11
11
  @cfg = Gem::ConfigFile.new([])
12
12
  assert ! @cfg.backtrace
13
- assert_equal File.join(ENV['HOME'], '.gemrc'), @cfg.config_file_name
13
+ assert_equal File.join(Gem.user_home, '.gemrc'), @cfg.config_file_name
14
14
  end
15
15
 
16
16
  def test_backtrace
@@ -0,0 +1,163 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'test/unit'
4
+ require 'rubygems/dependency_list'
5
+ require 'rubygems/specification'
6
+
7
+ class TestDependencyList < Test::Unit::TestCase
8
+ def setup
9
+ @deplist = Gem::DependencyList.new
10
+ end
11
+
12
+ def test_create
13
+ assert @deplist.ok?, "all dependencies should be satisfied"
14
+ end
15
+
16
+ def test_one_unsatisfied_gem
17
+ @deplist.add(bspec)
18
+ assert ! @deplist.ok?
19
+ end
20
+
21
+ def test_one_satisfied_gem
22
+ @deplist.add(create_spec("a", "1.1"))
23
+ assert @deplist.ok?
24
+ end
25
+
26
+ def test_two_gems_with_dependency
27
+ @deplist.add(create_spec("a", "1.1"))
28
+ @deplist.add(bspec)
29
+ assert @deplist.ok?
30
+ end
31
+
32
+ def test_removing_required_gem
33
+ @deplist.add(create_spec("a", "1.1"))
34
+ @deplist.add(bspec)
35
+ a = @deplist.remove_by_name("a-1.1")
36
+ assert ! @deplist.ok?
37
+ end
38
+
39
+ def test_removing_redundent_gem
40
+ @deplist.add(create_spec("a", "1.1"))
41
+ @deplist.add(create_spec("a", "1.3"))
42
+ @deplist.add(bspec)
43
+ a = @deplist.remove_by_name("a-1.1")
44
+ assert @deplist.ok?
45
+ end
46
+
47
+ def test_finding_gems
48
+ @deplist.add(create_spec("a", "1.1"))
49
+ @deplist.add(bspec)
50
+ assert_equal "a-1.1", @deplist.find_name("a-1.1").full_name
51
+ assert_equal "b-1.2", @deplist.find_name("b-1.2").full_name
52
+ assert_nil @deplist.find_name("c-1.2")
53
+ end
54
+
55
+ def test_ok_to_remove
56
+ @deplist.add(create_spec("a", "1.1"))
57
+ assert @deplist.ok_to_remove?("a-1.1")
58
+ end
59
+
60
+ def test_not_ok_to_remove
61
+ @deplist.add(create_spec("a", "1.1"))
62
+ @deplist.add(bspec)
63
+ assert ! @deplist.ok_to_remove?("a-1.1")
64
+ end
65
+
66
+ def test_ok_to_remove_with_extras
67
+ @deplist.add(create_spec("a", "1.1"))
68
+ @deplist.add(create_spec("a", "1.2"))
69
+ @deplist.add(bspec)
70
+ assert @deplist.ok_to_remove?("a-1.1")
71
+ assert @deplist.ok_to_remove?("a-1.2")
72
+ assert @deplist.ok_to_remove?("b-1.2")
73
+ end
74
+
75
+ def test_not_ok_to_remove_after_sibling_removed
76
+ @deplist.add(create_spec("a", "1.1"))
77
+ @deplist.add(create_spec("a", "1.2"))
78
+ @deplist.add(bspec)
79
+ assert @deplist.ok_to_remove?("a-1.1")
80
+ assert @deplist.ok_to_remove?("a-1.2")
81
+ @deplist.remove_by_name("a-1.1")
82
+ assert ! @deplist.ok_to_remove?("a-1.2")
83
+ end
84
+
85
+ def test_sorting
86
+ @deplist.add(create_spec("a", "1.1"))
87
+ @deplist.add(bspec)
88
+ @deplist.add(create_spec("a", "1.3"))
89
+ order = @deplist.dependency_order
90
+ assert_equal "b-1.2", order.first.full_name
91
+ end
92
+
93
+ def test_sorting_four_with_out_ambiguities
94
+ @deplist.add(Gem::Specification.new do |s|
95
+ s.name = "a"
96
+ s.version = '1.1'
97
+ end)
98
+ @deplist.add(Gem::Specification.new do |s|
99
+ s.name = "b"
100
+ s.version = '1.1'
101
+ s.add_dependency("a", ">= 1.1")
102
+ end)
103
+ @deplist.add(Gem::Specification.new do |s|
104
+ s.name = "c"
105
+ s.version = '1.1'
106
+ s.add_dependency("b", ">= 1.1")
107
+ end)
108
+ @deplist.add(Gem::Specification.new do |s|
109
+ s.name = "d"
110
+ s.version = '1.1'
111
+ s.add_dependency("c", ">= 1.1")
112
+ end)
113
+ order = @deplist.dependency_order
114
+ assert_equal ['d', 'c', 'b', 'a'], order.collect { |s| s.name }
115
+ end
116
+
117
+ def test_sorting_with_circular_dependency
118
+ @deplist.add(Gem::Specification.new do |s|
119
+ s.name = "a"
120
+ s.version = '1.1'
121
+ s.add_dependency("c", ">= 1.1")
122
+ end)
123
+ @deplist.add(Gem::Specification.new do |s|
124
+ s.name = "b"
125
+ s.version = '1.1'
126
+ s.add_dependency("a", ">= 1.1")
127
+ end)
128
+ @deplist.add(Gem::Specification.new do |s|
129
+ s.name = "c"
130
+ s.version = '1.1'
131
+ s.add_dependency("b", ">= 1.1")
132
+ end)
133
+ order = @deplist.dependency_order
134
+ end
135
+
136
+ def test_from_source_index
137
+ hash = {
138
+ 'a-1.1' => create_spec("a", "1.1"),
139
+ 'b-1.2' => bspec,
140
+ }
141
+ si = Gem::SourceIndex.new(hash)
142
+ deps = Gem::DependencyList.from_source_index(si)
143
+ assert_equal ['b-1.2', 'a-1.1'],
144
+ deps.dependency_order.collect { |s| s.full_name }
145
+ end
146
+
147
+ # ------------------------------------------------------------------
148
+
149
+ def bspec
150
+ Gem::Specification.new do |s|
151
+ s.name = "b"
152
+ s.version = "1.2"
153
+ s.add_dependency("a", ">= 1.1")
154
+ end
155
+ end
156
+
157
+ def create_spec(name, version)
158
+ Gem::Specification.new do |s|
159
+ s.name = name
160
+ s.version = version
161
+ end
162
+ end
163
+ end