diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/compile/headers.c | 2 | ||||
| -rw-r--r-- | src/compile/statements.c | 2 | ||||
| -rw-r--r-- | src/modules.c | 67 | ||||
| -rw-r--r-- | src/modules.h | 3 | ||||
| -rw-r--r-- | src/tomo.c | 11 | ||||
| -rw-r--r-- | src/typecheck.c | 2 |
6 files changed, 66 insertions, 21 deletions
diff --git a/src/compile/headers.c b/src/compile/headers.c index be564144..d1131bde 100644 --- a/src/compile/headers.c +++ b/src/compile/headers.c @@ -177,7 +177,7 @@ Text_t compile_statement_type_header(env_t *env, Path_t header_path, ast_t *ast) if (glob(String(TOMO_PREFIX "/lib/tomo_" TOMO_VERSION "/", folder, "/[!._0-9]*.tm"), GLOB_TILDE, NULL, &tm_files) != 0) { - if (!try_install_module(mod)) code_err(ast, "Could not find library"); + if (!try_install_module(mod, true)) code_err(ast, "Could not find library"); } Text_t includes = EMPTY_TEXT; diff --git a/src/compile/statements.c b/src/compile/statements.c index 82a91a5e..af6a5223 100644 --- a/src/compile/statements.c +++ b/src/compile/statements.c @@ -207,7 +207,7 @@ static Text_t _compile_statement(env_t *env, ast_t *ast) { if (glob(String(TOMO_PREFIX "/lib/tomo_" TOMO_VERSION "/", folder, "/[!._0-9]*.tm"), GLOB_TILDE, NULL, &tm_files) != 0) { - if (!try_install_module(mod)) code_err(ast, "Could not find library"); + if (!try_install_module(mod, true)) code_err(ast, "Could not find library"); } Text_t initialization = EMPTY_TEXT; diff --git a/src/modules.c b/src/modules.c index 5327f28b..6658f8a5 100644 --- a/src/modules.c +++ b/src/modules.c @@ -15,6 +15,7 @@ #include "stdlib/tables.h" #include "stdlib/text.h" #include "stdlib/types.h" +#include "stdlib/util.h" #define xsystem(...) \ ({ \ @@ -23,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; @@ -57,28 +85,35 @@ module_info_t get_module_info(ast_t *use) { 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(TOMO_PREFIX "/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("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; + 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..."); 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("The module \"", Text$from_str(mod.name), "\" ", Text$from_str(mod.version), + 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; + if (!(answer.length == 0 || Text$equal_values(answer, Text("Y")) || Text$equal_values(answer, Text("y")))) + return false; + } print("Installing ", mod.name, " from URL..."); @@ -102,12 +137,14 @@ bool try_install_module(module_info_t mod) { Path$remove(tmpdir, true); return true; } else if (mod.path) { - OptionalText_t answer = - ask(Texts("The module \"", Text$from_str(mod.name), "\" ", Text$from_str(mod.version), + 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; + 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("ln -s ", mod.path, " ", dest); diff --git a/src/modules.h b/src/modules.h index 1c3b2d8e..c36d96dd 100644 --- a/src/modules.h +++ b/src/modules.h @@ -11,4 +11,5 @@ typedef struct { } module_info_t; module_info_t get_module_info(ast_t *use); -bool try_install_module(module_info_t mod); +bool install_from_modules_ini(Path_t ini_file, bool ask_confirmation); +bool try_install_module(module_info_t mod, bool ask_confirmation); @@ -260,8 +260,15 @@ int main(int argc, char *argv[]) { // This *could* be done in parallel, but there may be some dependency issues. pid_t child = fork(); if (child == 0) { - build_library(*lib); - if (should_install) install_library(*lib); + if (Text$equal_values(Path$extension(*lib, false), Text("ini"))) { + if (!install_from_modules_ini(*lib, false)) { + print("Failed to install modules from file: ", *lib); + _exit(1); + } + } else { + build_library(*lib); + if (should_install) install_library(*lib); + } _exit(0); } wait_for_child_success(child); diff --git a/src/typecheck.c b/src/typecheck.c index adb267df..80c270ef 100644 --- a/src/typecheck.c +++ b/src/typecheck.c @@ -189,7 +189,7 @@ static env_t *load_module(env_t *env, ast_t *module_ast) { if (glob(String(TOMO_PREFIX "/lib/tomo_" TOMO_VERSION "/", folder, "/[!._0-9]*.tm"), GLOB_TILDE, NULL, &tm_files) != 0) { - if (!try_install_module(mod)) code_err(module_ast, "Couldn't find or install library: ", folder); + if (!try_install_module(mod, true)) code_err(module_ast, "Couldn't find or install library: ", folder); } env_t *module_env = fresh_scope(env); |
