rubygems-update 2.1.11 → 2.2.0.rc.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of rubygems-update might be problematic. Click here for more details.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/.autotest +37 -12
- data/History.txt +99 -2
- data/MIT.txt +1 -0
- data/Manifest.txt +59 -19
- data/Rakefile +4 -6
- data/lib/gauntlet_rubygems.rb +1 -1
- data/lib/rubygems.rb +102 -80
- data/lib/rubygems/available_set.rb +2 -2
- data/lib/rubygems/basic_specification.rb +97 -8
- data/lib/rubygems/commands/install_command.rb +58 -15
- data/lib/rubygems/commands/list_command.rb +1 -7
- data/lib/rubygems/commands/outdated_command.rb +1 -1
- data/lib/rubygems/commands/pristine_command.rb +14 -1
- data/lib/rubygems/commands/push_command.rb +9 -4
- data/lib/rubygems/commands/query_command.rb +33 -17
- data/lib/rubygems/commands/search_command.rb +0 -6
- data/lib/rubygems/commands/specification_command.rb +1 -1
- data/lib/rubygems/commands/unpack_command.rb +1 -1
- data/lib/rubygems/commands/update_command.rb +4 -1
- data/lib/rubygems/commands/which_command.rb +5 -8
- data/lib/rubygems/compatibility.rb +3 -0
- data/lib/rubygems/core_ext/kernel_gem.rb +6 -0
- data/lib/rubygems/defaults.rb +19 -0
- data/lib/rubygems/dependency_installer.rb +28 -9
- data/lib/rubygems/doctor.rb +17 -11
- data/lib/rubygems/errors.rb +16 -3
- data/lib/rubygems/exceptions.rb +52 -5
- data/lib/rubygems/ext.rb +1 -2
- data/lib/rubygems/ext/build_error.rb +6 -0
- data/lib/rubygems/ext/builder.rb +50 -17
- data/lib/rubygems/ext/cmake_builder.rb +1 -1
- data/lib/rubygems/ext/configure_builder.rb +1 -3
- data/lib/rubygems/ext/ext_conf_builder.rb +9 -3
- data/lib/rubygems/ext/rake_builder.rb +2 -5
- data/lib/rubygems/gemcutter_utilities.rb +8 -1
- data/lib/rubygems/installer.rb +14 -4
- data/lib/rubygems/installer_test_case.rb +0 -5
- data/lib/rubygems/package.rb +11 -2
- data/lib/rubygems/psych_additions.rb +1 -1
- data/lib/rubygems/rdoc.rb +1 -1
- data/lib/rubygems/remote_fetcher.rb +3 -3
- data/lib/rubygems/request.rb +16 -8
- data/lib/rubygems/request_set.rb +133 -42
- data/lib/rubygems/request_set/gem_dependency_api.rb +493 -11
- data/lib/rubygems/request_set/lockfile.rb +579 -0
- data/lib/rubygems/requirement.rb +58 -30
- data/lib/rubygems/resolver.rb +471 -0
- data/lib/rubygems/resolver/activation_request.rb +165 -0
- data/lib/rubygems/resolver/api_set.rb +110 -0
- data/lib/rubygems/resolver/api_specification.rb +79 -0
- data/lib/rubygems/resolver/best_set.rb +31 -0
- data/lib/rubygems/resolver/composed_set.rb +39 -0
- data/lib/rubygems/resolver/conflict.rb +122 -0
- data/lib/rubygems/{dependency_resolver → resolver}/current_set.rb +1 -4
- data/lib/rubygems/{dependency_resolver → resolver}/dependency_request.rb +37 -7
- data/lib/rubygems/resolver/git_set.rb +119 -0
- data/lib/rubygems/resolver/git_specification.rb +35 -0
- data/lib/rubygems/resolver/index_set.rb +74 -0
- data/lib/rubygems/resolver/index_specification.rb +69 -0
- data/lib/rubygems/resolver/installed_specification.rb +40 -0
- data/lib/rubygems/{dependency_resolver → resolver}/installer_set.rb +18 -17
- data/lib/rubygems/resolver/local_specification.rb +16 -0
- data/lib/rubygems/resolver/lock_set.rb +78 -0
- data/lib/rubygems/resolver/lock_specification.rb +58 -0
- data/lib/rubygems/resolver/requirement_list.rb +81 -0
- data/lib/rubygems/resolver/set.rb +27 -0
- data/lib/rubygems/resolver/spec_specification.rb +58 -0
- data/lib/rubygems/resolver/specification.rb +89 -0
- data/lib/rubygems/resolver/stats.rb +44 -0
- data/lib/rubygems/resolver/vendor_set.rb +83 -0
- data/lib/rubygems/resolver/vendor_specification.rb +24 -0
- data/lib/rubygems/security/trust_dir.rb +16 -2
- data/lib/rubygems/source.rb +71 -18
- data/lib/rubygems/source/git.rb +218 -0
- data/lib/rubygems/source/installed.rb +8 -1
- data/lib/rubygems/source/local.rb +14 -8
- data/lib/rubygems/source/lock.rb +48 -0
- data/lib/rubygems/source/specific_file.rb +14 -3
- data/lib/rubygems/source/vendor.rb +27 -0
- data/lib/rubygems/source_list.rb +74 -12
- data/lib/rubygems/spec_fetcher.rb +36 -4
- data/lib/rubygems/specification.rb +214 -65
- data/lib/rubygems/stub_specification.rb +57 -1
- data/lib/rubygems/syck_hack.rb +3 -3
- data/lib/rubygems/test_case.rb +226 -59
- data/lib/rubygems/test_utilities.rb +198 -0
- data/lib/rubygems/uninstaller.rb +22 -10
- data/lib/rubygems/uri_formatter.rb +20 -0
- data/lib/rubygems/user_interaction.rb +193 -71
- data/lib/rubygems/util.rb +121 -0
- data/lib/rubygems/util/list.rb +4 -0
- data/lib/rubygems/util/stringio.rb +34 -0
- data/lib/rubygems/validator.rb +6 -2
- data/lib/rubygems/version.rb +4 -8
- data/test/rubygems/test_bundled_ca.rb +1 -1
- data/test/rubygems/test_gem.rb +137 -29
- data/test/rubygems/test_gem_available_set.rb +19 -0
- data/test/rubygems/test_gem_commands_build_command.rb +1 -1
- data/test/rubygems/test_gem_commands_cert_command.rb +2 -2
- data/test/rubygems/test_gem_commands_cleanup_command.rb +13 -13
- data/test/rubygems/test_gem_commands_dependency_command.rb +24 -34
- data/test/rubygems/test_gem_commands_fetch_command.rb +43 -48
- data/test/rubygems/test_gem_commands_install_command.rb +244 -279
- data/test/rubygems/test_gem_commands_list_command.rb +3 -3
- data/test/rubygems/test_gem_commands_outdated_command.rb +7 -12
- data/test/rubygems/test_gem_commands_pristine_command.rb +73 -27
- data/test/rubygems/test_gem_commands_push_command.rb +76 -8
- data/test/rubygems/test_gem_commands_query_command.rb +239 -49
- data/test/rubygems/test_gem_commands_sources_command.rb +10 -43
- data/test/rubygems/test_gem_commands_specification_command.rb +24 -47
- data/test/rubygems/test_gem_commands_stale_command.rb +2 -2
- data/test/rubygems/test_gem_commands_uninstall_command.rb +3 -3
- data/test/rubygems/test_gem_commands_unpack_command.rb +16 -30
- data/test/rubygems/test_gem_commands_update_command.rb +149 -134
- data/test/rubygems/test_gem_commands_which_command.rb +4 -2
- data/test/rubygems/test_gem_dependency_installer.rb +68 -0
- data/test/rubygems/test_gem_dependency_list.rb +17 -17
- data/test/rubygems/test_gem_dependency_resolution_error.rb +28 -0
- data/test/rubygems/test_gem_doctor.rb +1 -1
- data/test/rubygems/test_gem_ext_builder.rb +178 -8
- data/test/rubygems/test_gem_ext_cmake_builder.rb +1 -7
- data/test/rubygems/test_gem_ext_configure_builder.rb +8 -10
- data/test/rubygems/test_gem_ext_ext_conf_builder.rb +18 -21
- data/test/rubygems/test_gem_ext_rake_builder.rb +1 -3
- data/test/rubygems/test_gem_impossible_dependencies_error.rb +10 -6
- data/test/rubygems/test_gem_indexer.rb +6 -6
- data/test/rubygems/test_gem_installer.rb +29 -10
- data/test/rubygems/test_gem_local_remote_options.rb +1 -1
- data/test/rubygems/test_gem_package.rb +18 -0
- data/test/rubygems/test_gem_rdoc.rb +1 -1
- data/test/rubygems/test_gem_remote_fetcher.rb +1 -1
- data/test/rubygems/test_gem_request.rb +37 -10
- data/test/rubygems/test_gem_request_set.rb +271 -9
- data/test/rubygems/test_gem_request_set_gem_dependency_api.rb +684 -0
- data/test/rubygems/test_gem_request_set_lockfile.rb +849 -0
- data/test/rubygems/test_gem_requirement.rb +21 -0
- data/test/rubygems/{test_gem_dependency_resolver.rb → test_gem_resolver.rb} +231 -70
- data/test/rubygems/test_gem_resolver_activation_request.rb +63 -0
- data/test/rubygems/test_gem_resolver_api_set.rb +167 -0
- data/test/rubygems/test_gem_resolver_api_specification.rb +104 -0
- data/test/rubygems/test_gem_resolver_best_set.rb +30 -0
- data/test/rubygems/test_gem_resolver_conflict.rb +75 -0
- data/test/rubygems/test_gem_resolver_dependency_request.rb +20 -0
- data/test/rubygems/test_gem_resolver_git_set.rb +148 -0
- data/test/rubygems/test_gem_resolver_git_specification.rb +100 -0
- data/test/rubygems/test_gem_resolver_index_set.rb +28 -0
- data/test/rubygems/test_gem_resolver_index_specification.rb +89 -0
- data/test/rubygems/test_gem_resolver_installed_specification.rb +49 -0
- data/test/rubygems/test_gem_resolver_installer_set.rb +22 -0
- data/test/rubygems/test_gem_resolver_local_specification.rb +45 -0
- data/test/rubygems/test_gem_resolver_lock_set.rb +57 -0
- data/test/rubygems/test_gem_resolver_lock_specification.rb +87 -0
- data/test/rubygems/test_gem_resolver_requirement_list.rb +20 -0
- data/test/rubygems/test_gem_resolver_specification.rb +32 -0
- data/test/rubygems/test_gem_resolver_vendor_set.rb +67 -0
- data/test/rubygems/test_gem_resolver_vendor_specification.rb +83 -0
- data/test/rubygems/test_gem_server.rb +4 -4
- data/test/rubygems/test_gem_source.rb +54 -64
- data/test/rubygems/test_gem_source_git.rb +231 -0
- data/test/rubygems/test_gem_source_list.rb +24 -0
- data/test/rubygems/test_gem_source_local.rb +1 -1
- data/test/rubygems/test_gem_source_lock.rb +114 -0
- data/test/rubygems/test_gem_source_vendor.rb +27 -0
- data/test/rubygems/test_gem_spec_fetcher.rb +116 -61
- data/test/rubygems/test_gem_specification.rb +526 -94
- data/test/rubygems/test_gem_stub_specification.rb +123 -10
- data/test/rubygems/test_gem_uninstaller.rb +28 -2
- data/test/rubygems/test_gem_util.rb +31 -0
- data/test/rubygems/test_gem_validator.rb +9 -0
- data/util/update_bundled_ca_certificates.rb +8 -1
- metadata +89 -29
- metadata.gz.sig +2 -4
- data/lib/rubygems/dependency_resolver.rb +0 -254
- data/lib/rubygems/dependency_resolver/activation_request.rb +0 -109
- data/lib/rubygems/dependency_resolver/api_set.rb +0 -65
- data/lib/rubygems/dependency_resolver/api_specification.rb +0 -39
- data/lib/rubygems/dependency_resolver/composed_set.rb +0 -18
- data/lib/rubygems/dependency_resolver/dependency_conflict.rb +0 -85
- data/lib/rubygems/dependency_resolver/index_set.rb +0 -64
- data/lib/rubygems/dependency_resolver/index_specification.rb +0 -60
- data/lib/rubygems/dependency_resolver/installed_specification.rb +0 -52
- data/test/rubygems/test_gem_dependency_resolver_api_specification.rb +0 -33
- data/test/rubygems/test_gem_dependency_resolver_dependency_conflict.rb +0 -36
- data/test/rubygems/test_gem_dependency_resolver_index_set.rb +0 -53
- data/test/rubygems/test_gem_dependency_resolver_index_specification.rb +0 -73
- data/test/rubygems/test_gem_dependency_resolver_installed_specification.rb +0 -19
- data/test/rubygems/test_gem_dependency_resolver_installer_set.rb +0 -28
@@ -1,6 +1,10 @@
|
|
1
|
+
##
|
2
|
+
# Represents an installed gem. This is used for dependency resolution.
|
3
|
+
|
1
4
|
class Gem::Source::Installed < Gem::Source
|
2
5
|
|
3
|
-
def initialize
|
6
|
+
def initialize # :nodoc:
|
7
|
+
@uri = nil
|
4
8
|
end
|
5
9
|
|
6
10
|
##
|
@@ -8,6 +12,9 @@ class Gem::Source::Installed < Gem::Source
|
|
8
12
|
|
9
13
|
def <=> other
|
10
14
|
case other
|
15
|
+
when Gem::Source::Lock,
|
16
|
+
Gem::Source::Vendor then
|
17
|
+
-1
|
11
18
|
when Gem::Source::Installed then
|
12
19
|
0
|
13
20
|
when Gem::Source then
|
@@ -1,5 +1,10 @@
|
|
1
|
+
##
|
2
|
+
# The local source finds gems in the current directory for fulfilling
|
3
|
+
# dependencies.
|
4
|
+
|
1
5
|
class Gem::Source::Local < Gem::Source
|
2
|
-
|
6
|
+
|
7
|
+
def initialize # :nodoc:
|
3
8
|
@specs = nil
|
4
9
|
@api_uri = nil
|
5
10
|
@uri = nil
|
@@ -10,7 +15,8 @@ class Gem::Source::Local < Gem::Source
|
|
10
15
|
|
11
16
|
def <=> other
|
12
17
|
case other
|
13
|
-
when Gem::Source::Installed
|
18
|
+
when Gem::Source::Installed,
|
19
|
+
Gem::Source::Lock then
|
14
20
|
-1
|
15
21
|
when Gem::Source::Local then
|
16
22
|
0
|
@@ -26,7 +32,7 @@ class Gem::Source::Local < Gem::Source
|
|
26
32
|
"#<%s specs: %p>" % [self.class, keys]
|
27
33
|
end
|
28
34
|
|
29
|
-
def load_specs
|
35
|
+
def load_specs type # :nodoc:
|
30
36
|
names = []
|
31
37
|
|
32
38
|
@specs = {}
|
@@ -68,8 +74,8 @@ class Gem::Source::Local < Gem::Source
|
|
68
74
|
names
|
69
75
|
end
|
70
76
|
|
71
|
-
def find_gem
|
72
|
-
prerelease=false
|
77
|
+
def find_gem gem_name, version = Gem::Requirement.default, # :nodoc:
|
78
|
+
prerelease = false
|
73
79
|
load_specs :complete
|
74
80
|
|
75
81
|
found = []
|
@@ -88,10 +94,10 @@ class Gem::Source::Local < Gem::Source
|
|
88
94
|
end
|
89
95
|
end
|
90
96
|
|
91
|
-
found.
|
97
|
+
found.max_by { |s| s.version }
|
92
98
|
end
|
93
99
|
|
94
|
-
def fetch_spec
|
100
|
+
def fetch_spec name # :nodoc:
|
95
101
|
load_specs :complete
|
96
102
|
|
97
103
|
if data = @specs[name]
|
@@ -101,7 +107,7 @@ class Gem::Source::Local < Gem::Source
|
|
101
107
|
end
|
102
108
|
end
|
103
109
|
|
104
|
-
def download
|
110
|
+
def download spec, cache_dir = nil # :nodoc:
|
105
111
|
load_specs :complete
|
106
112
|
|
107
113
|
@specs.each do |name, data|
|
@@ -0,0 +1,48 @@
|
|
1
|
+
##
|
2
|
+
# A Lock source wraps an installed gem's source and sorts before other sources
|
3
|
+
# during dependency resolution. This allows RubyGems to prefer gems from
|
4
|
+
# dependency lock files.
|
5
|
+
|
6
|
+
class Gem::Source::Lock < Gem::Source
|
7
|
+
|
8
|
+
##
|
9
|
+
# The wrapped Gem::Source
|
10
|
+
|
11
|
+
attr_reader :wrapped
|
12
|
+
|
13
|
+
##
|
14
|
+
# Creates a new Lock source that wraps +source+ and moves it earlier in the
|
15
|
+
# sort list.
|
16
|
+
|
17
|
+
def initialize source
|
18
|
+
@wrapped = source
|
19
|
+
end
|
20
|
+
|
21
|
+
def <=> other # :nodoc:
|
22
|
+
case other
|
23
|
+
when Gem::Source::Lock then
|
24
|
+
@wrapped <=> other.wrapped
|
25
|
+
when Gem::Source then
|
26
|
+
1
|
27
|
+
else
|
28
|
+
nil
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def == other # :nodoc:
|
33
|
+
0 == (self <=> other)
|
34
|
+
end
|
35
|
+
|
36
|
+
##
|
37
|
+
# Delegates to the wrapped source's fetch_spec method.
|
38
|
+
|
39
|
+
def fetch_spec name_tuple
|
40
|
+
@wrapped.fetch_spec name_tuple
|
41
|
+
end
|
42
|
+
|
43
|
+
def uri # :nodoc:
|
44
|
+
@wrapped.uri
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|
@@ -1,4 +1,12 @@
|
|
1
|
+
##
|
2
|
+
# A source representing a single .gem file. This is used for installation of
|
3
|
+
# local gems.
|
4
|
+
|
1
5
|
class Gem::Source::SpecificFile < Gem::Source
|
6
|
+
|
7
|
+
##
|
8
|
+
# Creates a new SpecificFile for the gem in +file+
|
9
|
+
|
2
10
|
def initialize(file)
|
3
11
|
@uri = nil
|
4
12
|
@path = ::File.expand_path(file)
|
@@ -8,19 +16,22 @@ class Gem::Source::SpecificFile < Gem::Source
|
|
8
16
|
@name = @spec.name_tuple
|
9
17
|
end
|
10
18
|
|
19
|
+
##
|
20
|
+
# The Gem::Specification extracted from this .gem.
|
21
|
+
|
11
22
|
attr_reader :spec
|
12
23
|
|
13
|
-
def load_specs
|
24
|
+
def load_specs *a # :nodoc:
|
14
25
|
[@name]
|
15
26
|
end
|
16
27
|
|
17
|
-
def fetch_spec
|
28
|
+
def fetch_spec name # :nodoc:
|
18
29
|
return @spec if name == @name
|
19
30
|
raise Gem::Exception, "Unable to find '#{name}'"
|
20
31
|
@spec
|
21
32
|
end
|
22
33
|
|
23
|
-
def download
|
34
|
+
def download spec, dir = nil # :nodoc:
|
24
35
|
return @path if spec == @spec
|
25
36
|
raise Gem::Exception, "Unable to download '#{spec.full_name}'"
|
26
37
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
##
|
2
|
+
# This represents a vendored source that is similar to an installed gem.
|
3
|
+
|
4
|
+
class Gem::Source::Vendor < Gem::Source::Installed
|
5
|
+
|
6
|
+
##
|
7
|
+
# Creates a new Vendor source for a gem that was unpacked at +path+.
|
8
|
+
|
9
|
+
def initialize path
|
10
|
+
@uri = path
|
11
|
+
end
|
12
|
+
|
13
|
+
def <=> other
|
14
|
+
case other
|
15
|
+
when Gem::Source::Lock then
|
16
|
+
-1
|
17
|
+
when Gem::Source::Vendor then
|
18
|
+
0
|
19
|
+
when Gem::Source then
|
20
|
+
1
|
21
|
+
else
|
22
|
+
nil
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
data/lib/rubygems/source_list.rb
CHANGED
@@ -1,28 +1,53 @@
|
|
1
1
|
require 'rubygems/source'
|
2
2
|
|
3
|
+
##
|
4
|
+
# The SourceList represents the sources rubygems has been configured to use.
|
5
|
+
# A source may be created from an array of sources:
|
6
|
+
#
|
7
|
+
# Gem::SourceList.from %w[https://rubygems.example https://internal.example]
|
8
|
+
#
|
9
|
+
# Or by adding them:
|
10
|
+
#
|
11
|
+
# sources = Gem::SourceList.new
|
12
|
+
# sources.add 'https://rubygems.example'
|
13
|
+
#
|
14
|
+
# The most common way to get a SourceList is Gem.sources.
|
15
|
+
|
3
16
|
class Gem::SourceList
|
17
|
+
|
18
|
+
include Enumerable
|
19
|
+
|
20
|
+
##
|
21
|
+
# Creates a new SourceList
|
22
|
+
|
4
23
|
def initialize
|
5
24
|
@sources = []
|
6
25
|
end
|
7
26
|
|
27
|
+
##
|
28
|
+
# The sources in this list
|
29
|
+
|
8
30
|
attr_reader :sources
|
9
31
|
|
32
|
+
##
|
33
|
+
# Creates a new SourceList from an array of sources.
|
34
|
+
|
10
35
|
def self.from(ary)
|
11
36
|
list = new
|
12
37
|
|
13
|
-
|
14
|
-
ary.each do |x|
|
15
|
-
list << x
|
16
|
-
end
|
17
|
-
end
|
38
|
+
list.replace ary
|
18
39
|
|
19
40
|
return list
|
20
41
|
end
|
21
42
|
|
22
|
-
def initialize_copy(other)
|
43
|
+
def initialize_copy(other) # :nodoc:
|
23
44
|
@sources = @sources.dup
|
24
45
|
end
|
25
46
|
|
47
|
+
##
|
48
|
+
# Appends +obj+ to the source list which may be a Gem::Source, URI or URI
|
49
|
+
# String.
|
50
|
+
|
26
51
|
def <<(obj)
|
27
52
|
src = case obj
|
28
53
|
when URI
|
@@ -37,8 +62,12 @@ class Gem::SourceList
|
|
37
62
|
src
|
38
63
|
end
|
39
64
|
|
65
|
+
##
|
66
|
+
# Replaces this SourceList with the sources in +other+ See #<< for
|
67
|
+
# acceptable items in +other+.
|
68
|
+
|
40
69
|
def replace(other)
|
41
|
-
|
70
|
+
clear
|
42
71
|
|
43
72
|
other.each do |x|
|
44
73
|
self << x
|
@@ -47,28 +76,58 @@ class Gem::SourceList
|
|
47
76
|
self
|
48
77
|
end
|
49
78
|
|
79
|
+
##
|
80
|
+
# Removes all sources from the SourceList.
|
81
|
+
|
82
|
+
def clear
|
83
|
+
@sources.clear
|
84
|
+
end
|
85
|
+
|
86
|
+
##
|
87
|
+
# Yields each source URI in the list.
|
88
|
+
|
50
89
|
def each
|
51
90
|
@sources.each { |s| yield s.uri.to_s }
|
52
91
|
end
|
53
92
|
|
93
|
+
##
|
94
|
+
# Yields each source in the list.
|
95
|
+
|
54
96
|
def each_source(&b)
|
55
97
|
@sources.each(&b)
|
56
98
|
end
|
57
99
|
|
58
|
-
|
100
|
+
##
|
101
|
+
# Returns true if there are no sources in this SourceList.
|
102
|
+
|
103
|
+
def empty?
|
104
|
+
@sources.empty?
|
105
|
+
end
|
106
|
+
|
107
|
+
def == other # :nodoc:
|
59
108
|
to_a == other
|
60
109
|
end
|
61
110
|
|
111
|
+
##
|
112
|
+
# Returns an Array of source URI Strings.
|
113
|
+
|
62
114
|
def to_a
|
63
115
|
@sources.map { |x| x.uri.to_s }
|
64
116
|
end
|
65
117
|
|
66
118
|
alias_method :to_ary, :to_a
|
67
119
|
|
120
|
+
##
|
121
|
+
# Returns the first source in the list.
|
122
|
+
|
68
123
|
def first
|
69
124
|
@sources.first
|
70
125
|
end
|
71
126
|
|
127
|
+
##
|
128
|
+
# Returns true if this source list includes +other+ which may be a
|
129
|
+
# Gem::Source or a source URI.
|
130
|
+
|
72
131
|
def include?(other)
|
73
132
|
if other.kind_of? Gem::Source
|
74
133
|
@sources.include? other
|
@@ -77,11 +136,14 @@ class Gem::SourceList
|
|
77
136
|
end
|
78
137
|
end
|
79
138
|
|
80
|
-
|
81
|
-
|
82
|
-
|
139
|
+
##
|
140
|
+
# Deletes +source+ from the source list which may be a Gem::Source or a URI.
|
141
|
+
|
142
|
+
def delete source
|
143
|
+
if source.kind_of? Gem::Source
|
144
|
+
@sources.delete source
|
83
145
|
else
|
84
|
-
@sources.delete_if { |x| x.uri.to_s ==
|
146
|
+
@sources.delete_if { |x| x.uri.to_s == source.to_s }
|
85
147
|
end
|
86
148
|
end
|
87
149
|
end
|
@@ -17,6 +17,11 @@ class Gem::SpecFetcher
|
|
17
17
|
|
18
18
|
attr_reader :latest_specs # :nodoc:
|
19
19
|
|
20
|
+
##
|
21
|
+
# Sources for this SpecFetcher
|
22
|
+
|
23
|
+
attr_reader :sources # :nodoc:
|
24
|
+
|
20
25
|
##
|
21
26
|
# Cache of all released specs
|
22
27
|
|
@@ -29,6 +34,10 @@ class Gem::SpecFetcher
|
|
29
34
|
|
30
35
|
@fetcher = nil
|
31
36
|
|
37
|
+
##
|
38
|
+
# Default fetcher instance. Use this instead of ::new to reduce object
|
39
|
+
# allocation.
|
40
|
+
|
32
41
|
def self.fetcher
|
33
42
|
@fetcher ||= new
|
34
43
|
end
|
@@ -37,7 +46,16 @@ class Gem::SpecFetcher
|
|
37
46
|
@fetcher = fetcher
|
38
47
|
end
|
39
48
|
|
40
|
-
|
49
|
+
##
|
50
|
+
# Creates a new SpecFetcher. Ordinarily you want to use the default fetcher
|
51
|
+
# from Gem::SpecFetcher::fetcher which uses the Gem.sources.
|
52
|
+
#
|
53
|
+
# If you need to retrieve specifications from a different +source+, you can
|
54
|
+
# send it as an argument.
|
55
|
+
|
56
|
+
def initialize sources = nil
|
57
|
+
@sources = sources || Gem.sources
|
58
|
+
|
41
59
|
@update_cache =
|
42
60
|
begin
|
43
61
|
File.stat(Gem.user_home).uid == Process.uid
|
@@ -70,7 +88,11 @@ class Gem::SpecFetcher
|
|
70
88
|
rejected_specs = {}
|
71
89
|
|
72
90
|
if dependency.prerelease?
|
73
|
-
|
91
|
+
if dependency.specific?
|
92
|
+
type = :complete
|
93
|
+
else
|
94
|
+
type = :abs_latest
|
95
|
+
end
|
74
96
|
elsif dependency.latest_version?
|
75
97
|
type = :latest
|
76
98
|
else
|
@@ -197,7 +219,7 @@ class Gem::SpecFetcher
|
|
197
219
|
errors = []
|
198
220
|
list = {}
|
199
221
|
|
200
|
-
|
222
|
+
@sources.each_source do |source|
|
201
223
|
begin
|
202
224
|
names = case type
|
203
225
|
when :latest
|
@@ -209,6 +231,12 @@ class Gem::SpecFetcher
|
|
209
231
|
tuples_for(source, :prerelease, true) +
|
210
232
|
tuples_for(source, :released)
|
211
233
|
|
234
|
+
names.sort
|
235
|
+
when :abs_latest
|
236
|
+
names =
|
237
|
+
tuples_for(source, :prerelease, true) +
|
238
|
+
tuples_for(source, :latest)
|
239
|
+
|
212
240
|
names.sort
|
213
241
|
when :prerelease
|
214
242
|
tuples_for(source, :prerelease)
|
@@ -225,7 +253,11 @@ class Gem::SpecFetcher
|
|
225
253
|
[list, errors]
|
226
254
|
end
|
227
255
|
|
228
|
-
|
256
|
+
##
|
257
|
+
# Retrieves NameTuples from +source+ of the given +type+ (:prerelease,
|
258
|
+
# etc.). If +gracefully_ignore+ is true, errors are ignored.
|
259
|
+
|
260
|
+
def tuples_for(source, type, gracefully_ignore=false) # :nodoc:
|
229
261
|
cache = @caches[type]
|
230
262
|
|
231
263
|
tuples =
|
@@ -12,6 +12,7 @@ require 'rubygems/platform'
|
|
12
12
|
require 'rubygems/deprecate'
|
13
13
|
require 'rubygems/basic_specification'
|
14
14
|
require 'rubygems/stub_specification'
|
15
|
+
require 'rubygems/util/stringio'
|
15
16
|
|
16
17
|
# :stopdoc:
|
17
18
|
# date.rb can't be loaded for `make install` due to miniruby
|
@@ -26,6 +27,7 @@ class Date; end
|
|
26
27
|
# Gem::Specification.new do |s|
|
27
28
|
# s.name = 'example'
|
28
29
|
# s.version = '0.1.0'
|
30
|
+
# s.licenses = ['MIT']
|
29
31
|
# s.summary = "This is an example!"
|
30
32
|
# s.description = "Much longer explanation of the example!"
|
31
33
|
# s.authors = ["Ruby Coder"]
|
@@ -71,13 +73,13 @@ class Gem::Specification < Gem::BasicSpecification
|
|
71
73
|
#
|
72
74
|
# NOTE RubyGems < 1.2 cannot load specification versions > 2.
|
73
75
|
|
74
|
-
CURRENT_SPECIFICATION_VERSION = 4
|
76
|
+
CURRENT_SPECIFICATION_VERSION = 4 # :nodoc:
|
75
77
|
|
76
78
|
##
|
77
79
|
# An informal list of changes to the specification. The highest-valued
|
78
80
|
# key should be equal to the CURRENT_SPECIFICATION_VERSION.
|
79
81
|
|
80
|
-
SPECIFICATION_VERSION_HISTORY = {
|
82
|
+
SPECIFICATION_VERSION_HISTORY = { # :nodoc:
|
81
83
|
-1 => ['(RubyGems versions up to and including 0.7 did not have versioned specifications)'],
|
82
84
|
1 => [
|
83
85
|
'Deprecated "test_suite_file" in favor of the new, but equivalent, "test_files"',
|
@@ -95,12 +97,18 @@ class Gem::Specification < Gem::BasicSpecification
|
|
95
97
|
]
|
96
98
|
}
|
97
99
|
|
98
|
-
MARSHAL_FIELDS = {
|
100
|
+
MARSHAL_FIELDS = { # :nodoc:
|
101
|
+
-1 => 16,
|
102
|
+
1 => 16,
|
103
|
+
2 => 16,
|
104
|
+
3 => 17,
|
105
|
+
4 => 18,
|
106
|
+
}
|
99
107
|
|
100
108
|
today = Time.now.utc
|
101
|
-
TODAY = Time.utc(today.year, today.month, today.day)
|
109
|
+
TODAY = Time.utc(today.year, today.month, today.day) # :nodoc:
|
102
110
|
|
103
|
-
LOAD_CACHE = {}
|
111
|
+
LOAD_CACHE = {} # :nodoc:
|
104
112
|
|
105
113
|
private_constant :LOAD_CACHE if defined? private_constant
|
106
114
|
|
@@ -153,7 +161,7 @@ class Gem::Specification < Gem::BasicSpecification
|
|
153
161
|
:version => nil,
|
154
162
|
}
|
155
163
|
|
156
|
-
Dupable = { }
|
164
|
+
Dupable = { } # :nodoc:
|
157
165
|
|
158
166
|
@@default_value.each do |k,v|
|
159
167
|
case v
|
@@ -199,6 +207,8 @@ class Gem::Specification < Gem::BasicSpecification
|
|
199
207
|
# Paths in the gem to add to <code>$LOAD_PATH</code> when this gem is
|
200
208
|
# activated.
|
201
209
|
#
|
210
|
+
# See also #require_paths
|
211
|
+
#
|
202
212
|
# If you have an extension you do not need to add <code>"ext"</code> to the
|
203
213
|
# require path, the extension build process will copy the extension files
|
204
214
|
# into "lib" for you.
|
@@ -210,7 +220,7 @@ class Gem::Specification < Gem::BasicSpecification
|
|
210
220
|
# # If all library files are in the root directory...
|
211
221
|
# spec.require_path = '.'
|
212
222
|
|
213
|
-
|
223
|
+
attr_writer :require_paths
|
214
224
|
|
215
225
|
##
|
216
226
|
# The version of RubyGems used to create this gem.
|
@@ -317,7 +327,7 @@ class Gem::Specification < Gem::BasicSpecification
|
|
317
327
|
add_bindir(@executables),
|
318
328
|
@extra_rdoc_files,
|
319
329
|
@extensions,
|
320
|
-
].flatten.uniq.compact
|
330
|
+
].flatten.sort.uniq.compact
|
321
331
|
end
|
322
332
|
|
323
333
|
######################################################################
|
@@ -504,6 +514,24 @@ class Gem::Specification < Gem::BasicSpecification
|
|
504
514
|
end
|
505
515
|
|
506
516
|
##
|
517
|
+
# The version of RubyGems that installed this gem. Returns
|
518
|
+
# <code>Gem::Version.new(0)</code> for gems installed by versions earlier
|
519
|
+
# than RubyGems 2.2.0.
|
520
|
+
|
521
|
+
def installed_by_version # :nodoc:
|
522
|
+
@installed_by_version ||= Gem::Version.new(0)
|
523
|
+
end
|
524
|
+
|
525
|
+
##
|
526
|
+
# Sets the version of RubyGems that installed this gem. See also
|
527
|
+
# #installed_by_version.
|
528
|
+
|
529
|
+
def installed_by_version= version # :nodoc:
|
530
|
+
@installed_by_version = Gem::Version.new version
|
531
|
+
end
|
532
|
+
|
533
|
+
##
|
534
|
+
# :category: Recommended gemspec attributes
|
507
535
|
# The license for this gem.
|
508
536
|
#
|
509
537
|
# The license must be a short name, no more than 64 characters.
|
@@ -512,7 +540,12 @@ class Gem::Specification < Gem::BasicSpecification
|
|
512
540
|
# text of the license should be inside of the gem when you build it.
|
513
541
|
#
|
514
542
|
# See http://opensource.org/licenses/alphabetical for a list of licenses and
|
515
|
-
# their abbreviations (or short names).
|
543
|
+
# their abbreviations (or short names). GitHub also provides a
|
544
|
+
# license picker at http://choosealicense.com/
|
545
|
+
#
|
546
|
+
# According to copyright law, not having an OSI-approved open source license
|
547
|
+
# means you have no rights to use the code for any purpose-- in other words,
|
548
|
+
# "all rights reserved".
|
516
549
|
#
|
517
550
|
# You can set multiple licenses with #licenses=
|
518
551
|
#
|
@@ -524,6 +557,7 @@ class Gem::Specification < Gem::BasicSpecification
|
|
524
557
|
end
|
525
558
|
|
526
559
|
##
|
560
|
+
# :category: Recommended gemspec attributes
|
527
561
|
# The license(s) for the library.
|
528
562
|
#
|
529
563
|
# Each license must be a short name, no more than 64 characters.
|
@@ -671,8 +705,7 @@ class Gem::Specification < Gem::BasicSpecification
|
|
671
705
|
LOAD_CACHE.clear
|
672
706
|
end
|
673
707
|
|
674
|
-
# :nodoc:
|
675
|
-
def self.each_gemspec(dirs)
|
708
|
+
def self.each_gemspec(dirs) # :nodoc:
|
676
709
|
dirs.each do |dir|
|
677
710
|
Dir[File.join(dir, "*.gemspec")].each do |path|
|
678
711
|
yield path.untaint
|
@@ -680,16 +713,14 @@ class Gem::Specification < Gem::BasicSpecification
|
|
680
713
|
end
|
681
714
|
end
|
682
715
|
|
683
|
-
# :nodoc:
|
684
|
-
def self.each_stub(dirs)
|
716
|
+
def self.each_stub(dirs) # :nodoc:
|
685
717
|
each_gemspec(dirs) do |path|
|
686
718
|
stub = Gem::StubSpecification.new(path)
|
687
719
|
yield stub if stub.valid?
|
688
720
|
end
|
689
721
|
end
|
690
722
|
|
691
|
-
# :nodoc:
|
692
|
-
def self.each_spec(dirs)
|
723
|
+
def self.each_spec(dirs) # :nodoc:
|
693
724
|
each_gemspec(dirs) do |path|
|
694
725
|
spec = self.load path
|
695
726
|
yield spec if spec
|
@@ -834,12 +865,8 @@ class Gem::Specification < Gem::BasicSpecification
|
|
834
865
|
# this resets the list of known specs.
|
835
866
|
|
836
867
|
def self.dirs= dirs
|
837
|
-
# TODO: find extra calls to dir=
|
838
|
-
# warn "NOTE: dirs= called from #{caller.first} for #{dirs.inspect}"
|
839
|
-
|
840
868
|
self.reset
|
841
869
|
|
842
|
-
# ugh
|
843
870
|
@@dirs = Array(dirs).map { |dir| File.join dir, "specifications" }
|
844
871
|
end
|
845
872
|
|
@@ -1004,7 +1031,7 @@ class Gem::Specification < Gem::BasicSpecification
|
|
1004
1031
|
spec = eval code, binding, file
|
1005
1032
|
|
1006
1033
|
if Gem::Specification === spec
|
1007
|
-
spec.loaded_from = file.to_s
|
1034
|
+
spec.loaded_from = File.expand_path file.to_s
|
1008
1035
|
LOAD_CACHE[file] = spec
|
1009
1036
|
return spec
|
1010
1037
|
end
|
@@ -1248,7 +1275,7 @@ class Gem::Specification < Gem::BasicSpecification
|
|
1248
1275
|
|
1249
1276
|
##
|
1250
1277
|
# Activate all unambiguously resolved runtime dependencies of this
|
1251
|
-
# spec. Add any
|
1278
|
+
# spec. Add any ambiguous dependencies to the unresolved list to be
|
1252
1279
|
# resolved later, as needed.
|
1253
1280
|
|
1254
1281
|
def activate_dependencies
|
@@ -1324,9 +1351,7 @@ class Gem::Specification < Gem::BasicSpecification
|
|
1324
1351
|
def add_self_to_load_path
|
1325
1352
|
return if default_gem?
|
1326
1353
|
|
1327
|
-
paths =
|
1328
|
-
File.join full_gem_path, path
|
1329
|
-
end
|
1354
|
+
paths = full_require_paths
|
1330
1355
|
|
1331
1356
|
# gem directories must come after -I and ENV['RUBYLIB']
|
1332
1357
|
insert_index = Gem.load_path_insert_index
|
@@ -1377,13 +1402,44 @@ class Gem::Specification < Gem::BasicSpecification
|
|
1377
1402
|
# Returns the build_args used to install the gem
|
1378
1403
|
|
1379
1404
|
def build_args
|
1380
|
-
if File.
|
1405
|
+
if File.exist? build_info_file
|
1381
1406
|
File.readlines(build_info_file).map { |x| x.strip }
|
1382
1407
|
else
|
1383
1408
|
[]
|
1384
1409
|
end
|
1385
1410
|
end
|
1386
1411
|
|
1412
|
+
##
|
1413
|
+
# Builds extensions for this platform if the gem has extensions listed and
|
1414
|
+
# the gem.build_complete file is missing.
|
1415
|
+
|
1416
|
+
def build_extensions # :nodoc:
|
1417
|
+
return if default_gem?
|
1418
|
+
return if extensions.empty?
|
1419
|
+
return if installed_by_version < Gem::Version.new('2.2.0.preview.2')
|
1420
|
+
return if File.exist? gem_build_complete_path
|
1421
|
+
return if !File.writable?(base_dir) &&
|
1422
|
+
!File.exist?(File.join(base_dir, 'extensions'))
|
1423
|
+
|
1424
|
+
begin
|
1425
|
+
# We need to require things in $LOAD_PATH without looking for the
|
1426
|
+
# extension we are about to build.
|
1427
|
+
unresolved_deps = Gem::Specification.unresolved_deps.dup
|
1428
|
+
Gem::Specification.unresolved_deps.clear
|
1429
|
+
|
1430
|
+
require 'rubygems/config_file'
|
1431
|
+
require 'rubygems/ext'
|
1432
|
+
require 'rubygems/user_interaction'
|
1433
|
+
|
1434
|
+
Gem::DefaultUserInteraction.use_ui Gem::SilentUI.new do
|
1435
|
+
builder = Gem::Ext::Builder.new self
|
1436
|
+
builder.build_extensions
|
1437
|
+
end
|
1438
|
+
ensure
|
1439
|
+
Gem::Specification.unresolved_deps.replace unresolved_deps
|
1440
|
+
end
|
1441
|
+
end
|
1442
|
+
|
1387
1443
|
##
|
1388
1444
|
# Returns the full path to the build info directory
|
1389
1445
|
|
@@ -1438,10 +1494,11 @@ class Gem::Specification < Gem::BasicSpecification
|
|
1438
1494
|
@date ||= TODAY
|
1439
1495
|
end
|
1440
1496
|
|
1441
|
-
DateTimeFormat =
|
1442
|
-
|
1443
|
-
|
1444
|
-
|
1497
|
+
DateTimeFormat = # :nodoc:
|
1498
|
+
/\A
|
1499
|
+
(\d{4})-(\d{2})-(\d{2})
|
1500
|
+
(\s+ \d{2}:\d{2}:\d{2}\.\d+ \s* (Z | [-+]\d\d:\d\d) )?
|
1501
|
+
\Z/x
|
1445
1502
|
|
1446
1503
|
##
|
1447
1504
|
# The date this gem was created
|
@@ -1514,7 +1571,6 @@ class Gem::Specification < Gem::BasicSpecification
|
|
1514
1571
|
# [depending_gem, dependency, [list_of_gems_that_satisfy_dependency]]
|
1515
1572
|
|
1516
1573
|
def dependent_gems
|
1517
|
-
# REFACTOR: out = []; each; out; ? Really? No #collect love?
|
1518
1574
|
out = []
|
1519
1575
|
Gem::Specification.each do |spec|
|
1520
1576
|
spec.dependencies.each do |dep|
|
@@ -1553,7 +1609,7 @@ class Gem::Specification < Gem::BasicSpecification
|
|
1553
1609
|
|
1554
1610
|
##
|
1555
1611
|
# Returns the full path to this spec's documentation directory. If +type+
|
1556
|
-
# is given it will be appended to the end. For
|
1612
|
+
# is given it will be appended to the end. For example:
|
1557
1613
|
#
|
1558
1614
|
# spec.doc_dir # => "/path/to/gem_repo/doc/a-1"
|
1559
1615
|
#
|
@@ -1674,8 +1730,7 @@ class Gem::Specification < Gem::BasicSpecification
|
|
1674
1730
|
spec
|
1675
1731
|
end
|
1676
1732
|
|
1677
|
-
# :nodoc:
|
1678
|
-
def find_full_gem_path
|
1733
|
+
def find_full_gem_path # :nodoc:
|
1679
1734
|
super || File.expand_path(File.join(gems_dir, original_name))
|
1680
1735
|
end
|
1681
1736
|
private :find_full_gem_path
|
@@ -1685,11 +1740,18 @@ class Gem::Specification < Gem::BasicSpecification
|
|
1685
1740
|
end
|
1686
1741
|
|
1687
1742
|
##
|
1688
|
-
#
|
1689
|
-
#
|
1743
|
+
# The path to the gem.build_complete file within the extension install
|
1744
|
+
# directory.
|
1690
1745
|
|
1691
|
-
def
|
1692
|
-
|
1746
|
+
def gem_build_complete_path # :nodoc:
|
1747
|
+
File.join extension_dir, 'gem.build_complete'
|
1748
|
+
end
|
1749
|
+
|
1750
|
+
##
|
1751
|
+
# Work around bundler removing my methods
|
1752
|
+
|
1753
|
+
def gem_dir # :nodoc:
|
1754
|
+
super
|
1693
1755
|
end
|
1694
1756
|
|
1695
1757
|
##
|
@@ -1742,6 +1804,7 @@ class Gem::Specification < Gem::BasicSpecification
|
|
1742
1804
|
@activated = false
|
1743
1805
|
self.loaded_from = nil
|
1744
1806
|
@original_platform = nil
|
1807
|
+
@installed_by_version = nil
|
1745
1808
|
|
1746
1809
|
@@nil_attributes.each do |key|
|
1747
1810
|
instance_variable_set "@#{key}", nil
|
@@ -1797,7 +1860,7 @@ class Gem::Specification < Gem::BasicSpecification
|
|
1797
1860
|
|
1798
1861
|
private :invalidate_memoized_attributes
|
1799
1862
|
|
1800
|
-
def inspect
|
1863
|
+
def inspect # :nodoc:
|
1801
1864
|
if $DEBUG
|
1802
1865
|
super
|
1803
1866
|
else
|
@@ -1853,7 +1916,6 @@ class Gem::Specification < Gem::BasicSpecification
|
|
1853
1916
|
@cache_dir = nil
|
1854
1917
|
@cache_file = nil
|
1855
1918
|
@doc_dir = nil
|
1856
|
-
@gem_dir = nil
|
1857
1919
|
@ri_dir = nil
|
1858
1920
|
@spec_dir = nil
|
1859
1921
|
@spec_file = nil
|
@@ -1945,8 +2007,12 @@ class Gem::Specification < Gem::BasicSpecification
|
|
1945
2007
|
q.group 2, 'Gem::Specification.new do |s|', 'end' do
|
1946
2008
|
q.breakable
|
1947
2009
|
|
1948
|
-
|
1949
|
-
|
2010
|
+
attributes = @@attributes - [:name, :version]
|
2011
|
+
attributes.unshift :installed_by_version
|
2012
|
+
attributes.unshift :version
|
2013
|
+
attributes.unshift :name
|
2014
|
+
|
2015
|
+
attributes.each do |attr_name|
|
1950
2016
|
current_value = self.send attr_name
|
1951
2017
|
if current_value != default_value(attr_name) or
|
1952
2018
|
self.class.required_attribute? attr_name then
|
@@ -2107,10 +2173,10 @@ class Gem::Specification < Gem::BasicSpecification
|
|
2107
2173
|
end
|
2108
2174
|
|
2109
2175
|
##
|
2110
|
-
# Used by Gem::
|
2176
|
+
# Used by Gem::Resolver to order Gem::Specification objects
|
2111
2177
|
|
2112
2178
|
def source # :nodoc:
|
2113
|
-
|
2179
|
+
Gem::Source::Installed.new
|
2114
2180
|
end
|
2115
2181
|
|
2116
2182
|
##
|
@@ -2183,16 +2249,14 @@ class Gem::Specification < Gem::BasicSpecification
|
|
2183
2249
|
# Returns a Ruby code representation of this specification, such that it can
|
2184
2250
|
# be eval'ed and reconstruct the same specification later. Attributes that
|
2185
2251
|
# still have their default values are omitted.
|
2186
|
-
#
|
2187
|
-
# REFACTOR: This, plus stuff like #ruby_code and #pretty_print, should
|
2188
|
-
# probably be extracted out into some sort of separate class. SRP, do you
|
2189
|
-
# speak it!??!
|
2190
2252
|
|
2191
2253
|
def to_ruby
|
2192
2254
|
mark_version
|
2193
2255
|
result = []
|
2194
2256
|
result << "# -*- encoding: utf-8 -*-"
|
2195
|
-
result << "#{Gem::StubSpecification::PREFIX}#{name} #{version} #{platform} #{require_paths.join("\0")}"
|
2257
|
+
result << "#{Gem::StubSpecification::PREFIX}#{name} #{version} #{platform} #{@require_paths.join("\0")}"
|
2258
|
+
result << "#{Gem::StubSpecification::PREFIX}#{extensions.join "\0"}" unless
|
2259
|
+
extensions.empty?
|
2196
2260
|
result << nil
|
2197
2261
|
result << "Gem::Specification.new do |s|"
|
2198
2262
|
|
@@ -2207,11 +2271,13 @@ class Gem::Specification < Gem::BasicSpecification
|
|
2207
2271
|
if metadata and !metadata.empty?
|
2208
2272
|
result << " s.metadata = #{ruby_code metadata} if s.respond_to? :metadata="
|
2209
2273
|
end
|
2274
|
+
result << " s.require_paths = #{ruby_code @require_paths}"
|
2210
2275
|
|
2211
2276
|
handled = [
|
2212
2277
|
:dependencies,
|
2213
2278
|
:name,
|
2214
2279
|
:platform,
|
2280
|
+
:require_paths,
|
2215
2281
|
:required_rubygems_version,
|
2216
2282
|
:specification_version,
|
2217
2283
|
:version,
|
@@ -2229,6 +2295,11 @@ class Gem::Specification < Gem::BasicSpecification
|
|
2229
2295
|
end
|
2230
2296
|
end
|
2231
2297
|
|
2298
|
+
if @installed_by_version then
|
2299
|
+
result << nil
|
2300
|
+
result << " s.installed_by_version = \"#{Gem::VERSION}\" if s.respond_to? :installed_by_version"
|
2301
|
+
end
|
2302
|
+
|
2232
2303
|
unless dependencies.empty? then
|
2233
2304
|
result << nil
|
2234
2305
|
result << " if s.respond_to? :specification_version then"
|
@@ -2300,7 +2371,7 @@ class Gem::Specification < Gem::BasicSpecification
|
|
2300
2371
|
builder << self
|
2301
2372
|
ast = builder.tree
|
2302
2373
|
|
2303
|
-
io =
|
2374
|
+
io = Gem::StringSink.new
|
2304
2375
|
io.set_encoding Encoding::UTF_8 if Object.const_defined? :Encoding
|
2305
2376
|
|
2306
2377
|
Psych::Visitors::Emitter.new(io).accept(ast)
|
@@ -2338,6 +2409,7 @@ class Gem::Specification < Gem::BasicSpecification
|
|
2338
2409
|
# checks..
|
2339
2410
|
|
2340
2411
|
def validate packaging = true
|
2412
|
+
@warnings = 0
|
2341
2413
|
require 'rubygems/user_interaction'
|
2342
2414
|
extend Gem::UserInteraction
|
2343
2415
|
normalize
|
@@ -2368,7 +2440,7 @@ class Gem::Specification < Gem::BasicSpecification
|
|
2368
2440
|
"invalid value for attribute name: \"#{name.inspect}\""
|
2369
2441
|
end
|
2370
2442
|
|
2371
|
-
if require_paths.empty? then
|
2443
|
+
if @require_paths.empty? then
|
2372
2444
|
raise Gem::InvalidSpecificationException,
|
2373
2445
|
'specification must have at least one require_path'
|
2374
2446
|
end
|
@@ -2386,6 +2458,11 @@ class Gem::Specification < Gem::BasicSpecification
|
|
2386
2458
|
"[\"#{non_files.join "\", \""}\"] are not files"
|
2387
2459
|
end
|
2388
2460
|
|
2461
|
+
if files.include? file_name then
|
2462
|
+
raise Gem::InvalidSpecificationException,
|
2463
|
+
"#{full_name} contains itself (#{file_name}), check your files list"
|
2464
|
+
end
|
2465
|
+
|
2389
2466
|
unless specification_version.is_a?(Fixnum)
|
2390
2467
|
raise Gem::InvalidSpecificationException,
|
2391
2468
|
'specification_version must be a Fixnum (did you mean version?)'
|
@@ -2413,7 +2490,6 @@ class Gem::Specification < Gem::BasicSpecification
|
|
2413
2490
|
end
|
2414
2491
|
end
|
2415
2492
|
|
2416
|
-
# FIX: uhhhh single element array.each?
|
2417
2493
|
[:authors].each do |field|
|
2418
2494
|
val = self.send field
|
2419
2495
|
raise Gem::InvalidSpecificationException, "#{field} may not be empty" if
|
@@ -2456,16 +2532,15 @@ class Gem::Specification < Gem::BasicSpecification
|
|
2456
2532
|
end
|
2457
2533
|
}
|
2458
2534
|
|
2459
|
-
|
2460
|
-
licenses is empty. Use a license abbreviation from:
|
2461
|
-
|
2535
|
+
warning <<-warning if licenses.empty?
|
2536
|
+
licenses is empty, but is recommended. Use a license abbreviation from:
|
2537
|
+
http://opensource.org/licenses/alphabetical
|
2462
2538
|
warning
|
2463
2539
|
|
2464
2540
|
validate_permissions
|
2465
2541
|
|
2466
2542
|
# reject lazy developers:
|
2467
2543
|
|
2468
|
-
# FIX: Doesn't this just evaluate to "FIXME" or "TODO"?
|
2469
2544
|
lazy = '"FIxxxXME" or "TOxxxDO"'.gsub(/xxx/, '')
|
2470
2545
|
|
2471
2546
|
unless authors.grep(/FI XME|TO DO/x).empty? then
|
@@ -2494,33 +2569,98 @@ licenses is empty. Use a license abbreviation from:
|
|
2494
2569
|
|
2495
2570
|
%w[author description email homepage summary].each do |attribute|
|
2496
2571
|
value = self.send attribute
|
2497
|
-
|
2572
|
+
warning "no #{attribute} specified" if value.nil? or value.empty?
|
2498
2573
|
end
|
2499
2574
|
|
2500
2575
|
if description == summary then
|
2501
|
-
|
2576
|
+
warning 'description and summary are identical'
|
2502
2577
|
end
|
2503
2578
|
|
2504
2579
|
# TODO: raise at some given date
|
2505
|
-
|
2580
|
+
warning "deprecated autorequire specified" if autorequire
|
2506
2581
|
|
2507
2582
|
executables.each do |executable|
|
2508
2583
|
executable_path = File.join(bindir, executable)
|
2509
2584
|
shebang = File.read(executable_path, 2) == '#!'
|
2510
2585
|
|
2511
|
-
|
2586
|
+
warning "#{executable_path} is missing #! line" unless shebang
|
2512
2587
|
end
|
2513
2588
|
|
2589
|
+
validate_dependencies
|
2590
|
+
|
2591
|
+
true
|
2592
|
+
ensure
|
2593
|
+
if $! or @warnings > 0 then
|
2594
|
+
alert_warning "See http://guides.rubygems.org/specification-reference/ for help"
|
2595
|
+
end
|
2596
|
+
end
|
2597
|
+
|
2598
|
+
##
|
2599
|
+
# Checks that dependencies use requirements as we recommend. Warnings are
|
2600
|
+
# issued when dependencies are open-ended or overly strict for semantic
|
2601
|
+
# versioning.
|
2602
|
+
|
2603
|
+
def validate_dependencies # :nodoc:
|
2604
|
+
seen = {}
|
2605
|
+
|
2514
2606
|
dependencies.each do |dep|
|
2607
|
+
if prev = seen[dep.name] then
|
2608
|
+
raise Gem::InvalidSpecificationException, <<-MESSAGE
|
2609
|
+
duplicate dependency on #{dep}, (#{prev.requirement}) use:
|
2610
|
+
add_runtime_dependency '#{dep.name}', '#{dep.requirement}', '#{prev.requirement}'
|
2611
|
+
MESSAGE
|
2612
|
+
end
|
2613
|
+
|
2614
|
+
seen[dep.name] = dep
|
2615
|
+
|
2515
2616
|
prerelease_dep = dep.requirements_list.any? do |req|
|
2516
2617
|
Gem::Requirement.new(req).prerelease?
|
2517
2618
|
end
|
2518
2619
|
|
2519
|
-
|
2620
|
+
warning "prerelease dependency on #{dep} is not recommended" if
|
2520
2621
|
prerelease_dep
|
2521
|
-
end
|
2522
2622
|
|
2523
|
-
|
2623
|
+
overly_strict = dep.requirement.requirements.length == 1 &&
|
2624
|
+
dep.requirement.requirements.any? do |op, version|
|
2625
|
+
op == '~>' and
|
2626
|
+
not version.prerelease? and
|
2627
|
+
version.segments.length > 2
|
2628
|
+
end
|
2629
|
+
|
2630
|
+
if overly_strict then
|
2631
|
+
_, dep_version = dep.requirement.requirements.first
|
2632
|
+
|
2633
|
+
base = dep_version.segments.first 2
|
2634
|
+
|
2635
|
+
warning <<-WARNING
|
2636
|
+
pessimistic dependency on #{dep} may be overly strict
|
2637
|
+
if #{dep.name} is semantically versioned, use:
|
2638
|
+
add_#{dep.type}_dependency '#{dep.name}', '~> #{base.join '.'}', '>= #{dep_version}'
|
2639
|
+
WARNING
|
2640
|
+
end
|
2641
|
+
|
2642
|
+
open_ended = dep.requirement.requirements.all? do |op, version|
|
2643
|
+
not version.prerelease? and (op == '>' or op == '>=')
|
2644
|
+
end
|
2645
|
+
|
2646
|
+
if open_ended then
|
2647
|
+
op, dep_version = dep.requirement.requirements.first
|
2648
|
+
|
2649
|
+
base = dep_version.segments.first 2
|
2650
|
+
|
2651
|
+
bugfix = if op == '>' then
|
2652
|
+
", '> #{dep_version}'"
|
2653
|
+
elsif op == '>=' and base != dep_version.segments then
|
2654
|
+
", '>= #{dep_version}'"
|
2655
|
+
end
|
2656
|
+
|
2657
|
+
warning <<-WARNING
|
2658
|
+
open-ended dependency on #{dep} is not recommended
|
2659
|
+
if #{dep.name} is semantically versioned, use:
|
2660
|
+
add_#{dep.type}_dependency '#{dep.name}', '~> #{base.join '.'}'#{bugfix}
|
2661
|
+
WARNING
|
2662
|
+
end
|
2663
|
+
end
|
2524
2664
|
end
|
2525
2665
|
|
2526
2666
|
##
|
@@ -2531,13 +2671,13 @@ licenses is empty. Use a license abbreviation from:
|
|
2531
2671
|
|
2532
2672
|
files.each do |file|
|
2533
2673
|
next if File.stat(file).mode & 0444 == 0444
|
2534
|
-
|
2674
|
+
warning "#{file} is not world-readable"
|
2535
2675
|
end
|
2536
2676
|
|
2537
2677
|
executables.each do |name|
|
2538
2678
|
exec = File.join @bindir, name
|
2539
2679
|
next if File.stat(exec).executable?
|
2540
|
-
|
2680
|
+
warning "#{exec} is not executable"
|
2541
2681
|
end
|
2542
2682
|
end
|
2543
2683
|
|
@@ -2554,7 +2694,10 @@ licenses is empty. Use a license abbreviation from:
|
|
2554
2694
|
return @version
|
2555
2695
|
end
|
2556
2696
|
|
2557
|
-
|
2697
|
+
def stubbed?
|
2698
|
+
false
|
2699
|
+
end
|
2700
|
+
|
2558
2701
|
def yaml_initialize(tag, vals) # :nodoc:
|
2559
2702
|
vals.each do |ivar, val|
|
2560
2703
|
case ivar
|
@@ -2592,6 +2735,12 @@ licenses is empty. Use a license abbreviation from:
|
|
2592
2735
|
@installed_by_version ||= nil
|
2593
2736
|
end
|
2594
2737
|
|
2738
|
+
def warning statement # :nodoc:
|
2739
|
+
@warnings += 1
|
2740
|
+
|
2741
|
+
alert_warning statement
|
2742
|
+
end
|
2743
|
+
|
2595
2744
|
extend Gem::Deprecate
|
2596
2745
|
|
2597
2746
|
# TODO:
|