diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/omc_indexer.c | 208 | 
1 files changed, 170 insertions, 38 deletions
| diff --git a/src/omc_indexer.c b/src/omc_indexer.c index 054a729..ebf3ba6 100644 --- a/src/omc_indexer.c +++ b/src/omc_indexer.c @@ -142,6 +142,7 @@ int indexer_get_files(struct StrList **out, const char *path, const char *patter      if (!(*out)) {          (*out) = strlist_init();          if (!(*out)) { +            guard_strlist_free(&list);              return -1;          }      } @@ -158,21 +159,45 @@ int indexer_get_files(struct StrList **out, const char *path, const char *patter      }      if (no_match >= strlist_count(list)) {          fprintf(stderr, "no files matching the pattern: %s\n", userpattern); +        guard_strlist_free(&list);          return -1;      } +    guard_strlist_free(&list);      return 0;  }  int get_latest_rc(struct Delivery ctx[], size_t nelem) {      int result = 0;      for (size_t i = 0; i < nelem; i++) { -        if (ctx[i].meta.rc > result) { +        if (&ctx[i] && ctx[i].meta.rc > result) {              result = ctx[i].meta.rc;          }      }      return result;  } +struct Delivery **get_latest_deliveries(struct Delivery ctx[], size_t nelem) { +    struct Delivery **result = NULL; +    int latest = 0; +    size_t n = 0; + +    result = calloc(nelem + 1, sizeof(result)); +    if (!result) { +        fprintf(stderr, "Unable to allocate %zu bytes for result delivery array: %s\n", nelem * sizeof(result), strerror(errno)); +        return NULL; +    } + +    latest = get_latest_rc(ctx, nelem); +    for (size_t i = 0; i < nelem; i++) { +        if (ctx[i].meta.rc == latest) { +            result[n] = &ctx[i]; +            n++; +        } +    } + +    return result; +} +  int micromamba(const char *write_to, const char *prefix, char *command, ...) {      struct utsname sys;      uname(&sys); @@ -239,62 +264,152 @@ int indexer_conda(struct Delivery *ctx) {      return status;  } -int indexer_readmes(struct Delivery ctx[], size_t nelem) { -    // Find unique architecture identifiers +static struct StrList *get_architectures(struct Delivery ctx[], size_t nelem) {      struct StrList *architectures = strlist_init();      for (size_t i = 0; i < nelem; i++) {          if (!strstr_array(architectures->data, ctx[i].system.arch)) {              strlist_append(&architectures, ctx[i].system.arch);          }      } +    return architectures; +} -    // Find unique platform identifiers +static struct StrList *get_platforms(struct Delivery ctx[], size_t nelem) {      struct StrList *platforms = strlist_init();      for (size_t i = 0; i < nelem; i++) {          if (!strstr_array(platforms->data, ctx[i].system.platform[DELIVERY_PLATFORM_RELEASE])) {              strlist_append(&platforms, ctx[i].system.platform[DELIVERY_PLATFORM_RELEASE]);          }      } +    return platforms; +} -    struct StrList *python_versions = strlist_init(); -    for (size_t i = 0; i < nelem; i++) { -        if (!strstr_array(python_versions->data, ctx[i].meta.python_compact)) { -            strlist_append(&python_versions, ctx[i].meta.python_compact); -        } -    } -    strlist_reverse(python_versions); +int indexer_symlinks(struct Delivery ctx[], size_t nelem) { +    struct Delivery **data = NULL; +    data = get_latest_deliveries(ctx, nelem); +    //int latest = get_latest_rc(ctx, nelem); + +    if (!pushd(ctx->storage.delivery_dir)) { +        for (size_t i = 0; i < nelem; i++) { +            char link_name_spec[PATH_MAX]; +            char link_name_readme[PATH_MAX]; + +            char file_name_spec[PATH_MAX]; +            char file_name_readme[PATH_MAX]; + +            if (!data[i]) { +                continue; +            } +            sprintf(link_name_spec, "latest-py%s-%s-%s.yml", data[i]->meta.python_compact, data[i]->system.platform[DELIVERY_PLATFORM_RELEASE], data[i]->system.arch); +            sprintf(file_name_spec, "%s.yml", data[i]->info.release_name); + +            sprintf(link_name_readme, "README-py%s-%s-%s.md", data[i]->meta.python_compact, data[i]->system.platform[DELIVERY_PLATFORM_RELEASE], data[i]->system.arch); +            sprintf(file_name_readme, "README-%s.md", data[i]->info.release_name); -    FILE *indexfp; -    char readmefile[PATH_MAX] = {0}; -    sprintf(readmefile, "%s/README.md", ctx->storage.delivery_dir); +            if (!access(link_name_spec, F_OK)) { +                if (unlink(link_name_spec)) { +                    fprintf(stderr, "Unable to remove spec link: %s\n", link_name_spec); +                } +            } +            if (!access(link_name_readme, F_OK)) { +                if (unlink(link_name_readme)) { +                    fprintf(stderr, "Unable to remove readme link: %s\n", link_name_readme); +                } +            } -    indexfp = fopen(readmefile, "w+"); -    if (!indexfp) { -        fprintf(stderr, "Unable to open %s for writing\n", readmefile); +            if (globals.verbose) { +                printf("%s -> %s\n", file_name_spec, link_name_spec); +            } +            if (symlink(file_name_spec, link_name_spec)) { +                fprintf(stderr, "Unable to link %s as %s\n", file_name_spec, link_name_spec); +            } + +            if (globals.verbose) { +                printf("%s -> %s\n", file_name_readme, link_name_readme); +            } +            if (symlink(file_name_readme, link_name_readme)) { +                fprintf(stderr, "Unable to link %s as %s\n", file_name_readme, link_name_readme); +            } +        } +        popd(); +    } else { +        fprintf(stderr, "Unable to enter delivery directory: %s\n", ctx->storage.delivery_dir); +        guard_free(data);          return -1;      } -    fprintf(indexfp, "# %s %s\n", ctx->meta.name, ctx->meta.version); -    int latest = get_latest_rc(ctx, nelem); -    for (size_t i = 0; i < strlist_count(python_versions); i++) { -        struct StrList *files = NULL; -        char *python_version = strlist_item(python_versions, i); -        fprintf(indexfp, "## py%s\n", python_version); -        if (indexer_get_files(&files, ctx->storage.delivery_dir, "README-*-%d-*py%s*.md", latest, python_version)) { -            fprintf(stderr, "Unable to list directory\n"); +    // "latest" is an array of pointers to ctx[]. Do not free the contents of the array. +    guard_free(data); +    return 0; +} + +int indexer_readmes(struct Delivery ctx[], size_t nelem) { +    struct Delivery **latest = NULL; +    latest = get_latest_deliveries(ctx, nelem); + +    char indexfile[PATH_MAX] = {0}; +    sprintf(indexfile, "%s/README.md", ctx->storage.delivery_dir); + +    if (!pushd(ctx->storage.delivery_dir)) { +        FILE *indexfp; +        indexfp = fopen(indexfile, "w+"); +        if (!indexfp) { +            fprintf(stderr, "Unable to open %s for writing\n", indexfile);              return -1;          } -        for (size_t x = 0; x < strlist_count(files); x++) { -            char *fname = strlist_item(files, x); -            if (globals.verbose) { -                puts(fname); +        struct StrList *archs = get_architectures(*latest, nelem); +        struct StrList *platforms = get_platforms(*latest, nelem); + +        fprintf(indexfp, "# %s-%s\n\n", ctx->meta.name, ctx->meta.version); +        for (size_t p = 0; p < strlist_count(platforms); p++) { +            char *platform = strlist_item(platforms, p); +            for (size_t a = 0; a < strlist_count(archs); a++) { +                char *arch = strlist_item(archs, a); +                int have_combo = 0; +                for (size_t i = 0; i < nelem; i++) { +                    if (strstr(latest[i]->system.platform[DELIVERY_PLATFORM_RELEASE], platform) && strstr(latest[i]->system.arch, arch)) { +                        have_combo = 1; +                    } +                } +                if (!have_combo) { +                    continue; +                } +                fprintf(indexfp, "## %s-%s\n\n", platform, arch); + +                fprintf(indexfp, "|Release|Info|Receipt|\n"); +                fprintf(indexfp, "|----|----|----|\n"); +                for (size_t i = 0; i < nelem; i++) { +                    char link_name[PATH_MAX]; +                    char readme_name[PATH_MAX]; +                    char conf_name[PATH_MAX]; +                    char conf_name_relative[PATH_MAX]; +                    if (!latest[i]) { +                        continue; +                    } +                    sprintf(link_name, "latest-py%s-%s-%s.yml", latest[i]->meta.python_compact, latest[i]->system.platform[DELIVERY_PLATFORM_RELEASE], latest[i]->system.arch); +                    sprintf(readme_name, "README-py%s-%s-%s.md", latest[i]->meta.python_compact, latest[i]->system.platform[DELIVERY_PLATFORM_RELEASE], latest[i]->system.arch); +                    sprintf(conf_name, "%s.ini", latest[i]->info.release_name); +                    sprintf(conf_name_relative, "../config/%s-rendered.ini", latest[i]->info.release_name); +                    if (strstr(link_name, platform) && strstr(link_name, arch)) { +                        fprintf(indexfp, "|[%s](%s)|[%s](%s)|[%s](%s)|\n", link_name, link_name, readme_name, readme_name, conf_name, conf_name_relative); +                    } +                } +                fprintf(indexfp, "\n");              } -            fprintf(indexfp, "- [%s](%s)\n", fname, fname); +            fprintf(indexfp, "\n");          } - -        guard_strlist_free(&files); +        guard_strlist_free(&archs); +        guard_strlist_free(&platforms); +        fclose(indexfp); +        popd(); +    } else { +        fprintf(stderr, "Unable to enter delivery directory: %s\n", ctx->storage.delivery_dir); +        guard_free(latest); +        return -1;      } -    fclose(indexfp); + +    // "latest" is an array of pointers to ctxs[]. Do not free the contents of the array. +    guard_free(latest);      return 0;  } @@ -353,6 +468,10 @@ int main(int argc, char *argv[]) {          }      } +    if (isempty(destdir)) { +        destdir = strdup("output"); +    } +      if (!rootdirs || !rootdirs_total) {          fprintf(stderr, "You must specify at least one OMC root directory to index\n");          exit(1); @@ -386,10 +505,14 @@ int main(int argc, char *argv[]) {      struct Delivery ctx;      memset(&ctx, 0, sizeof(ctx)); +    printf(BANNER, VERSION, AUTHOR); +      indexer_init_dirs(&ctx, workdir); -    msg(OMC_MSG_L1, "Merging delivery root %s\n", rootdirs_total > 1 ? "directories" : "directory"); -    if (indexer_combine_rootdirs(&ctx, workdir, rootdirs, rootdirs_total)) { +    msg(OMC_MSG_L1, "%s delivery root %s\n", +        rootdirs_total > 1 ? "Merging" : "Indexing", +        rootdirs_total > 1 ? "directories" : "directory"); +    if (indexer_combine_rootdirs(workdir, rootdirs, rootdirs_total)) {          SYSERROR("%s", "Copy operation failed");          rmtree(workdir);      } @@ -424,16 +547,22 @@ int main(int argc, char *argv[]) {          indexer_load_metadata(&local[i], path);      } -    msg(OMC_MSG_L1, "Indexing README files\n"); +    msg(OMC_MSG_L1, "Generating links to latest release iteration\n"); +    if (indexer_symlinks(local, strlist_count(metafiles))) { +        SYSERROR("%s", "Link generation failed"); +        exit(1); +    } + +    msg(OMC_MSG_L1, "Generating README.md\n");      if (indexer_readmes(local, strlist_count(metafiles))) { -        SYSERROR("%s", "README file indexing operation failed"); +        SYSERROR("%s", "README indexing operation failed");          exit(1);      }      msg(OMC_MSG_L1, "Copying indexed delivery to '%s'\n", destdir);      char cmd[PATH_MAX];      memset(cmd, 0, sizeof(cmd)); -    sprintf(cmd, "rsync -ah%s --delete --exclude 'tmp/' --exclude 'tools/' '%s/' '%s/'", globals.verbose ? "v" : "q", workdir, destdir); +    sprintf(cmd, "rsync -ah%s --delete --exclude 'tmp/' --exclude 'tools/' '%s/output/' '%s/'", globals.verbose ? "v" : "q", workdir, destdir);      guard_free(destdir);      if (globals.verbose) { @@ -451,6 +580,9 @@ int main(int argc, char *argv[]) {          SYSERROR("Failed to remove work directory: %s", strerror(errno));      } +    guard_strlist_free(&metafiles); +    delivery_free(&ctx); +    globals_free();      msg(OMC_MSG_L1, "Done!\n");      return 0;  }
\ No newline at end of file | 
