* [PATCH] scan-user-path option, to scan for git repos in users' homedirs
@ 2014-07-16 7:15 dcallagh
2014-07-16 7:22 ` mailings
0 siblings, 1 reply; 3+ messages in thread
From: dcallagh @ 2014-07-16 7:15 UTC (permalink / raw)
I'm using the --user-dir option for git-daemon to allow users to expose
git repos under ~/public_git. I wanted them to be listed in cgit as
well, so I added this scan-user-path option.
---
cgit.c | 9 ++++++++-
cgit.h | 1 +
cgitrc.5.txt | 16 +++++++++++++++
scan-tree.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++-------
scan-tree.h | 1 +
5 files changed, 84 insertions(+), 8 deletions(-)
diff --git a/cgit.c b/cgit.c
index 20f6e27..5bc1f9e 100644
--- a/cgit.c
+++ b/cgit.c
@@ -212,6 +212,8 @@ static void config_cb(const char *name, const char *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, "user-list"))
+ ctx.cfg.user_list = xstrdup(expand_macros(value));
else if (!strcmp(name, "scan-path"))
if (!ctx.cfg.nocache && ctx.cfg.cache_size)
process_cached_repolist(expand_macros(value));
@@ -222,7 +224,11 @@ static void config_cb(const char *name, const char *value)
scan_tree(expand_macros(value), repo_config);
else if (!strcmp(name, "scan-hidden-path"))
ctx.cfg.scan_hidden_path = atoi(value);
- else if (!strcmp(name, "section-from-path"))
+ else if (!strcmp(name, "scan-user-path")) {
+ if (ctx.cfg.user_list)
+ scan_homedirs(expand_macros(value),
+ ctx.cfg.user_list, repo_config);
+ } else if (!strcmp(name, "section-from-path"))
ctx.cfg.section_from_path = atoi(value);
else if (!strcmp(name, "repository-sort"))
ctx.cfg.repository_sort = xstrdup(value);
@@ -373,6 +379,7 @@ static void prepare_context(void)
ctx.cfg.summary_tags = 10;
ctx.cfg.max_atom_items = 10;
ctx.cfg.ssdiff = 0;
+ ctx.cfg.user_list = NULL;
ctx.env.cgit_config = getenv("CGIT_CONFIG");
ctx.env.http_host = getenv("HTTP_HOST");
ctx.env.https = getenv("HTTPS");
diff --git a/cgit.h b/cgit.h
index 0badc64..09e9c14 100644
--- a/cgit.h
+++ b/cgit.h
@@ -192,6 +192,7 @@ struct cgit_config {
char *mimetype_file;
char *module_link;
char *project_list;
+ char *user_list;
struct string_list readme;
char *robots;
char *root_title;
diff --git a/cgitrc.5.txt b/cgitrc.5.txt
index b7570db..b73e85a 100644
--- a/cgitrc.5.txt
+++ b/cgitrc.5.txt
@@ -379,6 +379,17 @@ scan-path::
Default value: none. See also: cache-scanrc-ttl, project-list,
"MACRO EXPANSION".
+scan-user-path::
+ Path (relative to the user's homedir) which will be scanned for
+ repositories. The homedir of each user named in the user-list file is
+ scanned, starting from this path. For example, if "alice" and "bob" are
+ named in the user-list file and scan-user-path is set to "public_git",
+ `~alice/public_git` and `~bob/public_git` will be scanned for
+ repositories.
+ User repository names are prefixed with ~username/ to prevent
+ collisions between users.
+ Default value: none. See also: user-list, "MACRO EXPANSION".
+
section::
The name of the current repository section - all repositories defined
after this option will inherit the current section name. Default value:
@@ -433,6 +444,11 @@ strict-export::
repositories to match those exported by git-daemon. This option must
be defined prior to scan-path.
+user-list::
+ Filename which lists usernames whose homedirs will be scanned by
+ scan-user-path.
+ Default value: none. See also: scan-user-path, "MACRO EXPANSION".
+
virtual-root::
Url which, if specified, will be used as root for all cgit links. It
will also cause cgit to generate 'virtual urls', i.e. urls like
diff --git a/scan-tree.c b/scan-tree.c
index 044bcdc..62dfc71 100644
--- a/scan-tree.c
+++ b/scan-tree.c
@@ -74,7 +74,8 @@ static char *xstrrchr(char *s, char *from, int c)
return from < s ? NULL : from;
}
-static void add_repo(const char *base, struct strbuf *path, repo_config_fn fn)
+static void add_repo(const char *base, struct strbuf *path,
+ const char *name_prefix, repo_config_fn fn)
{
struct stat st;
struct passwd *pwd;
@@ -105,6 +106,7 @@ static void add_repo(const char *base, struct strbuf *path, repo_config_fn fn)
return;
strbuf_setlen(path, pathlen);
+ strbuf_addstr(&rel, name_prefix);
if (!starts_with(path->buf, base))
strbuf_addbuf(&rel, path);
else
@@ -176,7 +178,8 @@ static void add_repo(const char *base, struct strbuf *path, repo_config_fn fn)
strbuf_release(&rel);
}
-static void scan_path(const char *base, const char *path, repo_config_fn fn)
+static void scan_path(const char *base, const char *path,
+ const char *name_prefix, repo_config_fn fn)
{
DIR *dir = opendir(path);
struct dirent *ent;
@@ -192,12 +195,12 @@ static void scan_path(const char *base, const char *path, repo_config_fn fn)
strbuf_add(&pathbuf, path, strlen(path));
if (is_git_dir(pathbuf.buf)) {
- add_repo(base, &pathbuf, fn);
+ add_repo(base, &pathbuf, name_prefix, fn);
goto end;
}
strbuf_addstr(&pathbuf, "/.git");
if (is_git_dir(pathbuf.buf)) {
- add_repo(base, &pathbuf, fn);
+ add_repo(base, &pathbuf, name_prefix, fn);
goto end;
}
/*
@@ -222,7 +225,7 @@ static void scan_path(const char *base, const char *path, repo_config_fn fn)
continue;
}
if (S_ISDIR(st.st_mode))
- scan_path(base, pathbuf.buf, fn);
+ scan_path(base, pathbuf.buf, name_prefix, fn);
}
end:
strbuf_release(&pathbuf);
@@ -246,7 +249,7 @@ void scan_projects(const char *path, const char *projectsfile, repo_config_fn fn
continue;
strbuf_insert(&line, 0, "/", 1);
strbuf_insert(&line, 0, path, strlen(path));
- scan_path(path, line.buf, fn);
+ scan_path(path, line.buf, "", fn);
}
if ((err = ferror(projects))) {
fprintf(stderr, "Error reading from projectsfile %s: %s (%d)\n",
@@ -258,5 +261,53 @@ void scan_projects(const char *path, const char *projectsfile, repo_config_fn fn
void scan_tree(const char *path, repo_config_fn fn)
{
- scan_path(path, path, fn);
+ scan_path(path, path, "", fn);
+}
+
+void scan_homedirs(const char *path, const char *usersfile, repo_config_fn fn)
+{
+ struct strbuf line = STRBUF_INIT;
+ struct strbuf pathbuf = STRBUF_INIT;
+ FILE *users;
+ struct passwd *pwd;
+ int err;
+
+ users = fopen(usersfile, "r");
+ if (!users) {
+ fprintf(stderr, "Error opening users-file %s: %s (%d)\n",
+ usersfile, strerror(errno), errno);
+ strbuf_release(&line);
+ strbuf_release(&pathbuf);
+ return;
+ }
+ while (strbuf_getline(&line, users, '\n') != EOF) {
+ if (!line.len)
+ continue;
+ errno = 0;
+ pwd = getpwnam(line.buf);
+ if (!pwd) {
+ if (errno) {
+ fprintf(stderr, "Error looking up user %s: %s (%d)\n",
+ line.buf, strerror(errno), errno);
+ } else {
+ fprintf(stderr, "User does not exist: %s\n", line.buf);
+ }
+ continue;
+ }
+ strbuf_reset(&pathbuf);
+ strbuf_addstr(&pathbuf, pwd->pw_dir);
+ strbuf_addch(&pathbuf, '/');
+ strbuf_addstr(&pathbuf, path);
+ /* use ~username/ as repo name prefix */
+ strbuf_insert(&line, 0, "~", 1);
+ strbuf_addch(&line, '/');
+ scan_path(pathbuf.buf, pathbuf.buf, line.buf, fn);
+ }
+ if ((err = ferror(users))) {
+ fprintf(stderr, "Error reading from users-file %s: %s (%d)\n",
+ usersfile, strerror(err), err);
+ }
+ fclose(users);
+ strbuf_release(&line);
+ strbuf_release(&pathbuf);
}
diff --git a/scan-tree.h b/scan-tree.h
index 1afbd4b..db21d56 100644
--- a/scan-tree.h
+++ b/scan-tree.h
@@ -1,2 +1,3 @@
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_homedirs(const char *path, const char *usersfile, repo_config_fn fn);
--
1.9.3
^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH] scan-user-path option, to scan for git repos in users' homedirs
2014-07-16 7:15 [PATCH] scan-user-path option, to scan for git repos in users' homedirs dcallagh
@ 2014-07-16 7:22 ` mailings
2014-07-16 7:26 ` dcallagh
0 siblings, 1 reply; 3+ messages in thread
From: mailings @ 2014-07-16 7:22 UTC (permalink / raw)
Great!
I've doing this through scripting so having it done automatically would
be awesome.
One thing though: if I could place the ~user repos in a configurable
section then that would even be more awesome.
My servers (https://github.com/reposerf/reposerf) put the user repos
under a section called 'Developer Repositories' while non-user repos are
under other sections, like 'Release Repositories' etc.
Ferry
On 16/07/14 09:15, Dan Callaghan wrote:
> I'm using the --user-dir option for git-daemon to allow users to expose
> git repos under ~/public_git. I wanted them to be listed in cgit as
> well, so I added this scan-user-path option.
> ---
> cgit.c | 9 ++++++++-
> cgit.h | 1 +
> cgitrc.5.txt | 16 +++++++++++++++
> scan-tree.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++-------
> scan-tree.h | 1 +
> 5 files changed, 84 insertions(+), 8 deletions(-)
>
> diff --git a/cgit.c b/cgit.c
> index 20f6e27..5bc1f9e 100644
> --- a/cgit.c
> +++ b/cgit.c
> @@ -212,6 +212,8 @@ static void config_cb(const char *name, const char *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, "user-list"))
> + ctx.cfg.user_list = xstrdup(expand_macros(value));
> else if (!strcmp(name, "scan-path"))
> if (!ctx.cfg.nocache && ctx.cfg.cache_size)
> process_cached_repolist(expand_macros(value));
> @@ -222,7 +224,11 @@ static void config_cb(const char *name, const char *value)
> scan_tree(expand_macros(value), repo_config);
> else if (!strcmp(name, "scan-hidden-path"))
> ctx.cfg.scan_hidden_path = atoi(value);
> - else if (!strcmp(name, "section-from-path"))
> + else if (!strcmp(name, "scan-user-path")) {
> + if (ctx.cfg.user_list)
> + scan_homedirs(expand_macros(value),
> + ctx.cfg.user_list, repo_config);
> + } else if (!strcmp(name, "section-from-path"))
> ctx.cfg.section_from_path = atoi(value);
> else if (!strcmp(name, "repository-sort"))
> ctx.cfg.repository_sort = xstrdup(value);
> @@ -373,6 +379,7 @@ static void prepare_context(void)
> ctx.cfg.summary_tags = 10;
> ctx.cfg.max_atom_items = 10;
> ctx.cfg.ssdiff = 0;
> + ctx.cfg.user_list = NULL;
> ctx.env.cgit_config = getenv("CGIT_CONFIG");
> ctx.env.http_host = getenv("HTTP_HOST");
> ctx.env.https = getenv("HTTPS");
> diff --git a/cgit.h b/cgit.h
> index 0badc64..09e9c14 100644
> --- a/cgit.h
> +++ b/cgit.h
> @@ -192,6 +192,7 @@ struct cgit_config {
> char *mimetype_file;
> char *module_link;
> char *project_list;
> + char *user_list;
> struct string_list readme;
> char *robots;
> char *root_title;
> diff --git a/cgitrc.5.txt b/cgitrc.5.txt
> index b7570db..b73e85a 100644
> --- a/cgitrc.5.txt
> +++ b/cgitrc.5.txt
> @@ -379,6 +379,17 @@ scan-path::
> Default value: none. See also: cache-scanrc-ttl, project-list,
> "MACRO EXPANSION".
>
> +scan-user-path::
> + Path (relative to the user's homedir) which will be scanned for
> + repositories. The homedir of each user named in the user-list file is
> + scanned, starting from this path. For example, if "alice" and "bob" are
> + named in the user-list file and scan-user-path is set to "public_git",
> + `~alice/public_git` and `~bob/public_git` will be scanned for
> + repositories.
> + User repository names are prefixed with ~username/ to prevent
> + collisions between users.
> + Default value: none. See also: user-list, "MACRO EXPANSION".
> +
> section::
> The name of the current repository section - all repositories defined
> after this option will inherit the current section name. Default value:
> @@ -433,6 +444,11 @@ strict-export::
> repositories to match those exported by git-daemon. This option must
> be defined prior to scan-path.
>
> +user-list::
> + Filename which lists usernames whose homedirs will be scanned by
> + scan-user-path.
> + Default value: none. See also: scan-user-path, "MACRO EXPANSION".
> +
> virtual-root::
> Url which, if specified, will be used as root for all cgit links. It
> will also cause cgit to generate 'virtual urls', i.e. urls like
> diff --git a/scan-tree.c b/scan-tree.c
> index 044bcdc..62dfc71 100644
> --- a/scan-tree.c
> +++ b/scan-tree.c
> @@ -74,7 +74,8 @@ static char *xstrrchr(char *s, char *from, int c)
> return from < s ? NULL : from;
> }
>
> -static void add_repo(const char *base, struct strbuf *path, repo_config_fn fn)
> +static void add_repo(const char *base, struct strbuf *path,
> + const char *name_prefix, repo_config_fn fn)
> {
> struct stat st;
> struct passwd *pwd;
> @@ -105,6 +106,7 @@ static void add_repo(const char *base, struct strbuf *path, repo_config_fn fn)
> return;
> strbuf_setlen(path, pathlen);
>
> + strbuf_addstr(&rel, name_prefix);
> if (!starts_with(path->buf, base))
> strbuf_addbuf(&rel, path);
> else
> @@ -176,7 +178,8 @@ static void add_repo(const char *base, struct strbuf *path, repo_config_fn fn)
> strbuf_release(&rel);
> }
>
> -static void scan_path(const char *base, const char *path, repo_config_fn fn)
> +static void scan_path(const char *base, const char *path,
> + const char *name_prefix, repo_config_fn fn)
> {
> DIR *dir = opendir(path);
> struct dirent *ent;
> @@ -192,12 +195,12 @@ static void scan_path(const char *base, const char *path, repo_config_fn fn)
>
> strbuf_add(&pathbuf, path, strlen(path));
> if (is_git_dir(pathbuf.buf)) {
> - add_repo(base, &pathbuf, fn);
> + add_repo(base, &pathbuf, name_prefix, fn);
> goto end;
> }
> strbuf_addstr(&pathbuf, "/.git");
> if (is_git_dir(pathbuf.buf)) {
> - add_repo(base, &pathbuf, fn);
> + add_repo(base, &pathbuf, name_prefix, fn);
> goto end;
> }
> /*
> @@ -222,7 +225,7 @@ static void scan_path(const char *base, const char *path, repo_config_fn fn)
> continue;
> }
> if (S_ISDIR(st.st_mode))
> - scan_path(base, pathbuf.buf, fn);
> + scan_path(base, pathbuf.buf, name_prefix, fn);
> }
> end:
> strbuf_release(&pathbuf);
> @@ -246,7 +249,7 @@ void scan_projects(const char *path, const char *projectsfile, repo_config_fn fn
> continue;
> strbuf_insert(&line, 0, "/", 1);
> strbuf_insert(&line, 0, path, strlen(path));
> - scan_path(path, line.buf, fn);
> + scan_path(path, line.buf, "", fn);
> }
> if ((err = ferror(projects))) {
> fprintf(stderr, "Error reading from projectsfile %s: %s (%d)\n",
> @@ -258,5 +261,53 @@ void scan_projects(const char *path, const char *projectsfile, repo_config_fn fn
>
> void scan_tree(const char *path, repo_config_fn fn)
> {
> - scan_path(path, path, fn);
> + scan_path(path, path, "", fn);
> +}
> +
> +void scan_homedirs(const char *path, const char *usersfile, repo_config_fn fn)
> +{
> + struct strbuf line = STRBUF_INIT;
> + struct strbuf pathbuf = STRBUF_INIT;
> + FILE *users;
> + struct passwd *pwd;
> + int err;
> +
> + users = fopen(usersfile, "r");
> + if (!users) {
> + fprintf(stderr, "Error opening users-file %s: %s (%d)\n",
> + usersfile, strerror(errno), errno);
> + strbuf_release(&line);
> + strbuf_release(&pathbuf);
> + return;
> + }
> + while (strbuf_getline(&line, users, '\n') != EOF) {
> + if (!line.len)
> + continue;
> + errno = 0;
> + pwd = getpwnam(line.buf);
> + if (!pwd) {
> + if (errno) {
> + fprintf(stderr, "Error looking up user %s: %s (%d)\n",
> + line.buf, strerror(errno), errno);
> + } else {
> + fprintf(stderr, "User does not exist: %s\n", line.buf);
> + }
> + continue;
> + }
> + strbuf_reset(&pathbuf);
> + strbuf_addstr(&pathbuf, pwd->pw_dir);
> + strbuf_addch(&pathbuf, '/');
> + strbuf_addstr(&pathbuf, path);
> + /* use ~username/ as repo name prefix */
> + strbuf_insert(&line, 0, "~", 1);
> + strbuf_addch(&line, '/');
> + scan_path(pathbuf.buf, pathbuf.buf, line.buf, fn);
> + }
> + if ((err = ferror(users))) {
> + fprintf(stderr, "Error reading from users-file %s: %s (%d)\n",
> + usersfile, strerror(err), err);
> + }
> + fclose(users);
> + strbuf_release(&line);
> + strbuf_release(&pathbuf);
> }
> diff --git a/scan-tree.h b/scan-tree.h
> index 1afbd4b..db21d56 100644
> --- a/scan-tree.h
> +++ b/scan-tree.h
> @@ -1,2 +1,3 @@
> 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_homedirs(const char *path, const char *usersfile, repo_config_fn fn);
>
--
Ferry Huberts
^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH] scan-user-path option, to scan for git repos in users' homedirs
2014-07-16 7:22 ` mailings
@ 2014-07-16 7:26 ` dcallagh
0 siblings, 0 replies; 3+ messages in thread
From: dcallagh @ 2014-07-16 7:26 UTC (permalink / raw)
(Sorry wrong button, I meant to reply to the list)
Excerpts from Ferry Huberts's message of 2014-07-16 17:22:34 +1000:
> One thing though: if I could place the ~user repos in a configurable
> section then that would even be more awesome.
>
> My servers (https://github.com/reposerf/reposerf) put the user repos
> under a section called 'Developer Repositories' while non-user repos are
> under other sections, like 'Release Repositories' etc.
That works already with this patch, just set section= before
scan-user-path= in your cgitrc.
You can see it in action here:
https://git.beaker-project.org/cgit/
--
Dan Callaghan <dcallagh at redhat.com>
Software Engineer, Hosted & Shared Services
Red Hat, Inc.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 490 bytes
Desc: not available
URL: <http://lists.zx2c4.com/pipermail/cgit/attachments/20140716/754fdcba/attachment.asc>
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2014-07-16 7:26 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-07-16 7:15 [PATCH] scan-user-path option, to scan for git repos in users' homedirs dcallagh
2014-07-16 7:22 ` mailings
2014-07-16 7:26 ` dcallagh
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).