diff --git a/core/create_project.c b/core/create_project.c index 5d9b27e..11014e2 100644 --- a/core/create_project.c +++ b/core/create_project.c @@ -1,3 +1,11 @@ +/* Copyright (C) vx_clutch + * + * This file is part of yait + * + * This project and file is licenced under the BSD-3-Clause licence. + * + */ + #include #include #include @@ -10,15 +18,14 @@ #include "contents.h" #include "yait.h" -#error "TODO: make path project root" - #define DEFAULT_USER_NAME "unknown" #define DEFAULT_PROJECT_NAME "Project" #define DEFAULT_LICENCE BSD3 #define DEFAULT_GIT_INIT true #define DEFAULT_CLANG_FORMAT true +#define DEFAULT_GNU false -int depth; +int depth = 0; static int reset_path(void) { @@ -175,9 +182,12 @@ int setup_git(manifest_t manifest) return ret; int status = system("git init --quiet"); - if (status != 0) - fprintf(stderr, "setup_git: failed to initialize git: %s\n", - strerror(status)); + if (status == -1) { + fprintf(stderr, "...: %s\n", strerror(errno)); + } else if (WIFEXITED(status) && WEXITSTATUS(status) != 0) { + fprintf(stderr, "...: exited with status %d\n", + WEXITSTATUS(status)); + } return status; } @@ -201,7 +211,8 @@ int create_makefile(manifest_t manifest) return ret; } - int status = create_file_with_content("Makefile", makefile_template, M, m, M, m, M, M, m, M, m, M, m); + int status = create_file_with_content("Makefile", makefile_template, M, + m, M, m, M, M, m, M, m, M, m); free(m); free(M); @@ -242,14 +253,15 @@ int generate_source_code(manifest_t manifest, char *licence_line) struct tm tm = *localtime(&t); int year = tm.tm_year + 1900; - // Uncomment or fix when create_file_with_content supports this - // status = create_file_with_content("config.h", manifest.project, licence_line, year); - // if (status != 0) { - // fprintf(stderr, "generate_source_code: failed to create config.h: %s\n", strerror(status)); - // return status; - // } + status = create_file_with_content("config.h", config_h_template, + manifest.project, licence_line, year); + if (status != 0) { + fprintf(stderr, + "generate_source_code: failed to create config.h: %s\n", + strerror(status)); + return status; + } - status = create_and_enter_directory(manifest.project); if (status != 0) { fprintf(stderr, "generate_source_code: failed to create or enter directory: %s\n", @@ -259,13 +271,13 @@ int generate_source_code(manifest_t manifest, char *licence_line) depth++; if (manifest.flag.GNU) { - status = create_file_with_content("main.c", main_c_gnu_template, - manifest.project, - manifest.name); + status = create_file_with_content( + strcat(manifest.project, "main.c"), main_c_gnu_template, + manifest.project, manifest.name); } else { - status = create_file_with_content("main.c", main_c_template, - manifest.project, - manifest.name); + status = create_file_with_content( + strcat(manifest.project, "main.c"), main_c_template, + manifest.project, manifest.name); } return status; @@ -277,9 +289,8 @@ int create_project(manifest_t manifest) sanitize(&manifest); - depth = 0; + // TODO(vx-clutch): make the path the project root. if (strcmp(manifest.path, ".") != 0) { - status = create_and_enter_directory(manifest.project); if (status != 0) { fprintf(stderr, "create_project: failed to create or enter directory: %s\n", @@ -305,13 +316,6 @@ int create_project(manifest_t manifest) return status; } - status = setup_git(manifest); - if (status != 0) { - fprintf(stderr, - "create_project: warning: git initialization failed: %s\n", - strerror(status)); - } - status = maybe_create_clang_format(manifest); if (status != 0) { fprintf(stderr, @@ -353,5 +357,15 @@ int create_project(manifest_t manifest) return status; } + status = setup_git(manifest); + if (status != 0) { + fprintf(stderr, + "create_project: warning: git initialization failed: %s\n", + strerror(status)); + } + + // TODO(vx-clutch): Make path absolute. + fprintf(stderr, "Created %s at\n %s", manifest.project, manifest.path); + return 0; } diff --git a/core/file.c b/core/file.c index a39dbf5..165e8ef 100644 --- a/core/file.c +++ b/core/file.c @@ -9,56 +9,80 @@ #include #include #include +#include +#include #include #include #include #include "yait.h" -int create_file_with_content(char *path, char *format, ...) +int files_made = 0; + +static int mkdir_p(const char *path) { - FILE *fp = fopen(path, "w"); - if (!fp) { + char *copypath = strdup(path); + char *p = copypath; + int status = 0; + + if (!copypath) return -1; + + if (copypath[0] == '/') + p++; + + for (; *p; p++) { + if (*p == '/') { + *p = '\0'; + if (mkdir(copypath, 0777) && errno != EEXIST) { + status = -1; + break; + } + *p = '/'; + } } + + if (!status && mkdir(copypath, 0777) && errno != EEXIST) + status = -1; + + free(copypath); + return status; +} + +int create_file_with_content(const char *path, const char *format, ...) +{ + char *dirpath; + const char *slash = strrchr(path, '/'); + if (slash) { + size_t len = slash - path; + dirpath = malloc(len + 1); + if (!dirpath) + return -1; + memcpy(dirpath, path, len); + dirpath[len] = '\0'; + if (mkdir_p(dirpath)) { + free(dirpath); + return -1; + } + free(dirpath); + } + + FILE *fp = fopen(path, "w"); + if (!fp) + return -1; + va_list args; va_start(args, format); - vfprintf(fp, format, args); + if (vfprintf(fp, format, args) < 0) { + va_end(args); + fclose(fp); + return -1; + } va_end(args); + ++files_made; + emit_progress("Creating files", files_made); + fclose(fp); return 0; } - -int create_directory(char *format, ...) -{ - va_list args; - va_start(args, format); - - char path[MAX_PATH_LENGTH]; - int result = vsnprintf(path, sizeof(path), format, args); - va_end(args); - - /* Check if the path was truncated */ - if (result >= (int)sizeof(path)) { - return ENAMETOOLONG; - } - - if (mkdir(path, DEFAULT_DIR_PERMISSIONS) < 0) { - return errno; - } - - return 0; -} - -int create_and_enter_directory(const char *dirname) -{ - int err = create_directory("%s", dirname); - if (err) { - return err; - } - if (chdir(dirname) != 0) { - return errno; - } - return 0; -} diff --git a/core/util.c b/core/util.c new file mode 100644 index 0000000..f6f7495 --- /dev/null +++ b/core/util.c @@ -0,0 +1,19 @@ +/* Copyright (C) vx_clutch + * + * This file is part of yait + * + * This project and file is licenced under the BSD-3-Clause licence. + * + */ + +#include "yait.h" + +void emit_progress(const char *action, int count) +{ + if (count > 0) { + fprintf(stderr, "%s %d", strcat("\r", action), count); + fflush(stderr); + } else { + fprintf(stderr, ", done\n"); + } +} diff --git a/core/yait.h b/core/yait.h index 28a54ea..3b59cf9 100644 --- a/core/yait.h +++ b/core/yait.h @@ -15,11 +15,7 @@ int printfn(char *format, ...); -int create_and_enter_directory(const char *dirname); - -int create_file_with_content(char *path, char *format, ...); - -int create_directory(char *format, ...); +int create_file_with_content(const char *path, const char *format, ...); int parse_standard_options(void (*usage_func)(), int argc, char **argv); @@ -28,4 +24,6 @@ int program_exists(const char *prog); #include "manifest.h" int create_project(manifest_t manifest); +void emit_progress(const char *action, int count); + #endif // YAIT_H