cmUVProcessChain: Add working directory option

This commit is contained in:
Kyle Edwards
2023-05-26 10:30:05 -04:00
parent cf7b7600c6
commit 67bb1ee50c
5 changed files with 82 additions and 0 deletions

View File

@@ -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<char**>(arguments.data());
options.flags = UV_PROCESS_WINDOWS_HIDE;
if (!this->Builder->WorkingDirectory.empty()) {
options.cwd = this->Builder->WorkingDirectory.c_str();
}
std::array<uv_stdio_container_t, 3> stdio;
stdio[0] = uv_stdio_container_t();

View File

@@ -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<StdioConfiguration, 3> Stdio;
std::vector<ProcessConfiguration> Processes;
std::string WorkingDirectory;
};
class cmUVProcessChain

View File

@@ -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 $<TARGET_FILE:testUVProcessChainHelper>)

View File

@@ -11,6 +11,7 @@
#include <cm3p/uv.h>
#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;
}

View File

@@ -7,6 +7,8 @@
#include <string>
#include <thread>
#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;
}