d3af7d54ff
- CMakeLists.txt - main.cpp - data_collectors.cpp - data_collectors.h - runner.cpp - runner.h Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
78 lines
2.4 KiB
C++
78 lines
2.4 KiB
C++
#include "data_collectors.h"
|
|
|
|
#include <filesystem>
|
|
#include <fstream>
|
|
|
|
namespace fs = std::filesystem;
|
|
|
|
namespace {
|
|
|
|
std::string trim(std::string s) {
|
|
auto issp = [](unsigned char c) { return std::isspace(c); };
|
|
while (!s.empty() && issp((unsigned char)s.back())) s.pop_back();
|
|
size_t i = 0;
|
|
while (i < s.size() && issp((unsigned char)s[i])) ++i;
|
|
return s.substr(i);
|
|
}
|
|
|
|
// Strip wrapping quotes if present.
|
|
std::string unquote(std::string s) {
|
|
if (s.size() >= 2) {
|
|
char a = s.front(), b = s.back();
|
|
if ((a == '"' && b == '"') || (a == '\'' && b == '\'')) {
|
|
return s.substr(1, s.size() - 2);
|
|
}
|
|
}
|
|
return s;
|
|
}
|
|
|
|
// Parsing minimo: busca lineas top-level `id:`, `name:`, `description:`.
|
|
// Suficiente para metadata de collectors. Si la app necesita mas, anadir yaml-cpp.
|
|
void parse_manifest(const fs::path& yaml_path, Collector& c) {
|
|
std::ifstream f(yaml_path);
|
|
if (!f.is_open()) return;
|
|
std::string line;
|
|
while (std::getline(f, line)) {
|
|
std::string t = trim(line);
|
|
if (t.empty() || t[0] == '#') continue;
|
|
// Ignora lineas indentadas (sub-keys de listas/dicts).
|
|
if (line.size() > t.size() && line[0] == ' ') continue;
|
|
|
|
auto colon = t.find(':');
|
|
if (colon == std::string::npos) continue;
|
|
std::string key = trim(t.substr(0, colon));
|
|
std::string val = trim(t.substr(colon + 1));
|
|
val = unquote(val);
|
|
|
|
if (key == "id" && !val.empty()) c.id = val;
|
|
else if (key == "name" && !val.empty()) c.name = val;
|
|
else if (key == "description" && !val.empty()) c.description = val;
|
|
}
|
|
}
|
|
|
|
} // namespace
|
|
|
|
bool collectors_discover(const std::string& collectors_root,
|
|
std::vector<Collector>& out) {
|
|
out.clear();
|
|
std::error_code ec;
|
|
if (!fs::is_directory(collectors_root, ec)) return false;
|
|
|
|
for (auto& entry : fs::directory_iterator(collectors_root, ec)) {
|
|
if (ec) break;
|
|
if (!entry.is_directory()) continue;
|
|
Collector c;
|
|
c.dir = entry.path().string();
|
|
c.id = entry.path().filename().string();
|
|
c.run_py = (entry.path() / "run.py").string();
|
|
c.has_run = fs::exists(c.run_py);
|
|
|
|
fs::path manifest = entry.path() / "manifest.yaml";
|
|
if (fs::exists(manifest)) parse_manifest(manifest, c);
|
|
if (c.name.empty()) c.name = c.id;
|
|
|
|
out.push_back(std::move(c));
|
|
}
|
|
return true;
|
|
}
|