Skip to content

Commit 3576578

Browse files
committed
refactor(cli): use engine process runner
1 parent 49f3c7e commit 3576578

5 files changed

Lines changed: 115 additions & 268 deletions

File tree

‎src/build/BuildTaskProcessExecutor.cpp‎

Lines changed: 12 additions & 130 deletions
Original file line numberDiff line numberDiff line change
@@ -16,104 +16,10 @@
1616

1717
#include <vix/cli/build/BuildTaskProcessExecutor.hpp>
1818

19-
#include <cstdio>
20-
#include <filesystem>
21-
#include <sstream>
22-
23-
#ifndef _WIN32
24-
#include <sys/wait.h>
25-
#endif
19+
#include <vix/engine/Process.hpp>
2620

2721
namespace vix::cli::build
2822
{
29-
namespace fs = std::filesystem;
30-
31-
namespace
32-
{
33-
static std::string shell_quote(const std::string &value)
34-
{
35-
#ifdef _WIN32
36-
std::string out = "\"";
37-
for (char c : value)
38-
{
39-
if (c == '"')
40-
out += "\"\"";
41-
else
42-
out.push_back(c);
43-
}
44-
out += "\"";
45-
return out;
46-
#else
47-
std::string out = "'";
48-
for (char c : value)
49-
{
50-
if (c == '\'')
51-
out += "'\\''";
52-
else
53-
out.push_back(c);
54-
}
55-
out += "'";
56-
return out;
57-
#endif
58-
}
59-
60-
static std::string command_to_shell_string(const std::vector<std::string> &command)
61-
{
62-
std::ostringstream out;
63-
64-
for (std::size_t i = 0; i < command.size(); ++i)
65-
{
66-
if (i > 0)
67-
out << " ";
68-
69-
out << shell_quote(command[i]);
70-
}
71-
72-
return out.str();
73-
}
74-
75-
static std::string command_to_shell_string_with_working_directory(
76-
const std::vector<std::string> &command,
77-
const fs::path &workingDirectory)
78-
{
79-
std::ostringstream out;
80-
81-
#ifndef _WIN32
82-
if (!workingDirectory.empty())
83-
{
84-
out << "cd ";
85-
out << shell_quote(workingDirectory.string());
86-
out << " && ";
87-
}
88-
#else
89-
if (!workingDirectory.empty())
90-
{
91-
out << "cd /d ";
92-
out << shell_quote(workingDirectory.string());
93-
out << " && ";
94-
}
95-
#endif
96-
97-
out << command_to_shell_string(command);
98-
return out.str();
99-
}
100-
101-
static int normalize_exit_code(int code)
102-
{
103-
#ifdef _WIN32
104-
return code;
105-
#else
106-
if (WIFEXITED(code))
107-
return WEXITSTATUS(code);
108-
109-
if (WIFSIGNALED(code))
110-
return 128 + WTERMSIG(code);
111-
112-
return code;
113-
#endif
114-
}
115-
} // namespace
116-
11723
BuildTaskResult execute_build_task_process(BuildTask &task)
11824
{
11925
BuildTaskResult result;
@@ -127,44 +33,20 @@ namespace vix::cli::build
12733
return result;
12834
}
12935

130-
const std::string shellCommand =
131-
command_to_shell_string_with_working_directory(
132-
task.command,
133-
task.workingDirectory) +
134-
" 2>&1";
135-
136-
#ifdef _WIN32
137-
FILE *pipe = _popen(shellCommand.c_str(), "r");
138-
#else
139-
FILE *pipe = popen(shellCommand.c_str(), "r");
140-
#endif
141-
142-
if (!pipe)
143-
{
144-
result.state = BuildTaskState::Failed;
145-
result.exitCode = 127;
146-
result.output = "Failed to start task: " + task.id + "\n";
147-
return result;
148-
}
149-
150-
std::ostringstream output;
151-
char buffer[4096];
152-
153-
while (std::fgets(buffer, sizeof(buffer), pipe) != nullptr)
154-
output << buffer;
155-
156-
#ifdef _WIN32
157-
const int rawCode = _pclose(pipe);
158-
#else
159-
const int rawCode = pclose(pipe);
160-
#endif
36+
vix::engine::process::Command command;
37+
command.argv = task.command;
38+
command.workingDirectory = task.workingDirectory;
39+
command.mergeStdErr = true;
16140

162-
const int exitCode = normalize_exit_code(rawCode);
41+
const vix::engine::process::Result processResult =
42+
vix::engine::process::execute(command);
16343

164-
result.exitCode = exitCode;
165-
result.output = output.str();
44+
result.exitCode = processResult.exitCode;
45+
result.output = processResult.output;
46+
if (!processResult.errorMessage.empty())
47+
result.output += processResult.errorMessage + "\n";
16648

167-
if (exitCode == 0)
49+
if (processResult.success())
16850
result.state = BuildTaskState::Done;
16951
else
17052
result.state = BuildTaskState::Failed;

‎src/cmake/CMakeBuild.cpp‎

Lines changed: 33 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include <vix/cli/util/Fs.hpp>
2323
#include <vix/cli/util/Strings.hpp>
2424

25+
#include <vix/engine/Process.hpp>
2526
#include <vix/utils/Env.hpp>
2627

2728
#ifndef _WIN32
@@ -219,59 +220,27 @@ namespace vix::cli::build
219220
const std::vector<std::pair<std::string, std::string>> &extraEnv,
220221
std::string &outText)
221222
{
222-
process::ExecResult r;
223-
r.displayCommand = util::join_display_cmd(argv);
223+
vix::engine::process::Command command;
224+
command.argv = argv;
225+
command.environment = extraEnv;
226+
command.mergeStdErr = true;
224227

225-
int pipefd[2];
226-
if (::pipe(pipefd) != 0)
227-
{
228-
r.exitCode = 127;
229-
return r;
230-
}
228+
const vix::engine::process::Result processResult =
229+
vix::engine::process::execute(command);
231230

232-
pid_t pid = ::fork();
233-
if (pid == 0)
234-
{
235-
::dup2(pipefd[1], STDOUT_FILENO);
236-
::dup2(pipefd[1], STDERR_FILENO);
237-
::close(pipefd[0]);
238-
::close(pipefd[1]);
231+
outText = processResult.output;
232+
if (!processResult.errorMessage.empty())
233+
outText += processResult.errorMessage + "\n";
239234

240-
for (const auto &kv : extraEnv)
241-
::setenv(kv.first.c_str(), kv.second.c_str(), 1);
242-
243-
std::vector<char *> cargv;
244-
cargv.reserve(argv.size() + 1);
245-
for (const auto &s : argv)
246-
cargv.push_back(const_cast<char *>(s.c_str()));
247-
cargv.push_back(nullptr);
248-
249-
::execvp(cargv[0], cargv.data());
250-
_exit(127);
251-
}
252-
253-
::close(pipefd[1]);
254-
255-
std::string buf(8 * 1024, '\0');
256-
while (true)
257-
{
258-
const ssize_t n = ::read(pipefd[0], &buf[0], buf.size());
259-
if (n > 0)
260-
outText.append(buf.data(), static_cast<std::size_t>(n));
261-
else
262-
break;
263-
}
235+
process::ExecResult r;
236+
r.exitCode = processResult.exitCode;
237+
r.displayCommand = processResult.displayCommand;
238+
r.producedOutput = !outText.empty();
264239

265-
::close(pipefd[0]);
240+
const auto newline = outText.find('\n');
241+
r.capturedFirstLine =
242+
util::trim(newline == std::string::npos ? outText : outText.substr(0, newline));
266243

267-
int status = 0;
268-
if (::waitpid(pid, &status, 0) < 0)
269-
{
270-
r.exitCode = 127;
271-
return r;
272-
}
273-
274-
r.exitCode = process::normalize_exit_code(status);
275244
return r;
276245
}
277246

@@ -845,32 +814,27 @@ namespace vix::cli::build
845814
const std::vector<std::pair<std::string, std::string>> &extraEnv,
846815
std::string &outText)
847816
{
848-
process::ExecResult r;
849-
r.displayCommand = util::join_display_cmd(argv);
817+
vix::engine::process::Command command;
818+
command.argv = argv;
819+
command.environment = extraEnv;
820+
command.mergeStdErr = true;
850821

851-
for (const auto &kv : extraEnv)
852-
{
853-
std::string e = kv.first + "=" + kv.second;
854-
(void)_putenv(e.c_str());
855-
}
822+
const vix::engine::process::Result processResult =
823+
vix::engine::process::execute(command);
856824

857-
fs::path tmp = fs::temp_directory_path() / "vix_build_capture.tmp";
825+
outText = processResult.output;
826+
if (!processResult.errorMessage.empty())
827+
outText += processResult.errorMessage + "\n";
858828

859-
std::ostringstream oss;
860-
for (std::size_t i = 0; i < argv.size(); ++i)
861-
{
862-
if (i)
863-
oss << " ";
864-
oss << "\"" << argv[i] << "\"";
865-
}
829+
process::ExecResult r;
830+
r.exitCode = processResult.exitCode;
831+
r.displayCommand = processResult.displayCommand;
832+
r.producedOutput = !outText.empty();
866833

867-
const std::string cmd = oss.str() + " > \"" + tmp.string() + "\" 2>&1";
868-
const int raw = std::system(cmd.c_str());
869-
r.exitCode = process::normalize_exit_code(raw);
834+
const auto newline = outText.find('\n');
835+
r.capturedFirstLine =
836+
util::trim(newline == std::string::npos ? outText : outText.substr(0, newline));
870837

871-
outText = util::read_text_file_or_empty(tmp);
872-
std::error_code ec{};
873-
fs::remove(tmp, ec);
874838
return r;
875839
}
876840

‎src/process/Process_posix.cpp‎

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,23 +12,15 @@
1212
*/
1313
#include <vix/cli/process/Process.hpp>
1414

15+
#include <vix/engine/Process.hpp>
16+
1517
#ifndef _WIN32
16-
#include <sys/wait.h>
1718

1819
namespace vix::cli::process
1920
{
2021
int normalize_exit_code(int raw) noexcept
2122
{
22-
if (raw == -1)
23-
return 127;
24-
25-
if (WIFEXITED(raw))
26-
return WEXITSTATUS(raw);
27-
28-
if (WIFSIGNALED(raw))
29-
return 128 + WTERMSIG(raw);
30-
31-
return raw;
23+
return vix::engine::process::normalize_exit_code(raw);
3224
}
3325
} // namespace vix::cli::process
3426

‎src/process/Process_win.cpp‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,15 @@
1212
*/
1313
#include <vix/cli/process/Process.hpp>
1414

15+
#include <vix/engine/Process.hpp>
16+
1517
#ifdef _WIN32
1618

1719
namespace vix::cli::process
1820
{
1921
int normalize_exit_code(int raw) noexcept
2022
{
21-
return raw;
23+
return vix::engine::process::normalize_exit_code(raw);
2224
}
2325
} // namespace vix::cli::process
2426

0 commit comments

Comments
 (0)