From 67bb1ee50cde981dd36f2b9964013c330f7e92fe Mon Sep 17 00:00:00 2001 From: Kyle Edwards Date: Fri, 26 May 2023 10:30:05 -0400 Subject: cmUVProcessChain: Add working directory option --- Source/cmUVProcessChain.cxx | 10 +++++ Source/cmUVProcessChain.h | 2 + Tests/CMakeLib/CMakeLists.txt | 1 + Tests/CMakeLib/testUVProcessChain.cxx | 62 +++++++++++++++++++++++++++++ Tests/CMakeLib/testUVProcessChainHelper.cxx | 7 ++++ 5 files changed, 82 insertions(+) diff --git a/Source/cmUVProcessChain.cxx b/Source/cmUVProcessChain.cxx index 3faf2f6..5d00544 100644 --- a/Source/cmUVProcessChain.cxx +++ b/Source/cmUVProcessChain.cxx @@ -140,6 +140,13 @@ cmUVProcessChainBuilder& cmUVProcessChainBuilder::SetExternalStream( return *this; } +cmUVProcessChainBuilder& cmUVProcessChainBuilder::SetWorkingDirectory( + std::string dir) +{ + this->WorkingDirectory = std::move(dir); + return *this; +} + cmUVProcessChain cmUVProcessChainBuilder::Start() const { cmUVProcessChain chain; @@ -248,6 +255,9 @@ bool cmUVProcessChain::InternalData::AddCommand( arguments.push_back(nullptr); options.args = const_cast(arguments.data()); options.flags = UV_PROCESS_WINDOWS_HIDE; + if (!this->Builder->WorkingDirectory.empty()) { + options.cwd = this->Builder->WorkingDirectory.c_str(); + } std::array stdio; stdio[0] = uv_stdio_container_t(); diff --git a/Source/cmUVProcessChain.h b/Source/cmUVProcessChain.h index 5e8e7e6..44a4888 100644 --- a/Source/cmUVProcessChain.h +++ b/Source/cmUVProcessChain.h @@ -31,6 +31,7 @@ public: cmUVProcessChainBuilder& SetNoStream(Stream stdio); cmUVProcessChainBuilder& SetBuiltinStream(Stream stdio); cmUVProcessChainBuilder& SetExternalStream(Stream stdio, int fd); + cmUVProcessChainBuilder& SetWorkingDirectory(std::string dir); cmUVProcessChain Start() const; @@ -57,6 +58,7 @@ private: std::array Stdio; std::vector Processes; + std::string WorkingDirectory; }; class cmUVProcessChain diff --git a/Tests/CMakeLib/CMakeLists.txt b/Tests/CMakeLib/CMakeLists.txt index 0fc3deb..944b328 100644 --- a/Tests/CMakeLib/CMakeLists.txt +++ b/Tests/CMakeLib/CMakeLists.txt @@ -37,6 +37,7 @@ if (CMake_TEST_FILESYSTEM_PATH OR NOT CMake_HAVE_CXX_FILESYSTEM) endif() add_executable(testUVProcessChainHelper testUVProcessChainHelper.cxx) +target_link_libraries(testUVProcessChainHelper CMakeLib) set(testRST_ARGS ${CMAKE_CURRENT_SOURCE_DIR}) set(testUVProcessChain_ARGS $) diff --git a/Tests/CMakeLib/testUVProcessChain.cxx b/Tests/CMakeLib/testUVProcessChain.cxx index c924083..05262bc 100644 --- a/Tests/CMakeLib/testUVProcessChain.cxx +++ b/Tests/CMakeLib/testUVProcessChain.cxx @@ -11,6 +11,7 @@ #include #include "cmGetPipes.h" +#include "cmStringAlgorithms.h" #include "cmUVHandlePtr.h" #include "cmUVProcessChain.h" #include "cmUVStreambuf.h" @@ -314,6 +315,57 @@ bool testUVProcessChainNone(const char* helperCommand) return true; } +bool testUVProcessChainCwdUnchanged(const char* helperCommand) +{ + cmUVProcessChainBuilder builder; + builder.AddCommand({ helperCommand, "pwd" }) + .SetBuiltinStream(cmUVProcessChainBuilder::Stream_OUTPUT) + .SetBuiltinStream(cmUVProcessChainBuilder::Stream_ERROR); + + auto chain = builder.Start(); + chain.Wait(); + if (chain.GetStatus().front()->ExitStatus != 0) { + std::cout << "Exit status was " << chain.GetStatus().front()->ExitStatus + << ", expecting 0" << std::endl; + return false; + } + + auto cwd = getInput(*chain.OutputStream()); + if (!cmHasLiteralSuffix(cwd, "/Tests/CMakeLib")) { + std::cout << "Working directory was \"" << cwd + << "\", expected to end in \"/Tests/CMakeLib\"" << std::endl; + return false; + } + + return true; +} + +bool testUVProcessChainCwdChanged(const char* helperCommand) +{ + cmUVProcessChainBuilder builder; + builder.AddCommand({ helperCommand, "pwd" }) + .SetBuiltinStream(cmUVProcessChainBuilder::Stream_OUTPUT) + .SetBuiltinStream(cmUVProcessChainBuilder::Stream_ERROR) + .SetWorkingDirectory(".."); + + auto chain = builder.Start(); + chain.Wait(); + if (chain.GetStatus().front()->ExitStatus != 0) { + std::cout << "Exit status was " << chain.GetStatus().front()->ExitStatus + << ", expecting 0" << std::endl; + return false; + } + + auto cwd = getInput(*chain.OutputStream()); + if (!cmHasLiteralSuffix(cwd, "/Tests")) { + std::cout << "Working directory was \"" << cwd + << "\", expected to end in \"/Tests\"" << std::endl; + return false; + } + + return true; +} + int testUVProcessChain(int argc, char** const argv) { if (argc < 2) { @@ -336,5 +388,15 @@ int testUVProcessChain(int argc, char** const argv) return -1; } + if (!testUVProcessChainCwdUnchanged(argv[1])) { + std::cout << "While executing testUVProcessChainCwdUnchanged().\n"; + return -1; + } + + if (!testUVProcessChainCwdChanged(argv[1])) { + std::cout << "While executing testUVProcessChainCwdChanged().\n"; + return -1; + } + return 0; } diff --git a/Tests/CMakeLib/testUVProcessChainHelper.cxx b/Tests/CMakeLib/testUVProcessChainHelper.cxx index bc0ef8e..82dafd2 100644 --- a/Tests/CMakeLib/testUVProcessChainHelper.cxx +++ b/Tests/CMakeLib/testUVProcessChainHelper.cxx @@ -7,6 +7,8 @@ #include #include +#include "cmSystemTools.h" + static std::string getStdin() { char buffer[1024]; @@ -67,6 +69,11 @@ int main(int argc, char** argv) std::abort(); #endif } + if (command == "pwd") { + std::string cwd = cmSystemTools::GetCurrentWorkingDirectory(); + std::cout << cwd << std::flush; + return 0; + } return -1; } -- cgit v0.12