Skip to content

Commit 82fbedc

Browse files
joyeecheungtargos
authored andcommitted
src: port --bash-completion to C++
So that it gets handle earlier and faster during the bootstrap process. Drive-by fixes: - Remove `[has_eval_string]` and `[ssl_openssl_cert_store]` from the completion output - Set `kProfProcess` execution mode for `--prof-process` instead of `kPrintBashProcess` which is removed in this patch. - Append new line to the end of the output of --bash-completion PR-URL: #25901 Reviewed-By: Gus Caplan <[email protected]> Reviewed-By: James M Snell <[email protected]>
1 parent 5c522dd commit 82fbedc

File tree

6 files changed

+69
-39
lines changed

6 files changed

+69
-39
lines changed

lib/internal/main/print_bash_completion.js

-29
This file was deleted.

node.gyp

-1
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,6 @@
139139
'lib/internal/main/eval_string.js',
140140
'lib/internal/main/eval_stdin.js',
141141
'lib/internal/main/inspect.js',
142-
'lib/internal/main/print_bash_completion.js',
143142
'lib/internal/main/print_help.js',
144143
'lib/internal/main/prof_process.js',
145144
'lib/internal/main/repl.js',

src/node.cc

+12-3
Original file line numberDiff line numberDiff line change
@@ -400,9 +400,6 @@ MaybeLocal<Value> StartMainThreadExecution(Environment* env) {
400400
return StartExecution(env, "internal/main/print_help");
401401
}
402402

403-
if (per_process::cli_options->print_bash_completion) {
404-
return StartExecution(env, "internal/main/print_bash_completion");
405-
}
406403

407404
if (env->options()->prof_process) {
408405
return StartExecution(env, "internal/main/prof_process");
@@ -875,6 +872,12 @@ void Init(int* argc,
875872
exit(0);
876873
}
877874

875+
if (per_process::cli_options->print_bash_completion) {
876+
std::string completion = options_parser::GetBashCompletion();
877+
printf("%s\n", completion.c_str());
878+
exit(0);
879+
}
880+
878881
if (per_process::cli_options->print_v8_help) {
879882
V8::SetFlagsFromString("--help", 6); // Doesn't return.
880883
UNREACHABLE();
@@ -944,6 +947,12 @@ InitializationResult InitializeOncePerProcess(int argc, char** argv) {
944947
return result;
945948
}
946949

950+
if (per_process::cli_options->print_bash_completion) {
951+
std::string completion = options_parser::GetBashCompletion();
952+
printf("%s\n", completion.c_str());
953+
exit(0);
954+
}
955+
947956
if (per_process::cli_options->print_v8_help) {
948957
V8::SetFlagsFromString("--help", 6); // Doesn't return.
949958
UNREACHABLE();

src/node_options.cc

+39
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
#include "env-inl.h"
55
#include "node_binding.h"
66

7+
#include <errno.h>
8+
#include <sstream>
79
#include <cstdlib> // strtoul, errno
810

911
using v8::Boolean;
@@ -843,6 +845,43 @@ HostPort SplitHostPort(const std::string& arg,
843845
ParseAndValidatePort(arg.substr(colon + 1), errors) };
844846
}
845847

848+
std::string GetBashCompletion() {
849+
Mutex::ScopedLock lock(per_process::cli_options_mutex);
850+
const auto& parser = _ppop_instance;
851+
852+
std::ostringstream out;
853+
854+
out << "_node_complete() {\n"
855+
" local cur_word options\n"
856+
" cur_word=\"${COMP_WORDS[COMP_CWORD]}\"\n"
857+
" if [[ \"${cur_word}\" == -* ]] ; then\n"
858+
" COMPREPLY=( $(compgen -W '";
859+
860+
for (const auto& item : parser.options_) {
861+
if (item.first[0] != '[') {
862+
out << item.first << " ";
863+
}
864+
}
865+
for (const auto& item : parser.aliases_) {
866+
if (item.first[0] != '[') {
867+
out << item.first << " ";
868+
}
869+
}
870+
if (parser.aliases_.size() > 0) {
871+
out.seekp(-1, out.cur); // Strip the trailing space
872+
}
873+
874+
out << "' -- \"${cur_word}\") )\n"
875+
" return 0\n"
876+
" else\n"
877+
" COMPREPLY=( $(compgen -f \"${cur_word}\") )\n"
878+
" return 0\n"
879+
" fi\n"
880+
"}\n"
881+
"complete -F _node_complete node node_g";
882+
return out.str();
883+
}
884+
846885
// Return a map containing all the options and their metadata as well
847886
// as the aliases
848887
void GetOptions(const FunctionCallbackInfo<Value>& args) {

src/node_options.h

+2
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,7 @@ namespace options_parser {
253253
HostPort SplitHostPort(const std::string& arg,
254254
std::vector<std::string>* errors);
255255
void GetOptions(const v8::FunctionCallbackInfo<v8::Value>& args);
256+
std::string GetBashCompletion();
256257

257258
enum OptionType {
258259
kNoOp,
@@ -436,6 +437,7 @@ class OptionsParser {
436437
friend class OptionsParser;
437438

438439
friend void GetOptions(const v8::FunctionCallbackInfo<v8::Value>& args);
440+
friend std::string GetBashCompletion();
439441
};
440442

441443
using StringVector = std::vector<std::string>;

test/parallel/test-bash-completion.js

+16-6
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,32 @@
22
require('../common');
33
const assert = require('assert');
44
const child_process = require('child_process');
5+
const { inspect } = require('util');
56

67
const p = child_process.spawnSync(
78
process.execPath, [ '--completion-bash' ]);
89
assert.ifError(p.error);
9-
assert.ok(p.stdout.toString().includes(
10-
`_node_complete() {
10+
11+
const output = p.stdout.toString().trim().replace(/\r/g, '');
12+
console.log(output);
13+
14+
const prefix = `_node_complete() {
1115
local cur_word options
1216
cur_word="\${COMP_WORDS[COMP_CWORD]}"
1317
if [[ "\${cur_word}" == -* ]] ; then
14-
COMPREPLY=( $(compgen -W '`));
15-
assert.ok(p.stdout.toString().includes(
16-
`' -- "\${cur_word}") )
18+
COMPREPLY=( $(compgen -W '`.replace(/\r/g, '');
19+
const suffix = `' -- "\${cur_word}") )
1720
return 0
1821
else
1922
COMPREPLY=( $(compgen -f "\${cur_word}") )
2023
return 0
2124
fi
2225
}
23-
complete -F _node_complete node node_g`));
26+
complete -F _node_complete node node_g`.replace(/\r/g, '');
27+
28+
assert.ok(
29+
output.includes(prefix),
30+
`Expect\n\n ${inspect(output)}\n\nto include\n\n${inspect(prefix)}`);
31+
assert.ok(
32+
output.includes(suffix),
33+
`Expect\n\n ${inspect(output)}\n\nto include\n\n${inspect(suffix)}`);

0 commit comments

Comments
 (0)