diff options
| -rw-r--r-- | :w | 201 | ||||
| -rw-r--r-- | src/hooks.c | 1 | ||||
| -rw-r--r-- | src/recipes.c | 5 |
3 files changed, 202 insertions, 5 deletions
@@ -0,0 +1,201 @@ +/* + + pkgit - package it! + + Copyright (C) 2026 dacctal + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <https://www.gnu.org/licenses/>. + +*/ + +#include <dirent.h> +#include <string.h> +#include <unistd.h> + +#include "common.h" +#include "files.h" +#include "log.h" +#include "lua_state.h" +#include "pkg.h" +#include "state.h" + +#define try_pkg_fn(fn, pkg, operation, smol) \ + do { \ + if (pkg_read_status(smol, pkg)) return true; \ + if (!flags.quiet) log_info("'%.*s' %s in progress...", \ + str_fmt(&(pkg)->name), operation); \ + if (!(fn((pkg)))) { \ + log_error("%s failed", operation); \ + return false; \ + } \ + char big[2] = "\0"; \ + big[0] = smol; \ + if (!pkg_write_status(big, pkg)) return false; \ + log_info("'%.*s' %s done", str_fmt(&(pkg)->name), operation); \ + } 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)); + if (!file_exists(pkgit_status.data)) { + log_info("%.*s doesn't exist", str_fmt(&pkgit_status)); + str_free(&pkgit_status); + return false; + } + str status = file_read(&pkgit_status); + success = (str_find_char(&status, desired) == 0); + 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) { + if (!pkg_hook_fetch_sources(pkg)) { + log_error(GREEN "%.*s" COLOR_RESET " fetch failed", + str_fmt(&pkg->name)); + return false; + } + return true; +} + +static bool pkg_enter(package_t *pkg) { + if (!is_directory(pkg->src.data)) { + log_error(GREEN "%.*s" COLOR_RESET " is not a directory", + str_fmt(&pkg->src)); + return false; + } + chdir(pkg->src.data); + if (!pkg_write_status("e", pkg)) return false; + return true; +} + +bool pkg_setup(package_t *pkg) { + if (pkg_read_status('s', pkg)) return true; + if (!pkg_enter(pkg)) return false; + try_pkg_fn(pkg_hook_setup, pkg, "setup", 's'); + log_success("'%.*s' set up", str_fmt(&pkg->name)); + return true; +} + +bool pkg_build(package_t *pkg) { + if (pkg_read_status('b', pkg)) return true; + if (!pkg_enter(pkg)) return false; + try_pkg_fn(pkg_hook_build, pkg, "build", 'b'); + if (pkg_read_status('b', pkg)) return true; + if (!flags.quiet) log_info("'%.*s' build in progress...", str_fmt(&pkg->name)); + if (!pkg_hook_build(pkg)) { + log_error("build failed"); + return false; + } + if (!pkg_write_status("b", pkg)) return false; + log_info("'%.*s' build done", str_fmt(&pkg->name)); + log_success("'%.*s' built", str_fmt(&pkg->name)); + return true; +} + +bool pkg_install(package_t *pkg) { + if (is_pkg_installed(pkg) && !flags.force) return true; + try_pkg_fn(pkg_fetch_sources, pkg, "fetch", 'f'); + if (!pkg_enter(pkg)) return false; + //if (!pkg_setup(pkg)) printf("setup failed"); + try_pkg_fn(pkg_hook_setup, pkg, "setup", 's'); + //if (!pkg_build(pkg)) printf("build failed"); + try_pkg_fn(pkg_hook_build, pkg, "build", 'b'); + printf("test\n"); + try_pkg_fn(pkg_hook_install, pkg, "install", 'i'); + log_success("'%.*s' installed", str_fmt(&pkg->name)); + return true; +} + +bool pkg_remove(package_t *pkg) { + if (!pkg_enter(pkg)) return false; + if (!pkg_hook_remove(pkg)) return false; + if (!rmrf(&pkg->root)) return false; + log_success("'%.*s' removed", str_fmt(&pkg->name)); + return true; +} + +static bool is_latest(package_t *pkg) { + bool result = false; + if (str_is_valid(&pkg->src) && pkg->src.len > 0 && + chdir(pkg->src.data) != 0) return result; + str latest_version = pkg_get_latest_version(pkg); + result = (strcmp(pkg->version.data, latest_version.data) != 0); + str_free(&latest_version); + return result; +} + +bool pkg_update(package_t *pkg) { + if (!is_latest(pkg)) { + if (pkg_install(pkg)) log_success( + "'%.*s' is up to date", str_fmt(&pkg->name) + ); + } else if (flags.force) { + log_warn("'%.*s' is already up to date", str_fmt(&pkg->name)); + if (pkg_install(pkg)) log_success( + "'%.*s' is up to date", str_fmt(&pkg->name) + ); + } else { + log_info("'%.*s' is already up to date", str_fmt(&pkg->name)); + } + return true; +} + +bool all_update(void) { + struct dirent* dirent_ptr; + DIR* dir_ptr; + if ((dir_ptr = opendir(config.inst_dirs.src.data)) == NULL) { + log_error("could not open %s", str_fmt(&config.inst_dirs.src)); + } + while ((dirent_ptr = readdir(dir_ptr)) != NULL) { + if ( + strcmp(dirent_ptr->d_name, "..") == 0 || + strcmp(dirent_ptr->d_name, ".") == 0 + ) continue; + str pkg_name = mstr(dirent_ptr->d_name); + if (!pkg_exists(&pkg_name)) { + str_free(&pkg_name); + continue; + } + package_t pkg = pkg_create(&pkg_name); + pkg_update(&pkg); + pkg_free(&pkg); + if (str_is_valid(&pkg_name)) str_free(&pkg_name); + } + closedir(dir_ptr); + config_hook_on_update(); + return true; +} diff --git a/src/hooks.c b/src/hooks.c index 83fac15..20923b7 100644 --- a/src/hooks.c +++ b/src/hooks.c @@ -100,7 +100,6 @@ str pkg_get_latest_version(package_t *pkg) { } bool pkg_hook_recipe(char *recipe, package_t *pkg) { - printf("hello there\n"); lua_get_field_type("pkgs", table, &config.init_path, 1); lua_get_field_type(pkg->name.data, table, &config.init_path, 2); lua_get_field_type("recipe", table, &config.init_path, 3); diff --git a/src/recipes.c b/src/recipes.c index bb29c4e..246224e 100644 --- a/src/recipes.c +++ b/src/recipes.c @@ -64,7 +64,7 @@ static bool pkg_read_status(const char desired, package_t *pkg) { return false; } str status = file_read(&pkgit_status); - success = (str_find_char(&status, desired) == 0); + success = (str_find_char(&status, desired) != 0); str_free(&pkgit_status); str_free(&status); return success; @@ -122,11 +122,8 @@ bool pkg_install(package_t *pkg) { if (is_pkg_installed(pkg) && !flags.force) return true; try_pkg_fn(pkg_fetch_sources, pkg, "fetch", 'f'); if (!pkg_enter(pkg)) return false; - //if (!pkg_setup(pkg)) printf("setup failed"); try_pkg_fn(pkg_hook_setup, pkg, "setup", 's'); - //if (!pkg_build(pkg)) printf("build failed"); try_pkg_fn(pkg_hook_build, pkg, "build", 'b'); - printf("test\n"); try_pkg_fn(pkg_hook_install, pkg, "install", 'i'); log_success("'%.*s' installed", str_fmt(&pkg->name)); return true; |
