summaryrefslogtreecommitdiff
path: root/lib/bundler/cli/gem.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/bundler/cli/gem.rb')
-rw-r--r--lib/bundler/cli/gem.rb126
1 files changed, 75 insertions, 51 deletions
diff --git a/lib/bundler/cli/gem.rb b/lib/bundler/cli/gem.rb
index 31e3af5580..b6571d0e86 100644
--- a/lib/bundler/cli/gem.rb
+++ b/lib/bundler/cli/gem.rb
@@ -11,11 +11,11 @@ module Bundler
class CLI::Gem
TEST_FRAMEWORK_VERSIONS = {
"rspec" => "3.0",
- "minitest" => "5.0",
+ "minitest" => "5.16",
"test-unit" => "3.0",
}.freeze
- attr_reader :options, :gem_name, :thor, :name, :target
+ attr_reader :options, :gem_name, :thor, :name, :target, :extension
def initialize(options, gem_name, thor)
@options = options
@@ -28,7 +28,10 @@ module Bundler
@name = @gem_name
@target = SharedHelpers.pwd.join(gem_name)
- validate_ext_name if options[:ext]
+ @extension = options[:ext]
+
+ validate_ext_name if @extension
+ validate_rust_builder_rubygems_version if @extension == "rust"
end
def run
@@ -38,6 +41,7 @@ module Bundler
namespaced_path = name.tr("-", "/")
constant_name = name.gsub(/-[_-]*(?![_-]|$)/) { "::" }.gsub(/([_-]+|(::)|^)(.|$)/) { $2.to_s + $3.upcase }
constant_array = constant_name.split("::")
+ minitest_constant_name = constant_array.clone.tap {|a| a[-1] = "Test#{a[-1]}" }.join("::") # Foo::Bar => Foo::TestBar
use_git = Bundler.git_present? && options[:git]
@@ -54,21 +58,23 @@ module Bundler
end
config = {
- :name => name,
- :underscored_name => underscored_name,
- :namespaced_path => namespaced_path,
- :makefile_path => "#{underscored_name}/#{underscored_name}",
- :constant_name => constant_name,
- :constant_array => constant_array,
- :author => git_author_name.empty? ? "TODO: Write your name" : git_author_name,
- :email => git_user_email.empty? ? "TODO: Write your email address" : git_user_email,
- :test => options[:test],
- :ext => options[:ext],
- :exe => options[:exe],
- :bundler_version => bundler_dependency_version,
- :git => use_git,
- :github_username => github_username.empty? ? "[USERNAME]" : github_username,
- :required_ruby_version => required_ruby_version,
+ name: name,
+ underscored_name: underscored_name,
+ namespaced_path: namespaced_path,
+ makefile_path: "#{underscored_name}/#{underscored_name}",
+ constant_name: constant_name,
+ constant_array: constant_array,
+ author: git_author_name.empty? ? "TODO: Write your name" : git_author_name,
+ email: git_user_email.empty? ? "TODO: Write your email address" : git_user_email,
+ test: options[:test],
+ ext: extension,
+ exe: options[:exe],
+ bundler_version: bundler_dependency_version,
+ git: use_git,
+ github_username: github_username.empty? ? "[USERNAME]" : github_username,
+ required_ruby_version: required_ruby_version,
+ rust_builder_required_rubygems_version: rust_builder_required_rubygems_version,
+ minitest_constant_name: minitest_constant_name,
}
ensure_safe_gem_name(name, constant_array)
@@ -104,9 +110,17 @@ module Bundler
)
config[:test_task] = :spec
when "minitest"
+ # Generate path for minitest target file (FileList["test/**/test_*.rb"])
+ # foo => test/test_foo.rb
+ # foo-bar => test/foo/test_bar.rb
+ # foo_bar => test/test_foo_bar.rb
+ paths = namespaced_path.rpartition("/")
+ paths[2] = "test_#{paths[2]}"
+ minitest_namespaced_path = paths.join("")
+
templates.merge!(
"test/minitest/test_helper.rb.tt" => "test/test_helper.rb",
- "test/minitest/test_newgem.rb.tt" => "test/test_#{namespaced_path}.rb"
+ "test/minitest/test_newgem.rb.tt" => "test/#{minitest_namespaced_path}.rb"
)
config[:test_task] = :test
when "test-unit"
@@ -122,12 +136,13 @@ module Bundler
case config[:ci]
when "github"
templates.merge!("github/workflows/main.yml.tt" => ".github/workflows/main.yml")
- when "travis"
- templates.merge!("travis.yml.tt" => ".travis.yml")
+ config[:ci_config_path] = ".github "
when "gitlab"
templates.merge!("gitlab-ci.yml.tt" => ".gitlab-ci.yml")
+ config[:ci_config_path] = ".gitlab-ci.yml "
when "circle"
templates.merge!("circleci/config.yml.tt" => ".circleci/config.yml")
+ config[:ci_config_path] = ".circleci "
end
if ask_and_set(:mit, "Do you want to license your code permissively under the MIT license?",
@@ -178,14 +193,23 @@ module Bundler
templates.merge!("exe/newgem.tt" => "exe/#{name}") if config[:exe]
- if options[:ext]
+ if extension == "c"
templates.merge!(
- "ext/newgem/extconf.rb.tt" => "ext/#{name}/extconf.rb",
+ "ext/newgem/extconf-c.rb.tt" => "ext/#{name}/extconf.rb",
"ext/newgem/newgem.h.tt" => "ext/#{name}/#{underscored_name}.h",
"ext/newgem/newgem.c.tt" => "ext/#{name}/#{underscored_name}.c"
)
end
+ if extension == "rust"
+ templates.merge!(
+ "Cargo.toml.tt" => "Cargo.toml",
+ "ext/newgem/Cargo.toml.tt" => "ext/#{name}/Cargo.toml",
+ "ext/newgem/extconf-rust.rb.tt" => "ext/#{name}/extconf.rb",
+ "ext/newgem/src/lib.rs.tt" => "ext/#{name}/src/lib.rs",
+ )
+ end
+
if target.exist? && !target.directory?
Bundler.ui.error "Couldn't create a new gem named `#{gem_name}` because there's an existing file named `#{gem_name}`."
exit Bundler::BundlerError.all_errors[Bundler::GenericSystemCallError]
@@ -211,9 +235,7 @@ module Bundler
end
if use_git
- Dir.chdir(target) do
- `git add .`
- end
+ IO.popen(%w[git add .], { chdir: target }, &:read)
end
# Open gemspec in editor
@@ -260,7 +282,7 @@ module Bundler
Bundler.ui.info hint_text("test")
result = Bundler.ui.ask "Enter a test framework. rspec/minitest/test-unit/(none):"
- if result =~ /rspec|minitest|test-unit/
+ if /rspec|minitest|test-unit/.match?(result)
test_framework = result
else
test_framework = false
@@ -296,12 +318,11 @@ module Bundler
"* CircleCI: https://circleci.com/\n" \
"* GitHub Actions: https://github.com/features/actions\n" \
"* GitLab CI: https://docs.gitlab.com/ee/ci/\n" \
- "* Travis CI: https://travis-ci.org/\n" \
"\n"
Bundler.ui.info hint_text("ci")
- result = Bundler.ui.ask "Enter a CI service. github/travis/gitlab/circle/(none):"
- if result =~ /github|travis|gitlab|circle/
+ result = Bundler.ui.ask "Enter a CI service. github/gitlab/circle/(none):"
+ if /github|gitlab|circle/.match?(result)
ci_template = result
else
ci_template = false
@@ -327,12 +348,12 @@ module Bundler
Bundler.ui.confirm "Do you want to add a code linter and formatter to your gem? " \
"Supported Linters:\n" \
"* RuboCop: https://rubocop.org\n" \
- "* Standard: https://github.com/testdouble/standard\n" \
+ "* Standard: https://github.com/standardrb/standard\n" \
"\n"
Bundler.ui.info hint_text("linter")
result = Bundler.ui.ask "Enter a linter. rubocop/standard/(none):"
- if result =~ /rubocop|standard/
+ if /rubocop|standard/.match?(result)
linter_template = result
else
linter_template = false
@@ -358,15 +379,20 @@ module Bundler
def deprecated_rubocop_option
if !options[:rubocop].nil?
if options[:rubocop]
- Bundler::SharedHelpers.major_deprecation 2, "--rubocop is deprecated, use --linter=rubocop"
+ Bundler::SharedHelpers.major_deprecation 2,
+ "--rubocop is deprecated, use --linter=rubocop",
+ removed_message: "--rubocop has been removed, use --linter=rubocop"
"rubocop"
else
- Bundler::SharedHelpers.major_deprecation 2, "--no-rubocop is deprecated, use --linter"
+ Bundler::SharedHelpers.major_deprecation 2,
+ "--no-rubocop is deprecated, use --linter",
+ removed_message: "--no-rubocop has been removed, use --linter"
false
end
elsif !Bundler.settings["gem.rubocop"].nil?
Bundler::SharedHelpers.major_deprecation 2,
- "config gem.rubocop is deprecated; we've updated your config to use gem.linter instead"
+ "config gem.rubocop is deprecated; we've updated your config to use gem.linter instead",
+ removed_message: "config gem.rubocop has been removed; we've updated your config to use gem.linter instead"
Bundler.settings["gem.rubocop"] ? "rubocop" : false
end
end
@@ -379,7 +405,7 @@ module Bundler
end
def ensure_safe_gem_name(name, constant_array)
- if name =~ /^\d/
+ if /^\d/.match?(name)
Bundler.ui.error "Invalid gem name #{name} Please give a name which does not start with numbers."
exit 1
end
@@ -405,28 +431,26 @@ module Bundler
thor.run(%(#{editor} "#{file}"))
end
+ def rust_builder_required_rubygems_version
+ "3.3.11"
+ end
+
def required_ruby_version
- if Gem.ruby_version < Gem::Version.new("2.4.a") then "2.3.0"
- elsif Gem.ruby_version < Gem::Version.new("2.5.a") then "2.4.0"
- elsif Gem.ruby_version < Gem::Version.new("2.6.a") then "2.5.0"
- else
- "2.6.0"
- end
+ "3.0.0"
end
def rubocop_version
- if Gem.ruby_version < Gem::Version.new("2.4.a") then "0.81.0"
- elsif Gem.ruby_version < Gem::Version.new("2.5.a") then "1.12"
- else
- "1.21"
- end
+ "1.21"
end
def standard_version
- if Gem.ruby_version < Gem::Version.new("2.4.a") then "0.2.5"
- elsif Gem.ruby_version < Gem::Version.new("2.5.a") then "1.0"
- else
- "1.3"
+ "1.3"
+ end
+
+ def validate_rust_builder_rubygems_version
+ if Gem::Version.new(rust_builder_required_rubygems_version) > Gem.rubygems_version
+ Bundler.ui.error "Your RubyGems version (#{Gem.rubygems_version}) is too old to build Rust extension. Please update your RubyGems using `gem update --system` or any other way and try again."
+ exit 1
end
end
end