aboutsummaryrefslogtreecommitdiff
path: root/src/recipes.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/recipes.c')
-rw-r--r--src/recipes.c83
1 files changed, 71 insertions, 12 deletions
diff --git a/src/recipes.c b/src/recipes.c
index 5f387b4..b84a026 100644
--- a/src/recipes.c
+++ b/src/recipes.c
@@ -24,14 +24,59 @@
#include "files.h"
#include "log.h"
#include "pkg.h"
+#include "state.h"
+
+#define try_pkg_fn(fn, pkg, operation) \
+ do { \
+ log_info("attempting to %s '%.*s'", operation, str_fmt(&(pkg)->name)); \
+ if (!(fn((pkg)))) { \
+ log_error("%s failed", operation); \
+ return false; \
+ } \
+ } while (0)
+
+static bool pkg_write_status(const char *status, package_t *pkg) {
+ bool success = false;
+ str status_str = mstr(status);
+ str pkgit_status = str_format("%.*s/.pkgit_status", str_fmt(&pkg->src));
+ success = file_write(&status_str, &pkgit_status);
+ str_free(&pkgit_status);
+ str_free(&status_str);
+ return success;
+}
+
+static bool pkg_read_status(const char desired, package_t *pkg) {
+ bool success = false;
+ str pkgit_status = str_format("%.*s/.pkgit_status",
+ str_fmt(&pkg->src));
+ str status = file_read(&pkgit_status);
+ success = str_find_char(&status, desired);
+ str_free(&pkgit_status);
+ str_free(&status);
+ return success;
+}
+
+static bool is_pkg_installed(package_t *pkg) {
+ if (pkg_read_status('i', pkg)) {
+ if (flags.force) log_warn(
+ "%.*s is already installed",
+ str_fmt(&pkg->name));
+ else log_info(
+ "%.*s is already installed",
+ str_fmt(&pkg->name));
+ return true;
+ } else return false;
+}
static bool pkg_fetch_sources(package_t *pkg) {
+ bool success = false;
if (!pkg_hook_fetch_sources(pkg)) {
log_error(GREEN "%.*s" COLOR_RESET " fetch failed",
str_fmt(&pkg->name));
return false;
}
- return true;
+ success = pkg_write_status("f", pkg);
+ return success;
}
static bool pkg_enter(package_t *pkg) {
@@ -41,38 +86,52 @@ static bool pkg_enter(package_t *pkg) {
return false;
}
chdir(pkg->src.data);
+ if (!pkg_write_status("e", pkg)) return false;
return true;
}
bool pkg_setup(package_t *pkg) {
- if (!pkg_enter(pkg)) return false;
- if (!pkg_hook_setup(pkg)) return false;
+ if (pkg_read_status('s', pkg)) return true;
+ try_pkg_fn(pkg_enter, pkg, "enter");
+ try_pkg_fn(pkg_hook_setup, pkg, "setup");
+ if (!pkg_write_status("s", pkg)) return false;
return true;
}
bool pkg_build(package_t *pkg) {
- if (!pkg_enter(pkg)) return false;
- if (!pkg_hook_build(pkg)) return false;
+ if (pkg_read_status('b', pkg)) return true;
+ try_pkg_fn(pkg_enter, pkg, "enter");
+ try_pkg_fn(pkg_hook_build, pkg, "build");
+ if (!pkg_write_status("b", pkg)) return false;
return true;
}
bool pkg_install(package_t *pkg) {
- if (!pkg_fetch_sources(pkg)) return false;
- if (!pkg_enter(pkg)) return false;
- if (!pkg_hook_setup(pkg)) return false;
- if (!pkg_hook_build(pkg)) return false;
+ if (is_pkg_installed(pkg) && !flags.force) return true;
+ log_info("fetching '%.*s'", str_fmt(&pkg->name));
+ if (!pkg_read_status('f', pkg) && !pkg_fetch_sources(pkg)) return false;
+ log_info("entering '%.*s'", str_fmt(&pkg->src));
+ if (!pkg_read_status('e', pkg) && !pkg_enter(pkg)) return false;
+ log_info("setting up '%.*s'", str_fmt(&pkg->name));
+ if (!pkg_read_status('s', pkg) && !pkg_hook_setup(pkg)) return false;
+ log_info("building '%.*s'", str_fmt(&pkg->name));
+ if (!pkg_read_status('b', pkg) && !pkg_hook_build(pkg)) return false;
+ log_info("installing '%.*s'", str_fmt(&pkg->name));
if (!pkg_hook_install(pkg)) return false;
+ if (!pkg_write_status("i", pkg)) return false;
+ log_success("installed '%.*s'", str_fmt(&pkg->name));
return true;
}
bool pkg_remove(package_t *pkg) {
if (!pkg_enter(pkg)) return false;
- if (!pkg_hook_setup(pkg)) return false;
+ if (!pkg_hook_remove(pkg)) return false;
+ if (!rmrf(&pkg->root)) return false;
+ log_success("removed '%.*s'", str_fmt(&pkg->name));
return true;
}
bool pkg_update(package_t *pkg) {
- if (!pkg_enter(pkg)) return false;
- if (!pkg_hook_setup(pkg)) return false;
+ pkg_install(pkg);
return true;
}