bundler 2.2.11 → 2.3.6

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.
Files changed (174) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +414 -5
  3. data/README.md +1 -1
  4. data/bundler.gemspec +2 -3
  5. data/exe/bundle +7 -8
  6. data/lib/bundler/.document +1 -0
  7. data/lib/bundler/build_metadata.rb +2 -2
  8. data/lib/bundler/cli/cache.rb +1 -1
  9. data/lib/bundler/cli/check.rb +4 -2
  10. data/lib/bundler/cli/common.rb +15 -2
  11. data/lib/bundler/cli/doctor.rb +24 -5
  12. data/lib/bundler/cli/exec.rb +1 -6
  13. data/lib/bundler/cli/gem.rb +130 -26
  14. data/lib/bundler/cli/info.rb +16 -4
  15. data/lib/bundler/cli/install.rb +12 -27
  16. data/lib/bundler/cli/issue.rb +4 -3
  17. data/lib/bundler/cli/list.rb +7 -1
  18. data/lib/bundler/cli/lock.rb +5 -1
  19. data/lib/bundler/cli/open.rb +1 -2
  20. data/lib/bundler/cli/outdated.rb +10 -11
  21. data/lib/bundler/cli/platform.rb +1 -1
  22. data/lib/bundler/cli/remove.rb +1 -2
  23. data/lib/bundler/cli/update.rb +17 -8
  24. data/lib/bundler/cli.rb +41 -55
  25. data/lib/bundler/compact_index_client/cache.rb +0 -9
  26. data/lib/bundler/compact_index_client/updater.rb +10 -11
  27. data/lib/bundler/compact_index_client.rb +2 -8
  28. data/lib/bundler/current_ruby.rb +5 -4
  29. data/lib/bundler/definition.rb +147 -290
  30. data/lib/bundler/dependency.rb +5 -7
  31. data/lib/bundler/digest.rb +71 -0
  32. data/lib/bundler/dsl.rb +67 -66
  33. data/lib/bundler/endpoint_specification.rb +21 -11
  34. data/lib/bundler/env.rb +1 -1
  35. data/lib/bundler/environment_preserver.rb +4 -1
  36. data/lib/bundler/errors.rb +19 -3
  37. data/lib/bundler/feature_flag.rb +0 -4
  38. data/lib/bundler/fetcher/compact_index.rb +10 -15
  39. data/lib/bundler/fetcher/downloader.rb +9 -6
  40. data/lib/bundler/fetcher/index.rb +0 -27
  41. data/lib/bundler/fetcher.rb +10 -16
  42. data/lib/bundler/friendly_errors.rb +5 -32
  43. data/lib/bundler/gem_helper.rb +21 -16
  44. data/lib/bundler/index.rb +2 -7
  45. data/lib/bundler/injector.rb +12 -3
  46. data/lib/bundler/inline.rb +2 -1
  47. data/lib/bundler/installer/gem_installer.rb +4 -22
  48. data/lib/bundler/installer/parallel_installer.rb +36 -15
  49. data/lib/bundler/installer/standalone.rb +14 -9
  50. data/lib/bundler/installer.rb +8 -17
  51. data/lib/bundler/lazy_specification.rb +23 -2
  52. data/lib/bundler/lockfile_generator.rb +1 -1
  53. data/lib/bundler/lockfile_parser.rb +16 -45
  54. data/lib/bundler/man/bundle-add.1 +10 -2
  55. data/lib/bundler/man/bundle-add.1.ronn +7 -1
  56. data/lib/bundler/man/bundle-binstubs.1 +1 -1
  57. data/lib/bundler/man/bundle-cache.1 +1 -1
  58. data/lib/bundler/man/bundle-check.1 +1 -1
  59. data/lib/bundler/man/bundle-clean.1 +1 -1
  60. data/lib/bundler/man/bundle-config.1 +23 -15
  61. data/lib/bundler/man/bundle-config.1.ronn +24 -17
  62. data/lib/bundler/man/bundle-doctor.1 +1 -1
  63. data/lib/bundler/man/bundle-exec.1 +1 -1
  64. data/lib/bundler/man/bundle-gem.1 +14 -1
  65. data/lib/bundler/man/bundle-gem.1.ronn +16 -0
  66. data/lib/bundler/man/bundle-info.1 +1 -1
  67. data/lib/bundler/man/bundle-init.1 +1 -1
  68. data/lib/bundler/man/bundle-inject.1 +1 -1
  69. data/lib/bundler/man/bundle-install.1 +2 -2
  70. data/lib/bundler/man/bundle-install.1.ronn +2 -2
  71. data/lib/bundler/man/bundle-list.1 +1 -1
  72. data/lib/bundler/man/bundle-lock.1 +1 -1
  73. data/lib/bundler/man/bundle-open.1 +1 -1
  74. data/lib/bundler/man/bundle-outdated.1 +1 -1
  75. data/lib/bundler/man/bundle-platform.1 +1 -1
  76. data/lib/bundler/man/bundle-pristine.1 +1 -1
  77. data/lib/bundler/man/bundle-remove.1 +1 -1
  78. data/lib/bundler/man/bundle-show.1 +1 -1
  79. data/lib/bundler/man/bundle-update.1 +5 -5
  80. data/lib/bundler/man/bundle-update.1.ronn +5 -4
  81. data/lib/bundler/man/bundle-viz.1 +1 -1
  82. data/lib/bundler/man/bundle.1 +1 -1
  83. data/lib/bundler/man/gemfile.5 +28 -2
  84. data/lib/bundler/man/gemfile.5.ronn +9 -1
  85. data/lib/bundler/plugin/api/source.rb +22 -0
  86. data/lib/bundler/plugin/index.rb +4 -1
  87. data/lib/bundler/plugin/installer.rb +10 -10
  88. data/lib/bundler/plugin/source_list.rb +4 -0
  89. data/lib/bundler/plugin.rb +28 -8
  90. data/lib/bundler/process_lock.rb +1 -1
  91. data/lib/bundler/psyched_yaml.rb +1 -13
  92. data/lib/bundler/remote_specification.rb +7 -0
  93. data/lib/bundler/resolver/spec_group.rb +1 -25
  94. data/lib/bundler/resolver.rb +55 -147
  95. data/lib/bundler/retry.rb +1 -1
  96. data/lib/bundler/ruby_version.rb +1 -1
  97. data/lib/bundler/rubygems_ext.rb +30 -8
  98. data/lib/bundler/rubygems_gem_installer.rb +68 -1
  99. data/lib/bundler/rubygems_integration.rb +43 -60
  100. data/lib/bundler/runtime.rb +18 -11
  101. data/lib/bundler/self_manager.rb +168 -0
  102. data/lib/bundler/settings.rb +96 -20
  103. data/lib/bundler/setup.rb +2 -2
  104. data/lib/bundler/shared_helpers.rb +4 -19
  105. data/lib/bundler/source/git/git_proxy.rb +8 -6
  106. data/lib/bundler/source/git.rb +22 -4
  107. data/lib/bundler/source/metadata.rb +1 -5
  108. data/lib/bundler/source/path/installer.rb +1 -1
  109. data/lib/bundler/source/path.rb +3 -1
  110. data/lib/bundler/source/rubygems.rb +111 -106
  111. data/lib/bundler/source/rubygems_aggregate.rb +68 -0
  112. data/lib/bundler/source.rb +21 -0
  113. data/lib/bundler/source_list.rb +100 -60
  114. data/lib/bundler/source_map.rb +58 -0
  115. data/lib/bundler/spec_set.rb +17 -31
  116. data/lib/bundler/stub_specification.rb +8 -0
  117. data/lib/bundler/templates/Executable.bundler +7 -7
  118. data/lib/bundler/templates/Gemfile +0 -2
  119. data/lib/bundler/templates/gems.rb +0 -3
  120. data/lib/bundler/templates/newgem/Gemfile.tt +5 -2
  121. data/lib/bundler/templates/newgem/README.md.tt +5 -3
  122. data/lib/bundler/templates/newgem/Rakefile.tt +15 -2
  123. data/lib/bundler/templates/newgem/github/workflows/main.yml.tt +15 -6
  124. data/lib/bundler/templates/newgem/newgem.gemspec.tt +18 -16
  125. data/lib/bundler/templates/newgem/sig/newgem.rbs.tt +8 -0
  126. data/lib/bundler/templates/newgem/standard.yml.tt +3 -0
  127. data/lib/bundler/templates/newgem/test/minitest/{newgem_test.rb.tt → test_newgem.rb.tt} +1 -1
  128. data/lib/bundler/ui/shell.rb +1 -1
  129. data/lib/bundler/vendor/.document +1 -0
  130. data/lib/bundler/vendor/connection_pool/LICENSE +20 -0
  131. data/lib/bundler/vendor/connection_pool/lib/connection_pool/timed_stack.rb +19 -21
  132. data/lib/bundler/vendor/connection_pool/lib/connection_pool/version.rb +1 -1
  133. data/lib/bundler/vendor/connection_pool/lib/connection_pool/wrapper.rb +57 -0
  134. data/lib/bundler/vendor/connection_pool/lib/connection_pool.rb +39 -74
  135. data/lib/bundler/vendor/fileutils/LICENSE.txt +22 -0
  136. data/lib/bundler/vendor/molinillo/LICENSE +9 -0
  137. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb +2 -2
  138. data/lib/bundler/vendor/molinillo/lib/molinillo/modules/specification_provider.rb +1 -1
  139. data/lib/bundler/vendor/net-http-persistent/README.rdoc +82 -0
  140. data/lib/bundler/vendor/thor/LICENSE.md +20 -0
  141. data/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb +5 -5
  142. data/lib/bundler/vendor/thor/lib/thor/actions/inject_into_file.rb +1 -2
  143. data/lib/bundler/vendor/thor/lib/thor/actions.rb +6 -2
  144. data/lib/bundler/vendor/thor/lib/thor/core_ext/hash_with_indifferent_access.rb +6 -0
  145. data/lib/bundler/vendor/thor/lib/thor/error.rb +9 -4
  146. data/lib/bundler/vendor/thor/lib/thor/parser/options.rb +19 -1
  147. data/lib/bundler/vendor/thor/lib/thor/shell/basic.rb +22 -4
  148. data/lib/bundler/vendor/thor/lib/thor/shell.rb +1 -1
  149. data/lib/bundler/vendor/thor/lib/thor/util.rb +1 -1
  150. data/lib/bundler/vendor/thor/lib/thor/version.rb +1 -1
  151. data/lib/bundler/vendor/tmpdir/lib/tmpdir.rb +1 -1
  152. data/lib/bundler/vendor/tsort/LICENSE.txt +22 -0
  153. data/lib/bundler/vendor/tsort/lib/tsort.rb +453 -0
  154. data/lib/bundler/vendor/uri/LICENSE.txt +22 -0
  155. data/lib/bundler/vendor/uri/lib/uri/common.rb +17 -80
  156. data/lib/bundler/vendor/uri/lib/uri/ftp.rb +0 -1
  157. data/lib/bundler/vendor/uri/lib/uri/generic.rb +5 -6
  158. data/lib/bundler/vendor/uri/lib/uri/http.rb +0 -1
  159. data/lib/bundler/vendor/uri/lib/uri/https.rb +0 -1
  160. data/lib/bundler/vendor/uri/lib/uri/ldap.rb +1 -1
  161. data/lib/bundler/vendor/uri/lib/uri/mailto.rb +0 -1
  162. data/lib/bundler/vendor/uri/lib/uri/rfc2396_parser.rb +1 -14
  163. data/lib/bundler/vendor/uri/lib/uri/rfc3986_parser.rb +1 -12
  164. data/lib/bundler/vendor/uri/lib/uri/version.rb +1 -1
  165. data/lib/bundler/vendor/uri/lib/uri/ws.rb +84 -0
  166. data/lib/bundler/vendor/uri/lib/uri/wss.rb +22 -0
  167. data/lib/bundler/vendor/uri/lib/uri.rb +0 -1
  168. data/lib/bundler/vendored_tsort.rb +4 -0
  169. data/lib/bundler/version.rb +1 -1
  170. data/lib/bundler/worker.rb +19 -4
  171. data/lib/bundler.rb +28 -31
  172. metadata +27 -9
  173. data/lib/bundler/gemdeps.rb +0 -29
  174. data/lib/bundler/vendor/connection_pool/lib/connection_pool/monotonic_time.rb +0 -66
@@ -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
 
@@ -33,6 +34,18 @@ module Bundler
33
34
  spec.source == self
34
35
  end
35
36
 
37
+ def local!; end
38
+
39
+ def local_only!; end
40
+
41
+ def cached!; end
42
+
43
+ def remote!; end
44
+
45
+ def add_dependency_names(names)
46
+ @dependency_names = Array(dependency_names) | Array(names)
47
+ end
48
+
36
49
  # it's possible that gems from one source depend on gems from some
37
50
  # other source, so now we download gemspecs and iterate over those
38
51
  # dependencies, looking for gems we don't have info on yet.
@@ -42,6 +55,10 @@ module Bundler
42
55
  specs.dependency_names
43
56
  end
44
57
 
58
+ def spec_names
59
+ specs.spec_names
60
+ end
61
+
45
62
  def include?(other)
46
63
  other == self
47
64
  end
@@ -50,6 +67,10 @@ module Bundler
50
67
  "#<#{self.class}:0x#{object_id} #{self}>"
51
68
  end
52
69
 
70
+ def identifier
71
+ to_s
72
+ end
73
+
53
74
  def path?
54
75
  instance_of?(Bundler::Source::Path)
55
76
  end
@@ -5,24 +5,49 @@ module Bundler
5
5
  attr_reader :path_sources,
6
6
  :git_sources,
7
7
  :plugin_sources,
8
- :global_rubygems_source,
8
+ :global_path_source,
9
9
  :metadata_source
10
10
 
11
+ def global_rubygems_source
12
+ @global_rubygems_source ||= rubygems_aggregate_class.new("allow_local" => true)
13
+ end
14
+
11
15
  def initialize
12
16
  @path_sources = []
13
17
  @git_sources = []
14
18
  @plugin_sources = []
15
19
  @global_rubygems_source = nil
16
- @rubygems_aggregate = rubygems_aggregate_class.new
20
+ @global_path_source = nil
17
21
  @rubygems_sources = []
18
22
  @metadata_source = Source::Metadata.new
23
+
24
+ @merged_gem_lockfile_sections = false
25
+ end
26
+
27
+ def merged_gem_lockfile_sections?
28
+ @merged_gem_lockfile_sections
29
+ end
30
+
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?
38
+ end
39
+
40
+ def implicit_global_source?
41
+ global_rubygems_source.no_remotes?
19
42
  end
20
43
 
21
44
  def add_path_source(options = {})
22
45
  if options["gemspec"]
23
46
  add_source_to_list Source::Gemspec.new(options), path_sources
24
47
  else
25
- add_source_to_list Source::Path.new(options), path_sources
48
+ path_source = add_source_to_list Source::Path.new(options), path_sources
49
+ @global_path_source ||= path_source if options["global"]
50
+ path_source
26
51
  end
27
52
  end
28
53
 
@@ -33,32 +58,31 @@ module Bundler
33
58
  end
34
59
 
35
60
  def add_rubygems_source(options = {})
36
- add_source_to_list Source::Rubygems.new(options), @rubygems_sources
61
+ new_source = Source::Rubygems.new(options)
62
+ return @global_rubygems_source if @global_rubygems_source == new_source
63
+
64
+ add_source_to_list new_source, @rubygems_sources
37
65
  end
38
66
 
39
67
  def add_plugin_source(source, options = {})
40
68
  add_source_to_list Plugin.source(source).new(options), @plugin_sources
41
69
  end
42
70
 
43
- def global_rubygems_source=(uri)
44
- if Bundler.feature_flag.disable_multisource?
45
- @global_rubygems_source ||= rubygems_aggregate_class.new("remotes" => uri)
46
- end
47
- add_rubygems_remote(uri)
48
- end
49
-
50
- def add_rubygems_remote(uri)
51
- return if Bundler.feature_flag.disable_multisource?
52
- @rubygems_aggregate.add_remote(uri)
53
- @rubygems_aggregate
71
+ def add_global_rubygems_remote(uri)
72
+ global_rubygems_source.add_remote(uri)
73
+ global_rubygems_source
54
74
  end
55
75
 
56
76
  def default_source
57
- global_rubygems_source || @rubygems_aggregate
77
+ global_path_source || global_rubygems_source
58
78
  end
59
79
 
60
80
  def rubygems_sources
61
- @rubygems_sources + [default_source]
81
+ non_global_rubygems_sources + [global_rubygems_source]
82
+ end
83
+
84
+ def non_global_rubygems_sources
85
+ @rubygems_sources
62
86
  end
63
87
 
64
88
  def rubygems_remotes
@@ -69,37 +93,51 @@ module Bundler
69
93
  path_sources + git_sources + plugin_sources + rubygems_sources + [metadata_source]
70
94
  end
71
95
 
96
+ def non_default_explicit_sources
97
+ all_sources - [default_source, metadata_source]
98
+ end
99
+
72
100
  def get(source)
73
- source_list_for(source).find {|s| equal_source?(source, s) || equivalent_source?(source, s) }
101
+ source_list_for(source).find {|s| equivalent_source?(source, s) }
74
102
  end
75
103
 
76
104
  def lock_sources
77
- lock_sources = (path_sources + git_sources + plugin_sources).sort_by(&:to_s)
78
- if Bundler.feature_flag.disable_multisource?
79
- lock_sources + rubygems_sources.sort_by(&:to_s)
105
+ lock_other_sources + lock_rubygems_sources
106
+ end
107
+
108
+ def lock_other_sources
109
+ (path_sources + git_sources + plugin_sources).sort_by(&:identifier)
110
+ end
111
+
112
+ def lock_rubygems_sources
113
+ if merged_gem_lockfile_sections?
114
+ [combine_rubygems_sources]
80
115
  else
81
- lock_sources << combine_rubygems_sources
116
+ rubygems_sources.sort_by(&:identifier)
82
117
  end
83
118
  end
84
119
 
85
120
  # Returns true if there are changes
86
121
  def replace_sources!(replacement_sources)
87
- return true if replacement_sources.empty?
122
+ return false if replacement_sources.empty?
88
123
 
89
- [path_sources, git_sources, plugin_sources].each do |source_list|
90
- source_list.map! do |source|
91
- replacement_sources.find {|s| s == source } || source
92
- end
93
- end
124
+ @rubygems_sources, @path_sources, @git_sources, @plugin_sources = map_sources(replacement_sources)
125
+ @global_rubygems_source = global_replacement_source(replacement_sources)
126
+
127
+ different_sources?(lock_sources, replacement_sources)
128
+ end
94
129
 
95
- replacement_rubygems = !Bundler.feature_flag.disable_multisource? &&
96
- replacement_sources.detect {|s| s.is_a?(Source::Rubygems) }
97
- @rubygems_aggregate = replacement_rubygems if replacement_rubygems
130
+ # Returns true if there are changes
131
+ def expired_sources?(replacement_sources)
132
+ return false if replacement_sources.empty?
133
+
134
+ lock_sources = dup_with_replaced_sources(replacement_sources).lock_sources
98
135
 
99
- return true if !equal_sources?(lock_sources, replacement_sources) && !equivalent_sources?(lock_sources, replacement_sources)
100
- return true if replacement_rubygems && rubygems_remotes.sort_by(&:to_s) != replacement_rubygems.remotes.sort_by(&:to_s)
136
+ different_sources?(lock_sources, replacement_sources)
137
+ end
101
138
 
102
- false
139
+ def local_only!
140
+ all_sources.each(&:local_only!)
103
141
  end
104
142
 
105
143
  def cached!
@@ -110,11 +148,33 @@ module Bundler
110
148
  all_sources.each(&:remote!)
111
149
  end
112
150
 
113
- def rubygems_primary_remotes
114
- @rubygems_aggregate.remotes
151
+ private
152
+
153
+ def dup_with_replaced_sources(replacement_sources)
154
+ new_source_list = dup
155
+ new_source_list.replace_sources!(replacement_sources)
156
+ new_source_list
115
157
  end
116
158
 
117
- private
159
+ def map_sources(replacement_sources)
160
+ [@rubygems_sources, @path_sources, @git_sources, @plugin_sources].map do |sources|
161
+ sources.map do |source|
162
+ replacement_sources.find {|s| s == source } || source
163
+ end
164
+ end
165
+ end
166
+
167
+ def global_replacement_source(replacement_sources)
168
+ replacement_source = replacement_sources.find {|s| s == global_rubygems_source }
169
+ return global_rubygems_source unless replacement_source
170
+
171
+ replacement_source.local!
172
+ replacement_source
173
+ end
174
+
175
+ def different_sources?(lock_sources, replacement_sources)
176
+ !equivalent_sources?(lock_sources, replacement_sources)
177
+ end
118
178
 
119
179
  def rubygems_aggregate_class
120
180
  Source::Rubygems
@@ -150,32 +210,12 @@ module Bundler
150
210
  end
151
211
  end
152
212
 
153
- def equal_sources?(lock_sources, replacement_sources)
154
- lock_sources.sort_by(&:to_s) == replacement_sources.sort_by(&:to_s)
155
- end
156
-
157
- def equal_source?(source, other_source)
158
- source == other_source
159
- end
160
-
161
- def equivalent_source?(source, other_source)
162
- return false unless Bundler.settings[:allow_deployment_source_credential_changes] && source.is_a?(Source::Rubygems)
163
-
164
- equivalent_rubygems_sources?([source], [other_source])
165
- end
166
-
167
213
  def equivalent_sources?(lock_sources, replacement_sources)
168
- return false unless Bundler.settings[:allow_deployment_source_credential_changes]
169
-
170
- lock_rubygems_sources, lock_other_sources = lock_sources.partition {|s| s.is_a?(Source::Rubygems) }
171
- replacement_rubygems_sources, replacement_other_sources = replacement_sources.partition {|s| s.is_a?(Source::Rubygems) }
172
-
173
- equivalent_rubygems_sources?(lock_rubygems_sources, replacement_rubygems_sources) && equal_sources?(lock_other_sources, replacement_other_sources)
214
+ lock_sources.sort_by(&:identifier) == replacement_sources.sort_by(&:identifier)
174
215
  end
175
216
 
176
- def equivalent_rubygems_sources?(lock_sources, replacement_sources)
177
- actual_remotes = replacement_sources.map(&:remotes).flatten.uniq
178
- lock_sources.all? {|s| s.equivalent_remotes?(actual_remotes) }
217
+ def equivalent_source?(source, other_source)
218
+ source == other_source
179
219
  end
180
220
  end
181
221
  end
@@ -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
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "tsort"
3
+ require_relative "vendored_tsort"
4
4
 
5
5
  module Bundler
6
6
  class SpecSet
@@ -11,21 +11,20 @@ module Bundler
11
11
  @specs = specs
12
12
  end
13
13
 
14
- def for(dependencies, skip = [], check = false, match_current_platform = false, raise_on_missing = true)
14
+ def for(dependencies, check = false, match_current_platform = false)
15
15
  handled = []
16
16
  deps = dependencies.dup
17
17
  specs = []
18
- skip += ["bundler"]
19
18
 
20
19
  loop do
21
20
  break unless dep = deps.shift
22
- next if handled.include?(dep) || skip.include?(dep.name)
21
+ next if handled.any?{|d| d.name == dep.name && (match_current_platform || d.__platform == dep.__platform) } || dep.name == "bundler"
23
22
 
24
23
  handled << dep
25
24
 
26
25
  specs_for_dep = spec_for_dependency(dep, match_current_platform)
27
26
  if specs_for_dep.any?
28
- specs += specs_for_dep
27
+ match_current_platform ? specs += specs_for_dep : specs |= specs_for_dep
29
28
 
30
29
  specs_for_dep.first.dependencies.each do |d|
31
30
  next if d.type == :development
@@ -34,11 +33,6 @@ module Bundler
34
33
  end
35
34
  elsif check
36
35
  return false
37
- elsif raise_on_missing
38
- others = lookup[dep.name] if match_current_platform
39
- message = "Unable to find a spec satisfying #{dep} in the set. Perhaps the lockfile is corrupted?"
40
- message += " Found #{others.join(", ")} that did not match the current platform." if others && !others.empty?
41
- raise GemNotFound, message
42
36
  end
43
37
  end
44
38
 
@@ -46,11 +40,7 @@ module Bundler
46
40
  specs << spec
47
41
  end
48
42
 
49
- check ? true : SpecSet.new(specs)
50
- end
51
-
52
- def valid_for?(deps)
53
- self.for(deps, [], true)
43
+ check ? true : specs
54
44
  end
55
45
 
56
46
  def [](key)
@@ -76,32 +66,24 @@ module Bundler
76
66
  lookup.dup
77
67
  end
78
68
 
79
- def materialize(deps, missing_specs = nil)
80
- materialized = self.for(deps, [], false, true, !missing_specs).to_a
81
- deps = materialized.map(&:name).uniq
69
+ def materialize(deps)
70
+ materialized = self.for(deps, false, true)
71
+
82
72
  materialized.map! do |s|
83
73
  next s unless s.is_a?(LazySpecification)
84
- s.source.dependency_names = deps if s.source.respond_to?(:dependency_names=)
85
- spec = s.__materialize__
86
- unless spec
87
- unless missing_specs
88
- raise GemNotFound, "Could not find #{s.full_name} in any of the sources"
89
- end
90
- missing_specs << s
91
- end
92
- spec
74
+ s.source.local!
75
+ s.__materialize__ || s
93
76
  end
94
- SpecSet.new(missing_specs ? materialized.compact : materialized)
77
+ SpecSet.new(materialized)
95
78
  end
96
79
 
97
80
  # Materialize for all the specs in the spec set, regardless of what platform they're for
98
81
  # This is in contrast to how for does platform filtering (and specifically different from how `materialize` calls `for` only for the current platform)
99
82
  # @return [Array<Gem::Specification>]
100
83
  def materialized_for_all_platforms
101
- names = @specs.map(&:name).uniq
102
84
  @specs.map do |s|
103
85
  next s unless s.is_a?(LazySpecification)
104
- s.source.dependency_names = names if s.source.respond_to?(:dependency_names=)
86
+ s.source.local!
105
87
  s.source.remote!
106
88
  spec = s.__materialize__
107
89
  raise GemNotFound, "Could not find #{s.full_name} in any of the sources" unless spec
@@ -109,6 +91,10 @@ module Bundler
109
91
  end
110
92
  end
111
93
 
94
+ def missing_specs
95
+ @specs.select {|s| s.is_a?(LazySpecification) }
96
+ end
97
+
112
98
  def merge(set)
113
99
  arr = sorted.dup
114
100
  set.each do |set_spec|
@@ -186,7 +172,7 @@ module Bundler
186
172
  def spec_for_dependency(dep, match_current_platform)
187
173
  specs_for_platforms = lookup[dep.name]
188
174
  if match_current_platform
189
- GemHelpers.select_best_platform_match(specs_for_platforms, Bundler.local_platform)
175
+ GemHelpers.select_best_platform_match(specs_for_platforms.select{|s| Gem::Platform.match_spec?(s) }, Bundler.local_platform)
190
176
  else
191
177
  GemHelpers.select_best_platform_match(specs_for_platforms, dep.__platform)
192
178
  end
@@ -26,11 +26,19 @@ module Bundler
26
26
 
27
27
  # @!group Stub Delegates
28
28
 
29
+ def manually_installed?
30
+ # This is for manually installed gems which are gems that were fixed in place after a
31
+ # failed installation. Once the issue was resolved, the user then manually created
32
+ # the gem specification using the instructions provided by `gem help install`
33
+ installed_by_version == Gem::Version.new(0)
34
+ end
35
+
29
36
  # This is defined directly to avoid having to loading the full spec
30
37
  def missing_extensions?
31
38
  return false if default_gem?
32
39
  return false if extensions.empty?
33
40
  return false if File.exist? gem_build_complete_path
41
+ return false if manually_installed?
34
42
 
35
43
  true
36
44
  end
@@ -60,20 +60,20 @@ m = Module.new do
60
60
  Regexp.last_match(1)
61
61
  end
62
62
 
63
- def bundler_version
64
- @bundler_version ||=
63
+ def bundler_requirement
64
+ @bundler_requirement ||=
65
65
  env_var_version || cli_arg_version ||
66
- lockfile_version
66
+ bundler_requirement_for(lockfile_version)
67
67
  end
68
68
 
69
- def bundler_requirement
70
- return "#{Gem::Requirement.default}.a" unless bundler_version
69
+ def bundler_requirement_for(version)
70
+ return "#{Gem::Requirement.default}.a" unless version
71
71
 
72
- bundler_gem_version = Gem::Version.new(bundler_version)
72
+ bundler_gem_version = Gem::Version.new(version)
73
73
 
74
74
  requirement = bundler_gem_version.approximate_recommendation
75
75
 
76
- return requirement unless Gem::Version.new(Gem::VERSION) < Gem::Version.new("2.7.0")
76
+ return requirement unless Gem.rubygems_version < Gem::Version.new("2.7.0")
77
77
 
78
78
  requirement += ".a" if bundler_gem_version.prerelease?
79
79
 
@@ -2,6 +2,4 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
6
-
7
5
  # gem "rails"
@@ -1,8 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # A sample gems.rb
4
3
  source "https://rubygems.org"
5
4
 
6
- git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
7
-
8
5
  # gem "rails"
@@ -14,7 +14,10 @@ gem "rake-compiler"
14
14
 
15
15
  gem "<%= config[:test] %>", "~> <%= config[:test_framework_version] %>"
16
16
  <%- end -%>
17
- <%- if config[:rubocop] -%>
17
+ <%- if config[:linter] == "rubocop" -%>
18
18
 
19
- gem "rubocop", "~> <%= config[:rubocop_version] %>"
19
+ gem "rubocop", "~> <%= config[:linter_version] %>"
20
+ <%- elsif config[:linter] == "standard" -%>
21
+
22
+ gem "standard", "~> <%= config[:linter_version] %>"
20
23
  <%- end -%>
@@ -29,19 +29,21 @@ TODO: Write usage instructions here
29
29
  After checking out the repo, run `bin/setup` to install dependencies.<% if config[:test] %> Then, run `rake <%= config[:test].sub('mini', '').sub('rspec', 'spec') %>` to run the tests.<% end %> You can also run `bin/console` for an interactive prompt that will allow you to experiment.<% if config[:bin] %> Run `bundle exec <%= config[:name] %>` to use the gem in this directory, ignoring other installed copies of this gem.<% end %>
30
30
 
31
31
  To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
32
+ <% if config[:git] -%>
32
33
 
33
34
  ## Contributing
34
35
 
35
- Bug reports and pull requests are welcome on GitHub at https://github.com/<%= config[:github_username] %>/<%= config[:name] %>.<% if config[:coc] %> This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/<%= config[:github_username] %>/<%= config[:name] %>/blob/master/CODE_OF_CONDUCT.md).<% end %>
36
+ Bug reports and pull requests are welcome on GitHub at https://github.com/<%= config[:github_username] %>/<%= config[:name] %>.<% if config[:coc] %> This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/<%= config[:github_username] %>/<%= config[:name] %>/blob/<%= config[:git_default_branch] %>/CODE_OF_CONDUCT.md).<% end %>
37
+ <% end -%>
36
38
  <% if config[:mit] -%>
37
39
 
38
40
  ## License
39
41
 
40
42
  The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
41
43
  <% end -%>
42
- <% if config[:coc] -%>
44
+ <% if config[:git] && config[:coc] -%>
43
45
 
44
46
  ## Code of Conduct
45
47
 
46
- Everyone interacting in the <%= config[:constant_name] %> project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/<%= config[:github_username] %>/<%= config[:name] %>/blob/master/CODE_OF_CONDUCT.md).
48
+ Everyone interacting in the <%= config[:constant_name] %> project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/<%= config[:github_username] %>/<%= config[:name] %>/blob/<%= config[:git_default_branch] %>/CODE_OF_CONDUCT.md).
47
49
  <% end -%>
@@ -3,7 +3,16 @@
3
3
  require "bundler/gem_tasks"
4
4
  <% default_task_names = [config[:test_task]].compact -%>
5
5
  <% case config[:test] -%>
6
- <% when "minitest", "test-unit" -%>
6
+ <% when "minitest" -%>
7
+ require "rake/testtask"
8
+
9
+ Rake::TestTask.new(:test) do |t|
10
+ t.libs << "test"
11
+ t.libs << "lib"
12
+ t.test_files = FileList["test/**/test_*.rb"]
13
+ end
14
+
15
+ <% when "test-unit" -%>
7
16
  require "rake/testtask"
8
17
 
9
18
  Rake::TestTask.new(:test) do |t|
@@ -18,12 +27,16 @@ require "rspec/core/rake_task"
18
27
  RSpec::Core::RakeTask.new(:spec)
19
28
 
20
29
  <% end -%>
21
- <% if config[:rubocop] -%>
30
+ <% if config[:linter] == "rubocop" -%>
22
31
  <% default_task_names << :rubocop -%>
23
32
  require "rubocop/rake_task"
24
33
 
25
34
  RuboCop::RakeTask.new
26
35
 
36
+ <% elsif config[:linter] == "standard" -%>
37
+ <% default_task_names << :standard -%>
38
+ require "standard/rake"
39
+
27
40
  <% end -%>
28
41
  <% if config[:ext] -%>
29
42
  <% default_task_names.unshift(:clobber, :compile) -%>
@@ -1,18 +1,27 @@
1
1
  name: Ruby
2
2
 
3
- on: [push,pull_request]
3
+ on:
4
+ push:
5
+ branches:
6
+ - <%= config[:git_default_branch] %>
7
+
8
+ pull_request:
4
9
 
5
10
  jobs:
6
11
  build:
7
12
  runs-on: ubuntu-latest
13
+ name: Ruby ${{ matrix.ruby }}
14
+ strategy:
15
+ matrix:
16
+ ruby:
17
+ - '<%= RUBY_VERSION %>'
18
+
8
19
  steps:
9
20
  - uses: actions/checkout@v2
10
21
  - name: Set up Ruby
11
22
  uses: ruby/setup-ruby@v1
12
23
  with:
13
- ruby-version: <%= RUBY_VERSION %>
24
+ ruby-version: ${{ matrix.ruby }}
25
+ bundler-cache: true
14
26
  - name: Run the default task
15
- run: |
16
- gem install bundler -v <%= Bundler::VERSION %>
17
- bundle install
18
- bundle exec rake
27
+ run: bundle exec rake