@@ -254,6 +254,27 @@ FindPackageJson(const std::filesystem::path& cwd) {
254254 return {{package_json_path, raw_content, path_env_var}};
255255}
256256
257+ // Prints every "name: command" pair in the scripts object to the given stream.
258+ static void PrintScripts (FILE * out,
259+ simdjson::ondemand::object& scripts_object) {
260+ // Reset the object to iterate from the beginning, in case it was read before.
261+ scripts_object.reset ();
262+ simdjson::ondemand::value value;
263+ for (auto field : scripts_object) {
264+ std::string_view key_str;
265+ std::string_view value_str;
266+ if (!field.unescaped_key ().get (key_str) && !field.value ().get (value) &&
267+ !value.get_string ().get (value_str)) {
268+ fprintf (out,
269+ " %.*s: %.*s\n " ,
270+ static_cast <int >(key_str.size ()),
271+ key_str.data (),
272+ static_cast <int >(value_str.size ()),
273+ value_str.data ());
274+ }
275+ }
276+ }
277+
257278void RunTask (const std::shared_ptr<InitializationResultImpl>& result,
258279 std::string_view command_id,
259280 const std::vector<std::string_view>& positional_args) {
@@ -306,6 +327,16 @@ void RunTask(const std::shared_ptr<InitializationResultImpl>& result,
306327 return ;
307328 }
308329
330+ // With no command (e.g. bare `node --run`), list the available scripts but
331+ // exit non-zero so a script invoking `node --run $CMD` with an unset
332+ // variable still fails, as it did before bare `--run` was allowed.
333+ if (command_id.empty ()) {
334+ fprintf (stderr, " Available scripts are:\n " );
335+ PrintScripts (stderr, scripts_object);
336+ result->exit_code_ = ExitCode::kInvalidCommandLineArgument ;
337+ return ;
338+ }
339+
309340 // If the command_id is not found in the scripts object, throw an error.
310341 std::string_view command;
311342 if (auto command_error =
@@ -323,23 +354,7 @@ void RunTask(const std::shared_ptr<InitializationResultImpl>& result,
323354 command_id.data (),
324355 ConvertPathToUTF8 (path).c_str ());
325356 fprintf (stderr, " Available scripts are:\n " );
326-
327- // Reset the object to iterate over it again
328- scripts_object.reset ();
329- simdjson::ondemand::value value;
330- for (auto field : scripts_object) {
331- std::string_view key_str;
332- std::string_view value_str;
333- if (!field.unescaped_key ().get (key_str) && !field.value ().get (value) &&
334- !value.get_string ().get (value_str)) {
335- fprintf (stderr,
336- " %.*s: %.*s\n " ,
337- static_cast <int >(key_str.size ()),
338- key_str.data (),
339- static_cast <int >(value_str.size ()),
340- value_str.data ());
341- }
342- }
357+ PrintScripts (stderr, scripts_object);
343358 }
344359 result->exit_code_ = ExitCode::kGenericUserError ;
345360 return ;
0 commit comments