bundler 2.2.17 → 2.2.22
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of bundler might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +70 -0
- data/bundler.gemspec +2 -3
- data/lib/bundler.rb +2 -1
- data/lib/bundler/build_metadata.rb +2 -2
- data/lib/bundler/cli.rb +13 -33
- data/lib/bundler/cli/check.rb +4 -2
- data/lib/bundler/cli/doctor.rb +11 -1
- data/lib/bundler/cli/install.rb +7 -8
- data/lib/bundler/cli/lock.rb +5 -1
- data/lib/bundler/cli/outdated.rb +9 -10
- data/lib/bundler/cli/update.rb +8 -3
- data/lib/bundler/current_ruby.rb +4 -4
- data/lib/bundler/definition.rb +38 -127
- data/lib/bundler/dsl.rb +3 -11
- data/lib/bundler/feature_flag.rb +0 -3
- data/lib/bundler/fetcher/compact_index.rb +1 -1
- data/lib/bundler/fetcher/downloader.rb +1 -2
- data/lib/bundler/fetcher/index.rb +0 -1
- data/lib/bundler/friendly_errors.rb +2 -4
- data/lib/bundler/index.rb +1 -2
- data/lib/bundler/installer.rb +5 -12
- data/lib/bundler/lockfile_parser.rb +2 -20
- data/lib/bundler/man/bundle-add.1 +1 -1
- data/lib/bundler/man/bundle-binstubs.1 +1 -1
- data/lib/bundler/man/bundle-cache.1 +1 -1
- data/lib/bundler/man/bundle-check.1 +1 -1
- data/lib/bundler/man/bundle-clean.1 +1 -1
- data/lib/bundler/man/bundle-config.1 +1 -10
- data/lib/bundler/man/bundle-config.1.ronn +0 -11
- data/lib/bundler/man/bundle-doctor.1 +1 -1
- data/lib/bundler/man/bundle-exec.1 +1 -1
- data/lib/bundler/man/bundle-gem.1 +1 -1
- data/lib/bundler/man/bundle-info.1 +1 -1
- data/lib/bundler/man/bundle-init.1 +1 -1
- data/lib/bundler/man/bundle-inject.1 +1 -1
- data/lib/bundler/man/bundle-install.1 +1 -1
- data/lib/bundler/man/bundle-list.1 +1 -1
- data/lib/bundler/man/bundle-lock.1 +1 -1
- data/lib/bundler/man/bundle-open.1 +1 -1
- data/lib/bundler/man/bundle-outdated.1 +1 -1
- data/lib/bundler/man/bundle-platform.1 +1 -1
- data/lib/bundler/man/bundle-pristine.1 +1 -1
- data/lib/bundler/man/bundle-remove.1 +1 -1
- data/lib/bundler/man/bundle-show.1 +1 -1
- data/lib/bundler/man/bundle-update.1 +4 -4
- data/lib/bundler/man/bundle-update.1.ronn +3 -3
- data/lib/bundler/man/bundle-viz.1 +1 -1
- data/lib/bundler/man/bundle.1 +1 -1
- data/lib/bundler/man/gemfile.5 +1 -1
- data/lib/bundler/plugin/api/source.rb +14 -0
- data/lib/bundler/plugin/installer.rb +1 -1
- data/lib/bundler/resolver.rb +15 -96
- data/lib/bundler/resolver/spec_group.rb +0 -24
- data/lib/bundler/rubygems_ext.rb +2 -2
- data/lib/bundler/rubygems_integration.rb +4 -3
- data/lib/bundler/settings.rb +21 -4
- data/lib/bundler/source.rb +11 -0
- data/lib/bundler/source/rubygems.rb +22 -22
- data/lib/bundler/source/rubygems_aggregate.rb +64 -0
- data/lib/bundler/source_list.rb +69 -27
- data/lib/bundler/source_map.rb +58 -0
- data/lib/bundler/spec_set.rb +2 -6
- data/lib/bundler/templates/newgem/newgem.gemspec.tt +2 -2
- data/lib/bundler/version.rb +1 -1
- metadata +5 -3
@@ -526,13 +526,14 @@ module Bundler
|
|
526
526
|
Bundler::Retry.new("download gem from #{uri}").attempts do
|
527
527
|
fetcher.download(spec, uri, path)
|
528
528
|
end
|
529
|
+
rescue Gem::RemoteFetcher::FetchError => e
|
530
|
+
raise Bundler::HTTPError, "Could not download gem from #{uri} due to underlying error <#{e.message}>"
|
529
531
|
end
|
530
532
|
|
531
533
|
def gem_remote_fetcher
|
532
|
-
require "
|
534
|
+
require "rubygems/remote_fetcher"
|
533
535
|
proxy = configuration[:http_proxy]
|
534
|
-
|
535
|
-
Gem::RemoteFetcher.new(proxy, dns)
|
536
|
+
Gem::RemoteFetcher.new(proxy)
|
536
537
|
end
|
537
538
|
|
538
539
|
def gem_from_path(path, policy = nil)
|
data/lib/bundler/settings.rb
CHANGED
@@ -16,12 +16,10 @@ module Bundler
|
|
16
16
|
clean
|
17
17
|
default_install_uses_path
|
18
18
|
deployment
|
19
|
-
deployment_means_frozen
|
20
19
|
disable_checksum_validation
|
21
20
|
disable_exec_load
|
22
21
|
disable_local_branch_check
|
23
22
|
disable_local_revision_check
|
24
|
-
disable_multisource
|
25
23
|
disable_shared_gems
|
26
24
|
disable_version_check
|
27
25
|
force_ruby_platform
|
@@ -46,7 +44,6 @@ module Bundler
|
|
46
44
|
silence_deprecations
|
47
45
|
silence_root_warning
|
48
46
|
suppress_install_using_messages
|
49
|
-
unlock_source_unlocks_spec
|
50
47
|
update_requires_all_flag
|
51
48
|
use_gem_version_promoter_for_major_updates
|
52
49
|
].freeze
|
@@ -211,6 +208,13 @@ module Bundler
|
|
211
208
|
locations
|
212
209
|
end
|
213
210
|
|
211
|
+
def processor_count
|
212
|
+
require "etc"
|
213
|
+
Etc.nprocessors
|
214
|
+
rescue StandardError
|
215
|
+
1
|
216
|
+
end
|
217
|
+
|
214
218
|
# for legacy reasons, in Bundler 2, we do not respect :disable_shared_gems
|
215
219
|
def path
|
216
220
|
configs.each do |_level, settings|
|
@@ -443,7 +447,20 @@ module Bundler
|
|
443
447
|
valid_file = file.exist? && !file.size.zero?
|
444
448
|
return {} unless valid_file
|
445
449
|
require_relative "yaml_serializer"
|
446
|
-
YAMLSerializer.load
|
450
|
+
YAMLSerializer.load(file.read).inject({}) do |config, (k, v)|
|
451
|
+
new_k = k
|
452
|
+
|
453
|
+
if k.include?("-")
|
454
|
+
Bundler.ui.warn "Your #{file} config includes `#{k}`, which contains the dash character (`-`).\n" \
|
455
|
+
"This is deprecated, because configuration through `ENV` should be possible, but `ENV` keys cannot include dashes.\n" \
|
456
|
+
"Please edit #{file} and replace any dashes in configuration keys with a triple underscore (`___`)."
|
457
|
+
|
458
|
+
new_k = k.gsub("-", "___")
|
459
|
+
end
|
460
|
+
|
461
|
+
config[new_k] = v
|
462
|
+
config
|
463
|
+
end
|
447
464
|
end
|
448
465
|
end
|
449
466
|
|
data/lib/bundler/source.rb
CHANGED
@@ -7,6 +7,7 @@ module Bundler
|
|
7
7
|
autoload :Metadata, File.expand_path("source/metadata", __dir__)
|
8
8
|
autoload :Path, File.expand_path("source/path", __dir__)
|
9
9
|
autoload :Rubygems, File.expand_path("source/rubygems", __dir__)
|
10
|
+
autoload :RubygemsAggregate, File.expand_path("source/rubygems_aggregate", __dir__)
|
10
11
|
|
11
12
|
attr_accessor :dependency_names
|
12
13
|
|
@@ -35,10 +36,16 @@ module Bundler
|
|
35
36
|
|
36
37
|
def local!; end
|
37
38
|
|
39
|
+
def local_only!; end
|
40
|
+
|
38
41
|
def cached!; end
|
39
42
|
|
40
43
|
def remote!; end
|
41
44
|
|
45
|
+
def add_dependency_names(names)
|
46
|
+
@dependency_names = Array(dependency_names) | Array(names)
|
47
|
+
end
|
48
|
+
|
42
49
|
# it's possible that gems from one source depend on gems from some
|
43
50
|
# other source, so now we download gemspecs and iterate over those
|
44
51
|
# dependencies, looking for gems we don't have info on yet.
|
@@ -48,6 +55,10 @@ module Bundler
|
|
48
55
|
specs.dependency_names
|
49
56
|
end
|
50
57
|
|
58
|
+
def spec_names
|
59
|
+
specs.spec_names
|
60
|
+
end
|
61
|
+
|
51
62
|
def include?(other)
|
52
63
|
other == self
|
53
64
|
end
|
@@ -26,6 +26,12 @@ module Bundler
|
|
26
26
|
Array(options["remotes"]).reverse_each {|r| add_remote(r) }
|
27
27
|
end
|
28
28
|
|
29
|
+
def local_only!
|
30
|
+
@specs = nil
|
31
|
+
@allow_local = true
|
32
|
+
@allow_remote = false
|
33
|
+
end
|
34
|
+
|
29
35
|
def local!
|
30
36
|
return if @allow_local
|
31
37
|
|
@@ -61,13 +67,13 @@ module Bundler
|
|
61
67
|
o.is_a?(Rubygems) && (o.credless_remotes - credless_remotes).empty?
|
62
68
|
end
|
63
69
|
|
64
|
-
def
|
65
|
-
@remotes.size
|
70
|
+
def multiple_remotes?
|
71
|
+
@remotes.size > 1
|
66
72
|
end
|
67
73
|
|
68
74
|
def can_lock?(spec)
|
69
|
-
return super
|
70
|
-
spec.source
|
75
|
+
return super unless multiple_remotes?
|
76
|
+
include?(spec.source)
|
71
77
|
end
|
72
78
|
|
73
79
|
def options
|
@@ -246,21 +252,16 @@ module Bundler
|
|
246
252
|
other_remotes.map(&method(:remove_auth)) == @remotes.map(&method(:remove_auth))
|
247
253
|
end
|
248
254
|
|
249
|
-
def
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
@remotes = []
|
255
|
-
other_remotes.reverse_each do |r|
|
256
|
-
add_remote r.to_s
|
255
|
+
def spec_names
|
256
|
+
if @allow_remote && dependency_api_available?
|
257
|
+
remote_specs.spec_names
|
258
|
+
else
|
259
|
+
[]
|
257
260
|
end
|
258
|
-
|
259
|
-
!equivalent
|
260
261
|
end
|
261
262
|
|
262
263
|
def unmet_deps
|
263
|
-
if @allow_remote &&
|
264
|
+
if @allow_remote && dependency_api_available?
|
264
265
|
remote_specs.unmet_dependency_names
|
265
266
|
else
|
266
267
|
[]
|
@@ -276,7 +277,7 @@ module Bundler
|
|
276
277
|
|
277
278
|
def double_check_for(unmet_dependency_names)
|
278
279
|
return unless @allow_remote
|
279
|
-
return unless
|
280
|
+
return unless dependency_api_available?
|
280
281
|
|
281
282
|
unmet_dependency_names = unmet_dependency_names.call
|
282
283
|
unless unmet_dependency_names.nil?
|
@@ -298,17 +299,20 @@ module Bundler
|
|
298
299
|
remote_specs.each do |spec|
|
299
300
|
case spec
|
300
301
|
when EndpointSpecification, Gem::Specification, StubSpecification, LazySpecification
|
301
|
-
names.concat(spec.runtime_dependencies)
|
302
|
+
names.concat(spec.runtime_dependencies.map(&:name))
|
302
303
|
when RemoteSpecification # from the full index
|
303
304
|
return nil
|
304
305
|
else
|
305
306
|
raise "unhandled spec type (#{spec.inspect})"
|
306
307
|
end
|
307
308
|
end
|
308
|
-
names.map!(&:name) if names
|
309
309
|
names
|
310
310
|
end
|
311
311
|
|
312
|
+
def dependency_api_available?
|
313
|
+
api_fetchers.any?
|
314
|
+
end
|
315
|
+
|
312
316
|
protected
|
313
317
|
|
314
318
|
def credless_remotes
|
@@ -387,10 +391,6 @@ module Bundler
|
|
387
391
|
next if gemfile =~ /^bundler\-[\d\.]+?\.gem/
|
388
392
|
s ||= Bundler.rubygems.spec_from_gem(gemfile)
|
389
393
|
s.source = self
|
390
|
-
if Bundler.rubygems.spec_missing_extensions?(s, false)
|
391
|
-
Bundler.ui.debug "Source #{self} is ignoring #{s} because it is missing extensions"
|
392
|
-
next
|
393
|
-
end
|
394
394
|
idx << s
|
395
395
|
end
|
396
396
|
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Bundler
|
4
|
+
class Source
|
5
|
+
class RubygemsAggregate
|
6
|
+
attr_reader :source_map, :sources
|
7
|
+
|
8
|
+
def initialize(sources, source_map)
|
9
|
+
@sources = sources
|
10
|
+
@source_map = source_map
|
11
|
+
|
12
|
+
@index = build_index
|
13
|
+
end
|
14
|
+
|
15
|
+
def specs
|
16
|
+
@index
|
17
|
+
end
|
18
|
+
|
19
|
+
def to_s
|
20
|
+
"any of the sources"
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def build_index
|
26
|
+
Index.build do |idx|
|
27
|
+
dependency_names = source_map.pinned_spec_names
|
28
|
+
|
29
|
+
sources.all_sources.each do |source|
|
30
|
+
source.dependency_names = dependency_names - source_map.pinned_spec_names(source)
|
31
|
+
idx.add_source source.specs
|
32
|
+
dependency_names.concat(source.unmet_deps).uniq!
|
33
|
+
end
|
34
|
+
|
35
|
+
double_check_for_index(idx, dependency_names)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# Suppose the gem Foo depends on the gem Bar. Foo exists in Source A. Bar has some versions that exist in both
|
40
|
+
# sources A and B. At this point, the API request will have found all the versions of Bar in source A,
|
41
|
+
# but will not have found any versions of Bar from source B, which is a problem if the requested version
|
42
|
+
# of Foo specifically depends on a version of Bar that is only found in source B. This ensures that for
|
43
|
+
# each spec we found, we add all possible versions from all sources to the index.
|
44
|
+
def double_check_for_index(idx, dependency_names)
|
45
|
+
pinned_names = source_map.pinned_spec_names
|
46
|
+
|
47
|
+
names = :names # do this so we only have to traverse to get dependency_names from the index once
|
48
|
+
unmet_dependency_names = lambda do
|
49
|
+
return names unless names == :names
|
50
|
+
new_names = sources.all_sources.map(&:dependency_names_to_double_check)
|
51
|
+
return names = nil if new_names.compact!
|
52
|
+
names = new_names.flatten(1).concat(dependency_names)
|
53
|
+
names.uniq!
|
54
|
+
names -= pinned_names
|
55
|
+
names
|
56
|
+
end
|
57
|
+
|
58
|
+
sources.all_sources.each do |source|
|
59
|
+
source.double_check_for(unmet_dependency_names)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
data/lib/bundler/source_list.rb
CHANGED
@@ -21,15 +21,20 @@ module Bundler
|
|
21
21
|
@rubygems_sources = []
|
22
22
|
@metadata_source = Source::Metadata.new
|
23
23
|
|
24
|
-
@
|
24
|
+
@merged_gem_lockfile_sections = false
|
25
25
|
end
|
26
26
|
|
27
|
-
def
|
28
|
-
@
|
27
|
+
def merged_gem_lockfile_sections?
|
28
|
+
@merged_gem_lockfile_sections
|
29
29
|
end
|
30
30
|
|
31
|
-
def merged_gem_lockfile_sections!
|
32
|
-
@
|
31
|
+
def merged_gem_lockfile_sections!(replacement_source)
|
32
|
+
@merged_gem_lockfile_sections = true
|
33
|
+
@global_rubygems_source = replacement_source
|
34
|
+
end
|
35
|
+
|
36
|
+
def aggregate_global_source?
|
37
|
+
global_rubygems_source.multiple_remotes?
|
33
38
|
end
|
34
39
|
|
35
40
|
def add_path_source(options = {})
|
@@ -49,18 +54,17 @@ module Bundler
|
|
49
54
|
end
|
50
55
|
|
51
56
|
def add_rubygems_source(options = {})
|
52
|
-
|
57
|
+
new_source = Source::Rubygems.new(options)
|
58
|
+
return @global_rubygems_source if @global_rubygems_source == new_source
|
59
|
+
|
60
|
+
add_source_to_list new_source, @rubygems_sources
|
53
61
|
end
|
54
62
|
|
55
63
|
def add_plugin_source(source, options = {})
|
56
64
|
add_source_to_list Plugin.source(source).new(options), @plugin_sources
|
57
65
|
end
|
58
66
|
|
59
|
-
def
|
60
|
-
@global_rubygems_source ||= rubygems_aggregate_class.new("remotes" => uri, "allow_local" => true)
|
61
|
-
end
|
62
|
-
|
63
|
-
def add_rubygems_remote(uri)
|
67
|
+
def add_global_rubygems_remote(uri)
|
64
68
|
global_rubygems_source.add_remote(uri)
|
65
69
|
global_rubygems_source
|
66
70
|
end
|
@@ -70,7 +74,11 @@ module Bundler
|
|
70
74
|
end
|
71
75
|
|
72
76
|
def rubygems_sources
|
73
|
-
|
77
|
+
non_global_rubygems_sources + [global_rubygems_source]
|
78
|
+
end
|
79
|
+
|
80
|
+
def non_global_rubygems_sources
|
81
|
+
@rubygems_sources
|
74
82
|
end
|
75
83
|
|
76
84
|
def rubygems_remotes
|
@@ -81,36 +89,50 @@ module Bundler
|
|
81
89
|
path_sources + git_sources + plugin_sources + rubygems_sources + [metadata_source]
|
82
90
|
end
|
83
91
|
|
92
|
+
def non_default_explicit_sources
|
93
|
+
all_sources - [default_source, metadata_source]
|
94
|
+
end
|
95
|
+
|
84
96
|
def get(source)
|
85
97
|
source_list_for(source).find {|s| equal_source?(source, s) || equivalent_source?(source, s) }
|
86
98
|
end
|
87
99
|
|
88
100
|
def lock_sources
|
89
|
-
|
90
|
-
|
91
|
-
|
101
|
+
lock_other_sources + lock_rubygems_sources
|
102
|
+
end
|
103
|
+
|
104
|
+
def lock_other_sources
|
105
|
+
(path_sources + git_sources + plugin_sources).sort_by(&:to_s)
|
106
|
+
end
|
107
|
+
|
108
|
+
def lock_rubygems_sources
|
109
|
+
if merged_gem_lockfile_sections?
|
110
|
+
[combine_rubygems_sources]
|
92
111
|
else
|
93
|
-
|
112
|
+
rubygems_sources.sort_by(&:to_s)
|
94
113
|
end
|
95
114
|
end
|
96
115
|
|
97
116
|
# Returns true if there are changes
|
98
117
|
def replace_sources!(replacement_sources)
|
99
|
-
return
|
118
|
+
return false if replacement_sources.empty?
|
100
119
|
|
101
|
-
|
102
|
-
source_list.map! do |source|
|
103
|
-
replacement_sources.find {|s| s == source } || source
|
104
|
-
end
|
105
|
-
end
|
120
|
+
@path_sources, @git_sources, @plugin_sources = map_sources(replacement_sources)
|
106
121
|
|
107
|
-
|
108
|
-
|
109
|
-
|
122
|
+
different_sources?(lock_sources, replacement_sources)
|
123
|
+
end
|
124
|
+
|
125
|
+
# Returns true if there are changes
|
126
|
+
def expired_sources?(replacement_sources)
|
127
|
+
return false if replacement_sources.empty?
|
128
|
+
|
129
|
+
lock_sources = dup_with_replaced_sources(replacement_sources).lock_sources
|
110
130
|
|
111
|
-
|
131
|
+
different_sources?(lock_sources, replacement_sources)
|
132
|
+
end
|
112
133
|
|
113
|
-
|
134
|
+
def local_only!
|
135
|
+
all_sources.each(&:local_only!)
|
114
136
|
end
|
115
137
|
|
116
138
|
def cached!
|
@@ -123,6 +145,24 @@ module Bundler
|
|
123
145
|
|
124
146
|
private
|
125
147
|
|
148
|
+
def dup_with_replaced_sources(replacement_sources)
|
149
|
+
new_source_list = dup
|
150
|
+
new_source_list.replace_sources!(replacement_sources)
|
151
|
+
new_source_list
|
152
|
+
end
|
153
|
+
|
154
|
+
def map_sources(replacement_sources)
|
155
|
+
[path_sources, git_sources, plugin_sources].map do |sources|
|
156
|
+
sources.map do |source|
|
157
|
+
replacement_sources.find {|s| s == source } || source
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
def different_sources?(lock_sources, replacement_sources)
|
163
|
+
!equal_sources?(lock_sources, replacement_sources) && !equivalent_sources?(lock_sources, replacement_sources)
|
164
|
+
end
|
165
|
+
|
126
166
|
def rubygems_aggregate_class
|
127
167
|
Source::Rubygems
|
128
168
|
end
|
@@ -162,6 +202,8 @@ module Bundler
|
|
162
202
|
end
|
163
203
|
|
164
204
|
def equal_source?(source, other_source)
|
205
|
+
return source.include?(other_source) if source.is_a?(Source::Rubygems) && other_source.is_a?(Source::Rubygems) && !merged_gem_lockfile_sections?
|
206
|
+
|
165
207
|
source == other_source
|
166
208
|
end
|
167
209
|
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Bundler
|
4
|
+
class SourceMap
|
5
|
+
attr_reader :sources, :dependencies
|
6
|
+
|
7
|
+
def initialize(sources, dependencies)
|
8
|
+
@sources = sources
|
9
|
+
@dependencies = dependencies
|
10
|
+
end
|
11
|
+
|
12
|
+
def pinned_spec_names(skip = nil)
|
13
|
+
direct_requirements.reject {|_, source| source == skip }.keys
|
14
|
+
end
|
15
|
+
|
16
|
+
def all_requirements
|
17
|
+
requirements = direct_requirements.dup
|
18
|
+
|
19
|
+
unmet_deps = sources.non_default_explicit_sources.map do |source|
|
20
|
+
(source.spec_names - pinned_spec_names).each do |indirect_dependency_name|
|
21
|
+
previous_source = requirements[indirect_dependency_name]
|
22
|
+
if previous_source.nil?
|
23
|
+
requirements[indirect_dependency_name] = source
|
24
|
+
else
|
25
|
+
no_ambiguous_sources = Bundler.feature_flag.bundler_3_mode?
|
26
|
+
|
27
|
+
msg = ["The gem '#{indirect_dependency_name}' was found in multiple relevant sources."]
|
28
|
+
msg.concat [previous_source, source].map {|s| " * #{s}" }.sort
|
29
|
+
msg << "You #{no_ambiguous_sources ? :must : :should} add this gem to the source block for the source you wish it to be installed from."
|
30
|
+
msg = msg.join("\n")
|
31
|
+
|
32
|
+
raise SecurityError, msg if no_ambiguous_sources
|
33
|
+
Bundler.ui.warn "Warning: #{msg}"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
source.unmet_deps
|
38
|
+
end
|
39
|
+
|
40
|
+
sources.default_source.add_dependency_names(unmet_deps.flatten - requirements.keys)
|
41
|
+
|
42
|
+
requirements
|
43
|
+
end
|
44
|
+
|
45
|
+
def direct_requirements
|
46
|
+
@direct_requirements ||= begin
|
47
|
+
requirements = {}
|
48
|
+
default = sources.default_source
|
49
|
+
dependencies.each do |dep|
|
50
|
+
dep_source = dep.source || default
|
51
|
+
dep_source.add_dependency_names(dep.name)
|
52
|
+
requirements[dep.name] = dep_source
|
53
|
+
end
|
54
|
+
requirements
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|