track installed packages
This commit is contained in:
@@ -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'
|
||||
@@ -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
38
src/db.h
Normal 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};
|
||||
};
|
||||
41
src/main.cc
41
src/main.cc
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user