aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/globs.h3
-rw-r--r--include/pkgit_lua.h8
-rw-r--r--src/build.c20
-rw-r--r--src/fetch.c4
-rw-r--r--src/help.c5
-rw-r--r--src/lua_globs.c9
-rw-r--r--src/lua_vars.c2
-rw-r--r--src/parse_args.c27
-rw-r--r--src/pkg_create.c39
-rw-r--r--src/pkg_exists.c54
-rw-r--r--src/pkg_free.c2
-rw-r--r--src/pkg_install.c (renamed from src/lua_install.c)36
-rw-r--r--src/pkg_remove.c199
13 files changed, 335 insertions, 73 deletions
diff --git a/include/globs.h b/include/globs.h
index bec1dc9..9416923 100644
--- a/include/globs.h
+++ b/include/globs.h
@@ -24,7 +24,7 @@
#include "str.h"
-#define VERSION "1.4.0_INDEV"
+#define VERSION "1.2.0_INDEV"
#define RED "\x1b[0;31m"
#define GREEN "\x1b[0;32m"
#define YELLOW "\x1b[0;33m"
@@ -121,6 +121,7 @@ typedef struct {
extern cli_flags_t flags;
extern config_t cfg;
extern install_dirs_t inst_dirs;
+extern str new_arg_str;
void init_vars(void);
void free_vars(void);
diff --git a/include/pkgit_lua.h b/include/pkgit_lua.h
index 05b9ff6..f5f86a1 100644
--- a/include/pkgit_lua.h
+++ b/include/pkgit_lua.h
@@ -51,9 +51,17 @@ void lua_isnt_type(char* variable, char* type);
void bldit_isnt_type(char* variable, char* type);
bool lua_try_function(lua_State *L, char *lua_file, char *fname);
bool lua_try_table(lua_State *L, char *lua_file, char *tname);
+bool pkg_exists(str *name);
+str pkg_get_url(str *name);
// install
void install_dependencies(lua_State *L);
void pkg_install(package_t *pkg);
+// remove
+bool repo_uninstall(package_t *pkg);
+bool bldit_uninstall(package_t *pkg);
+bool config_uninstall(package_t *pkg);
+void pkg_remove(package_t *pkg);
+
#endif
diff --git a/src/build.c b/src/build.c
index 0b97af7..740d739 100644
--- a/src/build.c
+++ b/src/build.c
@@ -12,7 +12,6 @@
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/>.
@@ -35,8 +34,7 @@ bool target_build(lua_State *L, char* lua_file, str *target) {
install_dependencies(L);
}
lua_pop(L, 1);
- if (!lua_try_function(L, lua_file, "build"))
- lua_pop(L, 2);
+ if (!lua_try_function(L, lua_file, "build")) return false;
return true;
}
@@ -56,7 +54,7 @@ bool repo_build(package_t *pkg) {
return false;
}
bool target_success = target_build(L, "init.lua", &pkg->target);
- lua_pop(L, 3);
+ lua_pop(L, 4);
return target_success;
}
@@ -119,24 +117,24 @@ bool config_build(package_t *pkg) {
}
bool build_loop(package_t *pkg) {
- log_info("attempting init.lua: 'repositories.%.*s.build'", str_fmt(&pkg->name));
+ if (flags.verbose) log_info("attempting init.lua: 'repositories.%.*s.build'", str_fmt(&pkg->name));
if (repo_build(pkg)) { return true; }
- log_warn("failed init.lua: 'repositories.%.*s.build'", str_fmt(&pkg->name));
+ if (flags.verbose) log_warn("failed init.lua: 'repositories.%.*s.build'", str_fmt(&pkg->name));
- log_info("attempting bldit.lua");
+ if (flags.verbose) log_info("attempting bldit.lua");
if (bldit(pkg)) { return true; }
- log_warn("failed bldit.lua");
+ if (flags.verbose) log_warn("failed bldit.lua");
- log_info("attempting init.lua: 'build_systems'");
+ if (flags.verbose) log_info("attempting init.lua: 'build_systems'");
if (config_build(pkg)) { return true; }
- log_warn("failed init.lua: 'build_systems'");
+ if (flags.verbose) log_warn("failed init.lua: 'build_systems'");
return false;
}
bool build(package_t *pkg) {
char cwd[MAX_PATH_LEN];
getcwd(cwd, MAX_PATH_LEN);
- if (str_equal_cstr(&pkg->src, cwd) && !pkg->is_local) chdir(pkg->src.data);
+ if (!str_equal_cstr(&pkg->src, cwd) && !pkg->is_local) chdir(pkg->src.data);
if (build_loop(pkg)) return true;
log_error("no usable build system was found for %.*s", str_fmt(&pkg->name));
diff --git a/src/fetch.c b/src/fetch.c
index 87c632d..3792a5e 100644
--- a/src/fetch.c
+++ b/src/fetch.c
@@ -51,7 +51,7 @@
bool fetch(package_t *pkg) {
if (pkg->url.data == NULL || pkg->src.data == NULL) {
- log_warn("invalid pkg: url or src is NULL");
+ if (flags.verbose) log_warn("invalid pkg: url or src is NULL");
return false;
}
@@ -97,7 +97,7 @@ bool fetch(package_t *pkg) {
waitpid(pid, &status, 0);
bool result = (WEXITSTATUS(status) == 0);
- if (!result) { log_warn("git clone failed"); }
+ if (!result) { log_error("git clone failed"); }
return result;
}
diff --git a/src/help.c b/src/help.c
index bacdcd9..a568e7c 100644
--- a/src/help.c
+++ b/src/help.c
@@ -21,7 +21,6 @@
#include <stdio.h>
#include "help.h"
-
#include "globs.h"
void help(void) {
@@ -70,7 +69,7 @@ void help(void) {
printf(RED "subcommand flags" COLOR_RESET ":\n");
for (size_t i = 0; i < LENGTH(cmd_flags); i++) {
- printf(COLOR_RESET "\t" GREEN "%-2s" COLOR_RESET ", " YELLOW
+ printf(COLOR_RESET " " GREEN "%-2s" COLOR_RESET ", " YELLOW
"%-12s" BLUE "%-16s" GRAY "# %s\n" COLOR_RESET,
cmd_flags[i].short_flag, cmd_flags[i].long_flag,
cmd_flags[i].arg, cmd_flags[i].desc);
@@ -78,7 +77,7 @@ void help(void) {
printf("\n" RED "modifier flags" COLOR_RESET ":\n");
for (size_t i = 0; i < LENGTH(mod_flags); i++) {
- printf(COLOR_RESET "\t" GREEN "%-2s" COLOR_RESET ", " YELLOW
+ printf(COLOR_RESET " " GREEN "%-2s" COLOR_RESET ", " YELLOW
"%-12s" BLUE "%-16s" GRAY "# %s\n" COLOR_RESET,
mod_flags[i].short_flag, mod_flags[i].long_flag,
mod_flags[i].arg, mod_flags[i].desc);
diff --git a/src/lua_globs.c b/src/lua_globs.c
index b14eb3a..5f333a4 100644
--- a/src/lua_globs.c
+++ b/src/lua_globs.c
@@ -61,7 +61,7 @@ void init_lua_state(void) {
}
if (file_exists(cfg.repos.data)) {
if (luaL_loadfile(L, cfg.repos.data) || lua_pcall(L, 0, 0, 0)) {
- log_warn("cannot load repository file: %s", lua_tostring(L, -1));
+ if (flags.verbose) log_warn("cannot load repository file: %s", lua_tostring(L, -1));
lua_pop(L, 1);
}
}
@@ -76,7 +76,7 @@ void init_bldit_state(void) {
luaL_openlibs(B);
if (luaL_loadfile(B, "bldit.lua") || lua_pcall(B, 0, 0, 0)) {
if (flags.verbose)
- log_warn("cannot run bldit: %s", lua_tostring(B, -1));
+ if (flags.verbose) log_warn("cannot run bldit: %s", lua_tostring(B, -1));
return;
}
lua_pushfstring(B, "%s", inst_dirs.prefix.data);
@@ -140,7 +140,7 @@ bool lua_try_function(lua_State *L, char *lua_file, char *fname) {
lua_isnt_type(fname, "function");
lua_pop(L, 1);
} else if (lua_pcall(L, 0, 1, 0) != LUA_OK) {
- log_warn(
+ if (flags.verbose) log_warn(
"%s: '%s' function borked: %s",
lua_file, fname, lua_tostring(L, -1)
);
@@ -148,7 +148,7 @@ bool lua_try_function(lua_State *L, char *lua_file, char *fname) {
return false;
}
if (!lua_isnumber(L, -1) || lua_tonumber(L, -1) != 0) {
- log_warn(
+ if (flags.verbose) log_warn(
"%s: '%s' failed: %s",
lua_file, fname, lua_tostring(L, -1)
);
@@ -166,7 +166,6 @@ bool lua_try_table(lua_State *L, char *lua_file, char *tname) {
bldit_isnt_type(tname, "table");
else
lua_isnt_type(tname, "table");
- lua_pop(L, 1);
return false;
}
return true;
diff --git a/src/lua_vars.c b/src/lua_vars.c
index ddb4c5a..7420ae0 100644
--- a/src/lua_vars.c
+++ b/src/lua_vars.c
@@ -58,11 +58,9 @@ void init_install_directories(void) {
void init_prefix_directory(void) {
lua_getglobal(L, "prefix");
if (!lua_isstring(L, -1)) {
-// printf(PRINT_ERROR "init.lua: 'prefix' is not a string.\n");
lua_isnt_type("prefix", "string.");
return;
}
inst_dirs.prefix = mstr(lua_tostring(L, -1));
-// snprintf(prefix_dir, MAX_PATH_LEN, "%s", lua_tostring(L, -1));
lua_pop(L, 1);
}
diff --git a/src/parse_args.c b/src/parse_args.c
index d4719c7..61e1fcb 100644
--- a/src/parse_args.c
+++ b/src/parse_args.c
@@ -23,14 +23,13 @@
#include "parse_args.h"
+#include "build.h"
#include "globs.h"
#include "log.h"
#include "str.h"
// #include "declare.h"
// #include "easter_egg.h"
#include "help.h"
-// #include "name_from_url.h"
-// #include "pkg_build.h"
#include "pkg.h"
// #include "pkg_search.h"
// #include "pkg_install.h"
@@ -38,7 +37,7 @@
// #include "pkg_list.h"
// #include "pkg_remove.h"
// #include "pkgit_globals.h"
-// #include "repo_add.h"
+#include "add_repo.h"
// #include "update.h"
#define COMMAND(large, small) \
@@ -50,7 +49,10 @@
void cmd_add(char **argv, int i) {
if (argv[i + 1]) {
printf("add repo %s\n", argv[i + 1]);
- // repo_add(argv[i + 1], name_from_url(argv[i + 1]));
+ str_slc arg = mstrslc(argv[i + 1]);
+ package_t pkg = pkg_create(arg);
+ add_repo(&pkg);
+ pkg_free(&pkg);
} else {
NOT_ENOUGH_ARGS(argv[i], "url");
}
@@ -61,16 +63,16 @@ void cmd_build(int argc, char **argv, int i) {
for (int j = i + 1; j < argc; j++) {
if (argv[j][0] == '-')
continue;
- printf("build pkg %s\n", argv[j]);
- // str_slc arg = mstrslc(argv[j]);
- // package_t pkg = pkg_create(arg);
- // pkg_build(pkg);
+ str_slc arg = mstrslc(argv[j]);
+ package_t pkg = pkg_create(arg);
+ build(&pkg);
+ pkg_free(&pkg);
}
} else {
- printf("build pkg .\n");
- // str_slc arg = mstrslc(".");
- // package_t pkg = pkg_create(arg);
- // pkg_build(pkg);
+ str_slc arg = mstrslc(".");
+ package_t pkg = pkg_create(arg);
+ build(&pkg);
+ pkg_free(&pkg);
}
}
@@ -79,7 +81,6 @@ void cmd_install(int argc, char **argv, int i) {
for (int j = i + 1; j < argc; j++) {
if (argv[j][0] == '-')
continue;
- printf("install pkg %s\n", argv[j]);
str_slc arg = mstrslc(argv[j]);
package_t pkg = pkg_create(arg);
pkg_install(&pkg);
diff --git a/src/pkg_create.c b/src/pkg_create.c
index de20038..728a955 100644
--- a/src/pkg_create.c
+++ b/src/pkg_create.c
@@ -7,7 +7,6 @@
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
@@ -15,7 +14,6 @@
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 <string.h>
@@ -26,8 +24,11 @@
#include "files.h"
#include "globs.h"
#include "log.h"
+#include "pkgit_lua.h"
#include "str.h"
+str new_arg_str;
+
static str get_destdir(str_slc cwd, str_slc arg) {
str_slc name = str_slc_from_after_delim(arg, '/');
if (str_slc_first(arg) == '.')
@@ -75,29 +76,25 @@ static void assign_pkg_target(package_t *pkg, str *new_arg_str) {
if (str_find_char(&pkg->target, '@')) pkg->target.len--;
str_free(&tmp_arg);
pkg->name.len -= pkg->target.len + 1;
+ } else if (!flags.verbose) {
+ pkg->target = mstr("quiet");
} else pkg->target = mstr("default");
}
package_t pkg_create(str_slc arg) {
package_t pkg = { .is_local = false, };
-
char cwd[MAX_PATH_LEN];
getcwd(cwd, MAX_PATH_LEN);
str_slc cwd_slc = mstrslc(cwd);
str cwd_str = mstr(cwd);
str dest_dir = get_destdir(cwd_slc, arg);
- str new_arg_str = str_from_str_slc(arg);
+ str tmp_str = str_from_str_slc(arg);
+ str_copy_into(&new_arg_str, &tmp_str);
+ str_free(&tmp_str);
bool is_installed_locally = is_directory(dest_dir.data);
-
- bool is_in_repos = false;
- // for (size_t i = 0; i < cached_repos_count; i++) {
- // if (strcmp(new_arg, cached_repos[i].source_key) == 0) {
- // is_in_repos = true;
- // break;
- // }
- // }
+ bool is_in_repos = pkg_exists(&new_arg_str);
assign_pkg_version(&pkg, &new_arg_str);
assign_pkg_target(&pkg, &new_arg_str);
@@ -105,12 +102,12 @@ package_t pkg_create(str_slc arg) {
str tmp = str_from_after_delim(&new_arg_str, '@');
new_arg_str.len -= tmp.len + 1;
str_free(&tmp);
- }
- if (str_find_char(&new_arg_str, ',')) {
+ } if (str_find_char(&new_arg_str, ',')) {
str tmp = str_from_after_delim(&new_arg_str, ',');
new_arg_str.len -= tmp.len + 1;
str_free(&tmp);
}
+
if (strncmp(arg.data, "http", 4) == 0 || strncmp(arg.data, "ssh", 3) == 0) {
pkg.url = new_arg_str;
pkg.name = str_from_after_delim(&new_arg_str, '/');
@@ -119,12 +116,9 @@ package_t pkg_create(str_slc arg) {
pkg.name = str_from_after_delim(&cwd_str, '/');
pkg.is_local = true;
} else if (is_in_repos) {
- // for (size_t i = 0; i < cached_repos_count; i++) {
- // if (strcmp(new_arg, cached_repos[i].source_key) == 0) {
- // pkg.url = strdup(cached_repos[i].source_value);
- // break;
- // }
- // }
+ str tmp_url = pkg_get_url(&new_arg_str);
+ str_copy_into(&pkg.url, &tmp_url);
+ str_free(&tmp_url);
pkg.name = new_arg_str;
} else if (is_installed_locally) {
pkg.url = mstr("");
@@ -132,12 +126,17 @@ package_t pkg_create(str_slc arg) {
pkg.is_local = true;
} else {
log_error("'%.*s' is not a valid package", str_fmt(&arg));
+ str_free(&cwd_str);
+ str_free(&dest_dir);
+ str_free(&new_arg_str);
exit(EXIT_FAILURE);
}
+
if (str_find_char(&new_arg_str, ',')
&& str_find_char(&new_arg_str, '@')
) pkg.name.len--;
pkg.src = get_pkgsrc(pkg);
+
str_free(&cwd_str);
str_free(&dest_dir);
return pkg;
diff --git a/src/pkg_exists.c b/src/pkg_exists.c
new file mode 100644
index 0000000..05aa238
--- /dev/null
+++ b/src/pkg_exists.c
@@ -0,0 +1,54 @@
+/*
+
+ 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 "pkgit_lua.h"
+#include "str.h"
+
+bool pkg_exists(str *name) {
+ lua_getglobal(L, "repositories");
+ if (!config_loaded || !lua_istable(L, -1)) {
+ lua_pop(L, 1);
+ return false;
+ }
+ if (!lua_try_table(L, "init.lua", name->data)) {
+ lua_pop(L, 2);
+ return false;
+ }
+ lua_pop(L, 2);
+ return true;
+}
+
+str pkg_get_url(str *name) {
+ lua_getglobal(L, "repositories");
+ if (!config_loaded || !lua_istable(L, -1)) {
+ lua_pop(L, 1);
+ return mstr("");
+ }
+ if (!lua_try_table(L, "init.lua", name->data)) {
+ lua_pop(L, 2);
+ return mstr("");
+ }
+ lua_getfield(L, -1, "url");
+ if (lua_isstring(L, -1)) {
+ return mstr(lua_tostring(L, -1));
+ }
+ lua_pop(L, 3);
+ return mstr("");
+}
diff --git a/src/pkg_free.c b/src/pkg_free.c
index 2b1d670..12659fe 100644
--- a/src/pkg_free.c
+++ b/src/pkg_free.c
@@ -1,4 +1,5 @@
#include "pkg.h"
+#include "globs.h"
void pkg_free(package_t *pkg) {
str_free(&pkg->name);
@@ -6,4 +7,5 @@ void pkg_free(package_t *pkg) {
str_free(&pkg->version);
str_free(&pkg->target);
str_free(&pkg->src);
+ str_free(&new_arg_str);
}
diff --git a/src/lua_install.c b/src/pkg_install.c
index 5bf5270..b727d01 100644
--- a/src/lua_install.c
+++ b/src/pkg_install.c
@@ -61,15 +61,12 @@ bool target_install(lua_State *L, char* lua_file, str *target) {
lua_pop(L, 1);
return false;
}
- lua_pop(L, 1);
- lua_try_function(L, lua_file, "pre_install");
- lua_pop(L, 1);
+ //lua_try_function(L, lua_file, "pre_install");
if (!lua_try_function(L, lua_file, "install")) {
lua_pop(L, 1);
return false;
}
- lua_pop(L, 1);
- lua_try_function(L, lua_file, "post_install");
+ //lua_try_function(L, lua_file, "post_install");
lua_pop(L, 1);
return true;
}
@@ -94,6 +91,10 @@ bool repo_install(package_t *pkg) {
bool bldit_install(package_t *pkg) {
init_bldit_state();
+ if (!bldit_loaded) {
+ lua_close(B);
+ return false;
+ }
//if (!is_bldit_usable()) {
// log_error("bldit version is newer than the installed pkgit version");
// log_error("consider updating pkgit");
@@ -122,6 +123,7 @@ bool config_install(package_t *pkg) {
str file_path = str_format("%.*s/%s", str_fmt(&pkg->src), key);
if (access(file_path.data, F_OK) != 0) {
lua_pop(L, 1);
+ str_free(&file_path);
continue;
}
str_free(&file_path);
@@ -131,6 +133,7 @@ bool config_install(package_t *pkg) {
}
target_success = target_install(L, "init.lua", &pkg->target);
lua_pop(L, 2);
+ if (target_success) break;
}
lua_pop(L, 1);
return target_success;
@@ -142,7 +145,7 @@ void pkg_install(package_t *pkg) {
log_info("%.*s is already installed.", str_fmt(&pkg->name));
return;
} else {
- log_warn("%.*s is already installed.", str_fmt(&pkg->name));
+ if (flags.verbose) log_warn("%.*s is already installed.", str_fmt(&pkg->name));
}
}
char cwd[MAX_PATH_LEN];
@@ -177,20 +180,21 @@ void pkg_install(package_t *pkg) {
}
log_success("installed " GREEN "%.*s" COLOR_RESET , str_fmt(&pkg->name));
- bool repo_exists = false;
+ //bool repo_exists = false;
+
//for (size_t i = 0; i < cached_repos_count; i++) {
//char *repo_name = name_from_url(cached_repos[i].source_key);
//if (strcmp(repo_name, pkg.name) == 0) { repo_exists = true; }
//free(repo_name);
//}
- if (!repo_exists) {
- log_pkgit("adding " GREEN "%.*s" COLOR_RESET , &pkg->name);
- if (pkg->url.len > 0) {
- add_repo(pkg);
- log_pkgit("added " GREEN "%.*s" COLOR_RESET , &pkg->name);
- }
- } else {
- log_info("repo already exists, done");
- }
+ //if (!repo_exists) {
+ // log_pkgit("adding " GREEN "%.*s" COLOR_RESET , &pkg->name);
+ // if (pkg->url.len > 0) {
+ // add_repo(pkg);
+ // log_pkgit("added " GREEN "%.*s" COLOR_RESET , &pkg->name);
+ // }
+ //} else {
+ // log_info("repo already exists, done");
+ //}
}
diff --git a/src/pkg_remove.c b/src/pkg_remove.c
new file mode 100644
index 0000000..1d4be14
--- /dev/null
+++ b/src/pkg_remove.c
@@ -0,0 +1,199 @@
+/*
+
+ 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 <ftw.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "pkgit_lua.h"
+#include "files.h"
+#include "globs.h"
+#include "log.h"
+
+bool target_uninstall(lua_State *L, char* lua_file, str *target) {
+ if (!lua_try_table(L, lua_file, target->data)) {
+ lua_pop(L, 1);
+ return false;
+ }
+ if (!lua_try_function(L, lua_file, "uninstall")) {
+ lua_pop(L, 1);
+ return false;
+ }
+ lua_pop(L, 1);
+ return true;
+}
+
+bool repo_uninstall(package_t *pkg) {
+ if (!config_loaded || !lua_istable(L, -1)) {
+ lua_isnt_type("repositories", "table");
+ lua_pop(L, 1);
+ return false;
+ }
+ if (!lua_try_table(L, "init.lua", pkg->name.data)) {
+ lua_isnt_type(pkg->name.data, "table");
+ lua_pop(L, 2);
+ return false;
+ }
+ if (!lua_try_table(L, "init.lua", "targets")) return false;
+ bool target_success = target_uninstall(L, "init.lua", &pkg->target);
+ lua_pop(L, 3);
+ return target_success;
+}
+
+bool bldit_uninstall(package_t *pkg) {
+ init_bldit_state();
+ if (!bldit_loaded) {
+ lua_close(B);
+ return false;
+ }
+ //if (!is_bldit_usable()) {
+ // log_error("bldit version is newer than the installed pkgit version");
+ // log_error("consider updating pkgit");
+ // if (!flags.force) return false;
+ //}
+ lua_pushfstring(B, "%s", inst_dirs.prefix.data);
+ lua_setglobal(B, "prefix");
+ lua_pop(B, 1);
+ if (!lua_try_table(B, "bldit.lua", "targets")) return false;
+ bool target_success = target_uninstall(B, "bldit.lua", &pkg->target);
+ lua_pop(B, 2);
+ lua_close(B);
+ return target_success;
+}
+
+bool config_uninstall(package_t *pkg) {
+ lua_getglobal(L, "build_systems");
+ lua_pushnil(L);
+ bool target_success = false;
+ while (lua_next(L, -2) != 0) {
+ const char *key = lua_tostring(L, -2);
+ if (!lua_istable(L, -1)) {
+ lua_pop(L, 1);
+ continue;
+ }
+ str file_path = str_format("%.*s/%s", str_fmt(&pkg->src), key);
+ if (access(file_path.data, F_OK) != 0) {
+ lua_pop(L, 1);
+ str_free(&file_path);
+ continue;
+ }
+ str_free(&file_path);
+ if (!lua_try_table(L, "init.lua", "targets")) {
+ lua_pop(L, 2);
+ continue;
+ }
+ target_success = target_uninstall(L, "init.lua", &pkg->target);
+ lua_pop(L, 2);
+ if (target_success) break;
+ }
+ lua_pop(L, 1);
+ return target_success;
+}
+
+static int remove_installed(
+ const char *src_path, const struct stat *sb,
+ int typeflag, struct FTW *ftwbuf
+) {
+ (void)sb;
+ (void)ftwbuf;
+
+ if (typeflag == FTW_F) {
+ const char *filename = src_path + ftwbuf->base;
+ const char *ext = strrchr(filename, '.');
+ if (!ext)
+ ext = "";
+
+ if (strncmp(ext, ".so", 3) == 0) {
+ char dest[MAX_PATH_LEN];
+ snprintf(dest, sizeof(dest), "%s/%s", inst_dirs.lib.data, filename);
+ if (file_exists(dest))
+ remove(dest);
+ } else if (access(src_path, X_OK) == 0) {
+ if (
+ strcmp(ext, ".sample") != 0 &&
+ strcmp(filename, "bldit") != 0 &&
+ strcmp(filename, "build.sh") != 0 &&
+ strcmp(filename, "compile.sh") != 0
+ ) {
+ char dest[MAX_PATH_LEN];
+ snprintf(dest, sizeof(dest), "%s/%s", inst_dirs.bin.data, filename);
+ if (file_exists(dest))
+ remove(dest);
+ }
+ } else if (strcmp(ext, ".h") == 0) {
+ char dest[MAX_PATH_LEN];
+ snprintf(dest, sizeof(dest), "%s/%s", inst_dirs.include.data, filename);
+ if (file_exists(dest))
+ remove(dest);
+ }
+ }
+ return 0;
+}
+
+static int remove_tree(
+ const char *fpath, const struct stat *sb,
+ int typeflag, struct FTW *ftwbuf
+) {
+ (void)sb;
+ (void)ftwbuf;
+ if (typeflag == FTW_F || typeflag == FTW_SL) {
+ unlink(fpath);
+ } else if (typeflag == FTW_DP) {
+ rmdir(fpath);
+ }
+ return 0;
+}
+
+void remove_pkg(package_t *pkg) {
+ if (!is_directory(pkg->src.data)) {
+ log_error("%.*s is not installed!", str_fmt(&pkg->name));
+ return;
+ }
+ chdir(pkg->src.data);
+
+ bool uninstall_available = false;
+ if (!uninstall_available) if (repo_uninstall(pkg))
+ uninstall_available = true;
+ if (!uninstall_available) if (bldit_uninstall(pkg))
+ uninstall_available = true;
+ if (!uninstall_available) if (config_uninstall(pkg))
+ uninstall_available = true;
+
+ if (!uninstall_available)
+ log_error(
+ "no uninstall function availible for package: %.*s",
+ str_fmt(&pkg->name)
+ );
+
+ nftw(pkg->src.data, remove_installed, 64, FTW_PHYS);
+ const char *last_slash = strrchr(pkg->src.data, '/');
+ char target[MAX_PATH_LEN];
+ if (last_slash && last_slash != pkg->src.data) {
+ size_t parent_len = last_slash - pkg->src.data;
+ snprintf(target, sizeof(target), "%.*s", (int)parent_len, pkg->src.data);
+ } else {
+ snprintf(target, sizeof(target), "%s", pkg->src.data);
+ }
+ nftw(pkg->src.data, remove_tree, 64, FTW_DEPTH | FTW_PHYS);
+ log_success("removed %s", str_fmt(&pkg->name));
+}