diff options
| -rw-r--r-- | cmd.c | 2 | ||||
| -rw-r--r-- | ui-snapshot.c | 94 | ||||
| -rw-r--r-- | ui-snapshot.h | 2 | 
3 files changed, 83 insertions, 15 deletions
| @@ -106,7 +106,7 @@ static void snapshot_fn(struct cgit_context *ctx)  {  	cgit_print_snapshot(ctx->qry.head, ctx->qry.sha1,  			    cgit_repobasename(ctx->repo->url), ctx->qry.path, -			    ctx->repo->snapshots); +			    ctx->repo->snapshots, ctx->qry.nohead);  }  static void summary_fn(struct cgit_context *ctx) diff --git a/ui-snapshot.c b/ui-snapshot.c index 7a597ff..9c4d086 100644 --- a/ui-snapshot.c +++ b/ui-snapshot.c @@ -64,6 +64,22 @@ const struct cgit_snapshot_format cgit_snapshot_formats[] = {  	{}  }; +static const struct cgit_snapshot_format *get_format(const char *filename) +{ +	const struct cgit_snapshot_format *fmt; +	int fl, sl; + +	fl = strlen(filename); +	for(fmt = cgit_snapshot_formats; fmt->suffix; fmt++) { +		sl = strlen(fmt->suffix); +		if (sl >= fl) +			continue; +		if (!strcmp(fmt->suffix, filename + fl - sl)) +			return fmt; +	} +	return NULL; +} +  static int make_snapshot(const struct cgit_snapshot_format *format,  			 const char *hex, const char *prefix,  			 const char *filename) @@ -98,23 +114,75 @@ static int make_snapshot(const struct cgit_snapshot_format *format,  	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. + */ +static const char *get_ref_from_filename(const char *url, const char *filename, +					 const struct cgit_snapshot_format *fmt) +{ +	const char *reponame = cgit_repobasename(url); +	fprintf(stderr, "reponame=%s, filename=%s\n", reponame, filename); +	if (prefixcmp(filename, reponame)) +		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, -			 const char *filename, int snapshots) +			 const char *filename, int snapshots, int dwim)  {  	const struct cgit_snapshot_format* f; -	int sl, fnl; -	fnl = strlen(filename); -	if (!hex) -		hex = head; -	for (f = cgit_snapshot_formats; f->suffix; f++) { -		if (!(snapshots & f->bit)) -			continue; -		sl = strlen(f->suffix); -		if(fnl < sl || strcmp(&filename[fnl-sl], f->suffix)) -			continue; -		make_snapshot(f, hex, prefix, filename); +	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;  	} -	cgit_print_error(fmt("Unsupported snapshot format: %s", filename)); + +	if (!hex && dwim) +		hex = get_ref_from_filename(ctx.repo->url, filename, f); + +	if (!hex) +		hex = head; + +	make_snapshot(f, hex, prefix, filename);  } diff --git a/ui-snapshot.h b/ui-snapshot.h index 6e03761..3540303 100644 --- a/ui-snapshot.h +++ b/ui-snapshot.h @@ -3,6 +3,6 @@  extern void cgit_print_snapshot(const char *head, const char *hex,  				const char *prefix, const char *filename, -				int snapshot); +				int snapshot, int dwim);  #endif /* UI_SNAPSHOT_H */ | 
