gel 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) hide show
  1. checksums.yaml +7 -0
  2. data/CODE_OF_CONDUCT.md +74 -0
  3. data/LICENSE.txt +21 -0
  4. data/README.md +39 -0
  5. data/exe/gel +13 -0
  6. data/lib/gel.rb +22 -0
  7. data/lib/gel/catalog.rb +153 -0
  8. data/lib/gel/catalog/common.rb +82 -0
  9. data/lib/gel/catalog/compact_index.rb +152 -0
  10. data/lib/gel/catalog/dependency_index.rb +125 -0
  11. data/lib/gel/catalog/legacy_index.rb +157 -0
  12. data/lib/gel/catalog/marshal_hacks.rb +16 -0
  13. data/lib/gel/command.rb +86 -0
  14. data/lib/gel/command/config.rb +11 -0
  15. data/lib/gel/command/env.rb +7 -0
  16. data/lib/gel/command/exec.rb +66 -0
  17. data/lib/gel/command/help.rb +7 -0
  18. data/lib/gel/command/install.rb +7 -0
  19. data/lib/gel/command/install_gem.rb +16 -0
  20. data/lib/gel/command/lock.rb +34 -0
  21. data/lib/gel/command/ruby.rb +10 -0
  22. data/lib/gel/command/shell_setup.rb +25 -0
  23. data/lib/gel/command/stub.rb +12 -0
  24. data/lib/gel/command/update.rb +11 -0
  25. data/lib/gel/compatibility.rb +4 -0
  26. data/lib/gel/compatibility/bundler.rb +54 -0
  27. data/lib/gel/compatibility/bundler/cli.rb +6 -0
  28. data/lib/gel/compatibility/bundler/friendly_errors.rb +3 -0
  29. data/lib/gel/compatibility/bundler/setup.rb +4 -0
  30. data/lib/gel/compatibility/rubygems.rb +192 -0
  31. data/lib/gel/compatibility/rubygems/command.rb +4 -0
  32. data/lib/gel/compatibility/rubygems/dependency_installer.rb +0 -0
  33. data/lib/gel/compatibility/rubygems/gem_runner.rb +6 -0
  34. data/lib/gel/config.rb +80 -0
  35. data/lib/gel/db.rb +294 -0
  36. data/lib/gel/direct_gem.rb +29 -0
  37. data/lib/gel/environment.rb +592 -0
  38. data/lib/gel/error.rb +104 -0
  39. data/lib/gel/gemfile_parser.rb +144 -0
  40. data/lib/gel/gemspec_parser.rb +95 -0
  41. data/lib/gel/git_catalog.rb +38 -0
  42. data/lib/gel/git_depot.rb +119 -0
  43. data/lib/gel/httpool.rb +148 -0
  44. data/lib/gel/installer.rb +251 -0
  45. data/lib/gel/lock_loader.rb +164 -0
  46. data/lib/gel/lock_parser.rb +64 -0
  47. data/lib/gel/locked_store.rb +126 -0
  48. data/lib/gel/multi_store.rb +96 -0
  49. data/lib/gel/package.rb +156 -0
  50. data/lib/gel/package/inspector.rb +23 -0
  51. data/lib/gel/package/installer.rb +267 -0
  52. data/lib/gel/path_catalog.rb +44 -0
  53. data/lib/gel/pinboard.rb +140 -0
  54. data/lib/gel/pub_grub/preference_strategy.rb +82 -0
  55. data/lib/gel/pub_grub/source.rb +153 -0
  56. data/lib/gel/runtime.rb +27 -0
  57. data/lib/gel/store.rb +205 -0
  58. data/lib/gel/store_catalog.rb +31 -0
  59. data/lib/gel/store_gem.rb +80 -0
  60. data/lib/gel/stub_set.rb +51 -0
  61. data/lib/gel/support/gem_platform.rb +225 -0
  62. data/lib/gel/support/gem_requirement.rb +264 -0
  63. data/lib/gel/support/gem_version.rb +398 -0
  64. data/lib/gel/support/tar.rb +13 -0
  65. data/lib/gel/support/tar/tar_header.rb +229 -0
  66. data/lib/gel/support/tar/tar_reader.rb +123 -0
  67. data/lib/gel/support/tar/tar_reader/entry.rb +154 -0
  68. data/lib/gel/support/tar/tar_writer.rb +339 -0
  69. data/lib/gel/tail_file.rb +205 -0
  70. data/lib/gel/version.rb +5 -0
  71. data/lib/gel/work_pool.rb +143 -0
  72. data/man/man1/gel-exec.1 +16 -0
  73. data/man/man1/gel-install.1 +16 -0
  74. data/man/man1/gel.1 +30 -0
  75. metadata +131 -0
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Gel::StoreCatalog
4
+ attr_reader :store
5
+
6
+ def initialize(store)
7
+ @store = store
8
+ @cache = {}
9
+ end
10
+
11
+ def gem_info(name)
12
+ @cache.fetch(name) { @cache[name] = _info(name) }
13
+ end
14
+
15
+ def _info(name)
16
+ info = {}
17
+
18
+ @store.each(name) do |store_gem|
19
+ info[store_gem.version] = {
20
+ dependencies: store_gem.dependencies.map do |name, pairs|
21
+ [name, pairs.map { |op, ver| "#{op} #{ver}" }]
22
+ end,
23
+ }
24
+ end
25
+
26
+ info
27
+ end
28
+
29
+ def prepare
30
+ end
31
+ end
@@ -0,0 +1,80 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Gel::StoreGem
4
+ EXTENSION_SUBDIR_TOKEN = ".."
5
+
6
+ attr_reader :root, :name, :version, :extensions, :info
7
+
8
+ def initialize(root, name, version, extensions, info)
9
+ @root = root
10
+ @name = name
11
+ @version = version
12
+ @extensions = extensions unless extensions && extensions.empty?
13
+ @info = info
14
+ end
15
+
16
+ def ==(other)
17
+ other.class == self.class && @name == other.name && @version == other.version
18
+ end
19
+
20
+ def hash
21
+ @name.hash ^ @version.hash
22
+ end
23
+
24
+ def satisfies?(requirements)
25
+ requirements.satisfied_by?(gem_version)
26
+ end
27
+
28
+ def require_paths
29
+ paths = _require_paths.map { |reqp| "#{root}/#{reqp}" }
30
+ paths << extensions if extensions
31
+ raise(paths.inspect) unless paths.all? { |path| path.is_a?(String) }
32
+ paths
33
+ end
34
+
35
+ def bindir
36
+ @info[:bindir] || "bin"
37
+ end
38
+
39
+ def dependencies
40
+ @info[:dependencies]
41
+ end
42
+
43
+ def executables
44
+ @info[:executables]
45
+ end
46
+
47
+ def path(file, subdir = nil)
48
+ if subdir == EXTENSION_SUBDIR_TOKEN && extensions
49
+ "#{extensions}/#{file}"
50
+ else
51
+ subdir ||= _default_require_path
52
+ "#{root}/#{subdir}/#{file}"
53
+ end
54
+ end
55
+
56
+ def libs
57
+ _require_paths.each do |subdir|
58
+ prefix = "#{root}/#{subdir}/"
59
+ Dir["#{prefix}**/*.rb"].each do |path|
60
+ next unless path.start_with?(prefix)
61
+ file = path[prefix.size..-1].sub(/\.rb$/, "")
62
+ yield file, subdir
63
+ end
64
+ end
65
+ end
66
+
67
+ private
68
+
69
+ def gem_version
70
+ @gem_version ||= Gel::Support::GemVersion.new(version)
71
+ end
72
+
73
+ def _require_paths
74
+ @info[:require_paths]
75
+ end
76
+
77
+ def _default_require_path
78
+ _require_paths.first
79
+ end
80
+ end
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "db"
4
+
5
+ class Gel::StubSet
6
+ attr_reader :root
7
+
8
+ def initialize(root)
9
+ @root = File.realpath(File.expand_path(root))
10
+ @db = Gel::DB.new(root, "stubs")
11
+ @dir = File.join(@root, "bin")
12
+ end
13
+
14
+ def add(store, executables)
15
+ @db.writing do
16
+ executables.each do |exe|
17
+ create_stub(exe) unless File.exist?(bin(exe))
18
+ @db[exe] = (@db[exe] || []) + [store]
19
+ end
20
+ end
21
+ end
22
+
23
+ def remove(store, executables)
24
+ @db.writing do
25
+ executables.each do |exe|
26
+ remaining_stores = (@db[exe] || []) - [store]
27
+ if remaining_stores.empty?
28
+ File.unlink(bin(exe))
29
+ @db.delete(exe)
30
+ else
31
+ @db[exe] = remaining_stores
32
+ end
33
+ end
34
+ end
35
+ end
36
+
37
+ def create_stub(exe)
38
+ Dir.mkdir(@dir) unless Dir.exist?(@dir)
39
+
40
+ File.open(bin(exe), "w", 0755) do |f|
41
+ f.write(<<STUB)
42
+ #!/usr/bin/env gel stub #{exe}
43
+ # This file is generated and managed by Gel.
44
+ STUB
45
+ end
46
+ end
47
+
48
+ def bin(exe)
49
+ File.join(@dir, exe)
50
+ end
51
+ end
@@ -0,0 +1,225 @@
1
+ # frozen_string_literal: true
2
+ #
3
+ # Copyright (c) Chad Fowler, Rich Kilmer, Jim Weirich and others.
4
+ # Portions copyright (c) Engine Yard and Andre Arko
5
+ #
6
+ # Redistributed under the terms of the MIT license
7
+ #
8
+
9
+ require "rubygems/deprecate"
10
+
11
+ ##
12
+ # Available list of platforms for targeting Gem installations.
13
+ #
14
+ # See `gem help platform` for information on platform matching.
15
+
16
+ class Gel::Support::GemPlatform
17
+
18
+ @local = nil
19
+
20
+ attr_accessor :cpu
21
+
22
+ attr_accessor :os
23
+
24
+ attr_accessor :version
25
+
26
+ def self.local
27
+ arch = RbConfig::CONFIG['arch']
28
+ arch = "#{arch}_60" if arch =~ /mswin(?:32|64)$/
29
+ @local ||= new(arch)
30
+ end
31
+
32
+ def self.platforms=(platforms)
33
+ @platforms = platforms
34
+ end
35
+
36
+ def self.platforms
37
+ @platforms ||= []
38
+ if @platforms.empty?
39
+ @platforms = [Gel::Support::GemPlatform::RUBY, Gel::Support::GemPlatform.local]
40
+ end
41
+ @platforms
42
+ end
43
+
44
+ def self.match(platform)
45
+ platforms.any? do |local_platform|
46
+ platform.nil? or
47
+ local_platform == platform or
48
+ (local_platform != Gel::Support::GemPlatform::RUBY and local_platform =~ platform)
49
+ end
50
+ end
51
+
52
+ def self.installable?(spec)
53
+ if spec.respond_to? :installable_platform?
54
+ spec.installable_platform?
55
+ else
56
+ match spec.platform
57
+ end
58
+ end
59
+
60
+ def self.new(arch) # :nodoc:
61
+ case arch
62
+ when Gel::Support::GemPlatform::CURRENT then
63
+ Gel::Support::GemPlatform.local
64
+ when Gel::Support::GemPlatform::RUBY, nil, '' then
65
+ Gel::Support::GemPlatform::RUBY
66
+ else
67
+ super
68
+ end
69
+ end
70
+
71
+ def initialize(arch)
72
+ case arch
73
+ when Array then
74
+ @cpu, @os, @version = arch
75
+ when String then
76
+ arch = arch.split '-'
77
+
78
+ if arch.length > 2 and arch.last !~ /\d/ # reassemble x86-linux-gnu
79
+ extra = arch.pop
80
+ arch.last << "-#{extra}"
81
+ end
82
+
83
+ cpu = arch.shift
84
+
85
+ @cpu = case cpu
86
+ when /i\d86/ then 'x86'
87
+ else cpu
88
+ end
89
+
90
+ if arch.length == 2 and arch.last =~ /^\d+(\.\d+)?$/ # for command-line
91
+ @os, @version = arch
92
+ return
93
+ end
94
+
95
+ os, = arch
96
+ @cpu, os = nil, cpu if os.nil? # legacy jruby
97
+
98
+ @os, @version = case os
99
+ when /aix(\d+)?/ then [ 'aix', $1 ]
100
+ when /cygwin/ then [ 'cygwin', nil ]
101
+ when /darwin(\d+)?/ then [ 'darwin', $1 ]
102
+ when /^macruby$/ then [ 'macruby', nil ]
103
+ when /freebsd(\d+)?/ then [ 'freebsd', $1 ]
104
+ when /hpux(\d+)?/ then [ 'hpux', $1 ]
105
+ when /^java$/, /^jruby$/ then [ 'java', nil ]
106
+ when /^java([\d.]*)/ then [ 'java', $1 ]
107
+ when /^dalvik(\d+)?$/ then [ 'dalvik', $1 ]
108
+ when /^dotnet$/ then [ 'dotnet', nil ]
109
+ when /^dotnet([\d.]*)/ then [ 'dotnet', $1 ]
110
+ when /linux/ then [ 'linux', $1 ]
111
+ when /mingw32/ then [ 'mingw32', nil ]
112
+ when /(mswin\d+)(\_(\d+))?/ then
113
+ os, version = $1, $3
114
+ @cpu = 'x86' if @cpu.nil? and os =~ /32$/
115
+ [os, version]
116
+ when /netbsdelf/ then [ 'netbsdelf', nil ]
117
+ when /openbsd(\d+\.\d+)?/ then [ 'openbsd', $1 ]
118
+ when /bitrig(\d+\.\d+)?/ then [ 'bitrig', $1 ]
119
+ when /solaris(\d+\.\d+)?/ then [ 'solaris', $1 ]
120
+ # test
121
+ when /^(\w+_platform)(\d+)?/ then [ $1, $2 ]
122
+ else [ 'unknown', nil ]
123
+ end
124
+ when Gel::Support::GemPlatform then
125
+ @cpu = arch.cpu
126
+ @os = arch.os
127
+ @version = arch.version
128
+ else
129
+ raise ArgumentError, "invalid argument #{arch.inspect}"
130
+ end
131
+ end
132
+
133
+ def inspect
134
+ "%s @cpu=%p, @os=%p, @version=%p>" % [super[0..-2], *to_a]
135
+ end
136
+
137
+ def to_a
138
+ [@cpu, @os, @version]
139
+ end
140
+
141
+ def to_s
142
+ to_a.compact.join '-'
143
+ end
144
+
145
+ ##
146
+ # Is +other+ equal to this platform? Two platforms are equal if they have
147
+ # the same CPU, OS and version.
148
+
149
+ def ==(other)
150
+ self.class === other and to_a == other.to_a
151
+ end
152
+
153
+ alias :eql? :==
154
+
155
+ def hash # :nodoc:
156
+ to_a.hash
157
+ end
158
+
159
+ ##
160
+ # Does +other+ match this platform? Two platforms match if they have the
161
+ # same CPU, or either has a CPU of 'universal', they have the same OS, and
162
+ # they have the same version, or either has no version.
163
+ #
164
+ # Additionally, the platform will match if the local CPU is 'arm' and the
165
+ # other CPU starts with "arm" (for generic ARM family support).
166
+
167
+ def ===(other)
168
+ return nil unless Gel::Support::GemPlatform === other
169
+
170
+ # cpu
171
+ ([nil,'universal'].include?(@cpu) or [nil, 'universal'].include?(other.cpu) or @cpu == other.cpu or
172
+ (@cpu == 'arm' and other.cpu =~ /\Aarm/)) and
173
+
174
+ # os
175
+ @os == other.os and
176
+
177
+ # version
178
+ (@version.nil? or other.version.nil? or @version == other.version)
179
+ end
180
+
181
+ ##
182
+ # Does +other+ match this platform? If +other+ is a String it will be
183
+ # converted to a Gel::Support::GemPlatform first. See #=== for matching rules.
184
+
185
+ def =~(other)
186
+ case other
187
+ when Gel::Support::GemPlatform then # nop
188
+ when String then
189
+ # This data is from http://gems.rubyforge.org/gems/yaml on 19 Aug 2007
190
+ other = case other
191
+ when /^i686-darwin(\d)/ then ['x86', 'darwin', $1 ]
192
+ when /^i\d86-linux/ then ['x86', 'linux', nil ]
193
+ when 'java', 'jruby' then [nil, 'java', nil ]
194
+ when /^dalvik(\d+)?$/ then [nil, 'dalvik', $1 ]
195
+ when /dotnet(\-(\d+\.\d+))?/ then ['universal','dotnet', $2 ]
196
+ when /mswin32(\_(\d+))?/ then ['x86', 'mswin32', $2 ]
197
+ when /mswin64(\_(\d+))?/ then ['x64', 'mswin64', $2 ]
198
+ when 'powerpc-darwin' then ['powerpc', 'darwin', nil ]
199
+ when /powerpc-darwin(\d)/ then ['powerpc', 'darwin', $1 ]
200
+ when /sparc-solaris2.8/ then ['sparc', 'solaris', '2.8' ]
201
+ when /universal-darwin(\d)/ then ['universal', 'darwin', $1 ]
202
+ else other
203
+ end
204
+
205
+ other = Gel::Support::GemPlatform.new other
206
+ else
207
+ return nil
208
+ end
209
+
210
+ self === other
211
+ end
212
+
213
+ ##
214
+ # A pure-Ruby gem that may use Gem::Specification#extensions to build
215
+ # binary files.
216
+
217
+ RUBY = 'ruby'.freeze
218
+
219
+ ##
220
+ # A platform-specific gem that is built for the packaging Ruby's platform.
221
+ # This will be replaced with Gel::Support::GemPlatform::local.
222
+
223
+ CURRENT = 'current'.freeze
224
+
225
+ end
@@ -0,0 +1,264 @@
1
+ # frozen_string_literal: true
2
+ #
3
+ # Copyright (c) Chad Fowler, Rich Kilmer, Jim Weirich and others.
4
+ # Portions copyright (c) Engine Yard and Andre Arko
5
+ #
6
+ # Redistributed under the terms of the MIT license
7
+ #
8
+
9
+ require_relative "gem_version"
10
+
11
+ ##
12
+ # A Requirement is a set of one or more version restrictions. It supports a
13
+ # few (<tt>=, !=, >, <, >=, <=, ~></tt>) different restriction operators.
14
+ #
15
+ # See Gem::Version for a description on how versions and requirements work
16
+ # together in RubyGems.
17
+
18
+ class Gel::Support::GemRequirement
19
+ OPS = { #:nodoc:
20
+ "=" => lambda { |v, r| v == r },
21
+ "!=" => lambda { |v, r| v != r },
22
+ ">" => lambda { |v, r| v > r },
23
+ "<" => lambda { |v, r| v < r },
24
+ ">=" => lambda { |v, r| v >= r },
25
+ "<=" => lambda { |v, r| v <= r },
26
+ "~>" => lambda { |v, r| v >= r && v.release < r.bump }
27
+ }
28
+
29
+ SOURCE_SET_REQUIREMENT = Struct.new(:for_lockfile).new "!" # :nodoc:
30
+
31
+ quoted = OPS.keys.map { |k| Regexp.quote k }.join "|"
32
+ PATTERN_RAW = "\\s*(#{quoted})?\\s*(#{Gel::Support::GemVersion::VERSION_PATTERN})\\s*" # :nodoc:
33
+
34
+ ##
35
+ # A regular expression that matches a requirement
36
+
37
+ PATTERN = /\A#{PATTERN_RAW}\z/
38
+
39
+ ##
40
+ # The default requirement matches any version
41
+
42
+ DefaultRequirement = [">=", Gel::Support::GemVersion.new(0)]
43
+
44
+ ##
45
+ # Raised when a bad requirement is encountered
46
+
47
+ class BadRequirementError < ArgumentError; end
48
+
49
+ ##
50
+ # Factory method to create a Gem::Requirement object. Input may be
51
+ # a Version, a String, or nil. Intended to simplify client code.
52
+ #
53
+ # If the input is "weird", the default version requirement is
54
+ # returned.
55
+
56
+ def self.create *inputs
57
+ return new inputs if inputs.length > 1
58
+
59
+ input = inputs.shift
60
+
61
+ case input
62
+ when Gel::Support::GemRequirement then
63
+ input
64
+ when Gel::Support::GemVersion, Array then
65
+ new input
66
+ when '!' then
67
+ source_set
68
+ else
69
+ if input.respond_to? :to_str then
70
+ new [input.to_str]
71
+ else
72
+ default
73
+ end
74
+ end
75
+ end
76
+
77
+ ##
78
+ # A default "version requirement" can surely _only_ be '>= 0'.
79
+
80
+ def self.default
81
+ new '>= 0'
82
+ end
83
+
84
+ ###
85
+ # A source set requirement, used for Gemfiles and lockfiles
86
+
87
+ def self.source_set # :nodoc:
88
+ SOURCE_SET_REQUIREMENT
89
+ end
90
+
91
+ ##
92
+ # Parse +obj+, returning an <tt>[op, version]</tt> pair. +obj+ can
93
+ # be a String or a Gem::Version.
94
+ #
95
+ # If +obj+ is a String, it can be either a full requirement
96
+ # specification, like <tt>">= 1.2"</tt>, or a simple version number,
97
+ # like <tt>"1.2"</tt>.
98
+ #
99
+ # parse("> 1.0") # => [">", Gem::Version.new("1.0")]
100
+ # parse("1.0") # => ["=", Gem::Version.new("1.0")]
101
+ # parse(Gem::Version.new("1.0")) # => ["=, Gem::Version.new("1.0")]
102
+
103
+ def self.parse obj
104
+ return ["=", obj] if Gel::Support::GemVersion === obj
105
+
106
+ unless PATTERN =~ obj.to_s
107
+ raise BadRequirementError, "Illformed requirement [#{obj.inspect}]"
108
+ end
109
+
110
+ if $1 == ">=" && $2 == "0"
111
+ DefaultRequirement
112
+ else
113
+ [$1 || "=", Gel::Support::GemVersion.new($2)]
114
+ end
115
+ end
116
+
117
+ ##
118
+ # An array of requirement pairs. The first element of the pair is
119
+ # the op, and the second is the Gem::Version.
120
+
121
+ attr_reader :requirements #:nodoc:
122
+
123
+ ##
124
+ # Constructs a requirement from +requirements+. Requirements can be
125
+ # Strings, Gem::Versions, or Arrays of those. +nil+ and duplicate
126
+ # requirements are ignored. An empty set of +requirements+ is the
127
+ # same as <tt>">= 0"</tt>.
128
+
129
+ def initialize *requirements
130
+ requirements = requirements.flatten
131
+ requirements.compact!
132
+ requirements.uniq!
133
+
134
+ if requirements.empty?
135
+ @requirements = [DefaultRequirement]
136
+ else
137
+ @requirements = requirements.map! { |r| self.class.parse r }
138
+ end
139
+ end
140
+
141
+ ##
142
+ # Concatenates the +new+ requirements onto this requirement.
143
+
144
+ def concat new
145
+ new = new.flatten
146
+ new.compact!
147
+ new.uniq!
148
+ new = new.map { |r| self.class.parse r }
149
+
150
+ @requirements.concat new
151
+ end
152
+
153
+ ##
154
+ # Formats this requirement for use in a Gem::RequestSet::Lockfile.
155
+
156
+ def for_lockfile # :nodoc:
157
+ return if [DefaultRequirement] == @requirements
158
+
159
+ list = requirements.sort_by { |_, version|
160
+ version
161
+ }.map { |op, version|
162
+ "#{op} #{version}"
163
+ }.uniq
164
+
165
+ " (#{list.join ', '})"
166
+ end
167
+
168
+ ##
169
+ # true if this gem has no requirements.
170
+
171
+ def none?
172
+ if @requirements.size == 1
173
+ @requirements[0] == DefaultRequirement
174
+ else
175
+ false
176
+ end
177
+ end
178
+
179
+ ##
180
+ # true if the requirement is for only an exact version
181
+
182
+ def exact?
183
+ return false unless @requirements.size == 1
184
+ @requirements[0][0] == "="
185
+ end
186
+
187
+ def as_list # :nodoc:
188
+ requirements.map { |op, version| "#{op} #{version}" }.sort
189
+ end
190
+
191
+ def hash # :nodoc:
192
+ requirements.sort.hash
193
+ end
194
+
195
+ def marshal_dump # :nodoc:
196
+ [@requirements]
197
+ end
198
+
199
+ def marshal_load array # :nodoc:
200
+ @requirements = array[0]
201
+ end
202
+
203
+ def yaml_initialize(tag, vals) # :nodoc:
204
+ vals.each do |ivar, val|
205
+ instance_variable_set "@#{ivar}", val
206
+ end
207
+ end
208
+
209
+ def init_with coder # :nodoc:
210
+ yaml_initialize coder.tag, coder.map
211
+ end
212
+
213
+ def to_yaml_properties # :nodoc:
214
+ ["@requirements"]
215
+ end
216
+
217
+ def encode_with coder # :nodoc:
218
+ coder.add 'requirements', @requirements
219
+ end
220
+
221
+ ##
222
+ # A requirement is a prerelease if any of the versions inside of it
223
+ # are prereleases
224
+
225
+ def prerelease?
226
+ requirements.any? { |r| r.last.prerelease? }
227
+ end
228
+
229
+ def pretty_print q # :nodoc:
230
+ q.group 1, 'Gel::Support::GemRequirement.new(', ')' do
231
+ q.pp as_list
232
+ end
233
+ end
234
+
235
+ ##
236
+ # True if +version+ satisfies this Requirement.
237
+
238
+ def satisfied_by? version
239
+ raise ArgumentError, "Need a Gel::Support::GemVersion: #{version.inspect}" unless
240
+ Gel::Support::GemVersion === version
241
+ # #28965: syck has a bug with unquoted '=' YAML.loading as YAML::DefaultKey
242
+ requirements.all? { |op, rv| (OPS[op] || OPS["="]).call version, rv }
243
+ end
244
+
245
+ alias :=== :satisfied_by?
246
+ alias :=~ :satisfied_by?
247
+
248
+ ##
249
+ # True if the requirement will not always match the latest version.
250
+
251
+ def specific?
252
+ return true if @requirements.length > 1 # GIGO, > 1, > 2 is silly
253
+
254
+ not %w[> >=].include? @requirements.first.first # grab the operator
255
+ end
256
+
257
+ def to_s # :nodoc:
258
+ as_list.join ", "
259
+ end
260
+
261
+ def == other # :nodoc:
262
+ Gel::Support::GemRequirement === other and to_s == other.to_s
263
+ end
264
+ end