diff options
| -rw-r--r-- | src/deps.c | 2 | ||||
| -rw-r--r-- | src/spm.c | 185 | ||||
| -rw-r--r-- | src/strings.c | 14 | 
3 files changed, 167 insertions, 34 deletions
| @@ -183,6 +183,6 @@ void dep_show(Dependencies **deps) {          return;      }      for (int i = 0; i < (*deps)->records; i++) { -        printf("%d: %s\n", i, (*deps)->list[i]); +        printf("  -> %s\n", (*deps)->list[i]);      }  } @@ -2,9 +2,31 @@   * SPM - Simple Package Manager   * @file spm.c   */ +#include <errno.h>  #include "spm.h" +int RUNTIME_VERBOSE = 0; +int RUNTIME_INSTALL = 0; +int RUNTIME_ROOTDIR = 0; +const int PACKAGE_MAX = 0xff; + +void usage(const char *program_name) { +    printf( +            "usage: %s [-hVv] [-I|--install {package ...}]\n" +            "  -h,  --help     show this help message\n" +            "  -V,  --version  show version\n" +            "  -v,  --verbose  show more information\n" +            "  -I,  --install  install package(s)\n" +            , program_name +    ); +} +  int main(int argc, char *argv[]) { +    char program_name[strlen(argv[0]) + 1]; +    memset(program_name, '\0', sizeof(program_name) + 1); +    strcpy(program_name, basename(argv[0])); + +      // not much to see here yet      // at the moment this will all be random tests, for better or worse      // everything here is subject to change without notice @@ -16,45 +38,150 @@ int main(int argc, char *argv[]) {      // Ensure external programs are available for use.      check_runtime_environment(); -    // Install a package to test things out -    char *match; -    char *package; -    const char *root = "/tmp/root"; -    if ((match = find_package("python")) == NULL) { -        fprintf(SYSERROR); -        exit(1); -    } -    if ((package = basename(match)) == NULL) { -        fprintf(stderr, "Unable to derive package name from package path:\n\t-> %s\n", match); -        exit(1); -    } +    char root[PATH_MAX]; +    memset(root, '\0', PATH_MAX); -    Dependencies *deps = NULL; -    dep_init(&deps); +    char *packages[PACKAGE_MAX]; +    memset(packages, '\0', sizeof(char *)); -    if (dep_all(&deps, package) < 0) { -        dep_free(&deps); -        free_global_config(); +    if (argc < 2) { +        usage(program_name);          exit(1);      } -    printf("%s requires:\n", package); -    dep_show(&deps); +    for (int i = 1; i < argc; i++) { +        char *arg = argv[i]; +        char *arg_next = argv[i + 1] ? argv[i + 1] : NULL; -    // Install dependencies first -    for (int i = 0; i < deps->records; i++) { -        if (install(root, deps->list[i]) < 0) { -            fprintf(SYSERROR); -            exit(errno); +        // options +        if (*arg == '-' || strncmp(arg, "--", 2) == 0) { +            if (strcmp(arg, "-h") == 0 || strcmp(arg, "--help") == 0) { +                usage(program_name); +                exit(0); +            } +            else if (strcmp(arg, "-V") == 0 || strcmp(arg, "--version") == 0) { +                printf("want version\n"); +            } +            else if (strcmp(arg, "-v") == 0 || strcmp(arg, "--verbose") == 0) { +                printf("verbose mode\n"); +                RUNTIME_VERBOSE = 1; +            } +            else if (strcmp(arg, "-r") == 0 || strcmp(arg, "--root") == 0) { +                RUNTIME_ROOTDIR = 1; +                if (!arg_next) { +                    fprintf(stderr, "-r|--root requires a path\n"); +                    usage(program_name); +                    exit(1); +                } +                strcpy(root, arg_next); +                i++; +            } +            else if (strcmp(arg, "-I") == 0 || strcmp(arg, "--install") == 0) { +                RUNTIME_INSTALL = 1; +                for (int p = 0; i < argc; p++) { +                    i++; +                    if (startswith(argv[i], "-") == 0 || startswith(argv[i], "--") == 0) { +                        if (!p) { +                            fprintf(stderr, "-I|--install requires at least one package (got: '%s')\n", argv[i]); +                            exit(1); +                        } +                        i--; +                        break; +                    } +                    packages[p] = argv[i]; +                } +            }          } +        else { +            printf("Unknown option: %s\n", arg); +            usage(program_name); +            exit(1); +        } +    } + +    if (RUNTIME_ROOTDIR && !RUNTIME_INSTALL) { +        fprintf(stderr, "-r|--root requires -I|--install\n"); +        usage(program_name); +        exit(1);      } -    // Install package -    if (install(root, package) < 0) { -        fprintf(SYSERROR); -        exit(errno); + +    if (isempty(root)) { +        printf("Using default installation root\n"); +        sprintf(root, "%s%c%s", getenv("HOME"), DIRSEP, "spm_root");      } -    dep_free(&deps); +    if (RUNTIME_INSTALL) { +        Dependencies *deps = NULL; +        dep_init(&deps); + +        printf("Installation root: %s\n", root); +        printf("Requested packages:\n"); +        for (int i = 0; i < PACKAGE_MAX; i++) { +            if (packages[i] == NULL) { +                break; +            } +            printf("  -> %s\n", packages[i]); +        } + +        printf("Resolving package requirements...\n"); +        for (int i = 0; i < PACKAGE_MAX; i++) { +            if (packages[i] == NULL) { +                break; +            } + +            // Install a package to test things out +            char *match = NULL; +            char *package = NULL; +            if ((match = find_package(packages[i])) == NULL) { +                fprintf(SYSERROR); +                exit(1); +            } +            if ((package = basename(match)) == NULL) { +                fprintf(stderr, "Unable to derive package name from package path:\n\t-> %s\n", match); +                exit(1); +            } + +            if (dep_all(&deps, package) < 0) { +                dep_free(&deps); +                free_global_config(); +                exit(1); +            } +        } +        dep_show(&deps); + +        printf("Installing package requirements:\n"); +        for (int i = 0; i < deps->records; i++) { +            printf("  -> %s\n", deps->list[i]); +            if (install(root, deps->list[i]) < 0) { +                fprintf(SYSERROR); +                exit(errno); +            } +        } + + +        printf("Installing package:\n"); +        for (int i = 0; i < PACKAGE_MAX; i++) { +            if (!packages[i]) { +                break; +            } + +            char *match = find_package(packages[i]); +            char *package = basename(match); + +            // If the package was already installed as a requirement of another dependency, skip it +            if (dep_seen(&deps, package)) { +                continue; +            } + +            printf("  -> %s\n", package); +            if (install(root, packages[i]) < 0) { +                fprintf(SYSERROR); +                exit(errno); +            } +            free(match); +        } +        dep_free(&deps); +    }      free_global_config();      return 0;  } diff --git a/src/strings.c b/src/strings.c index ad784d1..87d2eca 100644 --- a/src/strings.c +++ b/src/strings.c @@ -21,12 +21,15 @@ int num_chars(const char *sptr, int ch) {   *   * @param sptr string to scan   * @param pattern string to search for - * @return 0 = success, -1 = failure + * @return 0 = found, 1 = not found, -1 = error   */  int startswith(const char *sptr, const char *pattern) { +    if (!sptr) { +        return -1; +    }      for (size_t i = 0; i < strlen(pattern); i++) {          if (sptr[i] != pattern[i]) { -            return -1; +            return 1;          }      }      return 0; @@ -37,14 +40,17 @@ int startswith(const char *sptr, const char *pattern) {   *   * @param sptr string to scan   * @param pattern string to search for - * @return 0 = success, -1 = failure + * @return 0 = found, 1 = not found, -1 = error   */  int endswith(const char *sptr, const char *pattern) { +    if (!sptr) { +        return -1; +    }      size_t sptr_size = strlen(sptr);      size_t pattern_size = strlen(pattern);      for (size_t s = sptr_size - pattern_size, p = 0 ; s < sptr_size; s++, p++) {          if (sptr[s] != pattern[p]) { -            return -1; +            return 1;          }      }      return 0; | 
