resolving dependencies

This commit is contained in:
2026-02-15 16:08:12 +01:00
parent a19e668908
commit 9dc1068034
11 changed files with 156 additions and 18 deletions

11
packages/autoconf.shrap Normal file
View File

@@ -0,0 +1,11 @@
(package
(name "autoconf")
(version "2.72")
(homepage "https://www.gnu.org/software/autoconf/")
(dependencies m4 perl)
(src (tar
(url "https://ftp.gnu.org/gnu/autoconf/autoconf-2.72.tar.gz")
(dir "autoconf-2.72")
(blake3 "89aad7032c61efa3ea6cada364e20560c58441a92a7267db15e0fddff55638c7")))
(build
(configure_make)))

11
packages/automake.shrap Normal file
View File

@@ -0,0 +1,11 @@
(package
(name "automake")
(version "1.18")
(homepage "https://www.gnu.org/software/automake/")
(dependencies m4)
(src (tar
(url "https://ftp.gnu.org/gnu/automake/automake-1.18.tar.gz")
(dir "automake-1.18")
(blake3 "42458b6c690f6bf69d9dece26b023a7437830333e9149a13ab165f34ecbe90a3")))
(build
(configure_make)))

11
packages/bison.shrap Normal file
View File

@@ -0,0 +1,11 @@
(package
(name "bison")
(version "3.8.2")
(homepage "https://www.gnu.org/software/bison/")
(dependencies m4)
(src (tar
(url "https://ftp.gnu.org/gnu/bison/bison-3.8.2.tar.gz")
(dir "bison-3.8.2")
(blake3 "9a529d3945d46103faa144ad1998b6c7dcf4653166fceee1ef59baef3c853c34")))
(build
(configure_make)))

11
packages/flex.shrap Normal file
View File

@@ -0,0 +1,11 @@
(package
(name "flex")
(version "2.6.4")
(homepage "https://github.com/westes/flex")
(dependencies m4)
(src (tar
(url "https://github.com/westes/flex/releases/download/v2.6.4/flex-2.6.4.tar.gz")
(dir "flex-2.6.4")
(blake3 "d78b714ac38bd9de7f9b44a078efed82e96ed43e7cf9cd33944a7f379a2d09a4")))
(build
(configure_make)))

View File

@@ -1,5 +1,5 @@
(package
(name "glib")
(name "libglib")
(version "2.86.4")
(homepage "https://www.gtk.org/")
(dependencies meson ninja git libffi pkg-config slang)

View File

@@ -0,0 +1,12 @@
(package
(name "libreadline")
(version "8.3")
(homepage "https://tiswww.cwru.edu/php/chet/readline/rltop.html")
(dependencies libncurses)
(src (tar
(url "https://ftp.gnu.org/gnu/readline/readline-8.3.tar.gz")
(dir "readline-8.3")
(blake3 "7109f094062bda387a0c16b4875375b96e36437bebbbd8d8f91bb27ba01d687f")))
(build
(configure_make
(configure_flags "--disable-shared"))))

View File

@@ -2,6 +2,7 @@
(name "pkg-config")
(version "2.5.1")
(homepage "https://github.com/pkgconf/pkgconf")
(dependencies xz)
(src (tar
(url "https://distfiles.ariadne.space/pkgconf/pkgconf-2.5.1.tar.xz")
(dir "pkgconf-2.5.1")

12
packages/postgresql.shrap Normal file
View File

@@ -0,0 +1,12 @@
(package
(name "postgresql")
(version "18.2")
(homepage "https://www.postgresql.org/")
(dependencies pkg-config bison flex perl libreadline zlib)
(src (tar
(url "https://ftp.postgresql.org/pub/source/v18.2/postgresql-18.2.tar.gz")
(dir "postgresql-18.2")
(blake3 "ae352f4fecabf9ada3fe22e46f952507d6970864b6f9494d7a7e3b65bd009463")))
(build
(configure_make
(configure_flags "--without-icu"))))

12
packages/psmisc.shrap Normal file
View File

@@ -0,0 +1,12 @@
(package
(name "psmisc")
(version "23.7")
(homepage "https://gitlab.com/psmisc/psmisc")
(dependencies autoconf automake gettext libncurses)
(src (tar
(url "https://gitlab.com/psmisc/psmisc/-/archive/v23.7/psmisc-v23.7.tar.gz")
(dir "psmisc-v23.7")
(blake3 "3e213023c51dfcbbad4f51af77c8488d5ff5ee6f8bd08fa1ede77ae6ac56f7a5")))
(build
(shell "./autogen.sh")
(configure_make)))

View File

@@ -1,5 +1,5 @@
(package
(name "python3")
(name "python")
(version "3.14.3")
(homepage "https://www.python.org/")
(dependencies zlib libopenssl bzip2)

View File

@@ -1,31 +1,76 @@
#include "parser.h"
#include "util.h"
#include <filesystem>
#include <functional>
#include <span>
#include <sys/stat.h>
#include <thread>
#include <unordered_map>
static bool flag_raw = false;
std::unordered_map<std::string, Expr> packages;
bool flag_raw = false;
void install_package(const std::string &name) {
// TODO: get this by the name field not filename
// TODO: actually resolve dependency tree
// TODO: track installed packages
std::ifstream file("packages/" + name + ".shrap");
if (!file) {
std::cerr << "Package " << name << "not found.\n";
std::exit(1);
void load_packages() {
for (const auto &e : std::filesystem::directory_iterator("./packages/")) {
std::ifstream file(e.path());
if (!file) {
std::cerr << "Failed to open " << e.path() << "\n";
std::exit(1);
}
Expr pkg = Expr::parse(file);
packages[pkg.get_one("name").value] = pkg;
}
}
Expr pkg = Expr::parse(file);
std::vector<std::string>
resolve_dependencies(const std::vector<std::string> &roots) {
std::unordered_map<std::string, int> state;
std::vector<std::string> order;
std::function<void(const std::string &)> dfs = [&](const std::string &name) {
int s = state[name];
if (s == 2) {
return;
}
if (s == 1) {
throw std::runtime_error("dependency cycle detected");
}
if (!packages.contains(name)) {
std::cerr << "Package not found: " << name << "\n";
std::exit(1);
}
state[name] = 1;
if (!flag_raw) {
try {
const Expr &pkg = packages.at(name);
for (const auto &dep : pkg.get("dependencies").children) {
install_package(dep.value);
dfs(dep.value);
}
} catch (std::out_of_range &) {
}
state[name] = 2;
order.push_back(name);
};
for (const auto &r : roots) {
dfs(r);
}
return order;
}
void install_package(const std::string &name) {
// TODO: track installed packages
if (!packages.contains(name)) {
std::cerr << "Package not found: " << name << "\n";
std::exit(1);
}
Expr pkg = packages[name];
std::cout << "\n\n\tInstalling " << pkg.get_one("name").value << " ("
<< pkg.get_one("version").value << ")...\n\n\n";
@@ -123,22 +168,34 @@ int main(int argc, char **argv) {
}
Util::shell_command("mkdir -p /tmp/shrap");
std::vector<std::string> packages;
load_packages();
std::vector<std::string> to_install;
for (size_t i = 1; i < args.size(); ++i) {
std::string arg = args[i];
if (arg == "-r") {
flag_raw = true;
} else {
packages.push_back(arg);
to_install.push_back(arg);
}
}
if (packages.empty()) {
if (to_install.empty()) {
std::cerr << "Usage: " << args[0] << " [-r] package1 [package2 ...]\n";
return 1;
}
for (const auto &pkg : packages) {
if (!flag_raw) {
to_install = resolve_dependencies(to_install);
}
std::cout << "\nFollowing packages will be installed:\n";
for (const std::string &pkg : to_install) {
std::cout << " - " << pkg << std::endl;
}
std::cin.get();
for (const std::string &pkg : to_install) {
try {
install_package(pkg);
} catch (std::exception &e) {