aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/compile/headers.c2
-rw-r--r--src/compile/statements.c2
-rw-r--r--src/modules.c67
-rw-r--r--src/modules.h3
-rw-r--r--src/tomo.c11
-rw-r--r--src/typecheck.c2
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);
diff --git a/src/tomo.c b/src/tomo.c
index b6440f10..a1f21dcf 100644
--- a/src/tomo.c
+++ b/src/tomo.c
@@ -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);