diff options
| -rw-r--r-- | cgit.c | 3 | ||||
| -rw-r--r-- | cgit.h | 5 | ||||
| -rw-r--r-- | cgitrc.5.txt | 17 | ||||
| -rw-r--r-- | shared.c | 8 | ||||
| -rwxr-xr-x | tests/setup.sh | 1 | ||||
| -rwxr-xr-x | tests/t0102-summary.sh | 6 | ||||
| -rw-r--r-- | ui-commit.c | 6 | ||||
| -rw-r--r-- | ui-repolist.c | 2 | ||||
| -rw-r--r-- | ui-snapshot.c | 2 | ||||
| -rw-r--r-- | ui-summary.c | 4 | ||||
| -rw-r--r-- | ui-tree.c | 2 |
11 files changed, 40 insertions, 16 deletions
| @@ -244,6 +244,8 @@ void config_cb(const char *name, const char *value) | |||
| 244 | ctx.cfg.robots = xstrdup(value); | 244 | ctx.cfg.robots = xstrdup(value); |
| 245 | else if (!strcmp(name, "clone-prefix")) | 245 | else if (!strcmp(name, "clone-prefix")) |
| 246 | ctx.cfg.clone_prefix = xstrdup(value); | 246 | ctx.cfg.clone_prefix = xstrdup(value); |
| 247 | else if (!strcmp(name, "clone-url")) | ||
| 248 | ctx.cfg.clone_url = xstrdup(value); | ||
| 247 | else if (!strcmp(name, "local-time")) | 249 | else if (!strcmp(name, "local-time")) |
| 248 | ctx.cfg.local_time = atoi(value); | 250 | ctx.cfg.local_time = atoi(value); |
| 249 | else if (!prefixcmp(name, "mimetype.")) | 251 | else if (!prefixcmp(name, "mimetype.")) |
| @@ -463,6 +465,7 @@ static int prepare_repo_cmd(struct cgit_context *ctx) | |||
| 463 | cgit_print_docend(); | 465 | cgit_print_docend(); |
| 464 | return 1; | 466 | return 1; |
| 465 | } | 467 | } |
| 468 | cgit_prepare_repo_env(ctx->repo); | ||
| 466 | return 0; | 469 | return 0; |
| 467 | } | 470 | } |
| 468 | 471 | ||
| @@ -165,6 +165,7 @@ struct cgit_config { | |||
| 165 | char *agefile; | 165 | char *agefile; |
| 166 | char *cache_root; | 166 | char *cache_root; |
| 167 | char *clone_prefix; | 167 | char *clone_prefix; |
| 168 | char *clone_url; | ||
| 168 | char *css; | 169 | char *css; |
| 169 | char *favicon; | 170 | char *favicon; |
| 170 | char *footer; | 171 | char *footer; |
| @@ -319,9 +320,11 @@ extern const char *cgit_repobasename(const char *reponame); | |||
| 319 | 320 | ||
| 320 | extern int cgit_parse_snapshots_mask(const char *str); | 321 | extern int cgit_parse_snapshots_mask(const char *str); |
| 321 | 322 | ||
| 322 | extern int cgit_open_filter(struct cgit_filter *filter, struct cgit_repo * repo); | 323 | extern int cgit_open_filter(struct cgit_filter *filter); |
| 323 | extern int cgit_close_filter(struct cgit_filter *filter); | 324 | extern int cgit_close_filter(struct cgit_filter *filter); |
| 324 | 325 | ||
| 326 | extern void cgit_prepare_repo_env(struct cgit_repo * repo); | ||
| 327 | |||
| 325 | extern int readfile(const char *path, char **buf, size_t *size); | 328 | extern int readfile(const char *path, char **buf, size_t *size); |
| 326 | 329 | ||
| 327 | extern char *expand_macros(const char *txt); | 330 | extern char *expand_macros(const char *txt); |
diff --git a/cgitrc.5.txt b/cgitrc.5.txt index 9a9965b..5ba8134 100644 --- a/cgitrc.5.txt +++ b/cgitrc.5.txt | |||
| @@ -76,6 +76,11 @@ clone-prefix:: | |||
| 76 | setting is only used if `repo.clone-url` is unspecified. Default value: | 76 | setting is only used if `repo.clone-url` is unspecified. Default value: |
| 77 | none. | 77 | none. |
| 78 | 78 | ||
| 79 | clone-url:: | ||
| 80 | Space-separated list of clone-url templates. This setting is only | ||
| 81 | used if `repo.clone-url` is unspecified. Default value: none. See | ||
| 82 | also: "MACRO EXPANSION", "FILTER API". | ||
| 83 | |||
| 79 | commit-filter:: | 84 | commit-filter:: |
| 80 | Specifies a command which will be invoked to format commit messages. | 85 | Specifies a command which will be invoked to format commit messages. |
| 81 | The command will get the message on its STDIN, and the STDOUT from the | 86 | The command will get the message on its STDIN, and the STDOUT from the |
| @@ -363,7 +368,7 @@ repo.about-filter:: | |||
| 363 | 368 | ||
| 364 | repo.clone-url:: | 369 | repo.clone-url:: |
| 365 | A list of space-separated urls which can be used to clone this repo. | 370 | A list of space-separated urls which can be used to clone this repo. |
| 366 | Default value: none. | 371 | Default value: none. See also: "MACRO EXPANSION". |
| 367 | 372 | ||
| 368 | repo.commit-filter:: | 373 | repo.commit-filter:: |
| 369 | Override the default commit-filter. Default value: none. See also: | 374 | Override the default commit-filter. Default value: none. See also: |
| @@ -511,6 +516,12 @@ can be accomplished by adding the following line to /etc/cgitrc: | |||
| 511 | 516 | ||
| 512 | include=/etc/cgitrc.d/$HTTP_HOST | 517 | include=/etc/cgitrc.d/$HTTP_HOST |
| 513 | 518 | ||
| 519 | The following options are expanded during request processing, and support | ||
| 520 | the environment variables defined in "FILTER API": | ||
| 521 | |||
| 522 | - clone-url | ||
| 523 | - repo.clone-url | ||
| 524 | |||
| 514 | 525 | ||
| 515 | EXAMPLE CGITRC FILE | 526 | EXAMPLE CGITRC FILE |
| 516 | ------------------- | 527 | ------------------- |
| @@ -520,8 +531,8 @@ EXAMPLE CGITRC FILE | |||
| 520 | cache-size=1000 | 531 | cache-size=1000 |
| 521 | 532 | ||
| 522 | 533 | ||
| 523 | # Specify some default clone prefixes | 534 | # Specify some default clone urls using macro expansion |
| 524 | clone-prefix=git://example.com ssh://example.com/pub/git http://example.com/git | 535 | clone-url=git://foo.org/$CGIT_REPO_URL git@foo.org:$CGIT_REPO_URL |
| 525 | 536 | ||
| 526 | # Specify the css url | 537 | # Specify the css url |
| 527 | css=/css/cgit.css | 538 | css=/css/cgit.css |
| @@ -70,6 +70,7 @@ struct cgit_repo *cgit_add_repo(const char *url) | |||
| 70 | ret->about_filter = ctx.cfg.about_filter; | 70 | ret->about_filter = ctx.cfg.about_filter; |
| 71 | ret->commit_filter = ctx.cfg.commit_filter; | 71 | ret->commit_filter = ctx.cfg.commit_filter; |
| 72 | ret->source_filter = ctx.cfg.source_filter; | 72 | ret->source_filter = ctx.cfg.source_filter; |
| 73 | ret->clone_url = ctx.cfg.clone_url; | ||
| 73 | return ret; | 74 | return ret; |
| 74 | } | 75 | } |
| 75 | 76 | ||
| @@ -374,7 +375,8 @@ typedef struct { | |||
| 374 | char * value; | 375 | char * value; |
| 375 | } cgit_env_var; | 376 | } cgit_env_var; |
| 376 | 377 | ||
| 377 | static void prepare_env(struct cgit_repo * repo) { | 378 | void cgit_prepare_repo_env(struct cgit_repo * repo) |
| 379 | { | ||
| 378 | cgit_env_var env_vars[] = { | 380 | cgit_env_var env_vars[] = { |
| 379 | { .name = "CGIT_REPO_URL", .value = repo->url }, | 381 | { .name = "CGIT_REPO_URL", .value = repo->url }, |
| 380 | { .name = "CGIT_REPO_NAME", .value = repo->name }, | 382 | { .name = "CGIT_REPO_NAME", .value = repo->name }, |
| @@ -395,7 +397,7 @@ static void prepare_env(struct cgit_repo * repo) { | |||
| 395 | fprintf(stderr, warn, p->name, p->value); | 397 | fprintf(stderr, warn, p->name, p->value); |
| 396 | } | 398 | } |
| 397 | 399 | ||
| 398 | int cgit_open_filter(struct cgit_filter *filter, struct cgit_repo * repo) | 400 | int cgit_open_filter(struct cgit_filter *filter) |
| 399 | { | 401 | { |
| 400 | 402 | ||
| 401 | filter->old_stdout = chk_positive(dup(STDOUT_FILENO), | 403 | filter->old_stdout = chk_positive(dup(STDOUT_FILENO), |
| @@ -406,8 +408,6 @@ int cgit_open_filter(struct cgit_filter *filter, struct cgit_repo * repo) | |||
| 406 | close(filter->pipe_fh[1]); | 408 | close(filter->pipe_fh[1]); |
| 407 | chk_non_negative(dup2(filter->pipe_fh[0], STDIN_FILENO), | 409 | chk_non_negative(dup2(filter->pipe_fh[0], STDIN_FILENO), |
| 408 | "Unable to use pipe as STDIN"); | 410 | "Unable to use pipe as STDIN"); |
| 409 | if (repo) | ||
| 410 | prepare_env(repo); | ||
| 411 | execvp(filter->cmd, filter->argv); | 411 | execvp(filter->cmd, filter->argv); |
| 412 | die("Unable to exec subprocess %s: %s (%d)", filter->cmd, | 412 | die("Unable to exec subprocess %s: %s (%d)", filter->cmd, |
| 413 | strerror(errno), errno); | 413 | strerror(errno), errno); |
diff --git a/tests/setup.sh b/tests/setup.sh index b2f1169..1e06107 100755 --- a/tests/setup.sh +++ b/tests/setup.sh | |||
| @@ -62,6 +62,7 @@ enable-log-linecount=1 | |||
| 62 | summary-log=5 | 62 | summary-log=5 |
| 63 | summary-branches=5 | 63 | summary-branches=5 |
| 64 | summary-tags=5 | 64 | summary-tags=5 |
| 65 | clone-url=git://example.org/\$CGIT_REPO_URL.git | ||
| 65 | 66 | ||
| 66 | repo.url=foo | 67 | repo.url=foo |
| 67 | repo.path=$PWD/trash/repos/foo/.git | 68 | repo.path=$PWD/trash/repos/foo/.git |
diff --git a/tests/t0102-summary.sh b/tests/t0102-summary.sh index f0b0d9a..f299c5a 100755 --- a/tests/t0102-summary.sh +++ b/tests/t0102-summary.sh | |||
| @@ -9,6 +9,9 @@ run_test 'find commit 1' 'grep -e "commit 1" trash/tmp' | |||
| 9 | run_test 'find commit 5' 'grep -e "commit 5" trash/tmp' | 9 | run_test 'find commit 5' 'grep -e "commit 5" trash/tmp' |
| 10 | run_test 'find branch master' 'grep -e "master" trash/tmp' | 10 | run_test 'find branch master' 'grep -e "master" trash/tmp' |
| 11 | run_test 'no tags' '! grep -e "tags" trash/tmp' | 11 | run_test 'no tags' '! grep -e "tags" trash/tmp' |
| 12 | run_test 'clone-url expanded correctly' ' | ||
| 13 | grep -e "git://example.org/foo.git" trash/tmp | ||
| 14 | ' | ||
| 12 | 15 | ||
| 13 | run_test 'generate bar summary' 'cgit_url "bar" >trash/tmp' | 16 | run_test 'generate bar summary' 'cgit_url "bar" >trash/tmp' |
| 14 | run_test 'no commit 45' '! grep -e "commit 45" trash/tmp' | 17 | run_test 'no commit 45' '! grep -e "commit 45" trash/tmp' |
| @@ -16,5 +19,8 @@ run_test 'find commit 46' 'grep -e "commit 46" trash/tmp' | |||
| 16 | run_test 'find commit 50' 'grep -e "commit 50" trash/tmp' | 19 | run_test 'find commit 50' 'grep -e "commit 50" trash/tmp' |
| 17 | run_test 'find branch master' 'grep -e "master" trash/tmp' | 20 | run_test 'find branch master' 'grep -e "master" trash/tmp' |
| 18 | run_test 'no tags' '! grep -e "tags" trash/tmp' | 21 | run_test 'no tags' '! grep -e "tags" trash/tmp' |
| 22 | run_test 'clone-url expanded correctly' ' | ||
| 23 | grep -e "git://example.org/bar.git" trash/tmp | ||
| 24 | ' | ||
| 19 | 25 | ||
| 20 | tests_done | 26 | tests_done |
diff --git a/ui-commit.c b/ui-commit.c index a69dec6..536a8e8 100644 --- a/ui-commit.c +++ b/ui-commit.c | |||
| @@ -106,7 +106,7 @@ void cgit_print_commit(char *hex, const char *prefix) | |||
| 106 | html("</table>\n"); | 106 | html("</table>\n"); |
| 107 | html("<div class='commit-subject'>"); | 107 | html("<div class='commit-subject'>"); |
| 108 | if (ctx.repo->commit_filter) | 108 | if (ctx.repo->commit_filter) |
| 109 | cgit_open_filter(ctx.repo->commit_filter, ctx.repo); | 109 | cgit_open_filter(ctx.repo->commit_filter); |
| 110 | html_txt(info->subject); | 110 | html_txt(info->subject); |
| 111 | if (ctx.repo->commit_filter) | 111 | if (ctx.repo->commit_filter) |
| 112 | cgit_close_filter(ctx.repo->commit_filter); | 112 | cgit_close_filter(ctx.repo->commit_filter); |
| @@ -114,7 +114,7 @@ void cgit_print_commit(char *hex, const char *prefix) | |||
| 114 | html("</div>"); | 114 | html("</div>"); |
| 115 | html("<div class='commit-msg'>"); | 115 | html("<div class='commit-msg'>"); |
| 116 | if (ctx.repo->commit_filter) | 116 | if (ctx.repo->commit_filter) |
| 117 | cgit_open_filter(ctx.repo->commit_filter, ctx.repo); | 117 | cgit_open_filter(ctx.repo->commit_filter); |
| 118 | html_txt(info->msg); | 118 | html_txt(info->msg); |
| 119 | if (ctx.repo->commit_filter) | 119 | if (ctx.repo->commit_filter) |
| 120 | cgit_close_filter(ctx.repo->commit_filter); | 120 | cgit_close_filter(ctx.repo->commit_filter); |
| @@ -123,7 +123,7 @@ void cgit_print_commit(char *hex, const char *prefix) | |||
| 123 | html("<div class='notes-header'>Notes</div>"); | 123 | html("<div class='notes-header'>Notes</div>"); |
| 124 | html("<div class='notes'>"); | 124 | html("<div class='notes'>"); |
| 125 | if (ctx.repo->commit_filter) | 125 | if (ctx.repo->commit_filter) |
| 126 | cgit_open_filter(ctx.repo->commit_filter, ctx.repo); | 126 | cgit_open_filter(ctx.repo->commit_filter); |
| 127 | html_txt(notes.buf); | 127 | html_txt(notes.buf); |
| 128 | if (ctx.repo->commit_filter) | 128 | if (ctx.repo->commit_filter) |
| 129 | cgit_close_filter(ctx.repo->commit_filter); | 129 | cgit_close_filter(ctx.repo->commit_filter); |
diff --git a/ui-repolist.c b/ui-repolist.c index dce2eac..25c36ce 100644 --- a/ui-repolist.c +++ b/ui-repolist.c | |||
| @@ -300,7 +300,7 @@ void cgit_print_site_readme() | |||
| 300 | if (!ctx.cfg.root_readme) | 300 | if (!ctx.cfg.root_readme) |
| 301 | return; | 301 | return; |
| 302 | if (ctx.cfg.about_filter) | 302 | if (ctx.cfg.about_filter) |
| 303 | cgit_open_filter(ctx.cfg.about_filter, NULL); | 303 | cgit_open_filter(ctx.cfg.about_filter); |
| 304 | html_include(ctx.cfg.root_readme); | 304 | html_include(ctx.cfg.root_readme); |
| 305 | if (ctx.cfg.about_filter) | 305 | if (ctx.cfg.about_filter) |
| 306 | cgit_close_filter(ctx.cfg.about_filter); | 306 | cgit_close_filter(ctx.cfg.about_filter); |
diff --git a/ui-snapshot.c b/ui-snapshot.c index 126779d..07cc944 100644 --- a/ui-snapshot.c +++ b/ui-snapshot.c | |||
| @@ -19,7 +19,7 @@ static int write_compressed_tar_archive(struct archiver_args *args,const char *f | |||
| 19 | f.argv = malloc(2 * sizeof(char *)); | 19 | f.argv = malloc(2 * sizeof(char *)); |
| 20 | f.argv[0] = f.cmd; | 20 | f.argv[0] = f.cmd; |
| 21 | f.argv[1] = NULL; | 21 | f.argv[1] = NULL; |
| 22 | cgit_open_filter(&f, NULL); | 22 | cgit_open_filter(&f); |
| 23 | rv = write_tar_archive(args); | 23 | rv = write_tar_archive(args); |
| 24 | cgit_close_filter(&f); | 24 | cgit_close_filter(&f); |
| 25 | return rv; | 25 | return rv; |
diff --git a/ui-summary.c b/ui-summary.c index 1e9a1b6..227ed27 100644 --- a/ui-summary.c +++ b/ui-summary.c | |||
| @@ -62,7 +62,7 @@ void cgit_print_summary() | |||
| 62 | NULL, NULL, 0, 0); | 62 | NULL, NULL, 0, 0); |
| 63 | } | 63 | } |
| 64 | if (ctx.repo->clone_url) | 64 | if (ctx.repo->clone_url) |
| 65 | print_urls(ctx.repo->clone_url, NULL); | 65 | print_urls(expand_macros(ctx.repo->clone_url), NULL); |
| 66 | else if (ctx.cfg.clone_prefix) | 66 | else if (ctx.cfg.clone_prefix) |
| 67 | print_urls(ctx.cfg.clone_prefix, ctx.repo->url); | 67 | print_urls(ctx.cfg.clone_prefix, ctx.repo->url); |
| 68 | html("</table>"); | 68 | html("</table>"); |
| @@ -113,7 +113,7 @@ void cgit_print_repo_readme(char *path) | |||
| 113 | */ | 113 | */ |
| 114 | html("<div id='summary'>"); | 114 | html("<div id='summary'>"); |
| 115 | if (ctx.repo->about_filter) | 115 | if (ctx.repo->about_filter) |
| 116 | cgit_open_filter(ctx.repo->about_filter, ctx.repo); | 116 | cgit_open_filter(ctx.repo->about_filter); |
| 117 | if (ref) | 117 | if (ref) |
| 118 | cgit_print_file(tmp, ref); | 118 | cgit_print_file(tmp, ref); |
| 119 | else | 119 | else |
| @@ -45,7 +45,7 @@ static void print_text_buffer(const char *name, char *buf, unsigned long size) | |||
| 45 | if (ctx.repo->source_filter) { | 45 | if (ctx.repo->source_filter) { |
| 46 | html("<td class='lines'><pre><code>"); | 46 | html("<td class='lines'><pre><code>"); |
| 47 | ctx.repo->source_filter->argv[1] = xstrdup(name); | 47 | ctx.repo->source_filter->argv[1] = xstrdup(name); |
| 48 | cgit_open_filter(ctx.repo->source_filter, ctx.repo); | 48 | cgit_open_filter(ctx.repo->source_filter); |
| 49 | html_raw(buf, size); | 49 | html_raw(buf, size); |
| 50 | cgit_close_filter(ctx.repo->source_filter); | 50 | cgit_close_filter(ctx.repo->source_filter); |
| 51 | free(ctx.repo->source_filter->argv[1]); | 51 | free(ctx.repo->source_filter->argv[1]); |
