Skip to content
Merged
1 change: 0 additions & 1 deletion compile.c
Original file line number Diff line number Diff line change
Expand Up @@ -2106,7 +2106,6 @@ iseq_set_arguments(rb_iseq_t *iseq, LINK_ANCHOR *const optargs, const NODE *cons

EXPECT_NODE("iseq_set_arguments", node_args, NODE_ARGS, COMPILE_NG);

body->param.flags.ruby2_keywords = args->ruby2_keywords;
body->param.lead_num = arg_size = (int)args->pre_args_num;
if (body->param.lead_num > 0) body->param.flags.has_lead = TRUE;
debugs(" - argc: %d\n", body->param.lead_num);
Expand Down
20 changes: 13 additions & 7 deletions lib/bundler/cli.rb
Original file line number Diff line number Diff line change
Expand Up @@ -120,28 +120,31 @@ def cli_help
self.class.send(:class_options_help, shell)
end

desc "install_or_cli_help", "Tries to run bundle install but prints a summary of bundler commands if there is no Gemfile", hide: true
desc "install_or_cli_help", "Deprecated alias of install", hide: true
def install_or_cli_help
Bundler.ui.warn <<~MSG
`bundle install_or_cli_help` is a deprecated alias of `bundle install`.
It might be called due to the 'default_cli_command' being set to 'install_or_cli_help',
if so fix that by running `bundle config set default_cli_command install --global`.
MSG
invoke_other_command("install")
rescue GemfileNotFound => error
Bundler.ui.error error.message, wrap: true
invoke_other_command("cli_help")
end

def self.default_command(meth = nil)
return super if meth

unless Bundler.settings[:default_cli_command]
Bundler.ui.info <<-MSG
Bundler.ui.info <<~MSG
In a future version of Bundler, running `bundle` without argument will no longer run `bundle install`.
Instead, the `cli_help` command will be displayed. Please use `bundle install` explicitly for scripts like CI/CD.
You can use the future behavior now with `bundle config set default_cli_command cli_help --global`,
or you can continue to use the current behavior with `bundle config set default_cli_command install_or_cli_help --global`.
or you can continue to use the current behavior with `bundle config set default_cli_command install --global`.
This message will be removed after a default_cli_command value is set.

MSG
end

Bundler.settings[:default_cli_command] || "install_or_cli_help"
Bundler.settings[:default_cli_command] || "install"
end

class_option "no-color", type: :boolean, desc: "Disable colorization in output"
Expand Down Expand Up @@ -287,6 +290,9 @@ def install
Bundler.settings.temporary(no_install: false) do
Install.new(options).run
end
rescue GemfileNotFound => error
invoke_other_command("cli_help")
raise error # re-raise to show the error and get a failing exit status
end

map aliases_for("install")
Expand Down
22 changes: 22 additions & 0 deletions lib/bundler/endpoint_specification.rb
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,28 @@ def load_paths
end
end

# needed for binstubs
def executables
if @remote_specification
@remote_specification.executables
elsif _local_specification
_local_specification.executables
else
super
end
end

# needed for bundle clean
def bindir
if @remote_specification
@remote_specification.bindir
elsif _local_specification
_local_specification.bindir
else
super
end
end

# needed for post_install_messages during install
def post_install_message
if @remote_specification
Expand Down
16 changes: 0 additions & 16 deletions parse.y
Original file line number Diff line number Diff line change
Expand Up @@ -6385,11 +6385,7 @@ f_args : f_arg ',' f_opt_arg(arg_value) ',' f_rest_arg opt_args_tail(args_tail)

args_forward : tBDOT3
{
#ifdef FORWARD_ARGS_WITH_RUBY2_KEYWORDS
$$ = 0;
#else
$$ = idFWD_KWREST;
#endif
/*% ripper: args_forward! %*/
}
;
Expand Down Expand Up @@ -14434,12 +14430,6 @@ new_args(struct parser_params *p, rb_node_args_aux_t *pre_args, rb_node_opt_arg_

args->opt_args = opt_args;

#ifdef FORWARD_ARGS_WITH_RUBY2_KEYWORDS
args->ruby2_keywords = args->forwarding;
#else
args->ruby2_keywords = 0;
#endif

nd_set_loc(RNODE(tail), loc);

return tail;
Expand Down Expand Up @@ -15049,9 +15039,7 @@ static void
add_forwarding_args(struct parser_params *p)
{
arg_var(p, idFWD_REST);
#ifndef FORWARD_ARGS_WITH_RUBY2_KEYWORDS
arg_var(p, idFWD_KWREST);
#endif
arg_var(p, idFWD_BLOCK);
arg_var(p, idFWD_ALL);
}
Expand Down Expand Up @@ -15094,15 +15082,11 @@ static NODE *
new_args_forward_call(struct parser_params *p, NODE *leading, const YYLTYPE *loc, const YYLTYPE *argsloc)
{
NODE *rest = NEW_LVAR(idFWD_REST, loc);
#ifndef FORWARD_ARGS_WITH_RUBY2_KEYWORDS
NODE *kwrest = list_append(p, NEW_LIST(0, loc), NEW_LVAR(idFWD_KWREST, loc));
#endif
rb_node_block_pass_t *block = NEW_BLOCK_PASS(NEW_LVAR(idFWD_BLOCK, loc), argsloc, &NULL_LOC);
NODE *args = leading ? rest_arg_append(p, leading, rest, argsloc) : NEW_SPLAT(rest, loc, &NULL_LOC);
block->forwarding = TRUE;
#ifndef FORWARD_ARGS_WITH_RUBY2_KEYWORDS
args = arg_append(p, args, new_hash(p, kwrest, loc), argsloc);
#endif
return arg_blk_pass(args, block);
}

Expand Down
31 changes: 22 additions & 9 deletions prism/prism.c
Original file line number Diff line number Diff line change
Expand Up @@ -3077,6 +3077,17 @@ pm_call_target_node_create(pm_parser_t *parser, pm_call_node_t *target) {
.message_loc = target->message_loc
};

/* It is possible to get here where we have parsed an invalid syntax tree
* where the call operator was not present. In that case we will have a
* problem because it is a required location. In this case we need to fill
* it in with a fake location so that the syntax tree remains valid. */
if (node->call_operator_loc.start == NULL) {
node->call_operator_loc = (pm_location_t) {
.start = target->base.location.start,
.end = target->base.location.start
};
}

// Here we're going to free the target, since it is no longer necessary.
// However, we don't want to call `pm_node_destroy` because we want to keep
// around all of its children since we just reused them.
Expand Down Expand Up @@ -4096,8 +4107,8 @@ pm_hash_pattern_node_node_list_create(pm_parser_t *parser, pm_node_list_t *eleme

if (elements->size > 0) {
if (rest) {
start = elements->nodes[0]->location.start;
end = rest->location.end;
start = MIN(rest->location.start, elements->nodes[0]->location.start);
end = MAX(rest->location.end, elements->nodes[elements->size - 1]->location.end);
} else {
start = elements->nodes[0]->location.start;
end = elements->nodes[elements->size - 1]->location.end;
Expand All @@ -4117,11 +4128,7 @@ pm_hash_pattern_node_node_list_create(pm_parser_t *parser, pm_node_list_t *eleme
.closing_loc = { 0 }
};

pm_node_t *element;
PM_NODE_LIST_FOREACH(elements, index, element) {
pm_node_list_append(&node->elements, element);
}

pm_node_list_concat(&node->elements, elements);
return node;
}

Expand Down Expand Up @@ -12024,7 +12031,10 @@ parser_lex(pm_parser_t *parser) {
// string content.
if (heredoc_lex_mode->indent == PM_HEREDOC_INDENT_TILDE) {
const uint8_t *end = parser->current.end;
pm_newline_list_append(&parser->newline_list, end);

if (parser->heredoc_end == NULL) {
pm_newline_list_append(&parser->newline_list, end);
}

// Here we want the buffer to only
// include up to the backslash.
Expand Down Expand Up @@ -12533,7 +12543,10 @@ pm_node_unreference_each(const pm_node_t *node, void *data) {
);
}
parser->current_block_exits->size--;
return false;

/* Note returning true here because these nodes could have
* arguments that are themselves block exits. */
return true;
}

index++;
Expand Down
1 change: 0 additions & 1 deletion rubyparser.h
Original file line number Diff line number Diff line change
Expand Up @@ -782,7 +782,6 @@ struct rb_args_info {

struct RNode_OPT_ARG *opt_args;
unsigned int no_kwarg: 1;
unsigned int ruby2_keywords: 1;
unsigned int forwarding: 1;
};

Expand Down
3 changes: 2 additions & 1 deletion spec/bundler/bundler/cli_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -100,10 +100,11 @@ def out_with_macos_man_workaround
end

it "runs bundle install when default_cli_command set to install" do
bundle "config set default_cli_command install_or_cli_help"
bundle "config set default_cli_command install"
bundle "", raise_on_error: false
expect(out).to_not include("In a future version of Bundler")
expect(err).to include("Could not locate Gemfile")
expect(exitstatus).to_not be_zero
end
end

Expand Down
19 changes: 19 additions & 0 deletions spec/bundler/commands/install_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1885,6 +1885,25 @@ def run
expect(Dir.glob(vendored_gems("bin/*"))).to eq(expected_executables)
end

it "prevents removing binstubs when BUNDLE_CLEAN is set" do
build_repo4 do
build_gem "kamal", "4.0.6" do |s|
s.executables = ["kamal"]
end
end

gemfile = <<~G
source "https://gem.repo4"
gem "kamal"
G

install_gemfile(gemfile, env: { "BUNDLE_CLEAN" => "true", "BUNDLE_PATH" => "vendor/bundle" })

expected_executables = [vendored_gems("bin/kamal").to_s]
expected_executables << vendored_gems("bin/kamal.bat").to_s if Gem.win_platform?
expect(Dir.glob(vendored_gems("bin/*"))).to eq(expected_executables)
end

it "preserves lockfile versions conservatively" do
build_repo4 do
build_gem "mypsych", "4.0.6" do |s|
Expand Down