Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cli: ensure --run has proper pwd #53600

Open
wants to merge 11 commits into
base: main
Choose a base branch
from

Conversation

bmeck
Copy link
Member

@bmeck bmeck commented Jun 26, 2024

No description provided.

@nodejs-github-bot nodejs-github-bot added c++ Issues and PRs that require attention from people who are familiar with C++. needs-ci PRs that need a full CI run. labels Jun 26, 2024
@bmeck bmeck marked this pull request as draft June 26, 2024 21:26
test/fixtures/run-script/package.json Outdated Show resolved Hide resolved
Copy link
Member

@anonrig anonrig left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Small comments. The current test failure is due to test/message/node_run_non_existent.out.

After these small changes, I think we can ship it! Thank you for your contribution (and welcome!)

src/node_task_runner.cc Outdated Show resolved Hide resolved
src/node_task_runner.cc Outdated Show resolved Hide resolved
src/node_task_runner.cc Outdated Show resolved Hide resolved
test/parallel/test-node-run.js Show resolved Hide resolved
test/parallel/test-node-run.js Outdated Show resolved Hide resolved
test/parallel/test-node-run.js Outdated Show resolved Hide resolved
test/parallel/test-node-run.js Show resolved Hide resolved
Co-authored-by: Yagiz Nizipli <yagiz@nizipli.com>
src/node_task_runner.cc Outdated Show resolved Hide resolved
src/node_task_runner.cc Outdated Show resolved Hide resolved
Co-authored-by: Yagiz Nizipli <yagiz@nizipli.com>
@bmeck bmeck marked this pull request as ready for review June 28, 2024 14:11
@anonrig anonrig added author ready PRs that have at least one approval, no pending requests for changes, and a CI started. request-ci Add this label to start a Jenkins CI on a PR. commit-queue-squash Add this label to instruct the Commit Queue to squash all the PR commits into the first one. labels Jun 28, 2024
@github-actions github-actions bot removed the request-ci Add this label to start a Jenkins CI on a PR. label Jul 3, 2024
@anonrig anonrig added the request-ci Add this label to start a Jenkins CI on a PR. label Jul 8, 2024
@github-actions github-actions bot removed the request-ci Add this label to start a Jenkins CI on a PR. label Jul 8, 2024
@aduh95
Copy link
Contributor

aduh95 commented Jul 8, 2024

Compilation error on Windows:

  node_task_runner.cc
C:\workspace\node-compile-windows\node\src\node_task_runner.cc(210,27): error C2440: '=': cannot convert from 'const std::filesystem::path::value_type *' to 'const char *' [C:\workspace\node-compile-windows\node\libnode.vcxproj]
C:\workspace\node-compile-windows\node\src\node_task_runner.cc(210,27): message : Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or parenthesized function-style cast [C:\workspace\node-compile-windows\node\libnode.vcxproj]
C:\workspace\node-compile-windows\node\src\node_task_runner.cc(259,21): warning C4477: 'fprintf' : format string '%s' requires an argument of type 'char *', but variadic argument 1 has type 'const std::filesystem::path::value_type *' [C:\workspace\node-compile-windows\node\libnode.vcxproj]
C:\workspace\node-compile-windows\node\src\node_task_runner.cc(259,21): message : consider using '%ls' in the format string [C:\workspace\node-compile-windows\node\libnode.vcxproj]
C:\workspace\node-compile-windows\node\src\node_task_runner.cc(259,21): message : consider using '%lls' in the format string [C:\workspace\node-compile-windows\node\libnode.vcxproj]
C:\workspace\node-compile-windows\node\src\node_task_runner.cc(259,21): message : consider using '%Ls' in the format string [C:\workspace\node-compile-windows\node\libnode.vcxproj]
C:\workspace\node-compile-windows\node\src\node_task_runner.cc(259,21): message : consider using '%ws' in the format string [C:\workspace\node-compile-windows\node\libnode.vcxproj]
C:\workspace\node-compile-windows\node\src\node_task_runner.cc(276,21): warning C4477: 'fprintf' : format string '%s' requires an argument of type 'char *', but variadic argument 1 has type 'const std::filesystem::path::value_type *' [C:\workspace\node-compile-windows\node\libnode.vcxproj]
C:\workspace\node-compile-windows\node\src\node_task_runner.cc(276,21): message : consider using '%ls' in the format string [C:\workspace\node-compile-windows\node\libnode.vcxproj]
C:\workspace\node-compile-windows\node\src\node_task_runner.cc(276,21): message : consider using '%lls' in the format string [C:\workspace\node-compile-windows\node\libnode.vcxproj]
C:\workspace\node-compile-windows\node\src\node_task_runner.cc(276,21): message : consider using '%Ls' in the format string [C:\workspace\node-compile-windows\node\libnode.vcxproj]
C:\workspace\node-compile-windows\node\src\node_task_runner.cc(276,21): message : consider using '%ws' in the format string [C:\workspace\node-compile-windows\node\libnode.vcxproj]
C:\workspace\node-compile-windows\node\src\node_task_runner.cc(285,15): warning C4477: 'fprintf' : format string '%s' requires an argument of type 'char *', but variadic argument 1 has type 'const std::filesystem::path::value_type *' [C:\workspace\node-compile-windows\node\libnode.vcxproj]
C:\workspace\node-compile-windows\node\src\node_task_runner.cc(285,15): message : consider using '%ls' in the format string [C:\workspace\node-compile-windows\node\libnode.vcxproj]
C:\workspace\node-compile-windows\node\src\node_task_runner.cc(285,15): message : consider using '%lls' in the format string [C:\workspace\node-compile-windows\node\libnode.vcxproj]
C:\workspace\node-compile-windows\node\src\node_task_runner.cc(285,15): message : consider using '%Ls' in the format string [C:\workspace\node-compile-windows\node\libnode.vcxproj]
C:\workspace\node-compile-windows\node\src\node_task_runner.cc(285,15): message : consider using '%ws' in the format string [C:\workspace\node-compile-windows\node\libnode.vcxproj]
C:\workspace\node-compile-windows\node\src\node_task_runner.cc(288,23): warning C4477: 'fprintf' : format string '%s' requires an argument of type 'char *', but variadic argument 1 has type 'const std::filesystem::path::value_type *' [C:\workspace\node-compile-windows\node\libnode.vcxproj]
C:\workspace\node-compile-windows\node\src\node_task_runner.cc(288,23): message : consider using '%ls' in the format string [C:\workspace\node-compile-windows\node\libnode.vcxproj]
C:\workspace\node-compile-windows\node\src\node_task_runner.cc(288,23): message : consider using '%lls' in the format string [C:\workspace\node-compile-windows\node\libnode.vcxproj]
C:\workspace\node-compile-windows\node\src\node_task_runner.cc(288,23): message : consider using '%Ls' in the format string [C:\workspace\node-compile-windows\node\libnode.vcxproj]
C:\workspace\node-compile-windows\node\src\node_task_runner.cc(288,23): message : consider using '%ws' in the format string [C:\workspace\node-compile-windows\node\libnode.vcxproj]
C:\workspace\node-compile-windows\node\src\node_task_runner.cc(297,21): warning C4477: 'fprintf' : format string '%s' requires an argument of type 'char *', but variadic argument 1 has type 'const std::filesystem::path::value_type *' [C:\workspace\node-compile-windows\node\libnode.vcxproj]
C:\workspace\node-compile-windows\node\src\node_task_runner.cc(297,21): message : consider using '%ls' in the format string [C:\workspace\node-compile-windows\node\libnode.vcxproj]
C:\workspace\node-compile-windows\node\src\node_task_runner.cc(297,21): message : consider using '%lls' in the format string [C:\workspace\node-compile-windows\node\libnode.vcxproj]
C:\workspace\node-compile-windows\node\src\node_task_runner.cc(297,21): message : consider using '%Ls' in the format string [C:\workspace\node-compile-windows\node\libnode.vcxproj]
C:\workspace\node-compile-windows\node\src\node_task_runner.cc(297,21): message : consider using '%ws' in the format string [C:\workspace\node-compile-windows\node\libnode.vcxproj]
C:\workspace\node-compile-windows\node\src\node_task_runner.cc(308,15): warning C4477: 'fprintf' : format string '%s' requires an argument of type 'char *', but variadic argument 3 has type 'const std::filesystem::path::value_type *' [C:\workspace\node-compile-windows\node\libnode.vcxproj]
C:\workspace\node-compile-windows\node\src\node_task_runner.cc(308,15): message : consider using '%ls' in the format string [C:\workspace\node-compile-windows\node\libnode.vcxproj]
C:\workspace\node-compile-windows\node\src\node_task_runner.cc(308,15): message : consider using '%lls' in the format string [C:\workspace\node-compile-windows\node\libnode.vcxproj]
C:\workspace\node-compile-windows\node\src\node_task_runner.cc(308,15): message : consider using '%Ls' in the format string [C:\workspace\node-compile-windows\node\libnode.vcxproj]
C:\workspace\node-compile-windows\node\src\node_task_runner.cc(308,15): message : consider using '%ws' in the format string [C:\workspace\node-compile-windows\node\libnode.vcxproj]
C:\workspace\node-compile-windows\node\src\node_task_runner.cc(314,15): warning C4477: 'fprintf' : format string '%s' requires an argument of type 'char *', but variadic argument 3 has type 'const std::filesystem::path::value_type *' [C:\workspace\node-compile-windows\node\libnode.vcxproj]
C:\workspace\node-compile-windows\node\src\node_task_runner.cc(314,15): message : consider using '%ls' in the format string [C:\workspace\node-compile-windows\node\libnode.vcxproj]
C:\workspace\node-compile-windows\node\src\node_task_runner.cc(314,15): message : consider using '%lls' in the format string [C:\workspace\node-compile-windows\node\libnode.vcxproj]
C:\workspace\node-compile-windows\node\src\node_task_runner.cc(314,15): message : consider using '%Ls' in the format string [C:\workspace\node-compile-windows\node\libnode.vcxproj]
C:\workspace\node-compile-windows\node\src\node_task_runner.cc(314,15): message : consider using '%ws' in the format string [C:\workspace\node-compile-windows\node\libnode.vcxproj]
@StefanStojanovic
Copy link
Contributor

I'll check these compilation errors.

@bmeck
Copy link
Member Author

bmeck commented Jul 9, 2024

@StefanStojanovic I believe these likely came from removing some .c_str() calls

@StefanStojanovic
Copy link
Contributor

The issue here is the character type of std::filesystem::path (value_type) differs on Windows, where it is a wchar_t, compared to other platforms where it is char (Source: https://en.cppreference.com/w/cpp/filesystem/path). So, since that is the reason I've added an ifdef _WIN32 and added code to convert data to the correct format. I was able to compile with this change locally. @bmeck if this change makes sense to you feel free to apply the patch I provided in this comment to your branch.

From fc0f3ed6c020eb0180065bc89bce026b68e2216f Mon Sep 17 00:00:00 2001
From: StefanStojanovic <stefan.stojanovic@janeasystems.com>
Date: Tue, 9 Jul 2024 20:23:48 +0200
Subject: [PATCH 1/1] ProcessRunner::Run Windows fix

---
 src/node_task_runner.cc | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/src/node_task_runner.cc b/src/node_task_runner.cc
index cb2defee973..0c37b1072d6 100644
--- a/src/node_task_runner.cc
+++ b/src/node_task_runner.cc
@@ -207,7 +207,15 @@ void ProcessRunner::OnExit(int64_t exit_status, int term_signal) {
 void ProcessRunner::Run() {
   // keeps the string alive until destructor
   auto cwd = package_json_path_.parent_path();
+#ifdef _WIN32
+  std::wstring cwd_wstr = cwd.wstring();
+  int size = WideCharToMultiByte(CP_UTF8, 0, cwd_wstr.c_str(), -1, nullptr, 0, nullptr, nullptr);
+  std::string cwd_string(size, 0);
+  WideCharToMultiByte(CP_UTF8, 0, cwd_wstr.c_str(), -1, &cwd_string[0], size, nullptr, nullptr);
+  options_.cwd = cwd_string.c_str();
+#else
   options_.cwd = cwd.c_str();
+#endif
   if (int r = uv_spawn(loop_, &process_, &options_)) {
     fprintf(stderr, "Error: %s\n", uv_strerror(r));
   }
-- 
2.45.2.windows.1

@bmeck
Copy link
Member Author

bmeck commented Jul 9, 2024

@StefanStojanovic I'm ok with an ifdef but we would want to add it to quite a few places according to above

@StefanStojanovic
Copy link
Contributor

@StefanStojanovic I'm ok with an ifdef but we would want to add it to quite a few places according to above

If you are referring to the #53600 (comment), other logs are just warnings so at least the compilation would succeed. A potential problem is that those logs would be unusable. The good thing is that all of the warnings are from the same function RunTask and most of them (all except one) use the same value, so it shouldn't be too hard to fix them all in one place, or simply use %ls instead of %s on Windows.

One question I have though - what would be the easiest way to reproduce showing some of these logs?

@anonrig
Copy link
Member

anonrig commented Jul 9, 2024

You can run path.string() and convert the filesystem path to a std::string. It will create an unnecessary string and copy operation but it will work for both operating systems without any ifdef.

@huseyinacacak-janea
Copy link
Contributor

@StefanStojanovic is currently on vacation so I will be handling this in the meantime.

Thanks @anonrig, I've used the function that you've provided.

@bmeck I'm able to compile with the patch below locally. If this fix makes sense to you, feel free to apply it.

diff --git a/src/node_task_runner.cc b/src/node_task_runner.cc
index cb2defee973..429b72e3e5f 100644
--- a/src/node_task_runner.cc
+++ b/src/node_task_runner.cc
@@ -207,7 +207,7 @@ void ProcessRunner::OnExit(int64_t exit_status, int term_signal) {
 void ProcessRunner::Run() {
   // keeps the string alive until destructor
   auto cwd = package_json_path_.parent_path();
-  options_.cwd = cwd.c_str();
+  options_.cwd = cwd.string().c_str();
   if (int r = uv_spawn(loop_, &process_, &options_)) {
     fprintf(stderr, "Error: %s\n", uv_strerror(r));
   }
@@ -256,7 +256,7 @@ void RunTask(std::shared_ptr<InitializationResultImpl> result,
   auto package_json = FindPackageJson(cwd);
 
   if (!package_json.has_value()) {
-    fprintf(stderr, "Can't find package.json for directory %s\n", cwd.c_str());
+    fprintf(stderr, "Can't find package.json for directory %s\n", cwd.string().c_str());
     result->exit_code_ = ExitCode::kGenericUserError;
     return;
   }
@@ -273,7 +273,7 @@ void RunTask(std::shared_ptr<InitializationResultImpl> result,
   simdjson::error_code error = json_parser.iterate(raw_json).get(document);
 
   if (error) {
-    fprintf(stderr, "Can't parse %s\n", path.c_str());
+    fprintf(stderr, "Can't parse %s\n", path.string().c_str());
     result->exit_code_ = ExitCode::kGenericUserError;
     return;
   }
@@ -283,9 +283,9 @@ void RunTask(std::shared_ptr<InitializationResultImpl> result,
     if (root_error == simdjson::error_code::INCORRECT_TYPE) {
       fprintf(stderr,
               "Root value unexpected not an object for %s\n\n",
-              path.c_str());
+              path.string().c_str());
     } else {
-      fprintf(stderr, "Can't parse %s\n", path.c_str());
+      fprintf(stderr, "Can't parse %s\n", path.string().c_str());
     }
     result->exit_code_ = ExitCode::kGenericUserError;
     return;
@@ -294,7 +294,7 @@ void RunTask(std::shared_ptr<InitializationResultImpl> result,
   // If package_json object doesn't have "scripts" field, throw an error.
   simdjson::ondemand::object scripts_object;
   if (main_object["scripts"].get_object().get(scripts_object)) {
-    fprintf(stderr, "Can't find \"scripts\" field in %s\n", path.c_str());
+    fprintf(stderr, "Can't find \"scripts\" field in %s\n", path.string().c_str());
     result->exit_code_ = ExitCode::kGenericUserError;
     return;
   }
@@ -308,13 +308,13 @@ void RunTask(std::shared_ptr<InitializationResultImpl> result,
               "Script \"%.*s\" is unexpectedly not a string for %s\n\n",
               static_cast<int>(command_id.size()),
               command_id.data(),
-              path.c_str());
+              path.string().c_str());
     } else {
       fprintf(stderr,
               "Missing script: \"%.*s\" for %s\n\n",
               static_cast<int>(command_id.size()),
               command_id.data(),
-              path.c_str());
+              path.string().c_str());
       fprintf(stderr, "Available scripts are:\n");
 
       // Reset the object to iterate over it again
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
author ready PRs that have at least one approval, no pending requests for changes, and a CI started. c++ Issues and PRs that require attention from people who are familiar with C++. commit-queue-squash Add this label to instruct the Commit Queue to squash all the PR commits into the first one. needs-ci PRs that need a full CI run.
7 participants