gel 0.2.0
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.
- checksums.yaml +7 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/LICENSE.txt +21 -0
- data/README.md +39 -0
- data/exe/gel +13 -0
- data/lib/gel.rb +22 -0
- data/lib/gel/catalog.rb +153 -0
- data/lib/gel/catalog/common.rb +82 -0
- data/lib/gel/catalog/compact_index.rb +152 -0
- data/lib/gel/catalog/dependency_index.rb +125 -0
- data/lib/gel/catalog/legacy_index.rb +157 -0
- data/lib/gel/catalog/marshal_hacks.rb +16 -0
- data/lib/gel/command.rb +86 -0
- data/lib/gel/command/config.rb +11 -0
- data/lib/gel/command/env.rb +7 -0
- data/lib/gel/command/exec.rb +66 -0
- data/lib/gel/command/help.rb +7 -0
- data/lib/gel/command/install.rb +7 -0
- data/lib/gel/command/install_gem.rb +16 -0
- data/lib/gel/command/lock.rb +34 -0
- data/lib/gel/command/ruby.rb +10 -0
- data/lib/gel/command/shell_setup.rb +25 -0
- data/lib/gel/command/stub.rb +12 -0
- data/lib/gel/command/update.rb +11 -0
- data/lib/gel/compatibility.rb +4 -0
- data/lib/gel/compatibility/bundler.rb +54 -0
- data/lib/gel/compatibility/bundler/cli.rb +6 -0
- data/lib/gel/compatibility/bundler/friendly_errors.rb +3 -0
- data/lib/gel/compatibility/bundler/setup.rb +4 -0
- data/lib/gel/compatibility/rubygems.rb +192 -0
- data/lib/gel/compatibility/rubygems/command.rb +4 -0
- data/lib/gel/compatibility/rubygems/dependency_installer.rb +0 -0
- data/lib/gel/compatibility/rubygems/gem_runner.rb +6 -0
- data/lib/gel/config.rb +80 -0
- data/lib/gel/db.rb +294 -0
- data/lib/gel/direct_gem.rb +29 -0
- data/lib/gel/environment.rb +592 -0
- data/lib/gel/error.rb +104 -0
- data/lib/gel/gemfile_parser.rb +144 -0
- data/lib/gel/gemspec_parser.rb +95 -0
- data/lib/gel/git_catalog.rb +38 -0
- data/lib/gel/git_depot.rb +119 -0
- data/lib/gel/httpool.rb +148 -0
- data/lib/gel/installer.rb +251 -0
- data/lib/gel/lock_loader.rb +164 -0
- data/lib/gel/lock_parser.rb +64 -0
- data/lib/gel/locked_store.rb +126 -0
- data/lib/gel/multi_store.rb +96 -0
- data/lib/gel/package.rb +156 -0
- data/lib/gel/package/inspector.rb +23 -0
- data/lib/gel/package/installer.rb +267 -0
- data/lib/gel/path_catalog.rb +44 -0
- data/lib/gel/pinboard.rb +140 -0
- data/lib/gel/pub_grub/preference_strategy.rb +82 -0
- data/lib/gel/pub_grub/source.rb +153 -0
- data/lib/gel/runtime.rb +27 -0
- data/lib/gel/store.rb +205 -0
- data/lib/gel/store_catalog.rb +31 -0
- data/lib/gel/store_gem.rb +80 -0
- data/lib/gel/stub_set.rb +51 -0
- data/lib/gel/support/gem_platform.rb +225 -0
- data/lib/gel/support/gem_requirement.rb +264 -0
- data/lib/gel/support/gem_version.rb +398 -0
- data/lib/gel/support/tar.rb +13 -0
- data/lib/gel/support/tar/tar_header.rb +229 -0
- data/lib/gel/support/tar/tar_reader.rb +123 -0
- data/lib/gel/support/tar/tar_reader/entry.rb +154 -0
- data/lib/gel/support/tar/tar_writer.rb +339 -0
- data/lib/gel/tail_file.rb +205 -0
- data/lib/gel/version.rb +5 -0
- data/lib/gel/work_pool.rb +143 -0
- data/man/man1/gel-exec.1 +16 -0
- data/man/man1/gel-install.1 +16 -0
- data/man/man1/gel.1 +30 -0
- 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
|
data/lib/gel/stub_set.rb
ADDED
@@ -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
|