bundler 2.1.4 → 2.2.17

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.

Files changed (225) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1774 -1430
  3. data/README.md +6 -8
  4. data/bundler.gemspec +4 -4
  5. data/exe/bundle +3 -0
  6. data/lib/bundler.rb +33 -9
  7. data/lib/bundler/build_metadata.rb +3 -11
  8. data/lib/bundler/cli.rb +59 -23
  9. data/lib/bundler/cli/add.rb +1 -1
  10. data/lib/bundler/cli/binstubs.rb +6 -2
  11. data/lib/bundler/cli/cache.rb +2 -7
  12. data/lib/bundler/cli/clean.rb +1 -1
  13. data/lib/bundler/cli/common.rb +29 -2
  14. data/lib/bundler/cli/console.rb +1 -1
  15. data/lib/bundler/cli/doctor.rb +1 -1
  16. data/lib/bundler/cli/exec.rb +4 -4
  17. data/lib/bundler/cli/fund.rb +36 -0
  18. data/lib/bundler/cli/gem.rb +129 -28
  19. data/lib/bundler/cli/info.rb +15 -4
  20. data/lib/bundler/cli/init.rb +2 -2
  21. data/lib/bundler/cli/inject.rb +1 -1
  22. data/lib/bundler/cli/install.rb +13 -11
  23. data/lib/bundler/cli/issue.rb +2 -2
  24. data/lib/bundler/cli/list.rb +12 -10
  25. data/lib/bundler/cli/outdated.rb +88 -67
  26. data/lib/bundler/cli/plugin.rb +10 -0
  27. data/lib/bundler/cli/pristine.rb +5 -0
  28. data/lib/bundler/cli/show.rb +1 -1
  29. data/lib/bundler/cli/update.rb +3 -1
  30. data/lib/bundler/compact_index_client.rb +1 -1
  31. data/lib/bundler/compact_index_client/cache.rb +6 -14
  32. data/lib/bundler/compact_index_client/gem_parser.rb +28 -0
  33. data/lib/bundler/compact_index_client/updater.rb +13 -17
  34. data/lib/bundler/current_ruby.rb +1 -0
  35. data/lib/bundler/definition.rb +121 -131
  36. data/lib/bundler/dep_proxy.rb +16 -9
  37. data/lib/bundler/dependency.rb +3 -10
  38. data/lib/bundler/dsl.rb +40 -33
  39. data/lib/bundler/endpoint_specification.rb +1 -1
  40. data/lib/bundler/env.rb +1 -1
  41. data/lib/bundler/environment_preserver.rb +26 -2
  42. data/lib/bundler/errors.rb +1 -0
  43. data/lib/bundler/feature_flag.rb +0 -5
  44. data/lib/bundler/fetcher.rb +5 -4
  45. data/lib/bundler/fetcher/base.rb +1 -1
  46. data/lib/bundler/fetcher/compact_index.rb +1 -1
  47. data/lib/bundler/fetcher/downloader.rb +9 -5
  48. data/lib/bundler/fetcher/index.rb +3 -4
  49. data/lib/bundler/friendly_errors.rb +22 -13
  50. data/lib/bundler/gem_helper.rb +51 -18
  51. data/lib/bundler/gem_helpers.rb +36 -25
  52. data/lib/bundler/gem_version_promoter.rb +4 -4
  53. data/lib/bundler/graph.rb +1 -1
  54. data/lib/bundler/index.rb +12 -7
  55. data/lib/bundler/injector.rb +23 -5
  56. data/lib/bundler/inline.rb +3 -2
  57. data/lib/bundler/installer.rb +37 -49
  58. data/lib/bundler/installer/gem_installer.rb +3 -3
  59. data/lib/bundler/installer/parallel_installer.rb +46 -25
  60. data/lib/bundler/installer/standalone.rb +17 -2
  61. data/lib/bundler/lazy_specification.rb +45 -25
  62. data/lib/bundler/lockfile_generator.rb +1 -1
  63. data/lib/bundler/lockfile_parser.rb +4 -14
  64. data/lib/bundler/man/.document +1 -0
  65. data/{man → lib/bundler/man}/bundle-add.1 +1 -1
  66. data/{man/bundle-add.ronn → lib/bundler/man/bundle-add.1.ronn} +0 -0
  67. data/{man → lib/bundler/man}/bundle-binstubs.1 +5 -3
  68. data/{man/bundle-binstubs.ronn → lib/bundler/man/bundle-binstubs.1.ronn} +2 -4
  69. data/{man → lib/bundler/man}/bundle-cache.1 +1 -1
  70. data/{man/bundle-cache.ronn → lib/bundler/man/bundle-cache.1.ronn} +0 -0
  71. data/{man → lib/bundler/man}/bundle-check.1 +1 -1
  72. data/{man/bundle-check.ronn → lib/bundler/man/bundle-check.1.ronn} +0 -0
  73. data/{man → lib/bundler/man}/bundle-clean.1 +1 -1
  74. data/{man/bundle-clean.ronn → lib/bundler/man/bundle-clean.1.ronn} +0 -0
  75. data/{man → lib/bundler/man}/bundle-config.1 +42 -34
  76. data/{man/bundle-config.ronn → lib/bundler/man/bundle-config.1.ronn} +51 -43
  77. data/{man → lib/bundler/man}/bundle-doctor.1 +1 -1
  78. data/{man/bundle-doctor.ronn → lib/bundler/man/bundle-doctor.1.ronn} +0 -0
  79. data/{man → lib/bundler/man}/bundle-exec.1 +1 -1
  80. data/{man/bundle-exec.ronn → lib/bundler/man/bundle-exec.1.ronn} +0 -0
  81. data/{man → lib/bundler/man}/bundle-gem.1 +25 -3
  82. data/{man/bundle-gem.ronn → lib/bundler/man/bundle-gem.1.ronn} +30 -7
  83. data/{man → lib/bundler/man}/bundle-info.1 +1 -1
  84. data/{man/bundle-info.ronn → lib/bundler/man/bundle-info.1.ronn} +0 -0
  85. data/{man → lib/bundler/man}/bundle-init.1 +1 -1
  86. data/{man/bundle-init.ronn → lib/bundler/man/bundle-init.1.ronn} +0 -0
  87. data/{man → lib/bundler/man}/bundle-inject.1 +1 -1
  88. data/{man/bundle-inject.ronn → lib/bundler/man/bundle-inject.1.ronn} +0 -0
  89. data/{man → lib/bundler/man}/bundle-install.1 +30 -3
  90. data/{man/bundle-install.ronn → lib/bundler/man/bundle-install.1.ronn} +25 -3
  91. data/{man → lib/bundler/man}/bundle-list.1 +7 -7
  92. data/{man/bundle-list.ronn → lib/bundler/man/bundle-list.1.ronn} +6 -6
  93. data/{man → lib/bundler/man}/bundle-lock.1 +1 -1
  94. data/{man/bundle-lock.ronn → lib/bundler/man/bundle-lock.1.ronn} +0 -0
  95. data/{man → lib/bundler/man}/bundle-open.1 +1 -1
  96. data/{man/bundle-open.ronn → lib/bundler/man/bundle-open.1.ronn} +0 -0
  97. data/{man → lib/bundler/man}/bundle-outdated.1 +1 -1
  98. data/{man/bundle-outdated.ronn → lib/bundler/man/bundle-outdated.1.ronn} +0 -0
  99. data/{man → lib/bundler/man}/bundle-platform.1 +1 -1
  100. data/{man/bundle-platform.ronn → lib/bundler/man/bundle-platform.1.ronn} +0 -0
  101. data/{man → lib/bundler/man}/bundle-pristine.1 +1 -1
  102. data/{man/bundle-pristine.ronn → lib/bundler/man/bundle-pristine.1.ronn} +0 -0
  103. data/{man → lib/bundler/man}/bundle-remove.1 +1 -1
  104. data/{man/bundle-remove.ronn → lib/bundler/man/bundle-remove.1.ronn} +0 -0
  105. data/{man → lib/bundler/man}/bundle-show.1 +1 -1
  106. data/{man/bundle-show.ronn → lib/bundler/man/bundle-show.1.ronn} +0 -0
  107. data/{man → lib/bundler/man}/bundle-update.1 +1 -1
  108. data/{man/bundle-update.ronn → lib/bundler/man/bundle-update.1.ronn} +0 -0
  109. data/{man → lib/bundler/man}/bundle-viz.1 +1 -1
  110. data/{man/bundle-viz.ronn → lib/bundler/man/bundle-viz.1.ronn} +0 -0
  111. data/{man → lib/bundler/man}/bundle.1 +1 -1
  112. data/{man/bundle.ronn → lib/bundler/man/bundle.1.ronn} +0 -0
  113. data/{man → lib/bundler/man}/gemfile.5 +4 -4
  114. data/{man → lib/bundler/man}/gemfile.5.ronn +4 -4
  115. data/{man → lib/bundler/man}/index.txt +0 -0
  116. data/lib/bundler/mirror.rb +2 -2
  117. data/lib/bundler/plugin.rb +33 -7
  118. data/lib/bundler/plugin/api/source.rb +8 -1
  119. data/lib/bundler/plugin/dsl.rb +1 -1
  120. data/lib/bundler/plugin/index.rb +10 -1
  121. data/lib/bundler/plugin/installer.rb +9 -11
  122. data/lib/bundler/plugin/installer/rubygems.rb +1 -1
  123. data/lib/bundler/plugin/source_list.rb +5 -1
  124. data/lib/bundler/psyched_yaml.rb +0 -15
  125. data/lib/bundler/remote_specification.rb +5 -2
  126. data/lib/bundler/resolver.rb +133 -77
  127. data/lib/bundler/resolver/spec_group.rb +75 -48
  128. data/lib/bundler/retry.rb +2 -2
  129. data/lib/bundler/ruby_version.rb +1 -1
  130. data/lib/bundler/rubygems_ext.rb +69 -9
  131. data/lib/bundler/rubygems_gem_installer.rb +50 -9
  132. data/lib/bundler/rubygems_integration.rb +25 -60
  133. data/lib/bundler/runtime.rb +4 -14
  134. data/lib/bundler/settings.rb +107 -54
  135. data/lib/bundler/shared_helpers.rb +3 -3
  136. data/lib/bundler/similarity_detector.rb +1 -1
  137. data/lib/bundler/source.rb +7 -1
  138. data/lib/bundler/source/git.rb +24 -22
  139. data/lib/bundler/source/git/git_proxy.rb +82 -80
  140. data/lib/bundler/source/metadata.rb +0 -4
  141. data/lib/bundler/source/path.rb +10 -4
  142. data/lib/bundler/source/path/installer.rb +10 -10
  143. data/lib/bundler/source/rubygems.rb +45 -24
  144. data/lib/bundler/source/rubygems/remote.rb +1 -1
  145. data/lib/bundler/source_list.rb +31 -26
  146. data/lib/bundler/spec_set.rb +29 -17
  147. data/lib/bundler/stub_specification.rb +25 -7
  148. data/lib/bundler/templates/Gemfile +1 -1
  149. data/lib/bundler/templates/gems.rb +1 -1
  150. data/lib/bundler/templates/newgem/CHANGELOG.md.tt +5 -0
  151. data/lib/bundler/templates/newgem/CODE_OF_CONDUCT.md.tt +57 -47
  152. data/lib/bundler/templates/newgem/Gemfile.tt +9 -1
  153. data/lib/bundler/templates/newgem/README.md.tt +6 -5
  154. data/lib/bundler/templates/newgem/Rakefile.tt +19 -5
  155. data/lib/bundler/templates/newgem/bin/console.tt +1 -0
  156. data/lib/bundler/templates/newgem/circleci/config.yml.tt +13 -0
  157. data/lib/bundler/templates/newgem/ext/newgem/extconf.rb.tt +2 -0
  158. data/lib/bundler/templates/newgem/github/workflows/main.yml.tt +16 -0
  159. data/lib/bundler/templates/newgem/gitlab-ci.yml.tt +9 -0
  160. data/lib/bundler/templates/newgem/lib/newgem.rb.tt +4 -2
  161. data/lib/bundler/templates/newgem/lib/newgem/version.rb.tt +2 -0
  162. data/lib/bundler/templates/newgem/newgem.gemspec.tt +15 -7
  163. data/lib/bundler/templates/newgem/rubocop.yml.tt +13 -0
  164. data/lib/bundler/templates/newgem/spec/newgem_spec.rb.tt +2 -0
  165. data/lib/bundler/templates/newgem/spec/spec_helper.rb.tt +2 -1
  166. data/lib/bundler/templates/newgem/test/{newgem_test.rb.tt → minitest/newgem_test.rb.tt} +2 -0
  167. data/lib/bundler/templates/newgem/test/{test_helper.rb.tt → minitest/test_helper.rb.tt} +2 -0
  168. data/lib/bundler/templates/newgem/test/test-unit/newgem_test.rb.tt +15 -0
  169. data/lib/bundler/templates/newgem/test/test-unit/test_helper.rb.tt +6 -0
  170. data/lib/bundler/ui/shell.rb +5 -5
  171. data/lib/bundler/uri_credentials_filter.rb +3 -1
  172. data/lib/bundler/vendor/molinillo/lib/molinillo.rb +0 -1
  173. data/lib/bundler/vendor/molinillo/lib/molinillo/delegates/specification_provider.rb +7 -0
  174. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb +34 -2
  175. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/tag.rb +2 -2
  176. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/vertex.rb +11 -5
  177. data/lib/bundler/vendor/molinillo/lib/molinillo/errors.rb +3 -3
  178. data/lib/bundler/vendor/molinillo/lib/molinillo/gem_metadata.rb +1 -1
  179. data/lib/bundler/vendor/molinillo/lib/molinillo/modules/specification_provider.rb +12 -1
  180. data/lib/bundler/vendor/molinillo/lib/molinillo/resolution.rb +49 -47
  181. data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb +82 -189
  182. data/lib/bundler/vendor/thor/lib/thor.rb +5 -13
  183. data/lib/bundler/vendor/thor/lib/thor/actions.rb +1 -1
  184. data/lib/bundler/vendor/thor/lib/thor/actions/create_link.rb +2 -1
  185. data/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb +4 -2
  186. data/lib/bundler/vendor/thor/lib/thor/base.rb +9 -0
  187. data/lib/bundler/vendor/thor/lib/thor/error.rb +1 -1
  188. data/lib/bundler/vendor/thor/lib/thor/parser/arguments.rb +5 -1
  189. data/lib/bundler/vendor/thor/lib/thor/parser/options.rb +9 -8
  190. data/lib/bundler/vendor/thor/lib/thor/shell/basic.rb +5 -2
  191. data/lib/bundler/vendor/thor/lib/thor/shell/color.rb +5 -1
  192. data/lib/bundler/vendor/thor/lib/thor/version.rb +1 -1
  193. data/lib/bundler/vendor/tmpdir/lib/tmpdir.rb +154 -0
  194. data/lib/bundler/vendored_persistent.rb +0 -7
  195. data/lib/bundler/vendored_tmpdir.rb +4 -0
  196. data/lib/bundler/version.rb +1 -1
  197. data/lib/bundler/worker.rb +1 -1
  198. data/lib/bundler/yaml_serializer.rb +1 -1
  199. metadata +71 -85
  200. data/lib/bundler/vendor/molinillo/lib/molinillo/compatibility.rb +0 -26
  201. data/man/bundle-add.1.txt +0 -58
  202. data/man/bundle-binstubs.1.txt +0 -48
  203. data/man/bundle-cache.1.txt +0 -78
  204. data/man/bundle-check.1.txt +0 -33
  205. data/man/bundle-clean.1.txt +0 -26
  206. data/man/bundle-config.1.txt +0 -528
  207. data/man/bundle-doctor.1.txt +0 -44
  208. data/man/bundle-exec.1.txt +0 -178
  209. data/man/bundle-gem.1.txt +0 -91
  210. data/man/bundle-info.1.txt +0 -21
  211. data/man/bundle-init.1.txt +0 -34
  212. data/man/bundle-inject.1.txt +0 -32
  213. data/man/bundle-install.1.txt +0 -401
  214. data/man/bundle-list.1.txt +0 -43
  215. data/man/bundle-lock.1.txt +0 -93
  216. data/man/bundle-open.1.txt +0 -29
  217. data/man/bundle-outdated.1.txt +0 -131
  218. data/man/bundle-platform.1.txt +0 -57
  219. data/man/bundle-pristine.1.txt +0 -44
  220. data/man/bundle-remove.1.txt +0 -34
  221. data/man/bundle-show.1.txt +0 -27
  222. data/man/bundle-update.1.txt +0 -390
  223. data/man/bundle-viz.1.txt +0 -39
  224. data/man/bundle.1.txt +0 -116
  225. data/man/gemfile.5.txt +0 -649
@@ -13,7 +13,7 @@ module Bundler
13
13
  Bundler.load.clean(options[:"dry-run"])
14
14
  end
15
15
 
16
- protected
16
+ protected
17
17
 
18
18
  def require_path_or_force
19
19
  return unless Bundler.use_system_gems? && !options[:force]
@@ -14,6 +14,20 @@ module Bundler
14
14
  Bundler.ui.info msg
15
15
  end
16
16
 
17
+ def self.output_fund_metadata_summary
18
+ definition = Bundler.definition
19
+ current_dependencies = definition.requested_dependencies
20
+ current_specs = definition.specs
21
+
22
+ count = current_dependencies.count {|dep| current_specs[dep.name].first.metadata.key?("funding_uri") }
23
+
24
+ return if count.zero?
25
+
26
+ intro = count > 1 ? "#{count} installed gems you directly depend on are" : "#{count} installed gem you directly depend on is"
27
+ message = "#{intro} looking for funding.\n Run `bundle fund` for details"
28
+ Bundler.ui.info message
29
+ end
30
+
17
31
  def self.output_without_groups_message(command)
18
32
  return if Bundler.settings[:without].empty?
19
33
  Bundler.ui.confirm without_groups_message(command)
@@ -22,10 +36,15 @@ module Bundler
22
36
  def self.without_groups_message(command)
23
37
  command_in_past_tense = command == :install ? "installed" : "updated"
24
38
  groups = Bundler.settings[:without]
39
+ "Gems in the #{verbalize_groups(groups)} were not #{command_in_past_tense}."
40
+ end
41
+
42
+ def self.verbalize_groups(groups)
43
+ groups.map!{|g| "'#{g}'" }
25
44
  group_list = [groups[0...-1].join(", "), groups[-1..-1]].
26
45
  reject {|s| s.to_s.empty? }.join(" and ")
27
46
  group_str = groups.size == 1 ? "group" : "groups"
28
- "Gems in the #{group_str} #{group_list} were not #{command_in_past_tense}."
47
+ "#{group_str} #{group_list}"
29
48
  end
30
49
 
31
50
  def self.select_spec(name, regex_match = nil)
@@ -39,7 +58,13 @@ module Bundler
39
58
 
40
59
  case specs.count
41
60
  when 0
42
- raise GemNotFound, gem_not_found_message(name, Bundler.definition.dependencies)
61
+ dep_in_other_group = Bundler.definition.current_dependencies.find {|dep|dep.name == name }
62
+
63
+ if dep_in_other_group
64
+ raise GemNotFound, "Could not find gem '#{name}', because it's in the #{verbalize_groups(dep_in_other_group.groups)}, configured to be ignored."
65
+ else
66
+ raise GemNotFound, gem_not_found_message(name, Bundler.definition.dependencies)
67
+ end
43
68
  when 1
44
69
  specs.first
45
70
  else
@@ -69,6 +94,8 @@ module Bundler
69
94
  end
70
95
 
71
96
  def self.ensure_all_gems_in_lockfile!(names, locked_gems = Bundler.locked_gems)
97
+ return unless locked_gems
98
+
72
99
  locked_names = locked_gems.specs.map(&:name).uniq
73
100
  names.-(locked_names).each do |g|
74
101
  raise GemNotFound, gem_not_found_message(g, locked_names)
@@ -12,7 +12,7 @@ module Bundler
12
12
  Bundler::SharedHelpers.major_deprecation 2, "bundle console will be replaced " \
13
13
  "by `bin/console` generated by `bundle gem <name>`"
14
14
 
15
- group ? Bundler.require(:default, *group.split.map!(&:to_sym)) : Bundler.require
15
+ group ? Bundler.require(:default, *group.split(" ").map!(&:to_sym)) : Bundler.require
16
16
  ARGV.clear
17
17
 
18
18
  console = get_console(Bundler.settings[:console] || "irb")
@@ -93,7 +93,7 @@ module Bundler
93
93
  end
94
94
  end
95
95
 
96
- private
96
+ private
97
97
 
98
98
  def check_home_permissions
99
99
  require "find"
@@ -34,7 +34,7 @@ module Bundler
34
34
  end
35
35
  end
36
36
 
37
- private
37
+ private
38
38
 
39
39
  def validate_cmd!
40
40
  return unless cmd.nil?
@@ -63,10 +63,10 @@ module Bundler
63
63
  Kernel.load(file)
64
64
  rescue SystemExit, SignalException
65
65
  raise
66
- rescue Exception => e # rubocop:disable Lint/RescueException
66
+ rescue Exception # rubocop:disable Lint/RescueException
67
67
  Bundler.ui.error "bundler: failed to load command: #{cmd} (#{file})"
68
- backtrace = e.backtrace ? e.backtrace.take_while {|bt| !bt.start_with?(__FILE__) } : []
69
- abort "#{e.class}: #{e.message}\n #{backtrace.join("\n ")}"
68
+ Bundler::FriendlyErrors.disable!
69
+ raise
70
70
  end
71
71
 
72
72
  def process_title(file, args)
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bundler
4
+ class CLI::Fund
5
+ attr_reader :options
6
+
7
+ def initialize(options)
8
+ @options = options
9
+ end
10
+
11
+ def run
12
+ Bundler.definition.validate_runtime!
13
+
14
+ groups = Array(options[:group]).map(&:to_sym)
15
+
16
+ deps = if groups.any?
17
+ Bundler.definition.dependencies_for(groups)
18
+ else
19
+ Bundler.definition.current_dependencies
20
+ end
21
+
22
+ fund_info = deps.each_with_object([]) do |dep, arr|
23
+ spec = Bundler.definition.specs[dep.name].first
24
+ if spec.metadata.key?("funding_uri")
25
+ arr << "* #{spec.name} (#{spec.version})\n Funding: #{spec.metadata["funding_uri"]}"
26
+ end
27
+ end
28
+
29
+ if fund_info.empty?
30
+ Bundler.ui.info "None of the installed gems you directly depend on are looking for funding."
31
+ else
32
+ Bundler.ui.info fund_info.join("\n")
33
+ end
34
+ end
35
+ end
36
+ end
@@ -12,6 +12,7 @@ module Bundler
12
12
  TEST_FRAMEWORK_VERSIONS = {
13
13
  "rspec" => "3.0",
14
14
  "minitest" => "5.0",
15
+ "test-unit" => "3.0",
15
16
  }.freeze
16
17
 
17
18
  attr_reader :options, :gem_name, :thor, :name, :target
@@ -38,11 +39,19 @@ module Bundler
38
39
  constant_name = name.gsub(/-[_-]*(?![_-]|$)/) { "::" }.gsub(/([_-]+|(::)|^)(.|$)/) { $2.to_s + $3.upcase }
39
40
  constant_array = constant_name.split("::")
40
41
 
41
- git_installed = Bundler.git_present?
42
+ use_git = Bundler.git_present? && options[:git]
42
43
 
43
- git_author_name = git_installed ? `git config user.name`.chomp : ""
44
- github_username = git_installed ? `git config github.user`.chomp : ""
45
- git_user_email = git_installed ? `git config user.email`.chomp : ""
44
+ git_author_name = use_git ? `git config user.name`.chomp : ""
45
+ git_username = use_git ? `git config github.user`.chomp : ""
46
+ git_user_email = use_git ? `git config user.email`.chomp : ""
47
+
48
+ github_username = if options[:github_username].nil?
49
+ git_username
50
+ elsif options[:github_username] == false
51
+ ""
52
+ else
53
+ options[:github_username]
54
+ end
46
55
 
47
56
  config = {
48
57
  :name => name,
@@ -57,12 +66,14 @@ module Bundler
57
66
  :ext => options[:ext],
58
67
  :exe => options[:exe],
59
68
  :bundler_version => bundler_dependency_version,
69
+ :git => use_git,
60
70
  :github_username => github_username.empty? ? "[USERNAME]" : github_username,
71
+ :required_ruby_version => Gem.ruby_version < Gem::Version.new("2.4.a") ? "2.3.0" : "2.4.0",
61
72
  }
62
73
  ensure_safe_gem_name(name, constant_array)
63
74
 
64
75
  templates = {
65
- "Gemfile.tt" => "Gemfile",
76
+ "#{Bundler.preferred_gemfile_name}.tt" => Bundler.preferred_gemfile_name,
66
77
  "lib/newgem.rb.tt" => "lib/#{namespaced_path}.rb",
67
78
  "lib/newgem/version.rb.tt" => "lib/#{namespaced_path}/version.rb",
68
79
  "newgem.gemspec.tt" => "#{name}.gemspec",
@@ -77,14 +88,12 @@ module Bundler
77
88
  bin/setup
78
89
  ]
79
90
 
80
- templates.merge!("gitignore.tt" => ".gitignore") if Bundler.git_present?
91
+ templates.merge!("gitignore.tt" => ".gitignore") if use_git
81
92
 
82
93
  if test_framework = ask_and_set_test_framework
83
94
  config[:test] = test_framework
84
95
  config[:test_framework_version] = TEST_FRAMEWORK_VERSIONS[test_framework]
85
96
 
86
- templates.merge!("travis.yml.tt" => ".travis.yml")
87
-
88
97
  case test_framework
89
98
  when "rspec"
90
99
  templates.merge!(
@@ -92,15 +101,33 @@ module Bundler
92
101
  "spec/spec_helper.rb.tt" => "spec/spec_helper.rb",
93
102
  "spec/newgem_spec.rb.tt" => "spec/#{namespaced_path}_spec.rb"
94
103
  )
104
+ config[:test_task] = :spec
95
105
  when "minitest"
96
106
  templates.merge!(
97
- "test/test_helper.rb.tt" => "test/test_helper.rb",
98
- "test/newgem_test.rb.tt" => "test/#{namespaced_path}_test.rb"
107
+ "test/minitest/test_helper.rb.tt" => "test/test_helper.rb",
108
+ "test/minitest/newgem_test.rb.tt" => "test/#{namespaced_path}_test.rb"
109
+ )
110
+ config[:test_task] = :test
111
+ when "test-unit"
112
+ templates.merge!(
113
+ "test/test-unit/test_helper.rb.tt" => "test/test_helper.rb",
114
+ "test/test-unit/newgem_test.rb.tt" => "test/#{namespaced_path}_test.rb"
99
115
  )
116
+ config[:test_task] = :test
100
117
  end
101
118
  end
102
119
 
103
- config[:test_task] = config[:test] == "minitest" ? "test" : "spec"
120
+ config[:ci] = ask_and_set_ci
121
+ case config[:ci]
122
+ when "github"
123
+ templates.merge!("github/workflows/main.yml.tt" => ".github/workflows/main.yml")
124
+ when "travis"
125
+ templates.merge!("travis.yml.tt" => ".travis.yml")
126
+ when "gitlab"
127
+ templates.merge!("gitlab-ci.yml.tt" => ".gitlab-ci.yml")
128
+ when "circle"
129
+ templates.merge!("circleci/config.yml.tt" => ".circleci/config.yml")
130
+ end
104
131
 
105
132
  if ask_and_set(:mit, "Do you want to license your code permissively under the MIT license?",
106
133
  "This means that any other developer or company will be legally allowed to use your code " \
@@ -124,6 +151,29 @@ module Bundler
124
151
  templates.merge!("CODE_OF_CONDUCT.md.tt" => "CODE_OF_CONDUCT.md")
125
152
  end
126
153
 
154
+ if ask_and_set(:changelog, "Do you want to include a changelog?",
155
+ "A changelog is a file which contains a curated, chronologically ordered list of notable " \
156
+ "changes for each version of a project. To make it easier for users and contributors to" \
157
+ " see precisely what notable changes have been made between each release (or version) of" \
158
+ " the project. Whether consumers or developers, the end users of software are" \
159
+ " human beings who care about what's in the software. When the software changes, people " \
160
+ "want to know why and how. see https://keepachangelog.com")
161
+ config[:changelog] = true
162
+ Bundler.ui.info "Changelog enabled in config"
163
+ templates.merge!("CHANGELOG.md.tt" => "CHANGELOG.md")
164
+ end
165
+
166
+ if ask_and_set(:rubocop, "Do you want to add rubocop as a dependency for gems you generate?",
167
+ "RuboCop is a static code analyzer that has out-of-the-box rules for many " \
168
+ "of the guidelines in the community style guide. " \
169
+ "For more information, see the RuboCop docs (https://docs.rubocop.org/en/stable/) " \
170
+ "and the Ruby Style Guides (https://github.com/rubocop-hq/ruby-style-guide).")
171
+ config[:rubocop] = true
172
+ config[:rubocop_version] = Gem.ruby_version < Gem::Version.new("2.4.a") ? "0.81.0" : "1.7"
173
+ Bundler.ui.info "RuboCop enabled in config"
174
+ templates.merge!("rubocop.yml.tt" => ".rubocop.yml")
175
+ end
176
+
127
177
  templates.merge!("exe/newgem.tt" => "exe/#{name}") if config[:exe]
128
178
 
129
179
  if options[:ext]
@@ -134,24 +184,31 @@ module Bundler
134
184
  )
135
185
  end
136
186
 
187
+ if File.exist?(target) && !File.directory?(target)
188
+ Bundler.ui.error "Couldn't create a new gem named `#{gem_name}` because there's an existing file named `#{gem_name}`."
189
+ exit Bundler::BundlerError.all_errors[Bundler::GenericSystemCallError]
190
+ end
191
+
192
+ if use_git
193
+ Bundler.ui.info "Initializing git repo in #{target}"
194
+ `git init #{target}`
195
+
196
+ config[:git_default_branch] = File.read("#{target}/.git/HEAD").split("/").last.chomp
197
+ end
198
+
137
199
  templates.each do |src, dst|
138
200
  destination = target.join(dst)
139
- SharedHelpers.filesystem_access(destination) do
140
- thor.template("newgem/#{src}", destination, config)
141
- end
201
+ thor.template("newgem/#{src}", destination, config)
142
202
  end
143
203
 
144
204
  executables.each do |file|
145
- SharedHelpers.filesystem_access(target.join(file)) do |path|
146
- executable = (path.stat.mode | 0o111)
147
- path.chmod(executable)
148
- end
205
+ path = target.join(file)
206
+ executable = (path.stat.mode | 0o111)
207
+ path.chmod(executable)
149
208
  end
150
209
 
151
- if Bundler.git_present? && options[:git]
152
- Bundler.ui.info "Initializing git repo in #{target}"
210
+ if use_git
153
211
  Dir.chdir(target) do
154
- `git init`
155
212
  `git add .`
156
213
  end
157
214
  end
@@ -161,11 +218,9 @@ module Bundler
161
218
 
162
219
  Bundler.ui.info "Gem '#{name}' was successfully created. " \
163
220
  "For more information on making a RubyGem visit https://bundler.io/guides/creating_gem.html"
164
- rescue Errno::EEXIST => e
165
- raise GenericSystemCallError.new(e, "There was a conflict while creating the new gem.")
166
221
  end
167
222
 
168
- private
223
+ private
169
224
 
170
225
  def resolve_name(name)
171
226
  SharedHelpers.pwd.join(name).basename.to_s
@@ -197,11 +252,12 @@ module Bundler
197
252
  def ask_and_set_test_framework
198
253
  test_framework = options[:test] || Bundler.settings["gem.test"]
199
254
 
200
- if test_framework.nil?
255
+ if test_framework.to_s.empty?
201
256
  Bundler.ui.confirm "Do you want to generate tests with your gem?"
202
- result = Bundler.ui.ask "Type 'rspec' or 'minitest' to generate those test files now and " \
203
- "in the future. rspec/minitest/(none):"
204
- if result =~ /rspec|minitest/
257
+ Bundler.ui.info hint_text("test")
258
+
259
+ result = Bundler.ui.ask "Enter a test framework. rspec/minitest/test-unit/(none):"
260
+ if result =~ /rspec|minitest|test-unit/
205
261
  test_framework = result
206
262
  else
207
263
  test_framework = false
@@ -212,9 +268,54 @@ module Bundler
212
268
  Bundler.settings.set_global("gem.test", test_framework)
213
269
  end
214
270
 
271
+ if options[:test] == Bundler.settings["gem.test"]
272
+ Bundler.ui.info "#{options[:test]} is already configured, ignoring --test flag."
273
+ end
274
+
215
275
  test_framework
216
276
  end
217
277
 
278
+ def hint_text(setting)
279
+ if Bundler.settings["gem.#{setting}"] == false
280
+ "Your choice will only be applied to this gem."
281
+ else
282
+ "Future `bundle gem` calls will use your choice. " \
283
+ "This setting can be changed anytime with `bundle config gem.#{setting}`."
284
+ end
285
+ end
286
+
287
+ def ask_and_set_ci
288
+ ci_template = options[:ci] || Bundler.settings["gem.ci"]
289
+
290
+ if ci_template.to_s.empty?
291
+ Bundler.ui.confirm "Do you want to set up continuous integration for your gem? " \
292
+ "Supported services:\n" \
293
+ "* CircleCI: https://circleci.com/\n" \
294
+ "* GitHub Actions: https://github.com/features/actions\n" \
295
+ "* GitLab CI: https://docs.gitlab.com/ee/ci/\n" \
296
+ "* Travis CI: https://travis-ci.org/\n" \
297
+ "\n"
298
+ Bundler.ui.info hint_text("ci")
299
+
300
+ result = Bundler.ui.ask "Enter a CI service. github/travis/gitlab/circle/(none):"
301
+ if result =~ /github|travis|gitlab|circle/
302
+ ci_template = result
303
+ else
304
+ ci_template = false
305
+ end
306
+ end
307
+
308
+ if Bundler.settings["gem.ci"].nil?
309
+ Bundler.settings.set_global("gem.ci", ci_template)
310
+ end
311
+
312
+ if options[:ci] == Bundler.settings["gem.ci"]
313
+ Bundler.ui.info "#{options[:ci]} is already configured, ignoring --ci flag."
314
+ end
315
+
316
+ ci_template
317
+ end
318
+
218
319
  def bundler_dependency_version
219
320
  v = Gem::Version.new(Bundler::VERSION)
220
321
  req = v.segments[0..1]
@@ -22,7 +22,7 @@ module Bundler
22
22
  end
23
23
  end
24
24
 
25
- private
25
+ private
26
26
 
27
27
  def spec_for_gem(gem_name)
28
28
  spec = Bundler.definition.specs.find {|s| s.name == gem_name }
@@ -40,20 +40,31 @@ module Bundler
40
40
  end
41
41
 
42
42
  def print_gem_path(spec)
43
- path = if spec.name == "bundler"
44
- File.expand_path("../../../..", __FILE__)
43
+ if spec.name == "bundler"
44
+ path = File.expand_path("../../../..", __FILE__)
45
45
  else
46
- spec.full_gem_path
46
+ 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}"
49
+ end
47
50
  end
48
51
 
49
52
  Bundler.ui.info path
50
53
  end
51
54
 
52
55
  def print_gem_info(spec)
56
+ metadata = spec.metadata
53
57
  gem_info = String.new
54
58
  gem_info << " * #{spec.name} (#{spec.version}#{spec.git_version})\n"
55
59
  gem_info << "\tSummary: #{spec.summary}\n" if spec.summary
56
60
  gem_info << "\tHomepage: #{spec.homepage}\n" if spec.homepage
61
+ gem_info << "\tDocumentation: #{metadata["documentation_uri"]}\n" if metadata.key?("documentation_uri")
62
+ gem_info << "\tSource Code: #{metadata["source_code_uri"]}\n" if metadata.key?("source_code_uri")
63
+ gem_info << "\tFunding: #{metadata["funding_uri"]}\n" if metadata.key?("funding_uri")
64
+ gem_info << "\tWiki: #{metadata["wiki_uri"]}\n" if metadata.key?("wiki_uri")
65
+ gem_info << "\tChangelog: #{metadata["changelog_uri"]}\n" if metadata.key?("changelog_uri")
66
+ gem_info << "\tBug Tracker: #{metadata["bug_tracker_uri"]}\n" if metadata.key?("bug_tracker_uri")
67
+ gem_info << "\tMailing List: #{metadata["mailing_list_uri"]}\n" if metadata.key?("mailing_list_uri")
57
68
  gem_info << "\tPath: #{spec.full_gem_path}\n"
58
69
  gem_info << "\tDefault Gem: yes" if spec.respond_to?(:default_gem?) && spec.default_gem?
59
70
  Bundler.ui.info gem_info