From 3190ae1fe0b7b35a19f185cf94edd59f2888193c Mon Sep 17 00:00:00 2001 From: Joyee Cheung Date: Sun, 3 Feb 2019 11:47:26 +0800 Subject: [PATCH] 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 --- lib/internal/main/print_bash_completion.js | 29 ---------------- node.gyp | 1 - src/node.cc | 15 +++++++-- src/node_options.cc | 39 ++++++++++++++++++++++ src/node_options.h | 2 ++ 5 files changed, 53 insertions(+), 33 deletions(-) delete mode 100644 lib/internal/main/print_bash_completion.js diff --git a/lib/internal/main/print_bash_completion.js b/lib/internal/main/print_bash_completion.js deleted file mode 100644 index 41ebf0c6063e5f..00000000000000 --- a/lib/internal/main/print_bash_completion.js +++ /dev/null @@ -1,29 +0,0 @@ -'use strict'; -const { options, aliases } = require('internal/options'); - -const { - prepareMainThreadExecution -} = require('internal/bootstrap/pre_execution'); - -function print(stream) { - const all_opts = [...options.keys(), ...aliases.keys()]; - - stream.write(`_node_complete() { - local cur_word options - cur_word="\${COMP_WORDS[COMP_CWORD]}" - if [[ "\${cur_word}" == -* ]] ; then - COMPREPLY=( $(compgen -W '${all_opts.join(' ')}' -- "\${cur_word}") ) - return 0 - else - COMPREPLY=( $(compgen -f "\${cur_word}") ) - return 0 - fi -} -complete -F _node_complete node node_g`); -} - -prepareMainThreadExecution(); - -markBootstrapComplete(); - -print(process.stdout); diff --git a/node.gyp b/node.gyp index 926fe98959c21a..3a201eed4a540d 100644 --- a/node.gyp +++ b/node.gyp @@ -138,7 +138,6 @@ 'lib/internal/main/eval_string.js', 'lib/internal/main/eval_stdin.js', 'lib/internal/main/inspect.js', - 'lib/internal/main/print_bash_completion.js', 'lib/internal/main/print_help.js', 'lib/internal/main/prof_process.js', 'lib/internal/main/repl.js', diff --git a/src/node.cc b/src/node.cc index ac0e7dfce3f058..5110c8b55ccb53 100644 --- a/src/node.cc +++ b/src/node.cc @@ -396,9 +396,6 @@ MaybeLocal StartMainThreadExecution(Environment* env) { return StartExecution(env, "internal/main/print_help"); } - if (per_process::cli_options->print_bash_completion) { - return StartExecution(env, "internal/main/print_bash_completion"); - } if (env->options()->prof_process) { return StartExecution(env, "internal/main/prof_process"); @@ -771,6 +768,12 @@ void Init(int* argc, exit(0); } + if (per_process::cli_options->print_bash_completion) { + std::string completion = options_parser::GetBashCompletion(); + printf("%s\n", completion.c_str()); + exit(0); + } + if (per_process::cli_options->print_v8_help) { V8::SetFlagsFromString("--help", 6); // Doesn't return. UNREACHABLE(); @@ -829,6 +832,12 @@ InitializationResult InitializeOncePerProcess(int argc, char** argv) { return result; } + if (per_process::cli_options->print_bash_completion) { + std::string completion = options_parser::GetBashCompletion(); + printf("%s\n", completion.c_str()); + exit(0); + } + if (per_process::cli_options->print_v8_help) { V8::SetFlagsFromString("--help", 6); // Doesn't return. UNREACHABLE(); diff --git a/src/node_options.cc b/src/node_options.cc index a36666c3e0f452..f627c8fc64a9b9 100644 --- a/src/node_options.cc +++ b/src/node_options.cc @@ -4,6 +4,8 @@ #include "env-inl.h" #include "node_binding.h" +#include +#include #include // strtoul, errno using v8::Boolean; @@ -678,6 +680,43 @@ HostPort SplitHostPort(const std::string& arg, ParseAndValidatePort(arg.substr(colon + 1), errors) }; } +std::string GetBashCompletion() { + Mutex::ScopedLock lock(per_process::cli_options_mutex); + const auto& parser = _ppop_instance; + + std::ostringstream out; + + out << "_node_complete() {\n" + " local cur_word options\n" + " cur_word=\"${COMP_WORDS[COMP_CWORD]}\"\n" + " if [[ \"${cur_word}\" == -* ]] ; then\n" + " COMPREPLY=( $(compgen -W '"; + + for (const auto& item : parser.options_) { + if (item.first[0] != '[') { + out << item.first << " "; + } + } + for (const auto& item : parser.aliases_) { + if (item.first[0] != '[') { + out << item.first << " "; + } + } + if (parser.aliases_.size() > 0) { + out.seekp(-1, out.cur); // Strip the trailing space + } + + out << "' -- \"${cur_word}\") )\n" + " return 0\n" + " else\n" + " COMPREPLY=( $(compgen -f \"${cur_word}\") )\n" + " return 0\n" + " fi\n" + "}\n" + "complete -F _node_complete node node_g"; + return out.str(); +} + // Return a map containing all the options and their metadata as well // as the aliases void GetOptions(const FunctionCallbackInfo& args) { diff --git a/src/node_options.h b/src/node_options.h index db564ddb3d3e6d..19b0b51d6a4113 100644 --- a/src/node_options.h +++ b/src/node_options.h @@ -224,6 +224,7 @@ namespace options_parser { HostPort SplitHostPort(const std::string& arg, std::vector* errors); void GetOptions(const v8::FunctionCallbackInfo& args); +std::string GetBashCompletion(); enum OptionEnvvarSettings { kAllowedInEnvironment, @@ -412,6 +413,7 @@ class OptionsParser { friend class OptionsParser; friend void GetOptions(const v8::FunctionCallbackInfo& args); + friend std::string GetBashCompletion(); }; using StringVector = std::vector;