aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/common.h2
-rw-r--r--include/lua_state.h22
-rw-r--r--include/pkg.h20
-rw-r--r--include/state.h1
-rw-r--r--src/cli.c13
-rw-r--r--src/hooks.c87
-rw-r--r--src/lua_state.c28
-rw-r--r--src/main.c13
-rw-r--r--src/pkg.c93
-rw-r--r--src/state.c5
10 files changed, 238 insertions, 46 deletions
diff --git a/include/common.h b/include/common.h
index a77718b..32d8741 100644
--- a/include/common.h
+++ b/include/common.h
@@ -20,7 +20,7 @@
#ifndef PKGIT_COMMON_H
#define PKGIT_COMMON_H
-#define VERSION "1.2.0"
+#define VERSION "2.0.0_INDEV"
#define RED "\x1b[0;31m"
#define GREEN "\x1b[0;32m"
#define YELLOW "\x1b[0;33m"
diff --git a/include/lua_state.h b/include/lua_state.h
index 49f35e4..db689fe 100644
--- a/include/lua_state.h
+++ b/include/lua_state.h
@@ -12,5 +12,27 @@ extern bool L_is_loaded;
bool init_lua_state(void);
bool init_lua_config(void);
void free_lua_state(void);
+void free_lua_config(void);
+
+#define lua_get_field_type(name, type, file, pop_num) \
+ do { \
+ lua_getfield(L, -1, name); \
+ if (!lua_is##type(L, -1)) { \
+ log_error("lua: expected type '" #type "' for %s in %.*s", \
+ name, str_fmt(file)); \
+ lua_pop(L, pop_num); \
+ return false; \
+ } \
+ } while (0)
+
+#define lua_run_function(name, file, params, returns, pop_num) \
+ do { \
+ if (lua_pcall(L, params, returns, 0) { \
+ log_error("lua: '%s' function borked in %.*s: %s", \
+ name, str_fmt(file)), lua_tostring(L, -1); \
+ lua_pop(L, pop_num); \
+ return false; \
+ } \
+ } while (0)
#endif
diff --git a/include/pkg.h b/include/pkg.h
index 2410710..15990ab 100644
--- a/include/pkg.h
+++ b/include/pkg.h
@@ -3,22 +3,20 @@
#include "str.h"
-struct package_t;
-typedef bool (*package_hook_cb_t)(struct package_t *pkg);
-typedef str (*package_version_cb_t)(struct package_t *pkg);
-
typedef struct package_t {
str name, version, url, src;
unsigned int dep_count;
bool is_local;
- package_hook_cb_t setup, build, install, rm, on_update, fetch_sources;
- package_version_cb_t fetch_latest_version;
} package_t;
-bool setup(package_t *pkg), build(package_t *pkg),
- install(package_t *pkg), rm(package_t *pkg),
- on_update(package_t *pkg),
- fetch_sources(package_t *pkg);
-str fetch_latest_version(package_t *pkg);
+bool pkg_hook_url(package_t *pkg);
+str pkg_get_url(package_t *pkg);
+bool pkg_hook_setup(package_t *pkg);
+bool pkg_hook_build(package_t *pkg);
+bool pkg_hook_install(package_t *pkg);
+bool pkg_hook_remove(package_t *pkg);
+bool pkg_hook_on_update(package_t *pkg);
+bool pkg_hook_fetch_sources(package_t *pkg);
+str pkg_hook_fetch_latest_version(package_t *pkg);
#endif
diff --git a/include/state.h b/include/state.h
index a1c09d7..6793aff 100644
--- a/include/state.h
+++ b/include/state.h
@@ -38,4 +38,3 @@ typedef struct config_t {
extern cli_flags_t flags;
extern user_config_t config;
-extern inst_dirs_t inst_dirs;
diff --git a/src/cli.c b/src/cli.c
index c4499ff..24bace0 100644
--- a/src/cli.c
+++ b/src/cli.c
@@ -25,6 +25,7 @@
#include "common.h"
#include "help.h"
#include "log.h"
+#include "lua_state.h"
#include "state.h"
#include "str.h"
@@ -236,11 +237,17 @@ cli_result_t cli(int argc, char **argv) {
print_help();
return CLI_HELP_CALLED;
}
- if (!parse_flags(argc, argv))
- return CLI_FAIL;
- if (!parse_cmds(argc, argv))
+ init_lua_config();
+ init_lua_state();
+
+ if (!parse_flags(argc, argv)) {
+ free_lua_config();
return CLI_FAIL;
+ } else if (!parse_cmds(argc, argv)) {
+ free_lua_config();
+ return CLI_FAIL;
+ }
return CLI_SUCCESS;
}
diff --git a/src/hooks.c b/src/hooks.c
new file mode 100644
index 0000000..f47d928
--- /dev/null
+++ b/src/hooks.c
@@ -0,0 +1,87 @@
+/*
+
+ 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 <stdio.h>
+#include <string.h>
+
+#include "common.h"
+#include "log.h"
+#include "lua_state.h"
+#include "pkg.h"
+#include "str.h"
+#include "state.h"
+
+bool pkg_exists(str *name) {
+ lua_get_field_type("pkgs", table, &config.init_path, 1);
+ lua_get_field_type(name->data, table, &config.init_path, 2);
+ return true;
+}
+
+bool pkg_hook_url(package_t *pkg) {
+ 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("url", string, &config.init_path, 3);
+ return true;
+}
+
+str pkg_get_url(package_t *pkg) {
+ str url = str_new();
+ if (!pkg_hook_url(pkg)) return url;
+ url = mstr(lua_tostring(L, -1));
+ return url;
+}
+
+bool pkg_hook_fetch_sources(package_t *pkg) {
+ return true;
+}
+
+str pkg_hook_fetch_latest_version(package_t *pkg) {
+ str version = {0};
+ return version;
+}
+
+bool pkg_hook_recipe(char *recipe, package_t *pkg) {
+ 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);
+ lua_get_field_type(recipe, function, &config.init_path, 4);
+ return true;
+}
+
+bool pkg_hook_setup(package_t *pkg) {
+ pkg_hook_recipe("setup", pkg);
+ return true;
+}
+
+bool pkg_hook_build(package_t *pkg) {
+ return true;
+}
+
+bool pkg_hook_install(package_t *pkg) {
+ return true;
+}
+
+bool pkg_hook_remove(package_t *pkg) {
+ return true;
+}
+
+bool pkg_hook_on_update(package_t *pkg) {
+ return true;
+}
diff --git a/src/lua_state.c b/src/lua_state.c
index aa5247f..18040fc 100644
--- a/src/lua_state.c
+++ b/src/lua_state.c
@@ -10,6 +10,9 @@
lua_State *L = NULL;
bool L_is_loaded = false;
+cli_flags_t flags = {0};
+user_config_t config = {0};
+
static void lua_path_push(const char *new_path) {
lua_getglobal(L, "package");
lua_getfield(L, -1, "path");
@@ -90,28 +93,17 @@ static void setup_base_dirs(void) {
);
}
-#define lua_get_field_type(name, type, file) \
- do { \
- lua_getfield(L, -1, name); \
- if (!lua_is##type(L, -1)) { \
- log_error("lua: expected type " #type " for " name " in %.*s", \
- str_fmt(file)); \
- lua_pop(L, 1); \
- return false; \
- } \
- } while (0)
-
static bool load_init_lua(void) {
lua_setglobal(L, "__PkgitUserConfig");
lua_getglobal(L, "__PkgitUserConfig");
- lua_get_field_type("dirs", table, &config.init_path);
+ lua_get_field_type("dirs", table, &config.init_path, 1);
#define X(field) \
do { \
- lua_get_field_type(#field, string, &config.init_path); \
+ lua_get_field_type(#field, string, &config.init_path, 1); \
config.inst_dirs.field = str_adopt((char *)lua_tostring(L, -1)); \
- lua_pop(L, 1); \
+ lua_pop(L, 1); \
} while (0)
X(prefix);
@@ -147,4 +139,12 @@ void free_lua_state(void) {
void free_lua_config(void) {
free_lua_state();
+ str_free(&config.inst_dirs.prefix);
+ str_free(&config.inst_dirs.src);
+ str_free(&config.inst_dirs.bin);
+ str_free(&config.inst_dirs.lib);
+ str_free(&config.inst_dirs.include);
+ str_free(&config.dir);
+ str_free(&config.init_path);
+ str_free(&config.autogenerated_path);
}
diff --git a/src/main.c b/src/main.c
index 334f87e..efa2f67 100644
--- a/src/main.c
+++ b/src/main.c
@@ -19,12 +19,8 @@
*/
#include "cli.h"
-#include "lua_state.h"
int main(int argc, char **argv) {
- // if (!init_vars())
- // return 1;
-
int retval = 0;
cli_result_t result = cli(argc, argv);
if (!result) {
@@ -32,15 +28,6 @@ int main(int argc, char **argv) {
goto done;
}
- if (result != CLI_HELP_CALLED) {
- init_lua_config();
- init_lua_state();
- // if (!init_vars())
- // return 1;
- }
-
done:
- free_lua_state();
- // free_vars();
return retval;
}
diff --git a/src/pkg.c b/src/pkg.c
new file mode 100644
index 0000000..fe79b64
--- /dev/null
+++ b/src/pkg.c
@@ -0,0 +1,93 @@
+/*
+
+ 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 <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "common.h"
+#include "log.h"
+#include "pkg.h"
+#include "state.h"
+#include "str.h"
+
+static str get_destdir(str *cwd, str *arg) {
+ str result = {0};
+ if (str_first(arg) == '.' && arg->len == 1) {
+ result = str_format("%.*s/%.*s", str_fmt(&config.inst_dirs.src), str_fmt(cwd));
+ } else {
+ str name = {0};
+ if (str_find_char(arg, '/') != 0) name = str_from_after_delim(arg, '/');
+ else str_copy_into(&name, arg);
+ result = str_format("%.*s/%.*s", str_fmt(&config.inst_dirs.src), str_fmt(&name));
+ str_free(&name);
+ }
+ return result;
+}
+
+static str get_pkgsrc(package_t *pkg) {
+ if (pkg->is_local == 1)
+ return str_format("%.*s/%.*s", str_fmt(&config.inst_dirs.src), str_fmt(&pkg->name));
+ else
+ return str_format("%.*s/%.*s/%.*s", str_fmt(&config.inst_dirs.src),
+ str_fmt(&pkg->name), str_fmt(&pkg->version));
+}
+
+static void assign_pkg_version(package_t *pkg, str *new_arg_str) {
+ if (str_find_char(new_arg_str, '@')) {
+ pkg->version = str_from_after_delim(new_arg_str, '@');
+ pkg->name.len -= pkg->version.len + 1;
+ } else str_copy_cstr_into(&pkg->version, "HEAD");;
+}
+
+package_t pkg_create(str *arg) {
+ package_t pkg = { .is_local = false, };
+
+ assign_pkg_version(&pkg, arg);
+
+ char cwd_cstr[MAX_PATH_LEN];
+ getcwd(cwd_cstr, MAX_PATH_LEN);
+ str cwd = mstr(cwd_cstr);
+ str destdir = get_destdir(&cwd, arg);
+
+ if (strncmp(arg->data, "http", 4) == 0 || strncmp(arg->data, "ssh", 3) == 0) {
+ str_copy_into(&pkg.url, arg);
+ pkg.name = str_from_after_delim(arg, '/');
+ } else if (str_equal_cstr(arg, ".")) {
+ str_copy_cstr_into(&pkg.url, "");
+ pkg.name = str_from_after_delim(&cwd, '/');
+ pkg.is_local = true;
+ } else if (pkg_exists(arg)) {
+ str_copy_into(&pkg.name, arg);
+ pkg.url = pkg_get_url(&pkg);
+// } else if (is_installed_locally) {
+// str_copy_cstr_into(&pkg.url, "");
+// pkg.name = str_from_after_delim(&destdir, '/');
+// pkg.is_local = true;
+ } else {
+ log_error("'%.*s' is not a valid package", str_fmt(arg));
+ str_free(&cwd);
+ str_free(&destdir);
+ str_free(arg);
+ abort();
+ }
+
+ return pkg;
+}
diff --git a/src/state.c b/src/state.c
index e109628..4bdca51 100644
--- a/src/state.c
+++ b/src/state.c
@@ -22,6 +22,5 @@
#include "state.h"
-cli_flags_t flags = {0};
-user_config_t config = {0};
-inst_dirs_t inst_dirs = {0};
+//cli_flags_t flags = {0};
+//user_config_t config = {0};