Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 3 additions & 0 deletions .document
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ lib
# and some of the ext/ directory (which has its own .document file)
ext

# For `prism`, ruby code is in lib and c in the prism folder
prism

# rdoc files
NEWS.md

Expand Down
158 changes: 152 additions & 6 deletions dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -504,6 +504,20 @@ fnmatch(
}

VALUE rb_cDir;
static VALUE sym_directory, sym_link, sym_file, sym_unknown;

#ifdef DT_BLK
static VALUE sym_block_device;
#endif
#ifdef DT_CHR
static VALUE sym_character_device;
#endif
#ifdef DT_FIFO
static VALUE sym_fifo;
#endif
#ifdef DT_SOCK
static VALUE sym_socket;
#endif

struct dir_data {
DIR *dir;
Expand Down Expand Up @@ -905,14 +919,61 @@ dir_read(VALUE dir)
}
}

static VALUE dir_each_entry(VALUE, VALUE (*)(VALUE, VALUE), VALUE, int);
static VALUE dir_each_entry(VALUE, VALUE (*)(VALUE, VALUE, unsigned char), VALUE, int);

static VALUE
dir_yield(VALUE arg, VALUE path)
dir_yield(VALUE arg, VALUE path, unsigned char dtype)
{
return rb_yield(path);
}

static VALUE
dir_yield_with_type(VALUE arg, VALUE path, unsigned char dtype)
{
VALUE type;
switch (dtype) {
#ifdef DT_BLK
case DT_BLK:
type = sym_block_device;
break;
#endif
#ifdef DT_CHR
case DT_CHR:
type = sym_character_device;
break;
#endif
case DT_DIR:
type = sym_directory;
break;
#ifdef DT_FIFO
case DT_FIFO:
type = sym_fifo;
break;
#endif
case DT_LNK:
type = sym_link;
break;
case DT_REG:
type = sym_file;
break;
#ifdef DT_SOCK
case DT_SOCK:
type = sym_socket;
break;
#endif
default:
type = sym_unknown;
break;
}

if (NIL_P(arg)) {
return rb_yield_values(2, path, type);
}
else {
return rb_ary_push(arg, rb_assoc_new(path, type));
}
}

/*
* call-seq:
* each {|entry_name| ... } -> self
Expand Down Expand Up @@ -940,7 +1001,7 @@ dir_each(VALUE dir)
}

static VALUE
dir_each_entry(VALUE dir, VALUE (*each)(VALUE, VALUE), VALUE arg, int children_only)
dir_each_entry(VALUE dir, VALUE (*each)(VALUE, VALUE, unsigned char), VALUE arg, int children_only)
{
struct dir_data *dirp;
struct dirent *dp;
Expand All @@ -966,7 +1027,7 @@ dir_each_entry(VALUE dir, VALUE (*each)(VALUE, VALUE), VALUE arg, int children_o
else
#endif
path = rb_external_str_new_with_enc(name, namlen, dirp->enc);
(*each)(arg, path);
(*each)(arg, path, dp->d_type);
}
return dir;
}
Expand Down Expand Up @@ -3470,11 +3531,17 @@ dir_foreach(int argc, VALUE *argv, VALUE io)
return Qnil;
}

static VALUE
dir_entry_ary_push(VALUE ary, VALUE entry, unsigned char ftype)
{
return rb_ary_push(ary, entry);
}

static VALUE
dir_collect(VALUE dir)
{
VALUE ary = rb_ary_new();
dir_each_entry(dir, rb_ary_push, ary, FALSE);
dir_each_entry(dir, dir_entry_ary_push, ary, FALSE);
return ary;
}

Expand Down Expand Up @@ -3569,10 +3636,35 @@ static VALUE
dir_collect_children(VALUE dir)
{
VALUE ary = rb_ary_new();
dir_each_entry(dir, rb_ary_push, ary, TRUE);
dir_each_entry(dir, dir_entry_ary_push, ary, TRUE);
return ary;
}

/*
* call-seq:
* children -> array
*
* Returns an array of the entry names in +self+ along with their type
* except for <tt>'.'</tt> and <tt>'..'</tt>:
*
* dir = Dir.new('/example')
* dir.scan # => [["config.h", :file], ["lib", :directory], ["main.rb", :file]]
*
*/
static VALUE
dir_scan_children(VALUE dir)
{
if (rb_block_given_p()) {
dir_each_entry(dir, dir_yield_with_type, Qnil, TRUE);
return Qnil;
}
else {
VALUE ary = rb_ary_new();
dir_each_entry(dir, dir_yield_with_type, ary, TRUE);
return ary;
}
}

/*
* call-seq:
* Dir.children(dirpath) -> array
Expand Down Expand Up @@ -3601,6 +3693,40 @@ dir_s_children(int argc, VALUE *argv, VALUE io)
return rb_ensure(dir_collect_children, dir, dir_close, dir);
}

/*
* call-seq:
* Dir.scan(dirpath) {|entry_name, entry_type| ... } -> nil
* Dir.scan(dirpath, encoding: 'UTF-8') {|entry_name, entry_type| ... } -> nil
* Dir.scan(dirpath) -> [[entry_name, entry_type], ...]
* Dir.scan(dirpath, encoding: 'UTF-8') -> [[entry_name, entry_type], ...]
*
* Yields or returns an array of the entry names in the directory at +dirpath+
* associated with their type, except for <tt>'.'</tt> and <tt>'..'</tt>;
* sets the given encoding onto each returned entry name.
*
* The type symbol is one of:
* ``<code>:file</code>'', ``<code>:directory</code>'',
* ``<code>:characterSpecial</code>'', ``<code>:blockSpecial</code>'',
* ``<code>:fifo</code>'', ``<code>:link</code>'',
* or ``<code>:socket</code>'':
*
* Dir.children('/example') # => [["config.h", :file], ["lib", :directory], ["main.rb", :file]]
* Dir.children('/example').first.first.encoding
* # => #<Encoding:UTF-8>
* Dir.children('/example', encoding: 'US-ASCII').first.encoding
* # => #<Encoding:US-ASCII>
*
* See {String Encoding}[rdoc-ref:encodings.rdoc@String+Encoding].
*
* Raises an exception if the directory does not exist.
*/
static VALUE
dir_s_scan(int argc, VALUE *argv, VALUE klass)
{
VALUE dir = dir_open_dir(argc, argv);
return rb_ensure(dir_scan_children, dir, dir_close, dir);
}

static int
fnmatch_brace(const char *pattern, VALUE val, void *enc)
{
Expand Down Expand Up @@ -3804,6 +3930,24 @@ rb_dir_s_empty_p(VALUE obj, VALUE dirname)
void
Init_Dir(void)
{
sym_directory = ID2SYM(rb_intern("directory"));
sym_link = ID2SYM(rb_intern("link"));
sym_file = ID2SYM(rb_intern("file"));
sym_unknown = ID2SYM(rb_intern("unknown"));

#ifdef DT_BLK
sym_block_device = ID2SYM(rb_intern("blockSpecial"));
#endif
#ifdef DT_CHR
sym_character_device = ID2SYM(rb_intern("characterSpecial"));
#endif
#ifdef DT_FIFO
sym_fifo = ID2SYM(rb_intern("fifo"));
#endif
#ifdef DT_SOCK
sym_socket = ID2SYM(rb_intern("socket"));
#endif

rb_gc_register_address(&chdir_lock.path);
rb_gc_register_address(&chdir_lock.thread);

Expand All @@ -3817,6 +3961,7 @@ Init_Dir(void)
rb_define_singleton_method(rb_cDir, "entries", dir_entries, -1);
rb_define_singleton_method(rb_cDir, "each_child", dir_s_each_child, -1);
rb_define_singleton_method(rb_cDir, "children", dir_s_children, -1);
rb_define_singleton_method(rb_cDir, "scan", dir_s_scan, -1);

rb_define_method(rb_cDir,"fileno", dir_fileno, 0);
rb_define_method(rb_cDir,"path", dir_path, 0);
Expand All @@ -3826,6 +3971,7 @@ Init_Dir(void)
rb_define_method(rb_cDir,"each", dir_each, 0);
rb_define_method(rb_cDir,"each_child", dir_each_child_m, 0);
rb_define_method(rb_cDir,"children", dir_collect_children, 0);
rb_define_method(rb_cDir,"scan", dir_scan_children, 0);
rb_define_method(rb_cDir,"rewind", dir_rewind, 0);
rb_define_method(rb_cDir,"tell", dir_tell, 0);
rb_define_method(rb_cDir,"seek", dir_seek, 1);
Expand Down
6 changes: 5 additions & 1 deletion enc/make_encmake.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
#! ./miniruby

dir = File.expand_path("../..", __FILE__)
$:.unshift(Dir.pwd, "#{dir}/tool/lib", "#{dir}/lib")
# The source lib directory provides the standard library for miniruby.
# Don't add it when running with baseruby to avoid loading both
# baseruby's cgi/escape.so and source cgi/escape.rb via erb.
$:.unshift("#{dir}/lib") unless defined?(CROSS_COMPILING)
$:.unshift(Dir.pwd, "#{dir}/tool/lib")
if $".grep(/mkmf/).empty?
$" << "mkmf.rb"
load File.expand_path("lib/mkmf.rb", dir)
Expand Down
4 changes: 2 additions & 2 deletions gc/mmtk/mmtk.c
Original file line number Diff line number Diff line change
Expand Up @@ -689,8 +689,8 @@ rb_gc_impl_start(void *objspace_ptr, bool full_mark, bool immediate_mark, bool i
bool
rb_gc_impl_during_gc_p(void *objspace_ptr)
{
// TODO
return false;
struct objspace *objspace = objspace_ptr;
return objspace->world_stopped;
}

static void
Expand Down
7 changes: 6 additions & 1 deletion lib/bundler/source/rubygems.rb
Original file line number Diff line number Diff line change
Expand Up @@ -504,7 +504,12 @@ def download_cache_path(spec)
return unless remote = spec.remote
return unless cache_slug = remote.cache_slug

Bundler.user_cache.join("gems", cache_slug)
if Gem.respond_to?(:global_gem_cache_path)
Pathname.new(Gem.global_gem_cache_path).join(cache_slug)
else
# Fall back to old location for older RubyGems versions
Bundler.user_cache.join("gems", cache_slug)
end
end

def extension_cache_slug(spec)
Expand Down
9 changes: 6 additions & 3 deletions lib/prism/lex_compat.rb
Original file line number Diff line number Diff line change
Expand Up @@ -768,21 +768,24 @@ def result
source.byte_offset(line, column)
end

# Add :on_sp tokens
tokens = insert_on_sp(tokens, source, result.data_loc, bom, eof_token)
tokens = post_process_tokens(tokens, source, result.data_loc, bom, eof_token)

Result.new(tokens, result.comments, result.magic_comments, result.data_loc, result.errors, result.warnings, source)
end

private

def insert_on_sp(tokens, source, data_loc, bom, eof_token)
def post_process_tokens(tokens, source, data_loc, bom, eof_token)
new_tokens = []

prev_token_state = Translation::Ripper::Lexer::State[Translation::Ripper::EXPR_BEG]
prev_token_end = bom ? 3 : 0

tokens.each do |token|
# Skip missing heredoc ends.
next if token[1] == :on_heredoc_end && token[2] == ""

# Add :on_sp tokens.
line, column = token[0]
start_offset = source.byte_offset(line, column)

Expand Down
2 changes: 2 additions & 0 deletions lib/rubygems.rb
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,8 @@ def self.plugindir(install_dir = Gem.dir)
def self.clear_paths
@paths = nil
@user_home = nil
@cache_home = nil
@data_home = nil
Gem::Specification.reset
Gem::Security.reset if defined?(Gem::Security)
end
Expand Down
13 changes: 11 additions & 2 deletions lib/rubygems/config_file.rb
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ class Gem::ConfigFile
DEFAULT_IPV4_FALLBACK_ENABLED = false
# TODO: Use false as default value for this option in RubyGems 4.0
DEFAULT_INSTALL_EXTENSION_IN_LIB = true
DEFAULT_GLOBAL_GEM_CACHE = false

##
# For Ruby packagers to set configuration defaults. Set in
Expand Down Expand Up @@ -155,6 +156,12 @@ class Gem::ConfigFile

attr_accessor :ipv4_fallback_enabled

##
# Use a global cache for .gem files shared across all Ruby installations.
# When enabled, gems are cached to ~/.cache/gem/gems (or XDG_CACHE_HOME/gem/gems).

attr_accessor :global_gem_cache

##
# Path name of directory or file of openssl client certificate, used for remote https connection with client authentication

Expand Down Expand Up @@ -192,6 +199,7 @@ def initialize(args)
@cert_expiration_length_days = DEFAULT_CERT_EXPIRATION_LENGTH_DAYS
@install_extension_in_lib = DEFAULT_INSTALL_EXTENSION_IN_LIB
@ipv4_fallback_enabled = ENV["IPV4_FALLBACK_ENABLED"] == "true" || DEFAULT_IPV4_FALLBACK_ENABLED
@global_gem_cache = ENV["RUBYGEMS_GLOBAL_GEM_CACHE"] == "true" || DEFAULT_GLOBAL_GEM_CACHE

operating_system_config = Marshal.load Marshal.dump(OPERATING_SYSTEM_DEFAULTS)
platform_config = Marshal.load Marshal.dump(PLATFORM_DEFAULTS)
Expand All @@ -213,8 +221,8 @@ def initialize(args)
@hash.transform_keys! do |k|
# gemhome and gempath are not working with symbol keys
if %w[backtrace bulk_threshold verbose update_sources cert_expiration_length_days
install_extension_in_lib ipv4_fallback_enabled sources disable_default_gem_server
ssl_verify_mode ssl_ca_cert ssl_client_cert].include?(k)
install_extension_in_lib ipv4_fallback_enabled global_gem_cache sources
disable_default_gem_server ssl_verify_mode ssl_ca_cert ssl_client_cert].include?(k)
k.to_sym
else
k
Expand All @@ -230,6 +238,7 @@ def initialize(args)
@cert_expiration_length_days = @hash[:cert_expiration_length_days] if @hash.key? :cert_expiration_length_days
@install_extension_in_lib = @hash[:install_extension_in_lib] if @hash.key? :install_extension_in_lib
@ipv4_fallback_enabled = @hash[:ipv4_fallback_enabled] if @hash.key? :ipv4_fallback_enabled
@global_gem_cache = @hash[:global_gem_cache] if @hash.key? :global_gem_cache

@home = @hash[:gemhome] if @hash.key? :gemhome
@path = @hash[:gempath] if @hash.key? :gempath
Expand Down
9 changes: 9 additions & 0 deletions lib/rubygems/defaults.rb
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,15 @@ def self.cache_home
@cache_home ||= ENV["XDG_CACHE_HOME"] || File.join(Gem.user_home, ".cache")
end

##
# The path to the global gem cache directory.
# This is used when global_gem_cache is enabled to share .gem files
# across all Ruby installations.

def self.global_gem_cache_path
File.join(cache_home, "gem", "gems")
end

##
# The path to standard location of the user's data directory.

Expand Down
Loading