Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
15 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/bundler/cli/gem.rb
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ def run
open_editor(options["edit"], target.join("#{name}.gemspec")) if options[:edit]

Bundler.ui.info "\nGem '#{name}' was successfully created. " \
"For more information on making a RubyGem visit https://bundler.io/guides/creating_gem.html"
"For more information on making a RubyGem visit https://guides.rubygems.org/make-your-own-gem/"
end

private
Expand Down
6 changes: 6 additions & 0 deletions lib/bundler/man/bundle-config.1
Original file line number Diff line number Diff line change
Expand Up @@ -154,9 +154,15 @@ The path to the lockfile that bundler should use\. By default, Bundler adds \fB\
\fBlockfile_checksums\fR (\fBBUNDLE_LOCKFILE_CHECKSUMS\fR)
Whether Bundler should include a checksums section in new lockfiles, to protect from compromised gem sources\. Defaults to true\.
.TP
\fBno_build_extension\fR (\fBBUNDLE_NO_BUILD_EXTENSION\fR)
Whether Bundler should skip building native extensions during installation\. When set, gems are installed without compiling their C extensions\. To build extensions later, unset this setting and run \fBbundle pristine <gem>\fR\.
.TP
\fBno_install\fR (\fBBUNDLE_NO_INSTALL\fR)
Whether \fBbundle package\fR should skip installing gems\.
.TP
\fBno_install_plugin\fR (\fBBUNDLE_NO_INSTALL_PLUGIN\fR)
Whether Bundler should skip installing RubyGems plugins during installation\. When set, plugin files are not written to the plugins directory\. To install plugins later, unset this setting and run \fBbundle pristine <gem>\fR\.
.TP
\fBno_prune\fR (\fBBUNDLE_NO_PRUNE\fR)
Whether Bundler should leave outdated gems unpruned when caching\.
.TP
Expand Down
8 changes: 8 additions & 0 deletions lib/bundler/man/bundle-config.1.ronn
Original file line number Diff line number Diff line change
Expand Up @@ -200,8 +200,16 @@ learn more about their operation in [bundle install(1)](bundle-install.1.html).
Gemfile to disable lockfile creation entirely (see gemfile(5)).
* `lockfile_checksums` (`BUNDLE_LOCKFILE_CHECKSUMS`):
Whether Bundler should include a checksums section in new lockfiles, to protect from compromised gem sources. Defaults to true.
* `no_build_extension` (`BUNDLE_NO_BUILD_EXTENSION`):
Whether Bundler should skip building native extensions during installation.
When set, gems are installed without compiling their C extensions.
To build extensions later, unset this setting and run `bundle pristine <gem>`.
* `no_install` (`BUNDLE_NO_INSTALL`):
Whether `bundle package` should skip installing gems.
* `no_install_plugin` (`BUNDLE_NO_INSTALL_PLUGIN`):
Whether Bundler should skip installing RubyGems plugins during installation.
When set, plugin files are not written to the plugins directory.
To install plugins later, unset this setting and run `bundle pristine <gem>`.
* `no_prune` (`BUNDLE_NO_PRUNE`):
Whether Bundler should leave outdated gems unpruned when caching.
* `only` (`BUNDLE_ONLY`):
Expand Down
27 changes: 25 additions & 2 deletions lib/bundler/rubygems_gem_installer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,24 @@ def install
extract_files
end

build_extensions if spec.extensions.any?
if options[:build_extension] == false
warn_skipped_extensions
elsif spec.extensions.any?
build_extensions
end
write_build_info_file
run_post_build_hooks

SharedHelpers.filesystem_access(bin_dir, :write) do
generate_bin
end

generate_plugins
if options[:install_plugin] == false
remove_stale_plugins
warn_skipped_plugins
else
generate_plugins
end

write_spec

Expand Down Expand Up @@ -80,6 +89,20 @@ def generate_plugins
end
end

def warn_skipped_extensions
return if spec.extensions.empty?

Bundler.ui.warn "#{spec.full_name} contains native extensions that were not built.\n" \
"To build extensions, unset no_build_extension and run `bundle pristine #{spec.name}`."
end

def warn_skipped_plugins
return if spec.plugins.empty?

Bundler.ui.warn "#{spec.full_name} contains plugins that were not installed.\n" \
"To install plugins, unset no_install_plugin and run `bundle pristine #{spec.name}`."
end

if Bundler.rubygems.provides?("< 3.5.19")
def generate_bin_script(filename, bindir)
bin_script_path = File.join bindir, formatted_program_filename(filename)
Expand Down
2 changes: 2 additions & 0 deletions lib/bundler/settings.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@ class Settings
init_gems_rb
inline
lockfile_checksums
no_build_extension
no_install
no_install_plugin
no_prune
path.system
plugins
Expand Down
2 changes: 1 addition & 1 deletion lib/bundler/source/path/installer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def initialize(spec, options = {})
def post_install
run_hooks(:pre_install)

unless @disable_extensions
unless @disable_extensions || Bundler.settings[:no_build_extension]
build_extensions
run_hooks(:post_build)
end
Expand Down
4 changes: 3 additions & 1 deletion lib/bundler/source/rubygems.rb
Original file line number Diff line number Diff line change
Expand Up @@ -533,7 +533,9 @@ def rubygems_gem_installer(spec, options)
wrappers: true,
env_shebang: true,
build_args: options[:build_args],
bundler_extension_cache_path: extension_cache_path(spec)
bundler_extension_cache_path: extension_cache_path(spec),
build_extension: Bundler.settings[:no_build_extension] ? false : nil,
install_plugin: Bundler.settings[:no_install_plugin] ? false : nil
)
@gem_installers_mutex.synchronize { @gem_installers[spec.name] ||= installer }
end
Expand Down
2 changes: 1 addition & 1 deletion lib/bundler/templates/newgem/newgem.gemspec.tt
Original file line number Diff line number Diff line change
Expand Up @@ -54,5 +54,5 @@ Gem::Specification.new do |spec|
<%- end -%>

# For more information and examples about making a new gem, check out our
# guide at: https://bundler.io/guides/creating_gem.html
# guide at: https://guides.rubygems.org/make-your-own-gem/
end
10 changes: 5 additions & 5 deletions lib/ipaddr.rb
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ def loopback?
@addr & 0xff000000 == 0x7f000000 # 127.0.0.1/8
when Socket::AF_INET6
@addr == 1 || # ::1
(@addr & 0xffff_0000_0000 == 0xffff_0000_0000 && (
(@addr >> 32 == 0xffff && (
@addr & 0xff000000 == 0x7f000000 # ::ffff:127.0.0.1/8
))
else
Expand All @@ -314,10 +314,10 @@ def private?
@addr & 0xffff0000 == 0xc0a80000 # 192.168.0.0/16
when Socket::AF_INET6
@addr & 0xfe00_0000_0000_0000_0000_0000_0000_0000 == 0xfc00_0000_0000_0000_0000_0000_0000_0000 ||
(@addr & 0xffff_0000_0000 == 0xffff_0000_0000 && (
(@addr >> 32 == 0xffff && (
@addr & 0xff000000 == 0x0a000000 || # ::ffff:10.0.0.0/8
@addr & 0xfff00000 == 0xac100000 || # ::ffff::172.16.0.0/12
@addr & 0xffff0000 == 0xc0a80000 # ::ffff::192.168.0.0/16
@addr & 0xfff00000 == 0xac100000 || # ::ffff:172.16.0.0/12
@addr & 0xffff0000 == 0xc0a80000 # ::ffff:192.168.0.0/16
))
else
raise AddressFamilyError, "unsupported address family"
Expand All @@ -335,7 +335,7 @@ def link_local?
@addr & 0xffff0000 == 0xa9fe0000 # 169.254.0.0/16
when Socket::AF_INET6
@addr & 0xffc0_0000_0000_0000_0000_0000_0000_0000 == 0xfe80_0000_0000_0000_0000_0000_0000_0000 || # fe80::/10
(@addr & 0xffff_0000_0000 == 0xffff_0000_0000 && (
(@addr >> 32 == 0xffff && (
@addr & 0xffff0000 == 0xa9fe0000 # ::ffff:169.254.0.0/16
))
else
Expand Down
28 changes: 21 additions & 7 deletions lib/prism/translation/ripper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -704,6 +704,8 @@ def visit_array_node(node)
previous = element
end

visit_words_sep(opening_loc, node.elements.last, node.closing_loc)

bounds(node.closing_loc)
on_tstring_end(node.closing)
when /^%i/
Expand All @@ -723,6 +725,8 @@ def visit_array_node(node)
previous = element
end

visit_words_sep(opening_loc, node.elements.last, node.closing_loc)

bounds(node.closing_loc)
on_tstring_end(node.closing)
when /^%W/
Expand Down Expand Up @@ -760,6 +764,8 @@ def visit_array_node(node)
previous = element
end

visit_words_sep(opening_loc, node.elements.last, node.closing_loc)

bounds(node.closing_loc)
on_tstring_end(node.closing)
when /^%I/
Expand Down Expand Up @@ -797,6 +803,8 @@ def visit_array_node(node)
previous = element
end

visit_words_sep(opening_loc, node.elements.last, node.closing_loc)

bounds(node.closing_loc)
on_tstring_end(node.closing)
else
Expand All @@ -813,15 +821,21 @@ def visit_array_node(node)
on_array(elements)
end

# Dispatch a words_sep event that contains the space between the elements
# Dispatch words_sep events that contains the whitespace between the elements
# of list literals.
private def visit_words_sep(opening_loc, previous, current)
end_offset = (previous.nil? ? opening_loc : previous.location).end_offset
start_offset = current.location.start_offset

if end_offset != start_offset
bounds(current.location.copy(start_offset: end_offset))
on_words_sep(source.byteslice(end_offset...start_offset))
start_offset = (previous.nil? ? opening_loc : previous.location).end_offset
end_offset = current.start_offset
length = end_offset - start_offset

if length > 0
whitespace = source.byteslice(start_offset, length)
current_offset = start_offset
whitespace.each_line do |part|
bounds(opening_loc.copy(start_offset: current_offset, length: part.bytesize))
on_words_sep(part)
current_offset += part.bytesize
end
end
end

Expand Down
4 changes: 4 additions & 0 deletions lib/rubygems/dependency_installer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ def initialize(options = {})
@dir_mode = options[:dir_mode]
@data_mode = options[:data_mode]
@prog_mode = options[:prog_mode]
@build_extension = options[:build_extension]
@install_plugin = options[:install_plugin]

# Indicates that we should not try to update any deps unless
# we absolutely must.
Expand Down Expand Up @@ -169,6 +171,8 @@ def install(dep_or_name, version = Gem::Requirement.default)
dir_mode: @dir_mode,
data_mode: @data_mode,
prog_mode: @prog_mode,
build_extension: @build_extension,
install_plugin: @install_plugin,
}
options[:install_dir] = @install_dir if @only_install_dir

Expand Down
12 changes: 12 additions & 0 deletions lib/rubygems/install_update_options.rb
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,18 @@ def add_install_update_options
"rbconfig.rb for the deployment target platform") do |v, _o|
Gem.set_target_rbconfig(v)
end

add_option(:"Install/Update", "--[no-]build-extension",
"Build native extensions during installation.",
"Defaults to true") do |v, _o|
options[:build_extension] = v
end

add_option(:"Install/Update", "--[no-]install-plugin",
"Install plugins during installation.",
"Defaults to true") do |v, _o|
options[:install_plugin] = v
end
end

##
Expand Down
42 changes: 37 additions & 5 deletions lib/rubygems/installer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,12 @@ def install
run_post_build_hooks

generate_bin
generate_plugins
if options[:install_plugin] == false
remove_stale_plugins
warn_skipped_plugins
else
generate_plugins
end

write_spec
write_cache_file
Expand All @@ -298,7 +303,7 @@ def install

Gem::Specification.add_spec(spec) unless @install_dir

load_plugin
load_plugin unless options[:install_plugin] == false

run_post_install_hooks

Expand Down Expand Up @@ -804,11 +809,37 @@ def windows_stub_script(bindir, bin_file_name)
# configure scripts and rakefiles or mkrf_conf files.

def build_extensions
if options[:build_extension] == false
warn_skipped_extensions
return
end

builder = Gem::Ext::Builder.new spec, build_args, Gem.target_rbconfig, build_jobs

builder.build_extensions
end

def warn_skipped_extensions # :nodoc:
return if spec.extensions.empty?

alert_warning "#{spec.full_name} contains native extensions that were not built.\n" \
"To build extensions, run: gem pristine #{spec.name} --extensions"
end

def warn_skipped_plugins # :nodoc:
return if spec.plugins.empty?

alert_warning "#{spec.full_name} contains plugins that were not installed.\n" \
"To install plugins, run: gem pristine #{spec.name} --only-plugins"
end

def remove_stale_plugins # :nodoc:
return unless spec.plugins.empty?

ensure_writable_dir @plugins_dir
remove_plugins_for(spec, @plugins_dir)
end

##
# Reads the file index and extracts each file into the gem directory.
#
Expand Down Expand Up @@ -990,9 +1021,10 @@ def load_plugin
# are loaded at the same time.
return unless specs.size == 1

plugin_files = spec.plugins.map do |plugin|
File.join(@plugins_dir, "#{spec.name}_plugin#{File.extname(plugin)}")
plugin_files = spec.plugins.filter_map do |plugin|
path = File.join(@plugins_dir, "#{spec.name}_plugin#{File.extname(plugin)}")
path if File.exist?(path)
end
Gem.load_plugin_files(plugin_files)
Gem.load_plugin_files(plugin_files) unless plugin_files.empty?
end
end
2 changes: 1 addition & 1 deletion lib/rubygems/request_set.rb
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ def install(options, &block) # :yields: request, installer
# Install requested gems after they have been downloaded
sorted_requests.each do |req|
if req.installed? && @always_install.none? {|spec| spec == req.spec.spec }
req.spec.spec.build_extensions
req.spec.spec.build_extensions unless options[:build_extension] == false
yield req, nil if block_given?
next
end
Expand Down
54 changes: 54 additions & 0 deletions spec/bundler/install/gems/no_build_extension_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# frozen_string_literal: true

RSpec.describe "bundle install with --no-build-extension" do
before do
build_repo2 do
build_gem "with_extension" do |s|
s.extensions << "Rakefile"
s.write "Rakefile", <<-RUBY
task :default do
path = File.expand_path("lib", __dir__)
FileUtils.mkdir_p(path)
File.open("\#{path}/with_extension.rb", "w") do |f|
f.puts "WITH_EXTENSION = 'YES'"
end
end
RUBY
end
end
end

it "skips building native extensions and warns when no_build_extension is set" do
bundle_config "no_build_extension true"

gemfile <<-G
source "https://gem.repo2"
gem "with_extension"
gem "rake"
G

bundle :install

build_complete = default_bundle_path("extensions").join(
Gem::Platform.local.to_s,
Gem.extension_api_version.to_s,
"with_extension-1.0",
"gem.build_complete"
)
expect(build_complete).not_to exist
expect(err).to include("with_extension-1.0 contains native extensions that were not built")
expect(err).to include("unset no_build_extension and run `bundle pristine with_extension`")
end

it "builds native extensions by default" do
gemfile <<-G
source "https://gem.repo2"
gem "with_extension"
gem "rake"
G

bundle :install

expect(out).to include("Installing with_extension 1.0 with native extensions")
end
end
Loading