track installed packages

This commit is contained in:
2026-02-21 10:30:44 +01:00
parent 9f9c5b7c9c
commit 6559569986
4 changed files with 76 additions and 15 deletions

View File

@@ -1 +1 @@
Checks: '*,clang-analyzer-*,-llvmlibc-*,-fuchsia-*,-altera-*,-abseil-*,-android-*,-modernize-use-trailing-return-type,-readability-identifier-length,-*-readability-todo,-*-magic-numbers,-readability-function-cognitive-complexity,-*-easily-swappable-parameters,-*-non-private-member-variables-in-classes,-*-no-recursion,-concurrency-mt-unsafe,-*-runtime-int,-*-non-const-global-variables,-performance-inefficient-string-concatenation'
Checks: '*,clang-analyzer-*,-llvmlibc-*,-fuchsia-*,-altera-*,-abseil-*,-android-*,-modernize-use-trailing-return-type,-readability-identifier-length,-*-readability-todo,-*-magic-numbers,-readability-function-cognitive-complexity,-*-easily-swappable-parameters,-*-non-private-member-variables-in-classes,-*-no-recursion,-concurrency-mt-unsafe,-*-runtime-int,-*-non-const-global-variables,-performance-inefficient-string-concatenation,-cert-err58-cpp,-*-signed-bitwise'

View File

@@ -6,8 +6,16 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
find_package(blake3 REQUIRED)
include(FetchContent)
FetchContent_Declare(
SQLiteCpp
GIT_REPOSITORY https://github.com/SRombauts/SQLiteCpp
GIT_TAG 3.3.3
)
FetchContent_MakeAvailable(SQLiteCpp)
add_executable(${PROJECT_NAME} src/main.cc)
target_link_libraries(${PROJECT_NAME} PRIVATE blake3)
target_link_libraries(${PROJECT_NAME} PRIVATE blake3 SQLiteCpp)
set_target_properties(${PROJECT_NAME} PROPERTIES LINK_FLAGS "-static")

38
src/db.h Normal file
View File

@@ -0,0 +1,38 @@
#pragma once
#include <SQLiteCpp/SQLiteCpp.h>
class DB {
public:
constexpr static const std::string DB_PATH = "/var/lib/shrap";
void init_db() {
m_db.exec(R"(
CREATE TABLE IF NOT EXISTS installed (
name TEXT PRIMARY KEY,
version TEXT NOT NULL,
installed_at INTEGER NOT NULL
);
)");
}
bool is_installed(const std::string &name) {
SQLite::Statement query(m_db,
"SELECT version FROM installed WHERE name = ?");
query.bind(1, name);
return query.executeStep();
}
void mark_installed(const std::string &name, const std::string &version) {
SQLite::Statement insert(
m_db, "INSERT OR REPLACE INTO installed(name, version, "
"installed_at) VALUES (?, ?, strftime('%s','now'))");
insert.bind(1, name);
insert.bind(2, version);
insert.exec();
}
private:
SQLite::Database m_db{DB_PATH + "/shrap.db",
SQLite::OPEN_READWRITE | SQLite::OPEN_CREATE};
};

View File

@@ -1,3 +1,4 @@
#include "db.h"
#include "parser.h"
#include "util.h"
#include <algorithm>
@@ -7,9 +8,9 @@
#include <thread>
#include <unordered_map>
static const std::string BUILD_PATH = "/tmp/shrap";
std::unordered_map<std::string, Expr> packages;
bool flag_raw = false;
bool flag_graph = false;
void load_packages() {
for (const auto &e : std::filesystem::directory_iterator("./packages/")) {
@@ -25,11 +26,15 @@ void load_packages() {
}
std::vector<std::string>
resolve_dependencies(const std::vector<std::string> &roots) {
resolve_dependencies(const std::vector<std::string> &roots, DB &db) {
std::unordered_map<std::string, int> state;
std::vector<std::string> order;
std::function<void(const std::string &)> dfs = [&](const std::string &name) {
if (db.is_installed(name)) {
return;
}
int s = state[name];
if (s == 2) {
return;
@@ -63,7 +68,7 @@ resolve_dependencies(const std::vector<std::string> &roots) {
return order;
}
void install_package(const std::string &name) {
void install_package(const std::string &name, DB &db) {
// TODO: track installed packages
if (!packages.contains(name)) {
@@ -79,10 +84,10 @@ void install_package(const std::string &name) {
Expr src = pkg.get_one("src");
std::string src_type = src.children[0].value;
std::string src_url = src.get_one("url").value;
std::string src_path = "/tmp/shrap/" + src.get_one("dir").value;
std::string src_path = BUILD_PATH + "/" + src.get_one("dir").value;
if (src_type == "tar") {
std::string archive_path = "/tmp/shrap/" + Util::basename(src_url);
std::string archive_path = BUILD_PATH + "/" + Util::basename(src_url);
std::string expected_hash = src.get_one("blake3").value;
bool needs_download = true;
@@ -110,7 +115,7 @@ void install_package(const std::string &name) {
}
std::cout << "\n\tExtracting...\n";
Util::shell_command("tar xf " + archive_path + " -C /tmp/shrap/");
Util::shell_command("tar xf " + archive_path + " -C " + BUILD_PATH);
} else {
throw std::runtime_error("unrecognized src type");
}
@@ -176,10 +181,12 @@ void install_package(const std::string &name) {
throw std::runtime_error("unrecognized step type");
}
}
db.mark_installed(pkg.get_one("name").value, pkg.get_one("version").value);
}
void generate_graph(const std::vector<std::string> &to_highlight) {
std::ofstream out("/tmp/shrap/graph.dot");
std::ofstream out(BUILD_PATH + "/graph.dot");
out << "digraph dependencies {\n";
if (to_highlight.empty()) {
@@ -202,17 +209,25 @@ void generate_graph(const std::vector<std::string> &to_highlight) {
out << "}\n";
out.close();
Util::shell_command("dot -Tpng graph.dot > graph.png", "/tmp/shrap");
std::cout << "Graph saved to /tmp/shrap/graph.png\n";
Util::shell_command("dot -Tpng graph.dot > graph.png", BUILD_PATH);
std::cout << "Graph saved to " << BUILD_PATH << "/graph.png\n";
}
int main(int argc, char **argv) {
auto args = std::span(argv, static_cast<size_t>(argc));
Util::shell_command("mkdir -p /tmp/shrap");
std::filesystem::create_directories(BUILD_PATH);
std::filesystem::create_directories(DB::DB_PATH);
DB db;
db.init_db();
load_packages();
bool flag_raw = false;
bool flag_graph = false;
std::vector<std::string> to_install;
for (size_t i = 1; i < args.size(); ++i) {
std::string arg = args[i];
if (arg == "-r") {
@@ -225,7 +240,7 @@ int main(int argc, char **argv) {
}
if (!flag_raw) {
to_install = resolve_dependencies(to_install);
to_install = resolve_dependencies(to_install, db);
}
if (flag_graph) {
@@ -256,7 +271,7 @@ int main(int argc, char **argv) {
for (const std::string &pkg : to_install) {
try {
install_package(pkg);
install_package(pkg, db);
} catch (std::exception &e) {
std::cerr << "ERROR: " << e.what() << std::endl;
return 1;