diff options
Diffstat (limited to 'src/modules.c')
| -rw-r--r-- | src/modules.c | 119 |
1 files changed, 74 insertions, 45 deletions
diff --git a/src/modules.c b/src/modules.c index ff112c02..fafbbf86 100644 --- a/src/modules.c +++ b/src/modules.c @@ -5,6 +5,7 @@ #include <string.h> #include <sys/wait.h> +#include "config.h" #include "modules.h" #include "stdlib/memory.h" #include "stdlib/paths.h" @@ -14,6 +15,7 @@ #include "stdlib/tables.h" #include "stdlib/text.h" #include "stdlib/types.h" +#include "stdlib/util.h" #define xsystem(...) \ ({ \ @@ -22,6 +24,33 @@ errx(1, "Failed to run command: %s", String(__VA_ARGS__)); \ }) +bool install_from_modules_ini(Path_t ini_file, bool ask_confirmation) { + OptionalClosure_t by_line = Path$by_line(ini_file); + if (by_line.fn == NULL) return false; + OptionalText_t (*next_line)(void *) = by_line.fn; + module_info_t info = {}; + for (Text_t line; (line = next_line(by_line.userdata)).length >= 0;) { + char *line_str = Text$as_c_string(line); + const char *next_section = NULL; + if (!strparse(line_str, "[", &next_section, "]")) { + if (info.name) { + if (!try_install_module(info, ask_confirmation)) return false; + } + print("Checking module ", next_section, "..."); + info = (module_info_t){.name = next_section}; + continue; + } + if (!strparse(line_str, "version=", &info.version) || !strparse(line_str, "url=", &info.url) + || !strparse(line_str, "git=", &info.git) || !strparse(line_str, "path=", &info.path) + || !strparse(line_str, "revision=", &info.revision)) + continue; + } + if (info.name) { + if (!try_install_module(info, ask_confirmation)) return false; + } + return true; +} + static void read_modules_ini(Path_t ini_file, module_info_t *info) { OptionalClosure_t by_line = Path$by_line(ini_file); if (by_line.fn == NULL) return; @@ -50,47 +79,41 @@ module_info_t get_module_info(ast_t *use) { if (cached) return **cached; const char *name = Match(use, Use)->path; module_info_t *info = new (module_info_t, .name = name); - if (streq(name, "commands")) info->version = "v1.0"; - else if (streq(name, "random")) info->version = "v1.0"; - else if (streq(name, "base64")) info->version = "v1.1"; - else if (streq(name, "core")) info->version = "v1.0"; - else if (streq(name, "patterns")) info->version = "v1.1"; - else if (streq(name, "json")) info->version = "v1.1"; - else if (streq(name, "pthreads")) info->version = "v1.0"; - else if (streq(name, "shell")) info->version = "v1.0"; - else if (streq(name, "time")) info->version = "v1.0"; - else if (streq(name, "uuid")) info->version = "v1.1"; - else { - read_modules_ini(Path$sibling(Path$from_str(use->file->filename), Text("modules.ini")), info); - read_modules_ini(Path$with_extension(Path$from_str(use->file->filename), Text(":modules.ini"), false), info); - } + read_modules_ini(Path$sibling(Path$from_str(use->file->filename), Text("modules.ini")), info); + read_modules_ini(Path$with_extension(Path$from_str(use->file->filename), Text(":modules.ini"), false), info); Table$set(&cache, &use, &info, cache_type); return *info; } -bool try_install_module(module_info_t mod) { +bool try_install_module(module_info_t mod, bool ask_confirmation) { + Path_t dest = Path$from_text(Texts(Text$from_str(TOMO_PATH), "/lib/tomo_" TOMO_VERSION "/", Text$from_str(mod.name), + "_", Text$from_str(mod.version))); + if (Path$exists(dest)) return true; + if (mod.git) { - OptionalText_t answer = ask(Texts(Text("The module \""), Text$from_str(mod.name), - Text("\" is not installed.\nDo you want to install it from git URL "), - Text$from_str(mod.git), Text("? [Y/n] ")), - true, true); - if (!(answer.length == 0 || Text$equal_values(answer, Text("Y")) || Text$equal_values(answer, Text("y")))) - return false; + if (ask_confirmation) { + OptionalText_t answer = + ask(Texts("The module \"", Text$from_str(mod.name), "\" ", Text$from_str(mod.version), + " is not installed.\nDo you want to install it from git URL ", Text$from_str(mod.git), + "? [Y/n] "), + true, true); + if (!(answer.length == 0 || Text$equal_values(answer, Text("Y")) || Text$equal_values(answer, Text("y")))) + return false; + } print("Installing ", mod.name, " from git..."); - Path_t tmpdir = Path$unique_directory(Path("/tmp/tomo-module-XXXXXX")); - if (mod.revision) xsystem("git clone --depth=1 --revision ", mod.revision, " ", mod.git, " ", tmpdir); - else xsystem("git clone --depth=1 ", mod.git, " ", tmpdir); - if (mod.path) xsystem("tomo -IL ", tmpdir, "/", mod.path); - else xsystem("tomo -IL ", tmpdir); - Path$remove(tmpdir, true); + if (mod.revision) xsystem("git clone --depth=1 --revision ", mod.revision, " ", mod.git, " ", dest); + else xsystem("git clone --depth=1 ", mod.git, " ", dest); + xsystem("tomo -L ", dest); return true; } else if (mod.url) { - OptionalText_t answer = ask(Texts(Text("The module "), Text$from_str(mod.name), - Text(" is not installed.\nDo you want to install it from URL "), - Text$from_str(mod.url), Text("? [Y/n] ")), - true, true); - if (!(answer.length == 0 || Text$equal_values(answer, Text("Y")) || Text$equal_values(answer, Text("y")))) - return false; + if (ask_confirmation) { + OptionalText_t answer = ask( + Texts("The module \"", Text$from_str(mod.name), "\" ", Text$from_str(mod.version), + " is not installed.\nDo you want to install it from URL ", Text$from_str(mod.url), "? [Y/n] "), + true, true); + if (!(answer.length == 0 || Text$equal_values(answer, Text("Y")) || Text$equal_values(answer, Text("y")))) + return false; + } print("Installing ", mod.name, " from URL..."); @@ -101,25 +124,31 @@ bool try_install_module(module_info_t mod) { if (!p) return false; const char *extension = p + 1; Path_t tmpdir = Path$unique_directory(Path("/tmp/tomo-module-XXXXXX")); + tmpdir = Path$child(tmpdir, Text$from_str(mod.name)); + Path$create_directory(tmpdir, 0755); + xsystem("curl ", mod.url, " -o ", tmpdir); - if (streq(extension, ".zip")) xsystem("unzip ", tmpdir, "/", filename); - else if (streq(extension, ".tar.gz") || streq(extension, ".tar")) xsystem("tar xf ", tmpdir, "/", filename); + Path$create_directory(dest, 0755); + if (streq(extension, ".zip")) xsystem("unzip ", tmpdir, "/", filename, " -d ", dest); + else if (streq(extension, ".tar.gz") || streq(extension, ".tar")) + xsystem("tar xf ", tmpdir, "/", filename, " -C ", dest); else return false; - const char *basename = String(string_slice(filename, strcspn(filename, "."))); - if (mod.path) xsystem("tomo -IL ", tmpdir, "/", basename, "/", mod.path); - else xsystem("tomo -IL ", tmpdir, "/", basename); + xsystem("tomo -L ", dest); Path$remove(tmpdir, true); return true; } else if (mod.path) { - OptionalText_t answer = ask(Texts(Text("The module "), Text$from_str(mod.name), - Text(" is not installed.\nDo you want to install it from path "), - Text$from_str(mod.path), Text("? [Y/n] ")), - true, true); - if (!(answer.length == 0 || Text$equal_values(answer, Text("Y")) || Text$equal_values(answer, Text("y")))) - return false; + if (ask_confirmation) { + OptionalText_t answer = ask( + Texts("The module \"", Text$from_str(mod.name), "\" ", Text$from_str(mod.version), + " is not installed.\nDo you want to install it from path ", Text$from_str(mod.path), "? [Y/n] "), + true, true); + if (!(answer.length == 0 || Text$equal_values(answer, Text("Y")) || Text$equal_values(answer, Text("y")))) + return false; + } print("Installing ", mod.name, " from path..."); - xsystem("tomo -IL ", mod.path); + xsystem("ln -s ", mod.path, " ", dest); + xsystem("tomo -L ", dest); return true; } |
