bundler 2.2.11 → 2.3.26

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 (211) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +721 -5
  3. data/README.md +1 -1
  4. data/bundler.gemspec +8 -11
  5. data/exe/bundle +7 -8
  6. data/exe/bundler +1 -1
  7. data/lib/bundler/.document +1 -0
  8. data/lib/bundler/build_metadata.rb +3 -3
  9. data/lib/bundler/cli/cache.rb +1 -1
  10. data/lib/bundler/cli/check.rb +4 -2
  11. data/lib/bundler/cli/common.rb +17 -3
  12. data/lib/bundler/cli/config.rb +10 -1
  13. data/lib/bundler/cli/doctor.rb +24 -5
  14. data/lib/bundler/cli/exec.rb +1 -6
  15. data/lib/bundler/cli/gem.rb +130 -26
  16. data/lib/bundler/cli/info.rb +27 -6
  17. data/lib/bundler/cli/init.rb +5 -1
  18. data/lib/bundler/cli/install.rb +23 -54
  19. data/lib/bundler/cli/issue.rb +4 -3
  20. data/lib/bundler/cli/list.rb +7 -1
  21. data/lib/bundler/cli/lock.rb +5 -1
  22. data/lib/bundler/cli/open.rb +1 -2
  23. data/lib/bundler/cli/outdated.rb +22 -14
  24. data/lib/bundler/cli/platform.rb +2 -2
  25. data/lib/bundler/cli/remove.rb +1 -2
  26. data/lib/bundler/cli/show.rb +1 -1
  27. data/lib/bundler/cli/update.rb +17 -8
  28. data/lib/bundler/cli.rb +51 -63
  29. data/lib/bundler/compact_index_client/cache.rb +0 -9
  30. data/lib/bundler/compact_index_client/updater.rb +26 -14
  31. data/lib/bundler/compact_index_client.rb +2 -8
  32. data/lib/bundler/current_ruby.rb +17 -6
  33. data/lib/bundler/definition.rb +260 -362
  34. data/lib/bundler/dependency.rb +23 -71
  35. data/lib/bundler/digest.rb +71 -0
  36. data/lib/bundler/dsl.rb +72 -76
  37. data/lib/bundler/endpoint_specification.rb +19 -13
  38. data/lib/bundler/env.rb +1 -1
  39. data/lib/bundler/environment_preserver.rb +4 -1
  40. data/lib/bundler/errors.rb +29 -3
  41. data/lib/bundler/feature_flag.rb +0 -5
  42. data/lib/bundler/fetcher/base.rb +6 -8
  43. data/lib/bundler/fetcher/compact_index.rb +10 -15
  44. data/lib/bundler/fetcher/downloader.rb +9 -6
  45. data/lib/bundler/fetcher/index.rb +0 -27
  46. data/lib/bundler/fetcher.rb +22 -23
  47. data/lib/bundler/friendly_errors.rb +26 -36
  48. data/lib/bundler/gem_helper.rb +21 -16
  49. data/lib/bundler/gem_helpers.rb +9 -2
  50. data/lib/bundler/gem_version_promoter.rb +14 -25
  51. data/lib/bundler/index.rb +11 -46
  52. data/lib/bundler/injector.rb +18 -4
  53. data/lib/bundler/inline.rb +4 -13
  54. data/lib/bundler/installer/gem_installer.rb +16 -21
  55. data/lib/bundler/installer/parallel_installer.rb +36 -15
  56. data/lib/bundler/installer/standalone.rb +42 -10
  57. data/lib/bundler/installer.rb +25 -41
  58. data/lib/bundler/lazy_specification.rb +52 -30
  59. data/lib/bundler/lockfile_generator.rb +2 -2
  60. data/lib/bundler/lockfile_parser.rb +18 -43
  61. data/lib/bundler/man/bundle-add.1 +21 -5
  62. data/lib/bundler/man/bundle-add.1.ronn +16 -4
  63. data/lib/bundler/man/bundle-binstubs.1 +1 -1
  64. data/lib/bundler/man/bundle-cache.1 +7 -1
  65. data/lib/bundler/man/bundle-cache.1.ronn +7 -0
  66. data/lib/bundler/man/bundle-check.1 +1 -1
  67. data/lib/bundler/man/bundle-clean.1 +2 -2
  68. data/lib/bundler/man/bundle-clean.1.ronn +1 -1
  69. data/lib/bundler/man/bundle-config.1 +49 -22
  70. data/lib/bundler/man/bundle-config.1.ronn +49 -30
  71. data/lib/bundler/man/bundle-console.1 +53 -0
  72. data/lib/bundler/man/bundle-console.1.ronn +44 -0
  73. data/lib/bundler/man/bundle-doctor.1 +1 -1
  74. data/lib/bundler/man/bundle-exec.1 +2 -2
  75. data/lib/bundler/man/bundle-exec.1.ronn +1 -1
  76. data/lib/bundler/man/bundle-gem.1 +14 -1
  77. data/lib/bundler/man/bundle-gem.1.ronn +16 -0
  78. data/lib/bundler/man/bundle-help.1 +13 -0
  79. data/lib/bundler/man/bundle-help.1.ronn +12 -0
  80. data/lib/bundler/man/bundle-info.1 +1 -1
  81. data/lib/bundler/man/bundle-init.1 +1 -1
  82. data/lib/bundler/man/bundle-inject.1 +5 -2
  83. data/lib/bundler/man/bundle-inject.1.ronn +3 -1
  84. data/lib/bundler/man/bundle-install.1 +6 -2
  85. data/lib/bundler/man/bundle-install.1.ronn +8 -2
  86. data/lib/bundler/man/bundle-list.1 +1 -1
  87. data/lib/bundler/man/bundle-lock.1 +1 -1
  88. data/lib/bundler/man/bundle-open.1 +1 -1
  89. data/lib/bundler/man/bundle-outdated.1 +3 -10
  90. data/lib/bundler/man/bundle-outdated.1.ronn +1 -10
  91. data/lib/bundler/man/bundle-platform.1 +16 -6
  92. data/lib/bundler/man/bundle-platform.1.ronn +14 -7
  93. data/lib/bundler/man/bundle-plugin.1 +81 -0
  94. data/lib/bundler/man/bundle-plugin.1.ronn +59 -0
  95. data/lib/bundler/man/bundle-pristine.1 +1 -1
  96. data/lib/bundler/man/bundle-remove.1 +1 -1
  97. data/lib/bundler/man/bundle-show.1 +1 -1
  98. data/lib/bundler/man/bundle-update.1 +5 -5
  99. data/lib/bundler/man/bundle-update.1.ronn +5 -4
  100. data/lib/bundler/man/bundle-version.1 +35 -0
  101. data/lib/bundler/man/bundle-version.1.ronn +24 -0
  102. data/lib/bundler/man/bundle-viz.1 +4 -1
  103. data/lib/bundler/man/bundle-viz.1.ronn +2 -0
  104. data/lib/bundler/man/bundle.1 +15 -10
  105. data/lib/bundler/man/bundle.1.ronn +12 -7
  106. data/lib/bundler/man/gemfile.5 +117 -80
  107. data/lib/bundler/man/gemfile.5.ronn +105 -84
  108. data/lib/bundler/man/index.txt +4 -0
  109. data/lib/bundler/match_metadata.rb +13 -0
  110. data/lib/bundler/match_platform.rb +0 -1
  111. data/lib/bundler/match_remote_metadata.rb +29 -0
  112. data/lib/bundler/plugin/api/source.rb +24 -8
  113. data/lib/bundler/plugin/index.rb +4 -1
  114. data/lib/bundler/plugin/installer/git.rb +0 -4
  115. data/lib/bundler/plugin/installer/rubygems.rb +0 -4
  116. data/lib/bundler/plugin/installer.rb +10 -10
  117. data/lib/bundler/plugin/source_list.rb +4 -0
  118. data/lib/bundler/plugin.rb +30 -8
  119. data/lib/bundler/process_lock.rb +1 -1
  120. data/lib/bundler/remote_specification.rb +10 -4
  121. data/lib/bundler/resolver/base.rb +50 -0
  122. data/lib/bundler/resolver/spec_group.rb +31 -73
  123. data/lib/bundler/resolver.rb +193 -292
  124. data/lib/bundler/retry.rb +1 -1
  125. data/lib/bundler/ruby_dsl.rb +1 -1
  126. data/lib/bundler/ruby_version.rb +5 -18
  127. data/lib/bundler/rubygems_ext.rb +160 -26
  128. data/lib/bundler/rubygems_gem_installer.rb +86 -9
  129. data/lib/bundler/rubygems_integration.rb +46 -93
  130. data/lib/bundler/runtime.rb +18 -12
  131. data/lib/bundler/self_manager.rb +168 -0
  132. data/lib/bundler/settings.rb +98 -22
  133. data/lib/bundler/setup.rb +2 -2
  134. data/lib/bundler/shared_helpers.rb +15 -31
  135. data/lib/bundler/source/git/git_proxy.rb +8 -6
  136. data/lib/bundler/source/git.rb +29 -13
  137. data/lib/bundler/source/metadata.rb +3 -7
  138. data/lib/bundler/source/path/installer.rb +1 -1
  139. data/lib/bundler/source/path.rb +3 -1
  140. data/lib/bundler/source/rubygems.rb +199 -182
  141. data/lib/bundler/source/rubygems_aggregate.rb +68 -0
  142. data/lib/bundler/source.rb +24 -4
  143. data/lib/bundler/source_list.rb +104 -60
  144. data/lib/bundler/source_map.rb +71 -0
  145. data/lib/bundler/spec_set.rb +58 -52
  146. data/lib/bundler/stub_specification.rb +13 -3
  147. data/lib/bundler/templates/Executable +2 -4
  148. data/lib/bundler/templates/Executable.bundler +8 -8
  149. data/lib/bundler/templates/Executable.standalone +2 -4
  150. data/lib/bundler/templates/Gemfile +0 -2
  151. data/lib/bundler/templates/gems.rb +0 -3
  152. data/lib/bundler/templates/newgem/Gemfile.tt +5 -2
  153. data/lib/bundler/templates/newgem/README.md.tt +8 -12
  154. data/lib/bundler/templates/newgem/Rakefile.tt +15 -2
  155. data/lib/bundler/templates/newgem/github/workflows/main.yml.tt +16 -7
  156. data/lib/bundler/templates/newgem/gitlab-ci.yml.tt +5 -4
  157. data/lib/bundler/templates/newgem/newgem.gemspec.tt +19 -17
  158. data/lib/bundler/templates/newgem/sig/newgem.rbs.tt +8 -0
  159. data/lib/bundler/templates/newgem/standard.yml.tt +3 -0
  160. data/lib/bundler/templates/newgem/test/minitest/{newgem_test.rb.tt → test_newgem.rb.tt} +1 -1
  161. data/lib/bundler/ui/shell.rb +1 -1
  162. data/lib/bundler/vendor/.document +1 -0
  163. data/lib/bundler/vendor/connection_pool/LICENSE +20 -0
  164. data/lib/bundler/vendor/connection_pool/lib/connection_pool/timed_stack.rb +19 -21
  165. data/lib/bundler/vendor/connection_pool/lib/connection_pool/version.rb +1 -1
  166. data/lib/bundler/vendor/connection_pool/lib/connection_pool/wrapper.rb +57 -0
  167. data/lib/bundler/vendor/connection_pool/lib/connection_pool.rb +39 -74
  168. data/lib/bundler/vendor/fileutils/LICENSE.txt +22 -0
  169. data/lib/bundler/vendor/molinillo/LICENSE +9 -0
  170. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb +3 -3
  171. data/lib/bundler/vendor/molinillo/lib/molinillo/errors.rb +32 -26
  172. data/lib/bundler/vendor/molinillo/lib/molinillo/gem_metadata.rb +1 -1
  173. data/lib/bundler/vendor/molinillo/lib/molinillo/modules/specification_provider.rb +1 -1
  174. data/lib/bundler/vendor/net-http-persistent/README.rdoc +82 -0
  175. data/lib/bundler/vendor/thor/LICENSE.md +20 -0
  176. data/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb +5 -5
  177. data/lib/bundler/vendor/thor/lib/thor/actions/inject_into_file.rb +1 -2
  178. data/lib/bundler/vendor/thor/lib/thor/actions.rb +6 -2
  179. data/lib/bundler/vendor/thor/lib/thor/core_ext/hash_with_indifferent_access.rb +6 -0
  180. data/lib/bundler/vendor/thor/lib/thor/error.rb +9 -4
  181. data/lib/bundler/vendor/thor/lib/thor/parser/options.rb +19 -1
  182. data/lib/bundler/vendor/thor/lib/thor/shell/basic.rb +22 -4
  183. data/lib/bundler/vendor/thor/lib/thor/shell.rb +1 -1
  184. data/lib/bundler/vendor/thor/lib/thor/util.rb +1 -1
  185. data/lib/bundler/vendor/thor/lib/thor/version.rb +1 -1
  186. data/lib/bundler/vendor/tmpdir/lib/tmpdir.rb +1 -1
  187. data/lib/bundler/vendor/tsort/LICENSE.txt +22 -0
  188. data/lib/bundler/vendor/tsort/lib/tsort.rb +452 -0
  189. data/lib/bundler/vendor/uri/LICENSE.txt +22 -0
  190. data/lib/bundler/vendor/uri/lib/uri/common.rb +17 -80
  191. data/lib/bundler/vendor/uri/lib/uri/ftp.rb +0 -1
  192. data/lib/bundler/vendor/uri/lib/uri/generic.rb +5 -6
  193. data/lib/bundler/vendor/uri/lib/uri/http.rb +0 -1
  194. data/lib/bundler/vendor/uri/lib/uri/https.rb +0 -1
  195. data/lib/bundler/vendor/uri/lib/uri/ldap.rb +1 -1
  196. data/lib/bundler/vendor/uri/lib/uri/mailto.rb +0 -1
  197. data/lib/bundler/vendor/uri/lib/uri/rfc2396_parser.rb +1 -14
  198. data/lib/bundler/vendor/uri/lib/uri/rfc3986_parser.rb +1 -12
  199. data/lib/bundler/vendor/uri/lib/uri/version.rb +1 -1
  200. data/lib/bundler/vendor/uri/lib/uri/ws.rb +84 -0
  201. data/lib/bundler/vendor/uri/lib/uri/wss.rb +22 -0
  202. data/lib/bundler/vendor/uri/lib/uri.rb +0 -1
  203. data/lib/bundler/vendored_tsort.rb +4 -0
  204. data/lib/bundler/version.rb +1 -1
  205. data/lib/bundler/worker.rb +19 -4
  206. data/lib/bundler.rb +46 -39
  207. metadata +39 -12
  208. data/lib/bundler/dep_proxy.rb +0 -55
  209. data/lib/bundler/gemdeps.rb +0 -29
  210. data/lib/bundler/psyched_yaml.rb +0 -22
  211. data/lib/bundler/vendor/connection_pool/lib/connection_pool/monotonic_time.rb +0 -66
data/README.md CHANGED
@@ -32,7 +32,7 @@ See [bundler.io](https://bundler.io) for the full documentation.
32
32
 
33
33
  For help with common problems, see [TROUBLESHOOTING](doc/TROUBLESHOOTING.md).
34
34
 
35
- Still stuck? Try [filing an issue](doc/contributing/ISSUES.md).
35
+ Still stuck? Try [filing an issue](https://github.com/rubygems/rubygems/issues/new?labels=Bundler&template=bundler-related-issue.md).
36
36
 
37
37
  ### Other questions
38
38
 
data/bundler.gemspec CHANGED
@@ -22,25 +22,22 @@ Gem::Specification.new do |s|
22
22
  s.summary = "The best way to manage your application's dependencies"
23
23
  s.description = "Bundler manages an application's dependencies through its entire life, across many machines, systematically and repeatably"
24
24
 
25
- if s.respond_to?(:metadata=)
26
- s.metadata = {
27
- "bug_tracker_uri" => "https://github.com/rubygems/rubygems/issues?q=is%3Aopen+is%3Aissue+label%3ABundler",
28
- "changelog_uri" => "https://github.com/rubygems/rubygems/blob/master/bundler/CHANGELOG.md",
29
- "homepage_uri" => "https://bundler.io/",
30
- "source_code_uri" => "https://github.com/rubygems/rubygems/",
31
- }
32
- end
25
+ s.metadata = {
26
+ "bug_tracker_uri" => "https://github.com/rubygems/rubygems/issues?q=is%3Aopen+is%3Aissue+label%3ABundler",
27
+ "changelog_uri" => "https://github.com/rubygems/rubygems/blob/master/bundler/CHANGELOG.md",
28
+ "homepage_uri" => "https://bundler.io/",
29
+ "source_code_uri" => "https://github.com/rubygems/rubygems/tree/master/bundler",
30
+ }
33
31
 
34
32
  s.required_ruby_version = ">= 2.3.0"
35
33
  s.required_rubygems_version = ">= 2.5.2"
36
34
 
37
- s.files = Dir.glob("{lib,exe}/**/*", File::FNM_DOTMATCH).reject {|f| File.directory?(f) }
35
+ s.files = Dir.glob("lib/bundler{.rb,/**/*}", File::FNM_DOTMATCH).reject {|f| File.directory?(f) }
38
36
 
39
- # Include the CHANGELOG.md, LICENSE.md, README.md manually
40
- s.files += %w[CHANGELOG.md LICENSE.md README.md]
41
37
  # include the gemspec itself because warbler breaks w/o it
42
38
  s.files += %w[bundler.gemspec]
43
39
 
40
+ s.files += %w[CHANGELOG.md LICENSE.md README.md]
44
41
  s.bindir = "exe"
45
42
  s.executables = %w[bundle bundler]
46
43
  s.require_paths = ["lib"]
data/exe/bundle CHANGED
@@ -18,14 +18,13 @@ end
18
18
  # Workaround for non-activated bundler spec due to missing https://github.com/rubygems/rubygems/commit/4e306d7bcdee924b8d80ca9db6125aa59ee4e5a3
19
19
  gem "bundler", Bundler::VERSION if Gem.rubygems_version < Gem::Version.new("2.6.2")
20
20
 
21
- # Check if an older version of bundler is installed
22
- $LOAD_PATH.each do |path|
23
- next unless path =~ %r{/bundler-0\.(\d+)} && $1.to_i < 9
24
- err = String.new
25
- err << "Looks like you have a version of bundler that's older than 0.9.\n"
26
- err << "Please remove your old versions.\n"
27
- err << "An easy way to do this is by running `gem cleanup bundler`."
28
- abort(err)
21
+ if Gem.rubygems_version < Gem::Version.new("3.2.3") && Gem.ruby_version < Gem::Version.new("2.6.a") && !ENV["BUNDLER_NO_OLD_RUBYGEMS_WARNING"]
22
+ Bundler.ui.warn \
23
+ "Your RubyGems version (#{Gem::VERSION}) has a bug that prevents " \
24
+ "`required_ruby_version` from working for Bundler. Any scripts that use " \
25
+ "`gem install bundler` will break as soon as Bundler drops support for " \
26
+ "your Ruby version. Please upgrade RubyGems to avoid future breakage " \
27
+ "and silence this warning by running `gem update --system 3.2.3`"
29
28
  end
30
29
 
31
30
  if File.exist?(base_path)
data/exe/bundler CHANGED
@@ -1,4 +1,4 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
 
4
- load File.expand_path("../bundle", __FILE__)
4
+ load File.expand_path("bundle", __dir__)
@@ -0,0 +1 @@
1
+ # not in RDoc
@@ -4,8 +4,8 @@ module Bundler
4
4
  # Represents metadata from when the Bundler gem was built.
5
5
  module BuildMetadata
6
6
  # begin ivars
7
- @built_at = "2021-02-17".freeze
8
- @git_commit_sha = "6ca677a0eb".freeze
7
+ @built_at = "2022-11-17".freeze
8
+ @git_commit_sha = "23ec5b8501".freeze
9
9
  @release = true
10
10
  # end ivars
11
11
 
@@ -29,7 +29,7 @@ module Bundler
29
29
 
30
30
  # If Bundler has been installed without its .git directory and without a
31
31
  # commit instance variable then we can't determine its commits SHA.
32
- git_dir = File.join(File.expand_path("../../../..", __FILE__), ".git")
32
+ git_dir = File.expand_path("../../../.git", __dir__)
33
33
  if File.directory?(git_dir)
34
34
  return @git_commit_sha = Dir.chdir(git_dir) { `git rev-parse --short HEAD`.strip.freeze }
35
35
  end
@@ -9,7 +9,7 @@ module Bundler
9
9
  end
10
10
 
11
11
  def run
12
- Bundler.ui.level = "error" if options[:quiet]
12
+ Bundler.ui.level = "warn" if options[:quiet]
13
13
  Bundler.settings.set_command_option_if_given :path, options[:path]
14
14
  Bundler.settings.set_command_option_if_given :cache_path, options["cache-path"]
15
15
 
@@ -11,9 +11,11 @@ module Bundler
11
11
  def run
12
12
  Bundler.settings.set_command_option_if_given :path, options[:path]
13
13
 
14
+ definition = Bundler.definition
15
+ definition.validate_runtime!
16
+
14
17
  begin
15
- definition = Bundler.definition
16
- definition.validate_runtime!
18
+ definition.resolve_only_locally!
17
19
  not_installed = definition.missing_specs
18
20
  rescue GemNotFound, VersionConflict
19
21
  Bundler.ui.error "Bundler can't satisfy your Gemfile's dependencies."
@@ -15,6 +15,7 @@ module Bundler
15
15
  end
16
16
 
17
17
  def self.output_fund_metadata_summary
18
+ return if Bundler.settings["ignore_funding_requests"]
18
19
  definition = Bundler.definition
19
20
  current_dependencies = definition.requested_dependencies
20
21
  current_specs = definition.specs
@@ -36,10 +37,15 @@ module Bundler
36
37
  def self.without_groups_message(command)
37
38
  command_in_past_tense = command == :install ? "installed" : "updated"
38
39
  groups = Bundler.settings[:without]
40
+ "Gems in the #{verbalize_groups(groups)} were not #{command_in_past_tense}."
41
+ end
42
+
43
+ def self.verbalize_groups(groups)
44
+ groups.map! {|g| "'#{g}'" }
39
45
  group_list = [groups[0...-1].join(", "), groups[-1..-1]].
40
46
  reject {|s| s.to_s.empty? }.join(" and ")
41
47
  group_str = groups.size == 1 ? "group" : "groups"
42
- "Gems in the #{group_str} #{group_list} were not #{command_in_past_tense}."
48
+ "#{group_str} #{group_list}"
43
49
  end
44
50
 
45
51
  def self.select_spec(name, regex_match = nil)
@@ -53,7 +59,13 @@ module Bundler
53
59
 
54
60
  case specs.count
55
61
  when 0
56
- raise GemNotFound, gem_not_found_message(name, Bundler.definition.dependencies)
62
+ dep_in_other_group = Bundler.definition.current_dependencies.find {|dep|dep.name == name }
63
+
64
+ if dep_in_other_group
65
+ raise GemNotFound, "Could not find gem '#{name}', because it's in the #{verbalize_groups(dep_in_other_group.groups)}, configured to be ignored."
66
+ else
67
+ raise GemNotFound, gem_not_found_message(name, Bundler.definition.dependencies)
68
+ end
57
69
  when 1
58
70
  specs.first
59
71
  else
@@ -83,6 +95,8 @@ module Bundler
83
95
  end
84
96
 
85
97
  def self.ensure_all_gems_in_lockfile!(names, locked_gems = Bundler.locked_gems)
98
+ return unless locked_gems
99
+
86
100
  locked_names = locked_gems.specs.map(&:name).uniq
87
101
  names.-(locked_names).each do |g|
88
102
  raise GemNotFound, gem_not_found_message(g, locked_names)
@@ -96,7 +110,7 @@ module Bundler
96
110
 
97
111
  definition.gem_version_promoter.tap do |gvp|
98
112
  gvp.level = patch_level.first || :major
99
- gvp.strict = options[:strict] || options["update-strict"] || options["filter-strict"]
113
+ gvp.strict = options[:strict] || options["filter-strict"]
100
114
  end
101
115
  end
102
116
 
@@ -180,7 +180,7 @@ module Bundler
180
180
  scopes = %w[global local].select {|s| options[s] }
181
181
  case scopes.size
182
182
  when 0
183
- @scope = "global"
183
+ @scope = inside_app? ? "local" : "global"
184
184
  @explicit_scope = false
185
185
  when 1
186
186
  @scope = scopes.first
@@ -189,6 +189,15 @@ module Bundler
189
189
  "The options #{scopes.join " and "} were specified. Please only use one of the switches at a time."
190
190
  end
191
191
  end
192
+
193
+ private
194
+
195
+ def inside_app?
196
+ Bundler.root
197
+ true
198
+ rescue GemfileNotFound
199
+ false
200
+ end
192
201
  end
193
202
  end
194
203
  end
@@ -1,6 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "rbconfig"
4
+ require "shellwords"
5
+ require "fiddle"
4
6
 
5
7
  module Bundler
6
8
  class CLI::Doctor
@@ -22,14 +24,14 @@ module Bundler
22
24
  end
23
25
 
24
26
  def dylibs_darwin(path)
25
- output = `/usr/bin/otool -L "#{path}"`.chomp
27
+ output = `/usr/bin/otool -L #{path.shellescape}`.chomp
26
28
  dylibs = output.split("\n")[1..-1].map {|l| l.match(DARWIN_REGEX).captures[0] }.uniq
27
29
  # ignore @rpath and friends
28
30
  dylibs.reject {|dylib| dylib.start_with? "@" }
29
31
  end
30
32
 
31
33
  def dylibs_ldd(path)
32
- output = `/usr/bin/ldd "#{path}"`.chomp
34
+ output = `/usr/bin/ldd #{path.shellescape}`.chomp
33
35
  output.split("\n").map do |l|
34
36
  match = l.match(LDD_REGEX)
35
37
  next if match.nil?
@@ -61,7 +63,7 @@ module Bundler
61
63
  end
62
64
 
63
65
  def run
64
- Bundler.ui.level = "error" if options[:quiet]
66
+ Bundler.ui.level = "warn" if options[:quiet]
65
67
  Bundler.settings.validate!
66
68
  check!
67
69
 
@@ -70,7 +72,14 @@ module Bundler
70
72
 
71
73
  definition.specs.each do |spec|
72
74
  bundles_for_gem(spec).each do |bundle|
73
- bad_paths = dylibs(bundle).select {|f| !File.exist?(f) }
75
+ bad_paths = dylibs(bundle).select do |f|
76
+ begin
77
+ Fiddle.dlopen(f)
78
+ false
79
+ rescue Fiddle::DLError
80
+ true
81
+ end
82
+ end
74
83
  if bad_paths.any?
75
84
  broken_links[spec] ||= []
76
85
  broken_links[spec].concat(bad_paths)
@@ -100,8 +109,11 @@ module Bundler
100
109
  files_not_readable_or_writable = []
101
110
  files_not_rw_and_owned_by_different_user = []
102
111
  files_not_owned_by_current_user_but_still_rw = []
112
+ broken_symlinks = []
103
113
  Find.find(Bundler.bundle_path.to_s).each do |f|
104
- if !File.writable?(f) || !File.readable?(f)
114
+ if !File.exist?(f)
115
+ broken_symlinks << f
116
+ elsif !File.writable?(f) || !File.readable?(f)
105
117
  if File.stat(f).uid != Process.uid
106
118
  files_not_rw_and_owned_by_different_user << f
107
119
  else
@@ -113,6 +125,13 @@ module Bundler
113
125
  end
114
126
 
115
127
  ok = true
128
+
129
+ if broken_symlinks.any?
130
+ Bundler.ui.warn "Broken links exist in the Bundler home. Please report them to the offending gem's upstream repo. These files are:\n - #{broken_symlinks.join("\n - ")}"
131
+
132
+ ok = false
133
+ end
134
+
116
135
  if files_not_owned_by_current_user_but_still_rw.any?
117
136
  Bundler.ui.warn "Files exist in the Bundler home that are owned by another " \
118
137
  "user, but are still readable/writable. These files are:\n - #{files_not_owned_by_current_user_but_still_rw.join("\n - ")}"
@@ -12,12 +12,7 @@ module Bundler
12
12
  @options = options
13
13
  @cmd = args.shift
14
14
  @args = args
15
-
16
- if !Bundler.current_ruby.jruby?
17
- @args << { :close_others => !options.keep_file_descriptors? }
18
- elsif options.keep_file_descriptors?
19
- Bundler.ui.warn "Ruby version #{RUBY_VERSION} defaults to keeping non-standard file descriptors on Kernel#exec."
20
- end
15
+ @args << { :close_others => !options.keep_file_descriptors? } unless Bundler.current_ruby.jruby?
21
16
  end
22
17
 
23
18
  def run
@@ -38,12 +38,21 @@ module Bundler
38
38
  namespaced_path = name.tr("-", "/")
39
39
  constant_name = name.gsub(/-[_-]*(?![_-]|$)/) { "::" }.gsub(/([_-]+|(::)|^)(.|$)/) { $2.to_s + $3.upcase }
40
40
  constant_array = constant_name.split("::")
41
+ minitest_constant_name = constant_array.clone.tap {|a| a[-1] = "Test#{a[-1]}" }.join("::") # Foo::Bar => Foo::TestBar
41
42
 
42
- git_installed = Bundler.git_present?
43
+ use_git = Bundler.git_present? && options[:git]
43
44
 
44
- git_author_name = git_installed ? `git config user.name`.chomp : ""
45
- github_username = git_installed ? `git config github.user`.chomp : ""
46
- git_user_email = git_installed ? `git config user.email`.chomp : ""
45
+ git_author_name = use_git ? `git config user.name`.chomp : ""
46
+ git_username = use_git ? `git config github.user`.chomp : ""
47
+ git_user_email = use_git ? `git config user.email`.chomp : ""
48
+
49
+ github_username = if options[:github_username].nil?
50
+ git_username
51
+ elsif options[:github_username] == false
52
+ ""
53
+ else
54
+ options[:github_username]
55
+ end
47
56
 
48
57
  config = {
49
58
  :name => name,
@@ -58,8 +67,10 @@ module Bundler
58
67
  :ext => options[:ext],
59
68
  :exe => options[:exe],
60
69
  :bundler_version => bundler_dependency_version,
70
+ :git => use_git,
61
71
  :github_username => github_username.empty? ? "[USERNAME]" : github_username,
62
- :required_ruby_version => Gem.ruby_version < Gem::Version.new("2.4.a") ? "2.3.0" : "2.4.0",
72
+ :required_ruby_version => required_ruby_version,
73
+ :minitest_constant_name => minitest_constant_name,
63
74
  }
64
75
  ensure_safe_gem_name(name, constant_array)
65
76
 
@@ -67,6 +78,7 @@ module Bundler
67
78
  "#{Bundler.preferred_gemfile_name}.tt" => Bundler.preferred_gemfile_name,
68
79
  "lib/newgem.rb.tt" => "lib/#{namespaced_path}.rb",
69
80
  "lib/newgem/version.rb.tt" => "lib/#{namespaced_path}/version.rb",
81
+ "sig/newgem.rbs.tt" => "sig/#{namespaced_path}.rbs",
70
82
  "newgem.gemspec.tt" => "#{name}.gemspec",
71
83
  "Rakefile.tt" => "Rakefile",
72
84
  "README.md.tt" => "README.md",
@@ -79,7 +91,7 @@ module Bundler
79
91
  bin/setup
80
92
  ]
81
93
 
82
- templates.merge!("gitignore.tt" => ".gitignore") if Bundler.git_present?
94
+ templates.merge!("gitignore.tt" => ".gitignore") if use_git
83
95
 
84
96
  if test_framework = ask_and_set_test_framework
85
97
  config[:test] = test_framework
@@ -94,9 +106,17 @@ module Bundler
94
106
  )
95
107
  config[:test_task] = :spec
96
108
  when "minitest"
109
+ # Generate path for minitest target file (FileList["test/**/test_*.rb"])
110
+ # foo => test/test_foo.rb
111
+ # foo-bar => test/foo/test_bar.rb
112
+ # foo_bar => test/test_foo_bar.rb
113
+ paths = namespaced_path.rpartition("/")
114
+ paths[2] = "test_#{paths[2]}"
115
+ minitest_namespaced_path = paths.join("")
116
+
97
117
  templates.merge!(
98
118
  "test/minitest/test_helper.rb.tt" => "test/test_helper.rb",
99
- "test/minitest/newgem_test.rb.tt" => "test/#{namespaced_path}_test.rb"
119
+ "test/minitest/test_newgem.rb.tt" => "test/#{minitest_namespaced_path}.rb"
100
120
  )
101
121
  config[:test_task] = :test
102
122
  when "test-unit"
@@ -154,15 +174,16 @@ module Bundler
154
174
  templates.merge!("CHANGELOG.md.tt" => "CHANGELOG.md")
155
175
  end
156
176
 
157
- if ask_and_set(:rubocop, "Do you want to add rubocop as a dependency for gems you generate?",
158
- "RuboCop is a static code analyzer that has out-of-the-box rules for many " \
159
- "of the guidelines in the community style guide. " \
160
- "For more information, see the RuboCop docs (https://docs.rubocop.org/en/stable/) " \
161
- "and the Ruby Style Guides (https://github.com/rubocop-hq/ruby-style-guide).")
162
- config[:rubocop] = true
163
- config[:rubocop_version] = Gem.ruby_version < Gem::Version.new("2.4.a") ? "0.81.0" : "1.7"
177
+ config[:linter] = ask_and_set_linter
178
+ case config[:linter]
179
+ when "rubocop"
180
+ config[:linter_version] = rubocop_version
164
181
  Bundler.ui.info "RuboCop enabled in config"
165
182
  templates.merge!("rubocop.yml.tt" => ".rubocop.yml")
183
+ when "standard"
184
+ config[:linter_version] = standard_version
185
+ Bundler.ui.info "Standard enabled in config"
186
+ templates.merge!("standard.yml.tt" => ".standard.yml")
166
187
  end
167
188
 
168
189
  templates.merge!("exe/newgem.tt" => "exe/#{name}") if config[:exe]
@@ -175,24 +196,32 @@ module Bundler
175
196
  )
176
197
  end
177
198
 
199
+ if target.exist? && !target.directory?
200
+ Bundler.ui.error "Couldn't create a new gem named `#{gem_name}` because there's an existing file named `#{gem_name}`."
201
+ exit Bundler::BundlerError.all_errors[Bundler::GenericSystemCallError]
202
+ end
203
+
204
+ if use_git
205
+ Bundler.ui.info "Initializing git repo in #{target}"
206
+ require "shellwords"
207
+ `git init #{target.to_s.shellescape}`
208
+
209
+ config[:git_default_branch] = File.read("#{target}/.git/HEAD").split("/").last.chomp
210
+ end
211
+
178
212
  templates.each do |src, dst|
179
213
  destination = target.join(dst)
180
- SharedHelpers.filesystem_access(destination) do
181
- thor.template("newgem/#{src}", destination, config)
182
- end
214
+ thor.template("newgem/#{src}", destination, config)
183
215
  end
184
216
 
185
217
  executables.each do |file|
186
- SharedHelpers.filesystem_access(target.join(file)) do |path|
187
- executable = (path.stat.mode | 0o111)
188
- path.chmod(executable)
189
- end
218
+ path = target.join(file)
219
+ executable = (path.stat.mode | 0o111)
220
+ path.chmod(executable)
190
221
  end
191
222
 
192
- if Bundler.git_present? && options[:git]
193
- Bundler.ui.info "Initializing git repo in #{target}"
223
+ if use_git
194
224
  Dir.chdir(target) do
195
- `git init`
196
225
  `git add .`
197
226
  end
198
227
  end
@@ -202,8 +231,6 @@ module Bundler
202
231
 
203
232
  Bundler.ui.info "Gem '#{name}' was successfully created. " \
204
233
  "For more information on making a RubyGem visit https://bundler.io/guides/creating_gem.html"
205
- rescue Errno::EEXIST => e
206
- raise GenericSystemCallError.new(e, "There was a conflict while creating the new gem.")
207
234
  end
208
235
 
209
236
  private
@@ -302,6 +329,58 @@ module Bundler
302
329
  ci_template
303
330
  end
304
331
 
332
+ def ask_and_set_linter
333
+ linter_template = options[:linter] || Bundler.settings["gem.linter"]
334
+ linter_template = deprecated_rubocop_option if linter_template.nil?
335
+
336
+ if linter_template.to_s.empty?
337
+ Bundler.ui.confirm "Do you want to add a code linter and formatter to your gem? " \
338
+ "Supported Linters:\n" \
339
+ "* RuboCop: https://rubocop.org\n" \
340
+ "* Standard: https://github.com/testdouble/standard\n" \
341
+ "\n"
342
+ Bundler.ui.info hint_text("linter")
343
+
344
+ result = Bundler.ui.ask "Enter a linter. rubocop/standard/(none):"
345
+ if result =~ /rubocop|standard/
346
+ linter_template = result
347
+ else
348
+ linter_template = false
349
+ end
350
+ end
351
+
352
+ if Bundler.settings["gem.linter"].nil?
353
+ Bundler.settings.set_global("gem.linter", linter_template)
354
+ end
355
+
356
+ # Once gem.linter safely set, unset the deprecated gem.rubocop
357
+ unless Bundler.settings["gem.rubocop"].nil?
358
+ Bundler.settings.set_global("gem.rubocop", nil)
359
+ end
360
+
361
+ if options[:linter] == Bundler.settings["gem.linter"]
362
+ Bundler.ui.info "#{options[:linter]} is already configured, ignoring --linter flag."
363
+ end
364
+
365
+ linter_template
366
+ end
367
+
368
+ def deprecated_rubocop_option
369
+ if !options[:rubocop].nil?
370
+ if options[:rubocop]
371
+ Bundler::SharedHelpers.major_deprecation 2, "--rubocop is deprecated, use --linter=rubocop"
372
+ "rubocop"
373
+ else
374
+ Bundler::SharedHelpers.major_deprecation 2, "--no-rubocop is deprecated, use --linter"
375
+ false
376
+ end
377
+ elsif !Bundler.settings["gem.rubocop"].nil?
378
+ Bundler::SharedHelpers.major_deprecation 2,
379
+ "config gem.rubocop is deprecated; we've updated your config to use gem.linter instead"
380
+ Bundler.settings["gem.rubocop"] ? "rubocop" : false
381
+ end
382
+ end
383
+
305
384
  def bundler_dependency_version
306
385
  v = Gem::Version.new(Bundler::VERSION)
307
386
  req = v.segments[0..1]
@@ -335,5 +414,30 @@ module Bundler
335
414
  def open_editor(editor, file)
336
415
  thor.run(%(#{editor} "#{file}"))
337
416
  end
417
+
418
+ def required_ruby_version
419
+ if Gem.ruby_version < Gem::Version.new("2.4.a") then "2.3.0"
420
+ elsif Gem.ruby_version < Gem::Version.new("2.5.a") then "2.4.0"
421
+ elsif Gem.ruby_version < Gem::Version.new("2.6.a") then "2.5.0"
422
+ else
423
+ "2.6.0"
424
+ end
425
+ end
426
+
427
+ def rubocop_version
428
+ if Gem.ruby_version < Gem::Version.new("2.4.a") then "0.81.0"
429
+ elsif Gem.ruby_version < Gem::Version.new("2.5.a") then "1.12"
430
+ else
431
+ "1.21"
432
+ end
433
+ end
434
+
435
+ def standard_version
436
+ if Gem.ruby_version < Gem::Version.new("2.4.a") then "0.2.5"
437
+ elsif Gem.ruby_version < Gem::Version.new("2.5.a") then "1.0"
438
+ else
439
+ "1.3"
440
+ end
441
+ end
338
442
  end
339
443
  end
@@ -18,6 +18,7 @@ module Bundler
18
18
 
19
19
  if spec
20
20
  return print_gem_path(spec) if @options[:path]
21
+ return print_gem_version(spec) if @options[:version]
21
22
  print_gem_info(spec)
22
23
  end
23
24
  end
@@ -39,13 +40,18 @@ module Bundler
39
40
  raise GemNotFound, Bundler::CLI::Common.gem_not_found_message(gem_name, Bundler.definition.dependencies)
40
41
  end
41
42
 
43
+ def print_gem_version(spec)
44
+ Bundler.ui.info spec.version.to_s
45
+ end
46
+
42
47
  def print_gem_path(spec)
43
- if spec.name == "bundler"
44
- path = File.expand_path("../../../..", __FILE__)
48
+ name = spec.name
49
+ if name == "bundler"
50
+ path = File.expand_path("../../..", __dir__)
45
51
  else
46
52
  path = spec.full_gem_path
47
- unless File.directory?(path)
48
- return Bundler.ui.warn "The gem #{gem_name} has been deleted. It was installed at: #{path}"
53
+ if spec.deleted_gem?
54
+ return Bundler.ui.warn "The gem #{name} has been deleted. It was installed at: #{path}"
49
55
  end
50
56
  end
51
57
 
@@ -54,8 +60,9 @@ module Bundler
54
60
 
55
61
  def print_gem_info(spec)
56
62
  metadata = spec.metadata
63
+ name = spec.name
57
64
  gem_info = String.new
58
- gem_info << " * #{spec.name} (#{spec.version}#{spec.git_version})\n"
65
+ gem_info << " * #{name} (#{spec.version}#{spec.git_version})\n"
59
66
  gem_info << "\tSummary: #{spec.summary}\n" if spec.summary
60
67
  gem_info << "\tHomepage: #{spec.homepage}\n" if spec.homepage
61
68
  gem_info << "\tDocumentation: #{metadata["documentation_uri"]}\n" if metadata.key?("documentation_uri")
@@ -66,8 +73,22 @@ module Bundler
66
73
  gem_info << "\tBug Tracker: #{metadata["bug_tracker_uri"]}\n" if metadata.key?("bug_tracker_uri")
67
74
  gem_info << "\tMailing List: #{metadata["mailing_list_uri"]}\n" if metadata.key?("mailing_list_uri")
68
75
  gem_info << "\tPath: #{spec.full_gem_path}\n"
69
- gem_info << "\tDefault Gem: yes" if spec.respond_to?(:default_gem?) && spec.default_gem?
76
+ gem_info << "\tDefault Gem: yes\n" if spec.respond_to?(:default_gem?) && spec.default_gem?
77
+ gem_info << "\tReverse Dependencies: \n\t\t#{gem_dependencies.join("\n\t\t")}" if gem_dependencies.any?
78
+
79
+ if name != "bundler" && spec.deleted_gem?
80
+ return Bundler.ui.warn "The gem #{name} has been deleted. Gemspec information is still available though:\n#{gem_info}"
81
+ end
82
+
70
83
  Bundler.ui.info gem_info
71
84
  end
85
+
86
+ def gem_dependencies
87
+ @gem_dependencies ||= Bundler.definition.specs.map do |spec|
88
+ dependency = spec.dependencies.find {|dep| dep.name == gem_name }
89
+ next unless dependency
90
+ "#{spec.name} (#{spec.version}) depends on #{gem_name} (#{dependency.requirements_list.join(", ")})"
91
+ end.compact.sort
92
+ end
72
93
  end
73
94
  end
@@ -32,7 +32,11 @@ module Bundler
32
32
  file << spec.to_gemfile
33
33
  end
34
34
  else
35
- FileUtils.cp(File.expand_path("../../templates/#{gemfile}", __FILE__), gemfile)
35
+ File.open(File.expand_path("../templates/#{gemfile}", __dir__), "r") do |template|
36
+ File.open(gemfile, "wb") do |destination|
37
+ IO.copy_stream(template, destination)
38
+ end
39
+ end
36
40
  end
37
41
 
38
42
  puts "Writing new #{gemfile} to #{SharedHelpers.pwd}/#{gemfile}"