diff --git a/build.sh b/build.sh index 2620a2f..75dc2c1 100755 --- a/build.sh +++ b/build.sh @@ -1,4 +1,4 @@ cd tomlc99 make cd .. -cc tomlc99/toml.o main.c -o tbuild +cc tomlc99/toml.o main.c -o tbuild -O0 -ggdb diff --git a/main.c b/main.c index 62ef7cc..58479c4 100644 --- a/main.c +++ b/main.c @@ -201,19 +201,33 @@ char* find_project_root(void) "\n" \ "[Dependencies]\n" +typedef struct { + char *name, *uri; +} dependency; + +#define MAX_DEP 20 typedef struct project_manifest { char *name, *author, *version; - // FIXME: Add dependencies. + dependency dependencies[MAX_DEP]; + size_t dependencies_amount; } project_manifest; void free_manifest(project_manifest *manifest) { + int i; + free(manifest->name); free(manifest->author); free(manifest->version); + + for (i = 0; i < manifest->dependencies_amount; i++) { + free(manifest->dependencies[i].name); + free(manifest->dependencies[i].uri); + } } project_manifest* load_manifest(char const *path) { FILE* fp; + int i; char errbuf[200]; fp = fopen(path, "r"); @@ -259,12 +273,34 @@ project_manifest* load_manifest(char const *path) { new->author = author.u.s; new->version = version.u.s; + new->dependencies_amount = 0; + // FIXME: Add dependencies. + toml_table_t *dependencies = toml_table_in(conf, "Dependencies"); + if (!dependencies) { + fprintf(stderr, "Error: Cannot load manifest file: Cannot find [Dependencies] table.\n"); + return NULL; + } + + for (i = 0; ; i++) { + char const *key = toml_key_in(dependencies, i); + if (!key) break; + + toml_datum_t dep_uri = toml_string_in(dependencies, key); + new->dependencies_amount++; + char *name = calloc(1, sizeof(char) * (strlen(key) + 1)); + strcpy(name, key); + char *url = calloc(1, sizeof(char) * (strlen(dep_uri.u.s) + 1)); + strcpy(url, dep_uri.u.s); + + dependency dep = { + name, url + }; + + new->dependencies[i] = dep; + } toml_free(conf); - - printf("%s, %s, %s\n", new->name, new->author, new->version); - return new; } @@ -341,7 +377,7 @@ void print_help(char **argv) { printf("Usage: %s [command]\n", argv[0]); fputs("\nCommands:\n", stderr); fputs(" * init|i [path=.] - Setup a new project.\n", stderr); - fputs(" * build|. - Build project in current working directory.\n", stderr); + fputs(" * build|. [--zeal|-z|-Z] - Build project in current working directory.\n", stderr); fputs(" * clean - Clean output code in current working directory.\n", stderr); fputs("\nTo see manifest file usage, check out man tbuild(1)\n", stderr); } @@ -642,6 +678,8 @@ int main(int argc, char **argv) { if (argc > 2) free(project_path); } else if (cmd == 'b' || cmd == '.') { + int i; + struct { bool zeal_build; } options = { 0 }; @@ -681,9 +719,35 @@ int main(int argc, char **argv) { } project_manifest* manifest = load_manifest(text_format("%s/" MANIFEST_FNAME, project_path)); + if (!manifest) { + fputs("Error: Cannot build project: Failed to open manifest.\n", stderr); + return 1; + } puts(buffer_text_format); - // TODO: Validate dependencies. + text_format("%s/lib", project_path); + char *lib_dir = malloc((strlen(buffer_text_format)+1)*sizeof(char)); + strcpy(lib_dir, buffer_text_format); + if (!file_exists(lib_dir)) { + bool status = makedir(lib_dir); + if (!status) { + fputs("Error: Cannot build project: Cannot create lib directory.\n", stderr); + free_manifest(manifest); + return 1; + } + } + + for (i = 0; i < manifest->dependencies_amount; i++) { + dependency dep = manifest->dependencies[i]; + printf("%s -> %s (%i)\n", dep.name, dep.uri, i); + + puts(text_format("%s/%s", lib_dir, dep.name)); + if (!file_exists(text_format("%s/%s", lib_dir, dep.name))) + system(text_format("git clone --depth 1 --recursive --shallow-submodules '%s' '%s/%s'", dep.uri, lib_dir, dep.name)); + else + // FIXME: Make this cross platform. + system(text_format("cd '%s/%s' && git pull", lib_dir, dep.name)); + } // Create build directory text_format("%s/build", project_path); @@ -705,8 +769,8 @@ int main(int argc, char **argv) { puts("Populating build directory..."); clear_directory(build_dir); copy_directory(src_dir, build_dir); - if (file_exists(text_format("%s/libs", project_path))) - copy_directory(src_dir, buffer_text_format); + if (file_exists(lib_dir)) + copy_directory(lib_dir, build_dir); // Run scripts (if any) puts("Running scripts...");