cmProcessTools::RunProcess(): Replace cmsysProcess with cmUVProcessChain

And convert the VCS code to std::vector<std::string>.
This commit is contained in:
Kyle Edwards
2023-06-08 08:50:10 -04:00
parent 5420639a8d
commit ec124582ac
13 changed files with 233 additions and 264 deletions
+13 -18
View File
@@ -135,14 +135,14 @@ private:
std::string cmCTestBZR::LoadInfo() std::string cmCTestBZR::LoadInfo()
{ {
// Run "bzr info" to get the repository info from the work tree. // Run "bzr info" to get the repository info from the work tree.
const char* bzr = this->CommandLineTool.c_str(); std::string bzr = this->CommandLineTool;
const char* bzr_info[] = { bzr, "info", nullptr }; std::vector<std::string> bzr_info = { bzr, "info" };
InfoParser iout(this, "info-out> "); InfoParser iout(this, "info-out> ");
OutputLogger ierr(this->Log, "info-err> "); OutputLogger ierr(this->Log, "info-err> ");
this->RunChild(bzr_info, &iout, &ierr); this->RunChild(bzr_info, &iout, &ierr);
// Run "bzr revno" to get the repository revision number from the work tree. // Run "bzr revno" to get the repository revision number from the work tree.
const char* bzr_revno[] = { bzr, "revno", nullptr }; std::vector<std::string> bzr_revno = { bzr, "revno" };
std::string rev; std::string rev;
RevnoParser rout(this, "revno-out> ", rev); RevnoParser rout(this, "revno-out> ", rev);
OutputLogger rerr(this->Log, "revno-err> "); OutputLogger rerr(this->Log, "revno-err> ");
@@ -372,22 +372,18 @@ bool cmCTestBZR::UpdateImpl()
// TODO: if(this->CTest->GetTestModel() == cmCTest::NIGHTLY) // TODO: if(this->CTest->GetTestModel() == cmCTest::NIGHTLY)
// Use "bzr pull" to update the working tree. // Use "bzr pull" to update the working tree.
std::vector<char const*> bzr_update; std::vector<std::string> bzr_update;
bzr_update.push_back(this->CommandLineTool.c_str()); bzr_update.push_back(this->CommandLineTool);
bzr_update.push_back("pull"); bzr_update.push_back("pull");
for (std::string const& arg : args) { cm::append(bzr_update, args);
bzr_update.push_back(arg.c_str());
}
bzr_update.push_back(this->URL.c_str()); bzr_update.push_back(this->URL);
bzr_update.push_back(nullptr);
// For some reason bzr uses stderr to display the update status. // For some reason bzr uses stderr to display the update status.
OutputLogger out(this->Log, "pull-out> "); OutputLogger out(this->Log, "pull-out> ");
UpdateParser err(this, "pull-err> "); UpdateParser err(this, "pull-err> ");
return this->RunUpdateCommand(bzr_update.data(), &out, &err); return this->RunUpdateCommand(bzr_update, &out, &err);
} }
bool cmCTestBZR::LoadRevisions() bool cmCTestBZR::LoadRevisions()
@@ -408,10 +404,9 @@ bool cmCTestBZR::LoadRevisions()
} }
// Run "bzr log" to get all global revisions of interest. // Run "bzr log" to get all global revisions of interest.
const char* bzr = this->CommandLineTool.c_str(); std::string bzr = this->CommandLineTool;
const char* bzr_log[] = { std::vector<std::string> bzr_log = { bzr, "log", "-v", "-r",
bzr, "log", "-v", "-r", revs.c_str(), "--xml", this->URL.c_str(), nullptr revs, "--xml", this->URL };
};
{ {
LogParser out(this, "log-out> "); LogParser out(this, "log-out> ");
OutputLogger err(this->Log, "log-err> "); OutputLogger err(this->Log, "log-err> ");
@@ -467,8 +462,8 @@ private:
bool cmCTestBZR::LoadModifications() bool cmCTestBZR::LoadModifications()
{ {
// Run "bzr status" which reports local modifications. // Run "bzr status" which reports local modifications.
const char* bzr = this->CommandLineTool.c_str(); std::string bzr = this->CommandLineTool;
const char* bzr_status[] = { bzr, "status", "-SV", nullptr }; std::vector<std::string> bzr_status = { bzr, "status", "-SV" };
StatusParser out(this, "status-out> "); StatusParser out(this, "status-out> ");
OutputLogger err(this->Log, "status-err> "); OutputLogger err(this->Log, "status-err> ");
this->RunChild(bzr_status, &out, &err); this->RunChild(bzr_status, &out, &err);
+7 -11
View File
@@ -5,6 +5,7 @@
#include <utility> #include <utility>
#include <cm/string_view> #include <cm/string_view>
#include <cmext/algorithm>
#include "cmsys/FStream.hxx" #include "cmsys/FStream.hxx"
#include "cmsys/RegularExpression.hxx" #include "cmsys/RegularExpression.hxx"
@@ -89,18 +90,15 @@ bool cmCTestCVS::UpdateImpl()
} }
// Run "cvs update" to update the work tree. // Run "cvs update" to update the work tree.
std::vector<char const*> cvs_update; std::vector<std::string> cvs_update;
cvs_update.push_back(this->CommandLineTool.c_str()); cvs_update.push_back(this->CommandLineTool);
cvs_update.push_back("-z3"); cvs_update.push_back("-z3");
cvs_update.push_back("update"); cvs_update.push_back("update");
for (std::string const& arg : args) { cm::append(cvs_update, args);
cvs_update.push_back(arg.c_str());
}
cvs_update.push_back(nullptr);
UpdateParser out(this, "up-out> "); UpdateParser out(this, "up-out> ");
UpdateParser err(this, "up-err> "); UpdateParser err(this, "up-err> ");
return this->RunUpdateCommand(cvs_update.data(), &out, &err); return this->RunUpdateCommand(cvs_update, &out, &err);
} }
class cmCTestCVS::LogParser : public cmCTestVC::LineParser class cmCTestCVS::LogParser : public cmCTestVC::LineParser
@@ -221,10 +219,8 @@ void cmCTestCVS::LoadRevisions(std::string const& file, const char* branchFlag,
cmCTestLog(this->CTest, HANDLER_OUTPUT, "." << std::flush); cmCTestLog(this->CTest, HANDLER_OUTPUT, "." << std::flush);
// Run "cvs log" to get revisions of this file on this branch. // Run "cvs log" to get revisions of this file on this branch.
const char* cvs = this->CommandLineTool.c_str(); std::string cvs = this->CommandLineTool;
const char* cvs_log[] = { std::vector<std::string> cvs_log = { cvs, "log", "-N", branchFlag, file };
cvs, "log", "-N", branchFlag, file.c_str(), nullptr
};
LogParser out(this, "log-out> ", revisions); LogParser out(this, "log-out> ", revisions);
OutputLogger err(this->Log, "log-err> "); OutputLogger err(this->Log, "log-err> ");
+64 -66
View File
@@ -9,8 +9,9 @@
#include <utility> #include <utility>
#include <vector> #include <vector>
#include <cmext/algorithm>
#include "cmsys/FStream.hxx" #include "cmsys/FStream.hxx"
#include "cmsys/Process.h"
#include "cmCTest.h" #include "cmCTest.h"
#include "cmCTestVC.h" #include "cmCTestVC.h"
@@ -18,6 +19,7 @@
#include "cmProcessOutput.h" #include "cmProcessOutput.h"
#include "cmStringAlgorithms.h" #include "cmStringAlgorithms.h"
#include "cmSystemTools.h" #include "cmSystemTools.h"
#include "cmUVProcessChain.h"
#include "cmValue.h" #include "cmValue.h"
static unsigned int cmCTestGITVersion(unsigned int epic, unsigned int major, static unsigned int cmCTestGITVersion(unsigned int epic, unsigned int major,
@@ -58,9 +60,9 @@ private:
std::string cmCTestGIT::GetWorkingRevision() std::string cmCTestGIT::GetWorkingRevision()
{ {
// Run plumbing "git rev-list" to get work tree revision. // Run plumbing "git rev-list" to get work tree revision.
const char* git = this->CommandLineTool.c_str(); std::string git = this->CommandLineTool;
const char* git_rev_list[] = { git, "rev-list", "-n", "1", std::vector<std::string> git_rev_list = { git, "rev-list", "-n",
"HEAD", "--", nullptr }; "1", "HEAD", "--" };
std::string rev; std::string rev;
OneLineParser out(this, "rl-out> ", rev); OneLineParser out(this, "rl-out> ", rev);
OutputLogger err(this->Log, "rl-err> "); OutputLogger err(this->Log, "rl-err> ");
@@ -92,13 +94,13 @@ std::string cmCTestGIT::FindGitDir()
std::string git_dir; std::string git_dir;
// Run "git rev-parse --git-dir" to locate the real .git directory. // Run "git rev-parse --git-dir" to locate the real .git directory.
const char* git = this->CommandLineTool.c_str(); std::string git = this->CommandLineTool;
char const* git_rev_parse[] = { git, "rev-parse", "--git-dir", nullptr }; std::vector<std::string> git_rev_parse = { git, "rev-parse", "--git-dir" };
std::string git_dir_line; std::string git_dir_line;
OneLineParser rev_parse_out(this, "rev-parse-out> ", git_dir_line); OneLineParser rev_parse_out(this, "rev-parse-out> ", git_dir_line);
OutputLogger rev_parse_err(this->Log, "rev-parse-err> "); OutputLogger rev_parse_err(this->Log, "rev-parse-err> ");
if (this->RunChild(git_rev_parse, &rev_parse_out, &rev_parse_err, nullptr, if (this->RunChild(git_rev_parse, &rev_parse_out, &rev_parse_err,
cmProcessOutput::UTF8)) { std::string{}, cmProcessOutput::UTF8)) {
git_dir = git_dir_line; git_dir = git_dir_line;
} }
if (git_dir.empty()) { if (git_dir.empty()) {
@@ -117,11 +119,10 @@ std::string cmCTestGIT::FindGitDir()
std::string cygpath_exe = std::string cygpath_exe =
cmStrCat(cmSystemTools::GetFilenamePath(git), "/cygpath.exe"); cmStrCat(cmSystemTools::GetFilenamePath(git), "/cygpath.exe");
if (cmSystemTools::FileExists(cygpath_exe)) { if (cmSystemTools::FileExists(cygpath_exe)) {
char const* cygpath[] = { cygpath_exe.c_str(), "-w", git_dir.c_str(), std::vector<std::string> cygpath = { cygpath_exe, "-w", git_dir };
0 };
OneLineParser cygpath_out(this, "cygpath-out> ", git_dir_line); OneLineParser cygpath_out(this, "cygpath-out> ", git_dir_line);
OutputLogger cygpath_err(this->Log, "cygpath-err> "); OutputLogger cygpath_err(this->Log, "cygpath-err> ");
if (this->RunChild(cygpath, &cygpath_out, &cygpath_err, nullptr, if (this->RunChild(cygpath, &cygpath_out, &cygpath_err, std::string{},
cmProcessOutput::UTF8)) { cmProcessOutput::UTF8)) {
git_dir = git_dir_line; git_dir = git_dir_line;
} }
@@ -136,12 +137,12 @@ std::string cmCTestGIT::FindTopDir()
std::string top_dir = this->SourceDirectory; std::string top_dir = this->SourceDirectory;
// Run "git rev-parse --show-cdup" to locate the top of the tree. // Run "git rev-parse --show-cdup" to locate the top of the tree.
const char* git = this->CommandLineTool.c_str(); std::string git = this->CommandLineTool;
char const* git_rev_parse[] = { git, "rev-parse", "--show-cdup", nullptr }; std::vector<std::string> git_rev_parse = { git, "rev-parse", "--show-cdup" };
std::string cdup; std::string cdup;
OneLineParser rev_parse_out(this, "rev-parse-out> ", cdup); OneLineParser rev_parse_out(this, "rev-parse-out> ", cdup);
OutputLogger rev_parse_err(this->Log, "rev-parse-err> "); OutputLogger rev_parse_err(this->Log, "rev-parse-err> ");
if (this->RunChild(git_rev_parse, &rev_parse_out, &rev_parse_err, nullptr, if (this->RunChild(git_rev_parse, &rev_parse_out, &rev_parse_err, "",
cmProcessOutput::UTF8) && cmProcessOutput::UTF8) &&
!cdup.empty()) { !cdup.empty()) {
top_dir += "/"; top_dir += "/";
@@ -153,10 +154,10 @@ std::string cmCTestGIT::FindTopDir()
bool cmCTestGIT::UpdateByFetchAndReset() bool cmCTestGIT::UpdateByFetchAndReset()
{ {
const char* git = this->CommandLineTool.c_str(); std::string git = this->CommandLineTool;
// Use "git fetch" to get remote commits. // Use "git fetch" to get remote commits.
std::vector<char const*> git_fetch; std::vector<std::string> git_fetch;
git_fetch.push_back(git); git_fetch.push_back(git);
git_fetch.push_back("fetch"); git_fetch.push_back("fetch");
@@ -166,17 +167,12 @@ bool cmCTestGIT::UpdateByFetchAndReset()
opts = this->CTest->GetCTestConfiguration("GITUpdateOptions"); opts = this->CTest->GetCTestConfiguration("GITUpdateOptions");
} }
std::vector<std::string> args = cmSystemTools::ParseArguments(opts); std::vector<std::string> args = cmSystemTools::ParseArguments(opts);
for (std::string const& arg : args) { cm::append(git_fetch, args);
git_fetch.push_back(arg.c_str());
}
// Sentinel argument.
git_fetch.push_back(nullptr);
// Fetch upstream refs. // Fetch upstream refs.
OutputLogger fetch_out(this->Log, "fetch-out> "); OutputLogger fetch_out(this->Log, "fetch-out> ");
OutputLogger fetch_err(this->Log, "fetch-err> "); OutputLogger fetch_err(this->Log, "fetch-err> ");
if (!this->RunUpdateCommand(git_fetch.data(), &fetch_out, &fetch_err)) { if (!this->RunUpdateCommand(git_fetch, &fetch_out, &fetch_err)) {
return false; return false;
} }
@@ -207,25 +203,22 @@ bool cmCTestGIT::UpdateByFetchAndReset()
} }
// Reset the local branch to point at that tracked from upstream. // Reset the local branch to point at that tracked from upstream.
char const* git_reset[] = { git, "reset", "--hard", sha1.c_str(), nullptr }; std::vector<std::string> git_reset = { git, "reset", "--hard", sha1 };
OutputLogger reset_out(this->Log, "reset-out> "); OutputLogger reset_out(this->Log, "reset-out> ");
OutputLogger reset_err(this->Log, "reset-err> "); OutputLogger reset_err(this->Log, "reset-err> ");
return this->RunChild(&git_reset[0], &reset_out, &reset_err); return this->RunChild(git_reset, &reset_out, &reset_err);
} }
bool cmCTestGIT::UpdateByCustom(std::string const& custom) bool cmCTestGIT::UpdateByCustom(std::string const& custom)
{ {
cmList git_custom_command{ custom, cmList::EmptyElements::Yes }; cmList git_custom_command{ custom, cmList::EmptyElements::Yes };
std::vector<char const*> git_custom; std::vector<std::string> git_custom;
git_custom.reserve(git_custom_command.size() + 1); git_custom.reserve(git_custom_command.size());
for (std::string const& i : git_custom_command) { cm::append(git_custom, git_custom_command);
git_custom.push_back(i.c_str());
}
git_custom.push_back(nullptr);
OutputLogger custom_out(this->Log, "custom-out> "); OutputLogger custom_out(this->Log, "custom-out> ");
OutputLogger custom_err(this->Log, "custom-err> "); OutputLogger custom_err(this->Log, "custom-err> ");
return this->RunUpdateCommand(git_custom.data(), &custom_out, &custom_err); return this->RunUpdateCommand(git_custom, &custom_out, &custom_err);
} }
bool cmCTestGIT::UpdateInternal() bool cmCTestGIT::UpdateInternal()
@@ -244,13 +237,14 @@ bool cmCTestGIT::UpdateImpl()
} }
std::string top_dir = this->FindTopDir(); std::string top_dir = this->FindTopDir();
const char* git = this->CommandLineTool.c_str(); std::string git = this->CommandLineTool;
const char* recursive = "--recursive"; std::string recursive = "--recursive";
const char* sync_recursive = "--recursive"; std::string sync_recursive = "--recursive";
// Git < 1.6.5 did not support submodule --recursive // Git < 1.6.5 did not support submodule --recursive
bool support_recursive = true;
if (this->GetGitVersion() < cmCTestGITVersion(1, 6, 5, 0)) { if (this->GetGitVersion() < cmCTestGITVersion(1, 6, 5, 0)) {
recursive = nullptr; support_recursive = false;
// No need to require >= 1.6.5 if there are no submodules. // No need to require >= 1.6.5 if there are no submodules.
if (cmSystemTools::FileExists(top_dir + "/.gitmodules")) { if (cmSystemTools::FileExists(top_dir + "/.gitmodules")) {
this->Log << "Git < 1.6.5 cannot update submodules recursively\n"; this->Log << "Git < 1.6.5 cannot update submodules recursively\n";
@@ -258,8 +252,9 @@ bool cmCTestGIT::UpdateImpl()
} }
// Git < 1.8.1 did not support sync --recursive // Git < 1.8.1 did not support sync --recursive
bool support_sync_recursive = true;
if (this->GetGitVersion() < cmCTestGITVersion(1, 8, 1, 0)) { if (this->GetGitVersion() < cmCTestGITVersion(1, 8, 1, 0)) {
sync_recursive = nullptr; support_sync_recursive = false;
// No need to require >= 1.8.1 if there are no submodules. // No need to require >= 1.8.1 if there are no submodules.
if (cmSystemTools::FileExists(top_dir + "/.gitmodules")) { if (cmSystemTools::FileExists(top_dir + "/.gitmodules")) {
this->Log << "Git < 1.8.1 cannot synchronize submodules recursively\n"; this->Log << "Git < 1.8.1 cannot synchronize submodules recursively\n";
@@ -274,35 +269,39 @@ bool cmCTestGIT::UpdateImpl()
std::string init_submodules = std::string init_submodules =
this->CTest->GetCTestConfiguration("GITInitSubmodules"); this->CTest->GetCTestConfiguration("GITInitSubmodules");
if (cmIsOn(init_submodules)) { if (cmIsOn(init_submodules)) {
char const* git_submodule_init[] = { git, "submodule", "init", nullptr }; std::vector<std::string> git_submodule_init = { git, "submodule", "init" };
ret = this->RunChild(git_submodule_init, &submodule_out, &submodule_err, ret = this->RunChild(git_submodule_init, &submodule_out, &submodule_err,
top_dir.c_str()); top_dir);
if (!ret) { if (!ret) {
return false; return false;
} }
} }
char const* git_submodule_sync[] = { git, "submodule", "sync", std::vector<std::string> git_submodule_sync = { git, "submodule", "sync" };
sync_recursive, nullptr }; if (support_sync_recursive) {
git_submodule_sync.push_back(sync_recursive);
}
ret = this->RunChild(git_submodule_sync, &submodule_out, &submodule_err, ret = this->RunChild(git_submodule_sync, &submodule_out, &submodule_err,
top_dir.c_str()); top_dir);
if (!ret) { if (!ret) {
return false; return false;
} }
char const* git_submodule[] = { git, "submodule", "update", recursive, std::vector<std::string> git_submodule = { git, "submodule", "update" };
nullptr }; if (support_recursive) {
git_submodule.push_back(recursive);
}
return this->RunChild(git_submodule, &submodule_out, &submodule_err, return this->RunChild(git_submodule, &submodule_out, &submodule_err,
top_dir.c_str()); top_dir);
} }
unsigned int cmCTestGIT::GetGitVersion() unsigned int cmCTestGIT::GetGitVersion()
{ {
if (!this->CurrentGitVersion) { if (!this->CurrentGitVersion) {
const char* git = this->CommandLineTool.c_str(); std::string git = this->CommandLineTool;
char const* git_version[] = { git, "--version", nullptr }; std::vector<std::string> git_version = { git, "--version" };
std::string version; std::string version;
OneLineParser version_out(this, "version-out> ", version); OneLineParser version_out(this, "version-out> ", version);
OutputLogger version_err(this->Log, "version-err> "); OutputLogger version_err(this->Log, "version-err> ");
@@ -605,50 +604,49 @@ bool cmCTestGIT::LoadRevisions()
{ {
// Use 'git rev-list ... | git diff-tree ...' to get revisions. // Use 'git rev-list ... | git diff-tree ...' to get revisions.
std::string range = this->OldRevision + ".." + this->NewRevision; std::string range = this->OldRevision + ".." + this->NewRevision;
const char* git = this->CommandLineTool.c_str(); std::string git = this->CommandLineTool;
const char* git_rev_list[] = { git, "rev-list", "--reverse", std::vector<std::string> git_rev_list = { git, "rev-list", "--reverse",
range.c_str(), "--", nullptr }; range, "--" };
const char* git_diff_tree[] = { std::vector<std::string> git_diff_tree = {
git, "diff-tree", "--stdin", "--always", "-z", git, "diff-tree", "--stdin", "--always",
"-r", "--pretty=raw", "--encoding=utf-8", nullptr "-z", "-r", "--pretty=raw", "--encoding=utf-8"
}; };
this->Log << cmCTestGIT::ComputeCommandLine(git_rev_list) << " | " this->Log << cmCTestGIT::ComputeCommandLine(git_rev_list) << " | "
<< cmCTestGIT::ComputeCommandLine(git_diff_tree) << "\n"; << cmCTestGIT::ComputeCommandLine(git_diff_tree) << "\n";
cmsysProcess* cp = cmsysProcess_New(); cmUVProcessChainBuilder builder;
cmsysProcess_AddCommand(cp, git_rev_list); builder.AddCommand(git_rev_list)
cmsysProcess_AddCommand(cp, git_diff_tree); .AddCommand(git_diff_tree)
cmsysProcess_SetWorkingDirectory(cp, this->SourceDirectory.c_str()); .SetWorkingDirectory(this->SourceDirectory);
CommitParser out(this, "dt-out> "); CommitParser out(this, "dt-out> ");
OutputLogger err(this->Log, "dt-err> "); OutputLogger err(this->Log, "dt-err> ");
cmCTestGIT::RunProcess(cp, &out, &err, cmProcessOutput::UTF8); cmCTestGIT::RunProcess(builder, &out, &err, cmProcessOutput::UTF8);
// Send one extra zero-byte to terminate the last record. // Send one extra zero-byte to terminate the last record.
out.Process("", 1); out.Process("", 1);
cmsysProcess_Delete(cp);
return true; return true;
} }
bool cmCTestGIT::LoadModifications() bool cmCTestGIT::LoadModifications()
{ {
const char* git = this->CommandLineTool.c_str(); std::string git = this->CommandLineTool;
// Use 'git update-index' to refresh the index w.r.t. the work tree. // Use 'git update-index' to refresh the index w.r.t. the work tree.
const char* git_update_index[] = { git, "update-index", "--refresh", std::vector<std::string> git_update_index = { git, "update-index",
nullptr }; "--refresh" };
OutputLogger ui_out(this->Log, "ui-out> "); OutputLogger ui_out(this->Log, "ui-out> ");
OutputLogger ui_err(this->Log, "ui-err> "); OutputLogger ui_err(this->Log, "ui-err> ");
this->RunChild(git_update_index, &ui_out, &ui_err, nullptr, this->RunChild(git_update_index, &ui_out, &ui_err, "",
cmProcessOutput::UTF8); cmProcessOutput::UTF8);
// Use 'git diff-index' to get modified files. // Use 'git diff-index' to get modified files.
const char* git_diff_index[] = { git, "diff-index", "-z", std::vector<std::string> git_diff_index = { git, "diff-index", "-z", "HEAD",
"HEAD", "--", nullptr }; "--" };
DiffParser out(this, "di-out> "); DiffParser out(this, "di-out> ");
OutputLogger err(this->Log, "di-err> "); OutputLogger err(this->Log, "di-err> ");
this->RunChild(git_diff_index, &out, &err, nullptr, cmProcessOutput::UTF8); this->RunChild(git_diff_index, &out, &err, "", cmProcessOutput::UTF8);
for (Change const& c : out.Changes) { for (Change const& c : out.Changes) {
this->DoModification(PathModified, c.Path); this->DoModification(PathModified, c.Path);
+14 -21
View File
@@ -95,8 +95,8 @@ private:
std::string cmCTestHG::GetWorkingRevision() std::string cmCTestHG::GetWorkingRevision()
{ {
// Run plumbing "hg identify" to get work tree revision. // Run plumbing "hg identify" to get work tree revision.
const char* hg = this->CommandLineTool.c_str(); std::string hg = this->CommandLineTool;
const char* hg_identify[] = { hg, "identify", "-i", nullptr }; std::vector<std::string> hg_identify = { hg, "identify", "-i" };
std::string rev; std::string rev;
IdentifyParser out(this, "rev-out> ", rev); IdentifyParser out(this, "rev-out> ", rev);
OutputLogger err(this->Log, "rev-err> "); OutputLogger err(this->Log, "rev-err> ");
@@ -127,16 +127,16 @@ bool cmCTestHG::UpdateImpl()
{ {
// Use "hg pull" followed by "hg update" to update the working tree. // Use "hg pull" followed by "hg update" to update the working tree.
{ {
const char* hg = this->CommandLineTool.c_str(); std::string hg = this->CommandLineTool;
const char* hg_pull[] = { hg, "pull", "-v", nullptr }; std::vector<std::string> hg_pull = { hg, "pull", "-v" };
OutputLogger out(this->Log, "pull-out> "); OutputLogger out(this->Log, "pull-out> ");
OutputLogger err(this->Log, "pull-err> "); OutputLogger err(this->Log, "pull-err> ");
this->RunChild(&hg_pull[0], &out, &err); this->RunChild(hg_pull, &out, &err);
} }
// TODO: if(this->CTest->GetTestModel() == cmCTest::NIGHTLY) // TODO: if(this->CTest->GetTestModel() == cmCTest::NIGHTLY)
std::vector<char const*> hg_update; std::vector<std::string> hg_update;
hg_update.push_back(this->CommandLineTool.c_str()); hg_update.push_back(this->CommandLineTool.c_str());
hg_update.push_back("update"); hg_update.push_back("update");
hg_update.push_back("-v"); hg_update.push_back("-v");
@@ -147,16 +147,11 @@ bool cmCTestHG::UpdateImpl()
opts = this->CTest->GetCTestConfiguration("HGUpdateOptions"); opts = this->CTest->GetCTestConfiguration("HGUpdateOptions");
} }
std::vector<std::string> args = cmSystemTools::ParseArguments(opts); std::vector<std::string> args = cmSystemTools::ParseArguments(opts);
for (std::string const& arg : args) { cm::append(hg_update, args);
hg_update.push_back(arg.c_str());
}
// Sentinel argument.
hg_update.push_back(nullptr);
OutputLogger out(this->Log, "update-out> "); OutputLogger out(this->Log, "update-out> ");
OutputLogger err(this->Log, "update-err> "); OutputLogger err(this->Log, "update-err> ");
return this->RunUpdateCommand(hg_update.data(), &out, &err); return this->RunUpdateCommand(hg_update, &out, &err);
} }
class cmCTestHG::LogParser class cmCTestHG::LogParser
@@ -277,8 +272,8 @@ bool cmCTestHG::LoadRevisions()
// the project has spaces in the path. Also, they may not have // the project has spaces in the path. Also, they may not have
// proper XML escapes. // proper XML escapes.
std::string range = this->OldRevision + ":" + this->NewRevision; std::string range = this->OldRevision + ":" + this->NewRevision;
const char* hg = this->CommandLineTool.c_str(); std::string hg = this->CommandLineTool;
const char* hgXMLTemplate = "<logentry\n" std::string hgXMLTemplate = "<logentry\n"
" revision=\"{node|short}\">\n" " revision=\"{node|short}\">\n"
" <author>{author|person}</author>\n" " <author>{author|person}</author>\n"
" <email>{author|email}</email>\n" " <email>{author|email}</email>\n"
@@ -288,10 +283,8 @@ bool cmCTestHG::LoadRevisions()
" <file_adds>{file_adds}</file_adds>\n" " <file_adds>{file_adds}</file_adds>\n"
" <file_dels>{file_dels}</file_dels>\n" " <file_dels>{file_dels}</file_dels>\n"
"</logentry>\n"; "</logentry>\n";
const char* hg_log[] = { std::vector<std::string> hg_log = { hg, "log", "--removed", "-r",
hg, "log", "--removed", "-r", range.c_str(), range, "--template", hgXMLTemplate };
"--template", hgXMLTemplate, nullptr
};
LogParser out(this, "log-out> "); LogParser out(this, "log-out> ");
out.Process("<?xml version=\"1.0\"?>\n" out.Process("<?xml version=\"1.0\"?>\n"
@@ -305,8 +298,8 @@ bool cmCTestHG::LoadRevisions()
bool cmCTestHG::LoadModifications() bool cmCTestHG::LoadModifications()
{ {
// Use 'hg status' to get modified files. // Use 'hg status' to get modified files.
const char* hg = this->CommandLineTool.c_str(); std::string hg = this->CommandLineTool;
const char* hg_status[] = { hg, "status", nullptr }; std::vector<std::string> hg_status = { hg, "status" };
StatusParser out(this, "status-out> "); StatusParser out(this, "status-out> ");
OutputLogger err(this->Log, "status-err> "); OutputLogger err(this->Log, "status-err> ");
this->RunChild(hg_status, &out, &err); this->RunChild(hg_status, &out, &err);
+26 -40
View File
@@ -149,17 +149,16 @@ cmCTestP4::User cmCTestP4::GetUserData(const std::string& username)
auto it = this->Users.find(username); auto it = this->Users.find(username);
if (it == this->Users.end()) { if (it == this->Users.end()) {
std::vector<char const*> p4_users; std::vector<std::string> p4_users;
this->SetP4Options(p4_users); this->SetP4Options(p4_users);
p4_users.push_back("users"); p4_users.push_back("users");
p4_users.push_back("-m"); p4_users.push_back("-m");
p4_users.push_back("1"); p4_users.push_back("1");
p4_users.push_back(username.c_str()); p4_users.push_back(username);
p4_users.push_back(nullptr);
UserParser out(this, "users-out> "); UserParser out(this, "users-out> ");
OutputLogger err(this->Log, "users-err> "); OutputLogger err(this->Log, "users-err> ");
this->RunChild(p4_users.data(), &out, &err); this->RunChild(p4_users, &out, &err);
// The user should now be added to the map. Search again. // The user should now be added to the map. Search again.
it = this->Users.find(username); it = this->Users.find(username);
@@ -303,10 +302,10 @@ private:
} }
}; };
void cmCTestP4::SetP4Options(std::vector<char const*>& CommandOptions) void cmCTestP4::SetP4Options(std::vector<std::string>& CommandOptions)
{ {
if (this->P4Options.empty()) { if (this->P4Options.empty()) {
const char* p4 = this->CommandLineTool.c_str(); std::string p4 = this->CommandLineTool;
this->P4Options.emplace_back(p4); this->P4Options.emplace_back(p4);
// The CTEST_P4_CLIENT variable sets the P4 client used when issuing // The CTEST_P4_CLIENT variable sets the P4 client used when issuing
@@ -328,15 +327,12 @@ void cmCTestP4::SetP4Options(std::vector<char const*>& CommandOptions)
cm::append(this->P4Options, cmSystemTools::ParseArguments(opts)); cm::append(this->P4Options, cmSystemTools::ParseArguments(opts));
} }
CommandOptions.clear(); CommandOptions = this->P4Options;
for (std::string const& o : this->P4Options) {
CommandOptions.push_back(o.c_str());
}
} }
std::string cmCTestP4::GetWorkingRevision() std::string cmCTestP4::GetWorkingRevision()
{ {
std::vector<char const*> p4_identify; std::vector<std::string> p4_identify;
this->SetP4Options(p4_identify); this->SetP4Options(p4_identify);
p4_identify.push_back("changes"); p4_identify.push_back("changes");
@@ -345,14 +341,13 @@ std::string cmCTestP4::GetWorkingRevision()
p4_identify.push_back("-t"); p4_identify.push_back("-t");
std::string source = this->SourceDirectory + "/...#have"; std::string source = this->SourceDirectory + "/...#have";
p4_identify.push_back(source.c_str()); p4_identify.push_back(source);
p4_identify.push_back(nullptr);
std::string rev; std::string rev;
IdentifyParser out(this, "p4_changes-out> ", rev); IdentifyParser out(this, "p4_changes-out> ", rev);
OutputLogger err(this->Log, "p4_changes-err> "); OutputLogger err(this->Log, "p4_changes-err> ");
bool result = this->RunChild(p4_identify.data(), &out, &err); bool result = this->RunChild(p4_identify, &out, &err);
// If there was a problem contacting the server return "<unknown>" // If there was a problem contacting the server return "<unknown>"
if (!result) { if (!result) {
@@ -388,7 +383,7 @@ bool cmCTestP4::NoteNewRevision()
bool cmCTestP4::LoadRevisions() bool cmCTestP4::LoadRevisions()
{ {
std::vector<char const*> p4_changes; std::vector<std::string> p4_changes;
this->SetP4Options(p4_changes); this->SetP4Options(p4_changes);
// Use 'p4 changes ...@old,new' to get a list of changelists // Use 'p4 changes ...@old,new' to get a list of changelists
@@ -409,38 +404,36 @@ bool cmCTestP4::LoadRevisions()
.append(this->NewRevision); .append(this->NewRevision);
p4_changes.push_back("changes"); p4_changes.push_back("changes");
p4_changes.push_back(range.c_str()); p4_changes.push_back(range);
p4_changes.push_back(nullptr);
ChangesParser out(this, "p4_changes-out> "); ChangesParser out(this, "p4_changes-out> ");
OutputLogger err(this->Log, "p4_changes-err> "); OutputLogger err(this->Log, "p4_changes-err> ");
this->ChangeLists.clear(); this->ChangeLists.clear();
this->RunChild(p4_changes.data(), &out, &err); this->RunChild(p4_changes, &out, &err);
if (this->ChangeLists.empty()) { if (this->ChangeLists.empty()) {
return true; return true;
} }
// p4 describe -s ...@1111111,2222222 // p4 describe -s ...@1111111,2222222
std::vector<char const*> p4_describe; std::vector<std::string> p4_describe;
for (std::string const& i : cmReverseRange(this->ChangeLists)) { for (std::string const& i : cmReverseRange(this->ChangeLists)) {
this->SetP4Options(p4_describe); this->SetP4Options(p4_describe);
p4_describe.push_back("describe"); p4_describe.push_back("describe");
p4_describe.push_back("-s"); p4_describe.push_back("-s");
p4_describe.push_back(i.c_str()); p4_describe.push_back(i);
p4_describe.push_back(nullptr);
DescribeParser outDescribe(this, "p4_describe-out> "); DescribeParser outDescribe(this, "p4_describe-out> ");
OutputLogger errDescribe(this->Log, "p4_describe-err> "); OutputLogger errDescribe(this->Log, "p4_describe-err> ");
this->RunChild(p4_describe.data(), &outDescribe, &errDescribe); this->RunChild(p4_describe, &outDescribe, &errDescribe);
} }
return true; return true;
} }
bool cmCTestP4::LoadModifications() bool cmCTestP4::LoadModifications()
{ {
std::vector<char const*> p4_diff; std::vector<std::string> p4_diff;
this->SetP4Options(p4_diff); this->SetP4Options(p4_diff);
p4_diff.push_back("diff"); p4_diff.push_back("diff");
@@ -448,12 +441,11 @@ bool cmCTestP4::LoadModifications()
// Ideally we would use -Od but not all clients support it // Ideally we would use -Od but not all clients support it
p4_diff.push_back("-dn"); p4_diff.push_back("-dn");
std::string source = this->SourceDirectory + "/..."; std::string source = this->SourceDirectory + "/...";
p4_diff.push_back(source.c_str()); p4_diff.push_back(source);
p4_diff.push_back(nullptr);
DiffParser out(this, "p4_diff-out> "); DiffParser out(this, "p4_diff-out> ");
OutputLogger err(this->Log, "p4_diff-err> "); OutputLogger err(this->Log, "p4_diff-err> ");
this->RunChild(p4_diff.data(), &out, &err); this->RunChild(p4_diff, &out, &err);
return true; return true;
} }
@@ -461,17 +453,14 @@ bool cmCTestP4::UpdateCustom(const std::string& custom)
{ {
cmList p4_custom_command{ custom, cmList::EmptyElements::Yes }; cmList p4_custom_command{ custom, cmList::EmptyElements::Yes };
std::vector<char const*> p4_custom; std::vector<std::string> p4_custom;
p4_custom.reserve(p4_custom_command.size() + 1); p4_custom.reserve(p4_custom_command.size());
for (std::string const& i : p4_custom_command) { cm::append(p4_custom, p4_custom_command);
p4_custom.push_back(i.c_str());
}
p4_custom.push_back(nullptr);
OutputLogger custom_out(this->Log, "p4_customsync-out> "); OutputLogger custom_out(this->Log, "p4_customsync-out> ");
OutputLogger custom_err(this->Log, "p4_customsync-err> "); OutputLogger custom_err(this->Log, "p4_customsync-err> ");
return this->RunUpdateCommand(p4_custom.data(), &custom_out, &custom_err); return this->RunUpdateCommand(p4_custom, &custom_out, &custom_err);
} }
bool cmCTestP4::UpdateImpl() bool cmCTestP4::UpdateImpl()
@@ -488,7 +477,7 @@ bool cmCTestP4::UpdateImpl()
return false; return false;
} }
std::vector<char const*> p4_sync; std::vector<std::string> p4_sync;
this->SetP4Options(p4_sync); this->SetP4Options(p4_sync);
p4_sync.push_back("sync"); p4_sync.push_back("sync");
@@ -499,9 +488,7 @@ bool cmCTestP4::UpdateImpl()
opts = this->CTest->GetCTestConfiguration("P4UpdateOptions"); opts = this->CTest->GetCTestConfiguration("P4UpdateOptions");
} }
std::vector<std::string> args = cmSystemTools::ParseArguments(opts); std::vector<std::string> args = cmSystemTools::ParseArguments(opts);
for (std::string const& arg : args) { cm::append(p4_sync, args);
p4_sync.push_back(arg.c_str());
}
std::string source = this->SourceDirectory + "/..."; std::string source = this->SourceDirectory + "/...";
@@ -515,11 +502,10 @@ bool cmCTestP4::UpdateImpl()
source.append("@\"").append(date).append("\""); source.append("@\"").append(date).append("\"");
} }
p4_sync.push_back(source.c_str()); p4_sync.push_back(source);
p4_sync.push_back(nullptr);
OutputLogger out(this->Log, "p4_sync-out> "); OutputLogger out(this->Log, "p4_sync-out> ");
OutputLogger err(this->Log, "p4_sync-err> "); OutputLogger err(this->Log, "p4_sync-err> ");
return this->RunUpdateCommand(p4_sync.data(), &out, &err); return this->RunUpdateCommand(p4_sync, &out, &err);
} }
+1 -1
View File
@@ -39,7 +39,7 @@ private:
std::vector<std::string> P4Options; std::vector<std::string> P4Options;
User GetUserData(const std::string& username); User GetUserData(const std::string& username);
void SetP4Options(std::vector<char const*>& options); void SetP4Options(std::vector<std::string>& options);
std::string GetWorkingRevision(); std::string GetWorkingRevision();
bool NoteOldRevision() override; bool NoteOldRevision() override;
+15 -21
View File
@@ -33,7 +33,7 @@ cmCTestSVN::~cmCTestSVN() = default;
void cmCTestSVN::CleanupImpl() void cmCTestSVN::CleanupImpl()
{ {
std::vector<const char*> svn_cleanup; std::vector<std::string> svn_cleanup;
svn_cleanup.push_back("cleanup"); svn_cleanup.push_back("cleanup");
OutputLogger out(this->Log, "cleanup-out> "); OutputLogger out(this->Log, "cleanup-out> ");
OutputLogger err(this->Log, "cleanup-err> "); OutputLogger err(this->Log, "cleanup-err> ");
@@ -88,9 +88,9 @@ static bool cmCTestSVNPathStarts(std::string const& p1, std::string const& p2)
std::string cmCTestSVN::LoadInfo(SVNInfo& svninfo) std::string cmCTestSVN::LoadInfo(SVNInfo& svninfo)
{ {
// Run "svn info" to get the repository info from the work tree. // Run "svn info" to get the repository info from the work tree.
std::vector<const char*> svn_info; std::vector<std::string> svn_info;
svn_info.push_back("info"); svn_info.push_back("info");
svn_info.push_back(svninfo.LocalPath.c_str()); svn_info.push_back(svninfo.LocalPath);
std::string rev; std::string rev;
InfoParser out(this, "info-out> ", rev, svninfo); InfoParser out(this, "info-out> ", rev, svninfo);
OutputLogger err(this->Log, "info-err> "); OutputLogger err(this->Log, "info-err> ");
@@ -251,26 +251,24 @@ bool cmCTestSVN::UpdateImpl()
args.push_back("-r{" + this->GetNightlyTime() + " +0000}"); args.push_back("-r{" + this->GetNightlyTime() + " +0000}");
} }
std::vector<char const*> svn_update; std::vector<std::string> svn_update;
svn_update.push_back("update"); svn_update.push_back("update");
for (std::string const& arg : args) { cm::append(svn_update, args);
svn_update.push_back(arg.c_str());
}
UpdateParser out(this, "up-out> "); UpdateParser out(this, "up-out> ");
OutputLogger err(this->Log, "up-err> "); OutputLogger err(this->Log, "up-err> ");
return this->RunSVNCommand(svn_update, &out, &err); return this->RunSVNCommand(svn_update, &out, &err);
} }
bool cmCTestSVN::RunSVNCommand(std::vector<char const*> const& parameters, bool cmCTestSVN::RunSVNCommand(std::vector<std::string> const& parameters,
OutputParser* out, OutputParser* err) OutputParser* out, OutputParser* err)
{ {
if (parameters.empty()) { if (parameters.empty()) {
return false; return false;
} }
std::vector<char const*> args; std::vector<std::string> args;
args.push_back(this->CommandLineTool.c_str()); args.push_back(this->CommandLineTool);
cm::append(args, parameters); cm::append(args, parameters);
args.push_back("--non-interactive"); args.push_back("--non-interactive");
@@ -278,16 +276,12 @@ bool cmCTestSVN::RunSVNCommand(std::vector<char const*> const& parameters,
std::vector<std::string> parsedUserOptions = std::vector<std::string> parsedUserOptions =
cmSystemTools::ParseArguments(userOptions); cmSystemTools::ParseArguments(userOptions);
for (std::string const& opt : parsedUserOptions) { cm::append(args, parsedUserOptions);
args.push_back(opt.c_str());
}
args.push_back(nullptr); if (parameters[0] == "update") {
return this->RunUpdateCommand(args, out, err);
if (strcmp(parameters[0], "update") == 0) {
return this->RunUpdateCommand(args.data(), out, err);
} }
return this->RunChild(args.data(), out, err); return this->RunChild(args, out, err);
} }
class cmCTestSVN::LogParser class cmCTestSVN::LogParser
@@ -393,7 +387,7 @@ bool cmCTestSVN::LoadRevisions(SVNInfo& svninfo)
} }
// Run "svn log" to get all global revisions of interest. // Run "svn log" to get all global revisions of interest.
std::vector<const char*> svn_log; std::vector<std::string> svn_log;
svn_log.push_back("log"); svn_log.push_back("log");
svn_log.push_back("--xml"); svn_log.push_back("--xml");
svn_log.push_back("-v"); svn_log.push_back("-v");
@@ -472,7 +466,7 @@ private:
bool cmCTestSVN::LoadModifications() bool cmCTestSVN::LoadModifications()
{ {
// Run "svn status" which reports local modifications. // Run "svn status" which reports local modifications.
std::vector<const char*> svn_status; std::vector<std::string> svn_status;
svn_status.push_back("status"); svn_status.push_back("status");
StatusParser out(this, "status-out> "); StatusParser out(this, "status-out> ");
OutputLogger err(this->Log, "status-err> "); OutputLogger err(this->Log, "status-err> ");
@@ -534,7 +528,7 @@ bool cmCTestSVN::LoadRepositories()
this->RootInfo = &(this->Repositories.back()); this->RootInfo = &(this->Repositories.back());
// Run "svn status" to get the list of external repositories // Run "svn status" to get the list of external repositories
std::vector<const char*> svn_status; std::vector<std::string> svn_status;
svn_status.push_back("status"); svn_status.push_back("status");
ExternalParser out(this, "external-out> "); ExternalParser out(this, "external-out> ");
OutputLogger err(this->Log, "external-err> "); OutputLogger err(this->Log, "external-err> ");
+1 -1
View File
@@ -33,7 +33,7 @@ private:
bool NoteNewRevision() override; bool NoteNewRevision() override;
bool UpdateImpl() override; bool UpdateImpl() override;
bool RunSVNCommand(std::vector<char const*> const& parameters, bool RunSVNCommand(std::vector<std::string> const& parameters,
OutputParser* out, OutputParser* err); OutputParser* out, OutputParser* err);
// Information about an SVN repository (root repository or external) // Information about an SVN repository (root repository or external)
+19 -26
View File
@@ -7,10 +7,9 @@
#include <sstream> #include <sstream>
#include <vector> #include <vector>
#include "cmsys/Process.h"
#include "cmCTest.h" #include "cmCTest.h"
#include "cmSystemTools.h" #include "cmSystemTools.h"
#include "cmUVProcessChain.h"
#include "cmValue.h" #include "cmValue.h"
#include "cmXMLWriter.h" #include "cmXMLWriter.h"
@@ -55,18 +54,12 @@ bool cmCTestVC::InitialCheckout(const std::string& command)
// Construct the initial checkout command line. // Construct the initial checkout command line.
std::vector<std::string> args = cmSystemTools::ParseArguments(command); std::vector<std::string> args = cmSystemTools::ParseArguments(command);
std::vector<char const*> vc_co;
vc_co.reserve(args.size() + 1);
for (std::string const& arg : args) {
vc_co.push_back(arg.c_str());
}
vc_co.push_back(nullptr);
// Run the initial checkout command and log its output. // Run the initial checkout command and log its output.
this->Log << "--- Begin Initial Checkout ---\n"; this->Log << "--- Begin Initial Checkout ---\n";
OutputLogger out(this->Log, "co-out> "); OutputLogger out(this->Log, "co-out> ");
OutputLogger err(this->Log, "co-err> "); OutputLogger err(this->Log, "co-err> ");
bool result = this->RunChild(vc_co.data(), &out, &err, parent.c_str()); bool result = this->RunChild(args, &out, &err, parent);
this->Log << "--- End Initial Checkout ---\n"; this->Log << "--- End Initial Checkout ---\n";
if (!result) { if (!result) {
cmCTestLog(this->CTest, ERROR_MESSAGE, cmCTestLog(this->CTest, ERROR_MESSAGE,
@@ -75,35 +68,35 @@ bool cmCTestVC::InitialCheckout(const std::string& command)
return result; return result;
} }
bool cmCTestVC::RunChild(char const* const* cmd, OutputParser* out, bool cmCTestVC::RunChild(const std::vector<std::string>& cmd,
OutputParser* err, const char* workDir, OutputParser* out, OutputParser* err,
Encoding encoding) std::string workDir, Encoding encoding)
{ {
this->Log << cmCTestVC::ComputeCommandLine(cmd) << "\n"; this->Log << cmCTestVC::ComputeCommandLine(cmd) << "\n";
cmsysProcess* cp = cmsysProcess_New(); cmUVProcessChainBuilder builder;
cmsysProcess_SetCommand(cp, cmd); if (workDir.empty()) {
workDir = workDir ? workDir : this->SourceDirectory.c_str(); workDir = this->SourceDirectory;
cmsysProcess_SetWorkingDirectory(cp, workDir); }
cmCTestVC::RunProcess(cp, out, err, encoding); builder.AddCommand(cmd).SetWorkingDirectory(workDir);
int result = cmsysProcess_GetExitValue(cp); auto status = cmCTestVC::RunProcess(builder, out, err, encoding);
cmsysProcess_Delete(cp); return status.front().SpawnResult == 0 && status.front().ExitStatus == 0;
return result == 0;
} }
std::string cmCTestVC::ComputeCommandLine(char const* const* cmd) std::string cmCTestVC::ComputeCommandLine(const std::vector<std::string>& cmd)
{ {
std::ostringstream line; std::ostringstream line;
const char* sep = ""; const char* sep = "";
for (const char* const* arg = cmd; *arg; ++arg) { for (auto const& arg : cmd) {
line << sep << "\"" << *arg << "\""; line << sep << "\"" << arg << "\"";
sep = " "; sep = " ";
} }
return line.str(); return line.str();
} }
bool cmCTestVC::RunUpdateCommand(char const* const* cmd, OutputParser* out, bool cmCTestVC::RunUpdateCommand(const std::vector<std::string>& cmd,
OutputParser* err, Encoding encoding) OutputParser* out, OutputParser* err,
Encoding encoding)
{ {
// Report the command line. // Report the command line.
this->UpdateCommandLine = this->ComputeCommandLine(cmd); this->UpdateCommandLine = this->ComputeCommandLine(cmd);
@@ -113,7 +106,7 @@ bool cmCTestVC::RunUpdateCommand(char const* const* cmd, OutputParser* out,
} }
// Run the command. // Run the command.
return this->RunChild(cmd, out, err, nullptr, encoding); return this->RunChild(cmd, out, err, "", encoding);
} }
std::string cmCTestVC::GetNightlyTime() std::string cmCTestVC::GetNightlyTime()
+5 -4
View File
@@ -6,6 +6,7 @@
#include <iosfwd> #include <iosfwd>
#include <string> #include <string>
#include <vector>
#include "cmProcessOutput.h" #include "cmProcessOutput.h"
#include "cmProcessTools.h" #include "cmProcessTools.h"
@@ -108,15 +109,15 @@ protected:
}; };
/** Convert a list of arguments to a human-readable command line. */ /** Convert a list of arguments to a human-readable command line. */
static std::string ComputeCommandLine(char const* const* cmd); static std::string ComputeCommandLine(const std::vector<std::string>& cmd);
/** Run a command line and send output to given parsers. */ /** Run a command line and send output to given parsers. */
bool RunChild(char const* const* cmd, OutputParser* out, OutputParser* err, bool RunChild(const std::vector<std::string>& cmd, OutputParser* out,
const char* workDir = nullptr, OutputParser* err, std::string workDir = {},
Encoding encoding = cmProcessOutput::Auto); Encoding encoding = cmProcessOutput::Auto);
/** Run VC update command line and send output to given parsers. */ /** Run VC update command line and send output to given parsers. */
bool RunUpdateCommand(char const* const* cmd, OutputParser* out, bool RunUpdateCommand(const std::vector<std::string>& cmd, OutputParser* out,
OutputParser* err = nullptr, OutputParser* err = nullptr,
Encoding encoding = cmProcessOutput::Auto); Encoding encoding = cmProcessOutput::Auto);
+51 -31
View File
@@ -2,48 +2,68 @@
file Copyright.txt or https://cmake.org/licensing for details. */ file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmProcessTools.h" #include "cmProcessTools.h"
#include <algorithm>
#include <iterator>
#include <ostream> #include <ostream>
#include "cmsys/Process.h" #include <cm3p/uv.h>
#include "cmProcessOutput.h" #include "cmProcessOutput.h"
#include "cmUVHandlePtr.h"
#include "cmUVStream.h"
void cmProcessTools::RunProcess(struct cmsysProcess_s* cp, OutputParser* out, std::vector<cmUVProcessChain::Status> cmProcessTools::RunProcess(
OutputParser* err, Encoding encoding) cmUVProcessChainBuilder& builder, OutputParser* out, OutputParser* err,
Encoding encoding)
{ {
cmsysProcess_Execute(cp);
char* data = nullptr;
int length = 0;
int p;
cmProcessOutput processOutput(encoding); cmProcessOutput processOutput(encoding);
builder.SetBuiltinStream(cmUVProcessChainBuilder::Stream_OUTPUT)
.SetBuiltinStream(cmUVProcessChainBuilder::Stream_ERROR);
auto chain = builder.Start();
std::string strdata; std::string strdata;
while ((out || err) && cm::uv_pipe_ptr outputPipe;
(p = cmsysProcess_WaitForData(cp, &data, &length, nullptr))) { outputPipe.init(chain.GetLoop(), 0);
if (out && p == cmsysProcess_Pipe_STDOUT) { uv_pipe_open(outputPipe, chain.OutputStream());
processOutput.DecodeText(data, length, strdata, 1); auto outputHandle = cmUVStreamRead(
if (!out->Process(strdata.c_str(), static_cast<int>(strdata.size()))) { outputPipe,
out = nullptr; [&out, &processOutput, &strdata](std::vector<char> data) {
if (out) {
processOutput.DecodeText(data.data(), data.size(), strdata, 1);
if (!out->Process(strdata.c_str(), static_cast<int>(strdata.size()))) {
out = nullptr;
}
} }
} else if (err && p == cmsysProcess_Pipe_STDERR) { },
processOutput.DecodeText(data, length, strdata, 2); [&out]() { out = nullptr; });
if (!err->Process(strdata.c_str(), static_cast<int>(strdata.size()))) { cm::uv_pipe_ptr errorPipe;
err = nullptr; errorPipe.init(chain.GetLoop(), 0);
uv_pipe_open(errorPipe, chain.ErrorStream());
auto errorHandle = cmUVStreamRead(
errorPipe,
[&err, &processOutput, &strdata](std::vector<char> data) {
if (err) {
processOutput.DecodeText(data.data(), data.size(), strdata, 2);
if (!err->Process(strdata.c_str(), static_cast<int>(strdata.size()))) {
err = nullptr;
}
} }
} },
[&err]() { err = nullptr; });
while (out || err || !chain.Finished()) {
uv_run(&chain.GetLoop(), UV_RUN_ONCE);
} }
if (out) {
processOutput.DecodeText(std::string(), strdata, 1); std::vector<cmUVProcessChain::Status> result;
if (!strdata.empty()) { auto status = chain.GetStatus();
out->Process(strdata.c_str(), static_cast<int>(strdata.size())); std::transform(
} status.begin(), status.end(), std::back_inserter(result),
} [](const cmUVProcessChain::Status* s) -> cmUVProcessChain::Status {
if (err) { return *s;
processOutput.DecodeText(std::string(), strdata, 2); });
if (!strdata.empty()) { return result;
err->Process(strdata.c_str(), static_cast<int>(strdata.size()));
}
}
cmsysProcess_WaitForExit(cp, nullptr);
} }
cmProcessTools::LineParser::LineParser(char sep, bool ignoreCR) cmProcessTools::LineParser::LineParser(char sep, bool ignoreCR)
+5 -3
View File
@@ -7,8 +7,10 @@
#include <cstring> #include <cstring>
#include <iosfwd> #include <iosfwd>
#include <string> #include <string>
#include <vector>
#include "cmProcessOutput.h" #include "cmProcessOutput.h"
#include "cmUVProcessChain.h"
/** \class cmProcessTools /** \class cmProcessTools
* \brief Helper classes for process output parsing * \brief Helper classes for process output parsing
@@ -81,7 +83,7 @@ public:
}; };
/** Run a process and send output to given parsers. */ /** Run a process and send output to given parsers. */
static void RunProcess(struct cmsysProcess_s* cp, OutputParser* out, static std::vector<cmUVProcessChain::Status> RunProcess(
OutputParser* err = nullptr, cmUVProcessChainBuilder& builder, OutputParser* out,
Encoding encoding = cmProcessOutput::Auto); OutputParser* err = nullptr, Encoding encoding = cmProcessOutput::Auto);
}; };
+12 -21
View File
@@ -28,6 +28,7 @@
#include "cmStringAlgorithms.h" #include "cmStringAlgorithms.h"
#include "cmSystemTools.h" #include "cmSystemTools.h"
#include "cmTransformDepfile.h" #include "cmTransformDepfile.h"
#include "cmUVHandlePtr.h"
#include "cmUVProcessChain.h" #include "cmUVProcessChain.h"
#include "cmUVStream.h" #include "cmUVStream.h"
#include "cmUtils.hxx" #include "cmUtils.hxx"
@@ -295,14 +296,8 @@ int CLCompileAndDependencies(const std::vector<std::string>& args)
} }
} }
std::unique_ptr<cmsysProcess, void (*)(cmsysProcess*)> cp( cmUVProcessChainBuilder builder;
cmsysProcess_New(), cmsysProcess_Delete); builder.AddCommand(command).SetWorkingDirectory(currentBinaryDir);
std::vector<const char*> argv(command.size() + 1);
std::transform(command.begin(), command.end(), argv.begin(),
[](std::string const& s) { return s.c_str(); });
argv.back() = nullptr;
cmsysProcess_SetCommand(cp.get(), argv.data());
cmsysProcess_SetWorkingDirectory(cp.get(), currentBinaryDir.c_str());
cmsys::ofstream fout(depFile.c_str()); cmsys::ofstream fout(depFile.c_str());
if (!fout) { if (!fout) {
@@ -313,22 +308,18 @@ int CLCompileAndDependencies(const std::vector<std::string>& args)
CLOutputLogger errLogger(std::cerr); CLOutputLogger errLogger(std::cerr);
// Start the process. // Start the process.
cmProcessTools::RunProcess(cp.get(), &includeParser, &errLogger); auto result =
cmProcessTools::RunProcess(builder, &includeParser, &errLogger);
auto const& subStatus = result.front();
int status = 0; int status = 0;
// handle status of process // handle status of process
switch (cmsysProcess_GetState(cp.get())) { if (subStatus.SpawnResult != 0) {
case cmsysProcess_State_Exited: status = 2;
status = cmsysProcess_GetExitValue(cp.get()); } else if (subStatus.TermSignal != 0) {
break; status = 1;
case cmsysProcess_State_Exception: } else {
status = 1; status = subStatus.ExitStatus;
break;
case cmsysProcess_State_Error:
status = 2;
break;
default:
break;
} }
if (status != 0) { if (status != 0) {