Add support for 'project-list' option

This option specifies the location of a projectlist file as used by
gitweb - when 'scan-tree' is later specified, only the projects listed in
the projectlist file will be added.

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Signed-off-by: Lars Hjemli <hjemli@gmail.com>
This commit is contained in:
Jason A. Donenfeld 2010-07-29 17:52:29 +02:00 committed by Lars Hjemli
parent f914317126
commit 3516502aa0
5 changed files with 70 additions and 8 deletions

27
cgit.c
View File

@ -181,9 +181,14 @@ void config_cb(const char *name, const char *value)
ctx.cfg.max_repo_count = atoi(value); ctx.cfg.max_repo_count = atoi(value);
else if (!strcmp(name, "max-commit-count")) else if (!strcmp(name, "max-commit-count"))
ctx.cfg.max_commit_count = atoi(value); ctx.cfg.max_commit_count = atoi(value);
else if (!strcmp(name, "project-list"))
ctx.cfg.project_list = xstrdup(expand_macros(value));
else if (!strcmp(name, "scan-path")) else if (!strcmp(name, "scan-path"))
if (!ctx.cfg.nocache && ctx.cfg.cache_size) if (!ctx.cfg.nocache && ctx.cfg.cache_size)
process_cached_repolist(expand_macros(value)); process_cached_repolist(expand_macros(value));
else if (ctx.cfg.project_list)
scan_projects(expand_macros(value),
ctx.cfg.project_list, repo_config);
else else
scan_tree(expand_macros(value), repo_config); scan_tree(expand_macros(value), repo_config);
else if (!strcmp(name, "source-filter")) else if (!strcmp(name, "source-filter"))
@ -295,6 +300,7 @@ static void prepare_context(struct cgit_context *ctx)
ctx->cfg.max_blob_size = 0; ctx->cfg.max_blob_size = 0;
ctx->cfg.max_stats = 0; ctx->cfg.max_stats = 0;
ctx->cfg.module_link = "./?repo=%s&page=commit&id=%s"; ctx->cfg.module_link = "./?repo=%s&page=commit&id=%s";
ctx->cfg.project_list = NULL;
ctx->cfg.renamelimit = -1; ctx->cfg.renamelimit = -1;
ctx->cfg.robots = "index, nofollow"; ctx->cfg.robots = "index, nofollow";
ctx->cfg.root_title = "Git repository browser"; ctx->cfg.root_title = "Git repository browser";
@ -574,7 +580,10 @@ static int generate_cached_repolist(const char *path, const char *cached_rc)
return errno; return errno;
} }
idx = cgit_repolist.count; idx = cgit_repolist.count;
scan_tree(path, repo_config); if (ctx.cfg.project_list)
scan_projects(path, ctx.cfg.project_list, repo_config);
else
scan_tree(path, repo_config);
print_repolist(f, &cgit_repolist, idx); print_repolist(f, &cgit_repolist, idx);
if (rename(locked_rc, cached_rc)) if (rename(locked_rc, cached_rc))
fprintf(stderr, "[cgit] Error renaming %s to %s: %s (%d)\n", fprintf(stderr, "[cgit] Error renaming %s to %s: %s (%d)\n",
@ -588,17 +597,25 @@ static void process_cached_repolist(const char *path)
struct stat st; struct stat st;
char *cached_rc; char *cached_rc;
time_t age; time_t age;
unsigned long hash;
cached_rc = xstrdup(fmt("%s/rc-%8x", ctx.cfg.cache_root, hash = hash_str(path);
hash_str(path))); if (ctx.cfg.project_list)
hash += hash_str(ctx.cfg.project_list);
cached_rc = xstrdup(fmt("%s/rc-%8x", ctx.cfg.cache_root, hash));
if (stat(cached_rc, &st)) { if (stat(cached_rc, &st)) {
/* Nothing is cached, we need to scan without forking. And /* Nothing is cached, we need to scan without forking. And
* if we fail to generate a cached repolist, we need to * if we fail to generate a cached repolist, we need to
* invoke scan_tree manually. * invoke scan_tree manually.
*/ */
if (generate_cached_repolist(path, cached_rc)) if (generate_cached_repolist(path, cached_rc)) {
scan_tree(path, repo_config); if (ctx.cfg.project_list)
scan_projects(path, ctx.cfg.project_list,
repo_config);
else
scan_tree(path, repo_config);
}
return; return;
} }

1
cgit.h
View File

@ -166,6 +166,7 @@ struct cgit_config {
char *logo; char *logo;
char *logo_link; char *logo_link;
char *module_link; char *module_link;
char *project_list;
char *robots; char *robots;
char *root_title; char *root_title;
char *root_desc; char *root_desc;

View File

@ -224,6 +224,11 @@ noheader::
Flag which, when set to "1", will make cgit omit the standard header Flag which, when set to "1", will make cgit omit the standard header
on all pages. Default value: none. See also: "embedded". on all pages. Default value: none. See also: "embedded".
project-list::
A list of subdirectories inside of scan-path, relative to it, that
should loaded as git repositories. This must be defined prior to
scan-path. Default value: none. See also: scan-path.
renamelimit:: renamelimit::
Maximum number of files to consider when detecting renames. The value Maximum number of files to consider when detecting renames. The value
"-1" uses the compiletime value in git (for further info, look at "-1" uses the compiletime value in git (for further info, look at
@ -253,7 +258,10 @@ root-title::
scan-path:: scan-path::
A path which will be scanned for repositories. If caching is enabled, A path which will be scanned for repositories. If caching is enabled,
the result will be cached as a cgitrc include-file in the cache the result will be cached as a cgitrc include-file in the cache
directory. Default value: none. See also: cache-scanrc-ttl. directory. If project-list has been defined prior to scan-path,
scan-path loads only the directories listed in the file pointed to by
project-list. Default value: none. See also: cache-scanrc-ttl,
project-list.
section:: section::
The name of the current repository section - all repositories defined The name of the current repository section - all repositories defined

View File

@ -1,3 +1,12 @@
/* scan-tree.c
*
* Copyright (C) 2008-2009 Lars Hjemli
* Copyright (C) 2010 Jason A. Donenfeld <Jason@zx2c4.com>
*
* Licensed under GNU General Public License v2
* (see COPYING for full license text)
*/
#include "cgit.h" #include "cgit.h"
#include "configfile.h" #include "configfile.h"
#include "html.h" #include "html.h"
@ -142,6 +151,34 @@ static void scan_path(const char *base, const char *path, repo_config_fn fn)
closedir(dir); closedir(dir);
} }
#define lastc(s) s[strlen(s) - 1]
void scan_projects(const char *path, const char *projectsfile, repo_config_fn fn)
{
char line[MAX_PATH * 2], *z;
FILE *projects;
int err;
projects = fopen(projectsfile, "r");
if (!projects) {
fprintf(stderr, "Error opening projectsfile %s: %s (%d)\n",
projectsfile, strerror(errno), errno);
}
while (fgets(line, sizeof(line), projects) != NULL) {
for (z = &lastc(line);
strlen(line) && strchr("\n\r", *z);
z = &lastc(line))
*z = '\0';
if (strlen(line))
scan_path(path, fmt("%s/%s", path, line), fn);
}
if ((err = ferror(projects))) {
fprintf(stderr, "Error reading from projectsfile %s: %s (%d)\n",
projectsfile, strerror(err), err);
}
fclose(projects);
}
void scan_tree(const char *path, repo_config_fn fn) void scan_tree(const char *path, repo_config_fn fn)
{ {
scan_path(path, path, fn); scan_path(path, path, fn);

View File

@ -1,3 +1,2 @@
extern void scan_projects(const char *path, const char *projectsfile, repo_config_fn fn);
extern void scan_tree(const char *path, repo_config_fn fn); extern void scan_tree(const char *path, repo_config_fn fn);