DYTSrouce/src/workspace/CommandManager.cpp

145 lines
5.8 KiB
C++
Raw Normal View History

2025-10-13 00:20:53 +00:00
#include "workspace/CommandManager.h"
#include <QFileInfo>
#include "xml/tinyxml2.h"
#include "common/SpdLogger.h"
static QMap<QString, QString> parseEnvAttr(const QString& envAttr) {
QMap<QString, QString> env;
if (envAttr.isEmpty()) return env;
const auto pairs = envAttr.split(';', Qt::SkipEmptyParts);
for (const auto& p : pairs) {
const auto kv = p.split('=', Qt::KeepEmptyParts);
if (kv.size() >= 2) env.insert(kv[0].trimmed(), kv[1].trimmed());
}
return env;
}
void CommandManager::Reload(WorkSpace* ws) {
onCreate_.clear();
onLoad_.clear();
if (!ws) return;
2025-10-14 16:41:12 +00:00
const QString cmdPath = QString("%1/%2").arg(ws->GetDir(), ws->GetCommondFilePath());
2025-10-13 00:20:53 +00:00
if (cmdPath.isEmpty()) {
LOG_INFO("no command xml configured");
return;
}
QFileInfo fi(cmdPath);
if (!fi.exists() || !fi.isFile()) {
LOG_WARN("command xml not found: {}", cmdPath.toLocal8Bit().constData());
return;
}
tinyxml2::XMLDocument doc;
auto rc = doc.LoadFile(cmdPath.toLocal8Bit().constData());
if (rc != tinyxml2::XML_SUCCESS) {
2025-10-13 14:03:53 +00:00
LOG_WARN("load command xml failed: {} rc:{}", cmdPath.toLocal8Bit().constData(), static_cast<int>(rc));
2025-10-13 00:20:53 +00:00
return;
}
auto* root = doc.RootElement();
if (!root) {
LOG_WARN("command xml has no root: {}", cmdPath.toLocal8Bit().constData());
return;
}
for (auto* node = root->FirstChildElement(); node; node = node->NextSiblingElement()) {
const char* tag = node->Name();
if (!tag) continue;
QString tagQ = QString::fromUtf8(tag).toLower();
if (tagQ != QLatin1String("commond") && tagQ != QLatin1String("command")) continue;
Command cmd;
if (const char* nameAttr = node->Attribute("name")) cmd.name = QString::fromUtf8(nameAttr);
if (const char* exeAttr = node->Attribute("exe")) cmd.program = QString::fromUtf8(exeAttr);
if (cmd.program.isEmpty()) {
if (const char* programAttr = node->Attribute("program")) cmd.program = QString::fromUtf8(programAttr);
}
if (const char* pathAttr = node->Attribute("path")) cmd.path = QString::fromUtf8(pathAttr);
if (cmd.path.isEmpty()) {
if (const char* pathTypo = node->Attribute("paht")) cmd.path = QString::fromUtf8(pathTypo);
}
if (const char* argsAttr = node->Attribute("args")) cmd.rawArgs = QString::fromUtf8(argsAttr);
if (const char* cwdAttr = node->Attribute("workingDir")) cmd.workingDir = QString::fromUtf8(cwdAttr);
if (cmd.workingDir.isEmpty()) {
if (const char* cwdAttr2 = node->Attribute("cwd")) cmd.workingDir = QString::fromUtf8(cwdAttr2);
}
if (const char* enabledAttr = node->Attribute("enabled")) {
QString en = QString::fromUtf8(enabledAttr).toLower();
cmd.enabled = !(en == QLatin1String("false") || en == QLatin1String("0"));
}
if (const char* descAttr = node->Attribute("descript")) cmd.descript = QString::fromUtf8(descAttr);
if (cmd.descript.isEmpty()) {
if (const char* desc2 = node->Attribute("description")) cmd.descript = QString::fromUtf8(desc2);
}
if (const char* timeoutAttr = node->Attribute("timeoutSec")) {
bool ok = false; int v = QString::fromUtf8(timeoutAttr).toInt(&ok);
if (ok && v > 0) cmd.timeoutMs = v * 1000;
}
// env: either attribute env="KEY=VAL;K2=V2" or child elements <env key="" value=""/>
if (const char* envAttr = node->Attribute("env")) {
cmd.env = parseEnvAttr(QString::fromUtf8(envAttr));
}
for (auto* envNode = node->FirstChildElement("env"); envNode; envNode = envNode->NextSiblingElement("env")) {
const char* k = envNode->Attribute("key");
const char* v = envNode->Attribute("value");
if (k && v) cmd.env.insert(QString::fromUtf8(k), QString::fromUtf8(v));
}
// Pre-build args list from rawArgs (actual insertion of path happens in executor)
if (!cmd.rawArgs.isEmpty()) {
for (const auto& part : cmd.rawArgs.split(' ', Qt::SkipEmptyParts)) {
cmd.args << part;
}
}
// when routing
WorkSpace::CommandWhen target = WorkSpace::CommandWhen::OnCreate; // default
if (const char* whenAttr = node->Attribute("when")) {
QString wa = QString::fromUtf8(whenAttr).toLower();
if (wa == QLatin1String("onload")) target = WorkSpace::CommandWhen::OnLoad;
}
auto exec = std::make_unique<CommandExecutor>(cmd);
if (target == WorkSpace::CommandWhen::OnCreate) onCreate_.push_back(std::move(exec));
else onLoad_.push_back(std::move(exec));
}
}
void CommandManager::Execute(WorkSpace* ws, WorkSpace::CommandWhen when) {
// Reload each time to reflect latest XML
Reload(ws);
auto& list = (when == WorkSpace::CommandWhen::OnCreate) ? onCreate_ : onLoad_;
for (auto& exec : list) {
exec->Execute(ws, when);
}
2025-10-13 16:15:18 +00:00
}
std::vector<Command> CommandManager::ListCommands(WorkSpace* ws) {
std::vector<Command> items;
Reload(ws);
for (auto& exec : onCreate_) {
items.push_back(exec->Get());
}
for (auto& exec : onLoad_) {
items.push_back(exec->Get());
}
return items;
}
bool CommandManager::ExecuteByName(WorkSpace* ws, const QString& name) {
Reload(ws);
auto matchAndRun = [&](std::vector<std::unique_ptr<CommandExecutor>>& list, WorkSpace::CommandWhen when) -> bool {
for (auto& exec : list) {
if (exec->Get().name == name) {
exec->Execute(ws, when);
return true;
}
}
return false;
};
if (matchAndRun(onCreate_, WorkSpace::CommandWhen::OnCreate)) return true;
if (matchAndRun(onLoad_, WorkSpace::CommandWhen::OnLoad)) return true;
return false;
2025-10-13 00:20:53 +00:00
}