-rw-r--r-- | ui-snapshot.c | 92 |
1 files changed, 48 insertions, 44 deletions
diff --git a/ui-snapshot.c b/ui-snapshot.c index 9c4d086..6f09151 100644 --- a/ui-snapshot.c +++ b/ui-snapshot.c @@ -101,88 +101,92 @@ static int make_snapshot(const struct cgit_snapshot_format *format, if (prefix) { args.base = fmt("%s/", prefix); args.baselen = strlen(prefix) + 1; } else { args.base = ""; args.baselen = 0; } args.tree = commit->tree; args.time = commit->date; ctx.page.mimetype = xstrdup(format->mimetype); ctx.page.filename = xstrdup(filename); cgit_print_http_headers(&ctx); format->write_func(&args); return 0; } -char *dwim_filename = NULL; -const char *dwim_refname = NULL; - -static int ref_cb(const char *refname, const unsigned char *sha1, int flags, - void *cb_data) -{ - const char *r = refname; - while (r && *r) { - fprintf(stderr, " cmp %s with %s:", dwim_filename, r); - if (!strcmp(dwim_filename, r)) { - fprintf(stderr, "MATCH!\n"); - dwim_refname = refname; - return 1; - } - fprintf(stderr, "no match\n"); - if (isdigit(*r)) - break; - r++; - } - return 0; -} - -/* Try to guess the requested revision by combining repo name and tag name - * and comparing this to the requested snapshot name. E.g. the requested - * snapshot is "cgit-0.7.2.tar.gz" while repo name is "cgit" and tag name - * is "v0.7.2". First, the reponame is stripped off, leaving "-0.7.2.tar.gz". - * Next, any '-' and '_' characters are stripped, leaving "0.7.2.tar.gz". - * Finally, the requested format suffix is removed and we end up with "0.7.2". - * Then we test each tag against this dwimmed filename, and for each tag - * we even try to remove any leading characters which are non-digits. I.e. - * we first compare with "v0.7.2", then with "0.7.2" and we've got a match. +/* Try to guess the requested revision from the requested snapshot name. + * First the format extension is stripped, e.g. "cgit-0.7.2.tar.gz" become + * "cgit-0.7.2". If this is a valid commit object name we've got a winner. + * Otherwise, if the snapshot name has a prefix matching the result from + * repo_basename(), we strip the basename and any following '-' and '_' + * characters ("cgit-0.7.2" -> "0.7.2") and check the resulting name once + * more. If this still isn't a valid commit object name, we check if pre- + * pending a 'v' to the remaining snapshot name ("0.7.2" -> "v0.7.2") gives + * us something valid. */ static const char *get_ref_from_filename(const char *url, const char *filename, - const struct cgit_snapshot_format *fmt) + const struct cgit_snapshot_format *format) { - const char *reponame = cgit_repobasename(url); - fprintf(stderr, "reponame=%s, filename=%s\n", reponame, filename); - if (prefixcmp(filename, reponame)) + const char *reponame; + unsigned char sha1[20]; + char *snapshot; + + snapshot = xstrdup(filename); + snapshot[strlen(snapshot) - strlen(format->suffix)] = '\0'; + fprintf(stderr, "snapshot=%s\n", snapshot); + + if (get_sha1(snapshot, sha1) == 0) + return snapshot; + + reponame = cgit_repobasename(url); + fprintf(stderr, "reponame=%s\n", reponame); + if (prefixcmp(snapshot, reponame) == 0) { + snapshot += strlen(reponame); + while (snapshot && (*snapshot == '-' || *snapshot == '_')) + snapshot++; + } + + if (get_sha1(snapshot, sha1) == 0) + return snapshot; + + snapshot = fmt("v%s", snapshot); + if (get_sha1(snapshot, sha1) == 0) + return snapshot; + return NULL; - filename += strlen(reponame); - while (filename && (*filename == '-' || *filename == '_')) - filename++; - dwim_filename = xstrdup(filename); - dwim_filename[strlen(filename) - strlen(fmt->suffix)] = '\0'; - for_each_tag_ref(ref_cb, NULL); - return dwim_refname; } -void cgit_print_snapshot(const char *head, const char *hex, const char *prefix, +void cgit_print_snapshot(const char *head, const char *hex, const char *filename, int snapshots, int dwim) { const struct cgit_snapshot_format* f; + char *prefix = NULL; f = get_format(filename); if (!f) { ctx.page.mimetype = "text/html"; cgit_print_http_headers(&ctx); cgit_print_docstart(&ctx); cgit_print_pageheader(&ctx); cgit_print_error(fmt("Unsupported snapshot format: %s", filename)); cgit_print_docend(); return; } - if (!hex && dwim) + if (!hex && dwim) { hex = get_ref_from_filename(ctx.repo->url, filename, f); + if (hex != NULL) { + prefix = xstrdup(filename); + prefix[strlen(filename) - strlen(f->suffix)] = '\0'; + } + } if (!hex) hex = head; + if (!prefix) + prefix = xstrdup(cgit_repobasename(ctx.repo->url)); + make_snapshot(f, hex, prefix, filename); + free(prefix); } |