Skip to content

Commit

Permalink
rewrite with Command
Browse files Browse the repository at this point in the history
  • Loading branch information
yaito3014 committed Sep 16, 2024
1 parent 3c86157 commit 9fee2b9
Show file tree
Hide file tree
Showing 13 changed files with 165 additions and 148 deletions.
44 changes: 9 additions & 35 deletions src/Algos.cc
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "Algos.hpp"

#include "Command.hpp"
#include "Exception.hpp"
#include "Logger.hpp"
#include "Rustify.hpp"
Expand Down Expand Up @@ -39,48 +40,23 @@ toMacroName(const std::string_view name) noexcept {
}

int
execCmd(const std::string_view cmd) noexcept {
execCmd(const Command& cmd) noexcept {
logger::debug("Running `", cmd, '`');
const int status = std::system(cmd.data());
const int exitCode = status >> 8;
return exitCode;
}

static std::pair<std::string, int>
getCmdOutputImpl(const std::string_view cmd) {
constexpr usize bufferSize = 128;
std::array<char, bufferSize> buffer{};
std::string output;

FILE* pipe = popen(cmd.data(), "r");
if (!pipe) {
throw PoacError("popen() failed!");
}

while (fgets(buffer.data(), buffer.size(), pipe) != nullptr) {
output += buffer.data();
}

const int status = pclose(pipe);
if (status == -1) {
throw PoacError("pclose() failed!");
}
const int exitCode = status >> 8;
return { output, exitCode };
return cmd.output().exitCode;
}

std::string
getCmdOutput(const std::string_view cmd, const usize retry) {
getCmdOutput(const Command& cmd, const usize retry) {
logger::debug("Running `", cmd, '`');

int exitCode = EXIT_SUCCESS;
int waitTime = 1;
for (usize i = 0; i < retry; ++i) {
const auto result = getCmdOutputImpl(cmd);
if (result.second == EXIT_SUCCESS) {
return result.first;
const auto [output, status] = cmd.output();
if (status == EXIT_SUCCESS) {
return output;
}
exitCode = result.second;
exitCode = status;

// Sleep for an exponential backoff.
std::this_thread::sleep_for(std::chrono::seconds(waitTime));
Expand All @@ -91,9 +67,7 @@ getCmdOutput(const std::string_view cmd, const usize retry) {

bool
commandExists(const std::string_view cmd) noexcept {
std::string checkCmd = "command -v ";
checkCmd += cmd;
checkCmd += " >/dev/null 2>&1";
auto checkCmd = Command("command").addArg("-v").addArg(cmd);
return execCmd(checkCmd) == EXIT_SUCCESS;
}

Expand Down
5 changes: 3 additions & 2 deletions src/Algos.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#pragma once

#include "Command.hpp"
#include "Exception.hpp"
#include "Rustify.hpp"

Expand All @@ -20,8 +21,8 @@
std::string toUpper(std::string_view str) noexcept;
std::string toMacroName(std::string_view name) noexcept;

int execCmd(std::string_view cmd) noexcept;
std::string getCmdOutput(std::string_view cmd, usize retry = 3);
int execCmd(const Command& cmd) noexcept;
std::string getCmdOutput(const Command& cmd, usize retry = 3);
bool commandExists(std::string_view cmd) noexcept;

template <typename T>
Expand Down
111 changes: 56 additions & 55 deletions src/BuildConfig.cc
Original file line number Diff line number Diff line change
Expand Up @@ -110,10 +110,10 @@ struct BuildConfig {

std::string OUT_DIR;
std::string CXX = "clang++";
std::string CXXFLAGS;
std::string DEFINES;
std::string INCLUDES = " -I../../include";
std::string LIBS;
std::vector<std::string> CXXFLAGS;
std::vector<std::string> DEFINES;
std::vector<std::string> INCLUDES = { "-I../../include" };
std::vector<std::string> LIBS;

BuildConfig() = default;
explicit BuildConfig(const std::string& packageName)
Expand Down Expand Up @@ -334,21 +334,21 @@ BuildConfig::emitCompdb(const std::string_view baseDir, std::ostream& os)
const std::string file = targetInfo.sourceFile.value();
// The output is the target.
const std::string output = target;
std::string cmd = CXX;
cmd += ' ';
cmd += CXXFLAGS;
cmd += DEFINES;
cmd += INCLUDES;
cmd += " -c ";
cmd += file;
cmd += " -o ";
cmd += output;
const Command cmd = Command(CXX)
.addArg(" ")
.addArgs(CXXFLAGS)
.addArgs(DEFINES)
.addArgs(INCLUDES)
.addArg(" -c ")
.addArg(file)
.addArg(" -o ")
.addArg(output);

oss << indent1 << "{\n";
oss << indent2 << "\"directory\": " << baseDirPath << ",\n";
oss << indent2 << "\"file\": " << std::quoted(file) << ",\n";
oss << indent2 << "\"output\": " << std::quoted(output) << ",\n";
oss << indent2 << "\"command\": " << std::quoted(cmd) << "\n";
oss << indent2 << "\"command\": " << std::quoted(cmd.to_string()) << "\n";
oss << indent1 << "},\n";
}

Expand All @@ -366,18 +366,14 @@ BuildConfig::emitCompdb(const std::string_view baseDir, std::ostream& os)

std::string
BuildConfig::runMM(const std::string& sourceFile, const bool isTest) const {
std::string command = "cd ";
command += getOutDir();
command += " && ";
command += CXX;
command += CXXFLAGS;
command += DEFINES;
command += INCLUDES;
Command command =
Command(CXX).addArgs(CXXFLAGS).addArgs(DEFINES).addArgs(INCLUDES);
if (isTest) {
command += " -DPOAC_TEST";
command.addArg("-DPOAC_TEST");
}
command += " -MM ";
command += sourceFile;
command.addArg("-MM");
command.addArg(sourceFile);
command.setWorkingDirectory(getOutDir());
return getCmdOutput(command);
}

Expand Down Expand Up @@ -430,17 +426,16 @@ BuildConfig::containsTestCode(const std::string& sourceFile) const {
while (std::getline(ifs, line)) {
if (line.find("POAC_TEST") != std::string::npos) {
// TODO: Can't we somehow elegantly make the compiler command sharable?
std::string command = CXX;
command += " -E ";
command += CXXFLAGS;
command += DEFINES;
command += INCLUDES;
command += ' ';
command += sourceFile;
Command command(CXX);
command.addArg("-E");
command.addArgs(CXXFLAGS);
command.addArgs(DEFINES);
command.addArgs(INCLUDES);
command.addArg(sourceFile);

const std::string src = getCmdOutput(command);

command += " -DPOAC_TEST";
command.addArg("-DPOAC_TEST");
const std::string testSrc = getCmdOutput(command);

// If the source file contains POAC_TEST, by processing the source
Expand Down Expand Up @@ -570,42 +565,46 @@ void
BuildConfig::installDeps(const bool includeDevDeps) {
const std::vector<DepMetadata> deps = installDependencies(includeDevDeps);
for (const DepMetadata& dep : deps) {
INCLUDES += ' ' + dep.includes;
LIBS += ' ' + dep.libs;
INCLUDES.push_back(dep.includes);
LIBS.push_back(dep.libs);
}
logger::debug("INCLUDES: ", INCLUDES);
logger::debug("LIBS: ", LIBS);
logger::debug(fmt::format("INCLUDES: {}", fmt::join(INCLUDES, " ")));
logger::debug(fmt::format("LIBS: {}", fmt::join(LIBS, " ")));
}

void
BuildConfig::addDefine(
const std::string_view name, const std::string_view value
) {
DEFINES += fmt::format(" -D{}='\"{}\"'", name, value);
DEFINES.push_back(fmt::format("-D{}='\"{}\"'", name, value));
}

void
BuildConfig::setVariables(const bool isDebug) {
this->defineCondVar("CXX", CXX);

CXXFLAGS += " -std=c++" + getPackageEdition().getString();
CXXFLAGS.push_back("-std=c++" + getPackageEdition().getString());
if (shouldColor()) {
CXXFLAGS += " -fdiagnostics-color";
CXXFLAGS.push_back("-fdiagnostics-color");
}
if (isDebug) {
CXXFLAGS += " -g -O0 -DDEBUG";
CXXFLAGS.push_back("-g");
CXXFLAGS.push_back("-O0");
CXXFLAGS.push_back("-DDEBUG");
} else {
CXXFLAGS += " -O3 -DNDEBUG";
CXXFLAGS.push_back("-O3");
CXXFLAGS.push_back("-DNDEBUG");
}
const Profile& profile = isDebug ? getDevProfile() : getReleaseProfile();
if (profile.lto) {
CXXFLAGS += " -flto";
CXXFLAGS.push_back("-flto");
}
for (const std::string_view flag : profile.cxxflags) {
CXXFLAGS += ' ';
CXXFLAGS += flag;
CXXFLAGS.emplace_back(flag);
}
this->defineSimpleVar("CXXFLAGS", CXXFLAGS);
this->defineSimpleVar(
"CXXFLAGS", fmt::format("{:s}", fmt::join(CXXFLAGS, " "))
);

const std::string pkgName = toMacroName(this->packageName);
const Version& pkgVersion = getPackageVersion();
Expand Down Expand Up @@ -646,9 +645,13 @@ BuildConfig::setVariables(const bool isDebug) {
addDefine(key, val);
}

this->defineSimpleVar("DEFINES", DEFINES);
this->defineSimpleVar("INCLUDES", INCLUDES);
this->defineSimpleVar("LIBS", LIBS);
this->defineSimpleVar(
"DEFINES", fmt::format("{:s}", fmt::join(DEFINES, " "))
);
this->defineSimpleVar(
"INCLUDES", fmt::format("{:s}", fmt::join(INCLUDES, " "))
);
this->defineSimpleVar("LIBS", fmt::format("{:s}", fmt::join(LIBS, " ")));
}

void
Expand Down Expand Up @@ -956,18 +959,16 @@ modeToProfile(const bool isDebug) {
return isDebug ? "dev" : "release";
}

std::string
Command
getMakeCommand() {
std::string makeCommand;
if (isVerbose()) {
makeCommand = "make";
} else {
makeCommand = "make -s --no-print-directory Q=@";
Command makeCommand("make");
if (!isVerbose()) {
makeCommand.addArg("-s").addArg("--no-print-directory").addArg("Q=@");
}

const usize numThreads = getParallelism();
if (numThreads > 1) {
makeCommand += " -j" + std::to_string(numThreads);
makeCommand.addArg("-j" + std::to_string(numThreads));
}

return makeCommand;
Expand Down
4 changes: 3 additions & 1 deletion src/BuildConfig.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#pragma once

#include "Command.hpp"

#include <string>
#include <unordered_set>

Expand All @@ -16,4 +18,4 @@ std::string emitMakefile(bool isDebug, bool includeDevDeps);
std::string emitCompdb(bool isDebug, bool includeDevDeps);
std::string_view modeToString(bool isDebug);
std::string_view modeToProfile(bool isDebug);
std::string getMakeCommand();
Command getMakeCommand();
2 changes: 1 addition & 1 deletion src/Cmd/Build.cc
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ buildImpl(std::string& outDir, const bool isDebug) {
const auto start = std::chrono::steady_clock::now();

outDir = emitMakefile(isDebug, /*includeDevDeps=*/false);
const std::string makeCommand = getMakeCommand() + " -C " + outDir;
const auto makeCommand = getMakeCommand().addArg("-C").addArg(outDir);
const int exitCode = execCmd(makeCommand);

const auto end = std::chrono::steady_clock::now();
Expand Down
23 changes: 14 additions & 9 deletions src/Cmd/Fmt.cc
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ const Subcmd FMT_CMD =
static void
collectFormatTargetFiles(
const fs::path& manifestDir, const std::vector<fs::path>& excludes,
std::string& clangFormatArgs
std::vector<std::string>& clangFormatArgs
) {
// Read git repository if exists
git2::Repository repo = git2::Repository();
Expand Down Expand Up @@ -74,7 +74,7 @@ collectFormatTargetFiles(

const std::string ext = path.extension().string();
if (SOURCE_FILE_EXTS.contains(ext) || HEADER_FILE_EXTS.contains(ext)) {
clangFormatArgs += ' ' + path.string();
clangFormatArgs.push_back(path.string());
}
}
}
Expand Down Expand Up @@ -114,22 +114,27 @@ fmtMain(const std::span<const std::string_view> args) {
}

const std::string_view packageName = getPackageName();
std::string clangFormatArgs = "--style=file --fallback-style=LLVM -Werror";
std::vector<std::string> clangFormatArgs{
"--style=file",
"--fallback-style=LLVM",
"-Werror",
};
if (isVerbose()) {
clangFormatArgs += " --verbose";
clangFormatArgs.push_back("--verbose");
}
if (isCheck) {
clangFormatArgs += " --dry-run";
clangFormatArgs.push_back("--dry-run");
} else {
clangFormatArgs += " -i";
clangFormatArgs.push_back("-i");
logger::info("Formatting", packageName);
}

const fs::path& manifestDir = getManifestPath().parent_path();
collectFormatTargetFiles(manifestDir, excludes, clangFormatArgs);

const std::string clangFormat = "cd " + manifestDir.string()
+ " && ${POAC_FMT:-clang-format} "
+ clangFormatArgs;
const Command clangFormat =
Command("${POAC_FMT:-clang-format}", std::move(clangFormatArgs))
.setWorkingDirectory(manifestDir.string());

return execCmd(clangFormat);
}
Loading

0 comments on commit 9fee2b9

Please sign in to comment.