@@ -249,6 +249,27 @@ FindPackageJson(const std::filesystem::path& cwd) {
249249 return {{package_json_path, raw_content, path_env_var}};
250250}
251251
252+ // Prints every "name: command" pair in the scripts object to the given stream.
253+ static void PrintScripts (FILE * out,
254+ simdjson::ondemand::object& scripts_object) {
255+ // Reset the object to iterate from the beginning, in case it was read before.
256+ scripts_object.reset ();
257+ simdjson::ondemand::value value;
258+ for (auto field : scripts_object) {
259+ std::string_view key_str;
260+ std::string_view value_str;
261+ if (!field.unescaped_key ().get (key_str) && !field.value ().get (value) &&
262+ !value.get_string ().get (value_str)) {
263+ fprintf (out,
264+ " %.*s: %.*s\n " ,
265+ static_cast <int >(key_str.size ()),
266+ key_str.data (),
267+ static_cast <int >(value_str.size ()),
268+ value_str.data ());
269+ }
270+ }
271+ }
272+
252273void RunTask (const std::shared_ptr<InitializationResultImpl>& result,
253274 std::string_view command_id,
254275 const std::vector<std::string_view>& positional_args) {
@@ -300,6 +321,16 @@ void RunTask(const std::shared_ptr<InitializationResultImpl>& result,
300321 return ;
301322 }
302323
324+ // With no command (e.g. bare `node --run`), list the available scripts but
325+ // exit non-zero so a script invoking `node --run $CMD` with an unset
326+ // variable still fails, as it did before bare `--run` was allowed.
327+ if (command_id.empty ()) {
328+ fprintf (stderr, " Available scripts are:\n " );
329+ PrintScripts (stderr, scripts_object);
330+ result->exit_code_ = ExitCode::kInvalidCommandLineArgument ;
331+ return ;
332+ }
333+
303334 // If the command_id is not found in the scripts object, throw an error.
304335 std::string_view command;
305336 if (auto command_error =
@@ -317,23 +348,7 @@ void RunTask(const std::shared_ptr<InitializationResultImpl>& result,
317348 command_id.data (),
318349 path.string ().c_str ());
319350 fprintf (stderr, " Available scripts are:\n " );
320-
321- // Reset the object to iterate over it again
322- scripts_object.reset ();
323- simdjson::ondemand::value value;
324- for (auto field : scripts_object) {
325- std::string_view key_str;
326- std::string_view value_str;
327- if (!field.unescaped_key ().get (key_str) && !field.value ().get (value) &&
328- !value.get_string ().get (value_str)) {
329- fprintf (stderr,
330- " %.*s: %.*s\n " ,
331- static_cast <int >(key_str.size ()),
332- key_str.data (),
333- static_cast <int >(value_str.size ()),
334- value_str.data ());
335- }
336- }
351+ PrintScripts (stderr, scripts_object);
337352 }
338353 result->exit_code_ = ExitCode::kGenericUserError ;
339354 return ;
0 commit comments