From list at eworm.de Sun Jun 6 19:19:32 2021 From: list at eworm.de (Christian Hesse) Date: Sun, 6 Jun 2021 21:19:32 +0200 Subject: [PATCH 1/1] git: update to v2.32.0 Message-ID: <20210606191932.37114-1-list@eworm.de> From: Christian Hesse Update to git version v2.32.0, this requires changes for these upstream commits: * 47957485b3b731a7860e0554d2bd12c0dce1c75a tree.h API: simplify read_tree_recursive() signature Signed-off-by: Christian Hesse --- Makefile | 2 +- git | 2 +- ui-blame.c | 9 +++------ ui-blob.c | 20 ++++++++------------ ui-plain.c | 7 +++---- ui-tree.c | 21 ++++++++------------- 6 files changed, 24 insertions(+), 37 deletions(-) diff --git a/Makefile b/Makefile index abc52bc..d13c5bd 100644 --- a/Makefile +++ b/Makefile @@ -14,7 +14,7 @@ htmldir = $(docdir) pdfdir = $(docdir) mandir = $(prefix)/share/man SHA1_HEADER = -GIT_VER = 2.31.1 +GIT_VER = 2.32.0 GIT_URL = https://www.kernel.org/pub/software/scm/git/git-$(GIT_VER).tar.xz INSTALL = install COPYTREE = cp -r diff --git a/git b/git index 48bf2fa..ebf3c04 160000 --- a/git +++ b/git @@ -1 +1 @@ -Subproject commit 48bf2fa8bad054d66bd79c6ba903c89c704201f7 +Subproject commit ebf3c04b262aa27fbb97f8a0156c2347fecafafb diff --git a/ui-blame.c b/ui-blame.c index ec1d888..03136f7 100644 --- a/ui-blame.c +++ b/ui-blame.c @@ -221,8 +221,7 @@ cleanup: } static int walk_tree(const struct object_id *oid, struct strbuf *base, - const char *pathname, unsigned mode, int stage, - void *cbdata) + const char *pathname, unsigned mode, void *cbdata) { struct walk_tree_context *walk_tree_ctx = cbdata; @@ -291,10 +290,8 @@ void cgit_print_blame(void) walk_tree_ctx.match_baselen = (path_items.match) ? basedir_len(path_items.match) : -1; - read_tree_recursive(the_repository, - repo_get_commit_tree(the_repository, commit), - "", 0, 0, - &paths, walk_tree, &walk_tree_ctx); + read_tree(the_repository, repo_get_commit_tree(the_repository, commit), + &paths, walk_tree, &walk_tree_ctx); if (!walk_tree_ctx.state) cgit_print_error_page(404, "Not found", "Not found"); else if (walk_tree_ctx.state == 2) diff --git a/ui-blob.c b/ui-blob.c index f76c641..c10ae42 100644 --- a/ui-blob.c +++ b/ui-blob.c @@ -19,7 +19,7 @@ struct walk_tree_context { }; static int walk_tree(const struct object_id *oid, struct strbuf *base, - const char *pathname, unsigned mode, int stage, void *cbdata) + const char *pathname, unsigned mode, void *cbdata) { struct walk_tree_context *walk_tree_ctx = cbdata; @@ -56,9 +56,9 @@ int cgit_ref_path_exists(const char *path, const char *ref, int file_only) goto done; if (oid_object_info(the_repository, &oid, &size) != OBJ_COMMIT) goto done; - read_tree_recursive(the_repository, - repo_get_commit_tree(the_repository, lookup_commit_reference(the_repository, &oid)), - "", 0, 0, &paths, walk_tree, &walk_tree_ctx); + read_tree(the_repository, + repo_get_commit_tree(the_repository, lookup_commit_reference(the_repository, &oid)), + &paths, walk_tree, &walk_tree_ctx); done: free(path_items.match); @@ -92,10 +92,8 @@ int cgit_print_file(char *path, const char *head, int file_only) type = oid_object_info(the_repository, &oid, &size); if (type == OBJ_COMMIT) { commit = lookup_commit_reference(the_repository, &oid); - read_tree_recursive(the_repository, - repo_get_commit_tree(the_repository, commit), - "", 0, 0, &paths, walk_tree, - &walk_tree_ctx); + read_tree(the_repository, repo_get_commit_tree(the_repository, commit), + &paths, walk_tree, &walk_tree_ctx); if (!walk_tree_ctx.found_path) return -1; type = oid_object_info(the_repository, &oid, &size); @@ -151,10 +149,8 @@ void cgit_print_blob(const char *hex, char *path, const char *head, int file_onl if ((!hex) && type == OBJ_COMMIT && path) { commit = lookup_commit_reference(the_repository, &oid); - read_tree_recursive(the_repository, - repo_get_commit_tree(the_repository, commit), - "", 0, 0, &paths, walk_tree, - &walk_tree_ctx); + read_tree(the_repository, repo_get_commit_tree(the_repository, commit), + &paths, walk_tree, &walk_tree_ctx); type = oid_object_info(the_repository, &oid, &size); } diff --git a/ui-plain.c b/ui-plain.c index 001001c..65a205f 100644 --- a/ui-plain.c +++ b/ui-plain.c @@ -130,7 +130,7 @@ static void print_dir_tail(void) } static int walk_tree(const struct object_id *oid, struct strbuf *base, - const char *pathname, unsigned mode, int stage, void *cbdata) + const char *pathname, unsigned mode, void *cbdata) { struct walk_tree_context *walk_tree_ctx = cbdata; @@ -198,9 +198,8 @@ void cgit_print_plain(void) } else walk_tree_ctx.match_baselen = basedir_len(path_items.match); - read_tree_recursive(the_repository, - repo_get_commit_tree(the_repository, commit), - "", 0, 0, &paths, walk_tree, &walk_tree_ctx); + read_tree(the_repository, repo_get_commit_tree(the_repository, commit), + &paths, walk_tree, &walk_tree_ctx); if (!walk_tree_ctx.match) cgit_print_error_page(404, "Not found", "Not found"); else if (walk_tree_ctx.match == 2) diff --git a/ui-tree.c b/ui-tree.c index 1e4efb2..b61f6f5 100644 --- a/ui-tree.c +++ b/ui-tree.c @@ -139,8 +139,7 @@ struct single_tree_ctx { }; static int single_tree_cb(const struct object_id *oid, struct strbuf *base, - const char *pathname, unsigned mode, int stage, - void *cbdata) + const char *pathname, unsigned mode, void *cbdata) { struct single_tree_ctx *ctx = cbdata; @@ -185,8 +184,7 @@ static void write_tree_link(const struct object_id *oid, char *name, tree_ctx.name = NULL; tree_ctx.count = 0; - read_tree_recursive(the_repository, tree, "", 0, 1, - &paths, single_tree_cb, &tree_ctx); + read_tree(the_repository, tree, &paths, single_tree_cb, &tree_ctx); if (tree_ctx.count != 1) break; @@ -199,7 +197,7 @@ static void write_tree_link(const struct object_id *oid, char *name, } static int ls_item(const struct object_id *oid, struct strbuf *base, - const char *pathname, unsigned mode, int stage, void *cbdata) + const char *pathname, unsigned mode, void *cbdata) { struct walk_tree_context *walk_tree_ctx = cbdata; char *name; @@ -294,14 +292,13 @@ static void ls_tree(const struct object_id *oid, const char *path, struct walk_t } ls_head(); - read_tree_recursive(the_repository, tree, "", 0, 1, - &paths, ls_item, walk_tree_ctx); + read_tree(the_repository, tree, &paths, ls_item, walk_tree_ctx); ls_tail(); } static int walk_tree(const struct object_id *oid, struct strbuf *base, - const char *pathname, unsigned mode, int stage, void *cbdata) + const char *pathname, unsigned mode, void *cbdata) { struct walk_tree_context *walk_tree_ctx = cbdata; @@ -326,7 +323,7 @@ static int walk_tree(const struct object_id *oid, struct strbuf *base, return 0; } } - ls_item(oid, base, pathname, mode, stage, walk_tree_ctx); + ls_item(oid, base, pathname, mode, walk_tree_ctx); return 0; } @@ -374,10 +371,8 @@ void cgit_print_tree(const char *rev, char *path) goto cleanup; } - read_tree_recursive(the_repository, - repo_get_commit_tree(the_repository, commit), - "", 0, 0, - &paths, walk_tree, &walk_tree_ctx); + read_tree(the_repository, repo_get_commit_tree(the_repository, commit), + &paths, walk_tree, &walk_tree_ctx); if (walk_tree_ctx.state == 1) ls_tail(); else if (walk_tree_ctx.state == 2) From june at causal.agency Tue Jun 8 21:06:54 2021 From: june at causal.agency (C. McEnroe) Date: Tue, 8 Jun 2021 17:06:54 -0400 Subject: [PATCH] ui-atom: generate valid Atom feeds Message-ID: <20210608210654.89771-1-june@causal.agency> Fixes several RFC 4287 violations: > 4.1.1. The "atom:feed" Element > o atom:feed elements MUST contain exactly one atom:id element. > o atom:feed elements SHOULD contain one atom:link element with a rel > attribute value of "self". This is the preferred URI for > retrieving Atom Feed Documents representing this Atom feed. > o atom:feed elements MUST contain exactly one atom:updated element. An atom:id element is generated from cgit_currentfullurl(), and an atom:link element with a rel attribute of "self" is generated with the same URL. An atom:updated element is generated from the date of the first commit in the revision walk. > 4.1.2. The "atom:entry" Element > o atom:entry elements MUST NOT contain more than one atom:content > element. The second atom:content element with the type of "xhtml" is removed. > 4.2.6. The "atom:id" Element > Its content MUST be an IRI, as defined by [RFC3987]. Note that the > definition of "IRI" excludes relative references. Though the IRI > might use a dereferencable scheme, Atom Processors MUST NOT assume it > can be dereferenced. The atom:id elements for commits now use URNs in the "sha1" or "sha256" namespaces. Although these are not registered URN namespaces, they see use in the wild, for instance as part of magnet URIs. Signed-off-by: C. McEnroe --- ui-atom.c | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/ui-atom.c b/ui-atom.c index 1056f36..8329e01 100644 --- a/ui-atom.c +++ b/ui-atom.c @@ -67,17 +67,12 @@ static void add_entry(struct commit *commit, const char *host) html("'/>\n"); free(pageurl); } - htmlf("%s\n", hex); + html(""); + html_txtf("urn:%s:%s", the_hash_algo->name, hex); + html("\n"); html("\n"); html_txt(info->msg); html("\n"); - html("\n"); - html("
\n"); - html("
\n");
-	html_txt(info->msg);
-	html("
\n"); - html("
\n"); - html("
\n"); html("\n"); cgit_free_commitinfo(info); } @@ -90,6 +85,7 @@ void cgit_print_atom(char *tip, const char *path, int max_count) struct commit *commit; struct rev_info rev; int argc = 2; + int first = 1; if (ctx.qry.show_all) argv[1] = "--all"; @@ -130,15 +126,28 @@ void cgit_print_atom(char *tip, const char *path, int max_count) html_txt(ctx.repo->desc); html("\n"); if (host) { + char *fullurl = cgit_currentfullurl(); char *repourl = cgit_repourl(ctx.repo->url); + html(""); + html_txtf("%s%s%s", cgit_httpscheme(), host, fullurl); + html("\n"); + html("\n"); html("\n"); + free(fullurl); free(repourl); } while ((commit = get_revision(&rev)) != NULL) { + if (first) { + html(""); + html_txt(show_date(commit->date, 0, + date_mode_from_type(DATE_ISO8601_STRICT))); + html("\n"); + first = 0; + } add_entry(commit, host); free_commit_buffer(the_repository->parsed_objects, commit); free_commit_list(commit->parents); -- 2.31.1 From uinarf at autistici.org Thu Jun 10 14:05:14 2021 From: uinarf at autistici.org (uinarf at autistici.org) Date: Thu, 10 Jun 2021 14:05:14 +0000 Subject: About tab shows empty Message-ID: <0d0ad2da8a8a8370fa765f9041b85be7@autistici.org> Hi, first of all - thanks for cgit, it's great. I think I'm having a configuration issue: 'About' tab shows no images. I tried markdown and html, relative and absolute path and it still doesn't work. I'm running it on Gentoo, with nginx + uwsgi, not sure it matters but hey. Any pointers would be great here's content of my cgitrc: css=/cgit/cgit.css logo=/cgit/cgit.png virtual-root=/git remove-suffix=1 root-title=my repositories root-desc=All my repos root-readme=/var/git/about.md enable-index-owner=0 enable-http-clone=1 cache-size=1000 snapshots=tar.gz tar.bz2 clone-prefix=https://my.website.com robots=index, follow cache-about-ttl=1 cache-dynamic-ttl=1 cache-repo-ttl=1 readme=:README.md enable-commit-graph=1 favicon=/favicon.ico max-stats=quarter mimetype-file=/etc/mime.types mimetype.gif=image/gif mimetype.html=text/html mimetype.jpg=image/jpeg mimetype.jpeg=image/jpeg mimetype.pdf=application/pdf mimetype.png=image/png mimetype.svg=image/svg+xml repo.snapshots=0 about-filter=/usr/lib64/cgit/filters/about-formatting.sh source-filter=/usr/lib64/cgit/filters/syntax-highlighting.py scan-path=/var/git Cheers From me at cameronkatri.com Mon Jun 14 18:38:58 2021 From: me at cameronkatri.com (Cameron Katri) Date: Mon, 14 Jun 2021 14:38:58 -0400 Subject: [PATCH] man2html: Prefer mandoc over groff if it is installed Message-ID: <20210614183858.3skixbufdexgnpca@FreeBSDY540> Because the patch has some regex to remove html tags my email gets bounced when the patch is sent normally or as an attachment, so here is a link to download it https://git.cameronkatri.com/cgit/patch/?id=9bb632056911462379fe345b5638f54a2cd2276c When using mandoc, sections will have ids and proper spacing, which groff lacks. Example: https://cameronkatri.com/groff.png https://cameronkatri.com/mandoc.png -- Cameron Katri Email: me at cameronkatri.com PGP Fingerprint: 7D3B36CEA40FCC2181FB6DCDBAFFD97826540F1C -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 488 bytes Desc: not available URL: From me at cameronkatri.com Tue Jun 15 15:57:24 2021 From: me at cameronkatri.com (Cameron Katri) Date: Tue, 15 Jun 2021 11:57:24 -0400 Subject: [PATCH] Add a license tab Message-ID: <20210615155724.97097-1-me@cameronkatri.com> This tab is nearly identical to the about tab, use the license field in cgitrc to set a list of files to check for or use repo.license or cgit.license as a git-config key. --- This is useful in large repos where you gotta scroll and scroll to find the license text, you can just click the license tab and get it right there. cgit.c | 59 ++++++++++++++++++++++++++++++++++------------------ cgit.h | 3 +++ cgitrc.5.txt | 24 ++++++++++++++++++++- cmd.c | 27 +++++++++++++++++++++++- shared.c | 1 + ui-shared.c | 4 ++++ ui-summary.c | 17 +++++++-------- ui-summary.h | 4 +++- 8 files changed, 107 insertions(+), 32 deletions(-) diff --git a/cgit.c b/cgit.c index 08d81a1..c88dd5b 100644 --- a/cgit.c +++ b/cgit.c @@ -99,6 +99,10 @@ static void repo_config(struct cgit_repo *repo, const char *name, const char *va if (repo->readme.items == ctx.cfg.readme.items) memset(&repo->readme, 0, sizeof(repo->readme)); string_list_append(&repo->readme, xstrdup(value)); + } else if (!strcmp(name, "license") && value != NULL) { + if (repo->license.items == ctx.cfg.license.items) + memset(&repo->license, 0, sizeof(repo->license)); + string_list_append(&repo->license, xstrdup(value)); } else if (!strcmp(name, "logo") && value != NULL) repo->logo = xstrdup(value); else if (!strcmp(name, "logo-link") && value != NULL) @@ -135,6 +139,8 @@ static void config_cb(const char *name, const char *value) repo_config(ctx.repo, arg, value); else if (!strcmp(name, "readme")) string_list_append(&ctx.cfg.readme, xstrdup(value)); + else if (!strcmp(name, "license")) + string_list_append(&ctx.cfg.license, xstrdup(value)); else if (!strcmp(name, "root-title")) ctx.cfg.root_title = xstrdup(value); else if (!strcmp(name, "root-desc")) @@ -213,6 +219,8 @@ static void config_cb(const char *name, const char *value) ctx.cfg.cache_dynamic_ttl = atoi(value); else if (!strcmp(name, "cache-about-ttl")) ctx.cfg.cache_about_ttl = atoi(value); + else if (!strcmp(name, "cache-license-ttl")) + ctx.cfg.cache_license_ttl = atoi(value); else if (!strcmp(name, "cache-snapshot-ttl")) ctx.cfg.cache_snapshot_ttl = atoi(value); else if (!strcmp(name, "case-sensitive-sort")) @@ -367,6 +375,7 @@ static void prepare_context(void) ctx.cfg.cache_max_create_time = 5; ctx.cfg.cache_root = CGIT_CACHE_ROOT; ctx.cfg.cache_about_ttl = 15; + ctx.cfg.cache_license_ttl = 15; ctx.cfg.cache_snapshot_ttl = 5; ctx.cfg.cache_repo_ttl = 5; ctx.cfg.cache_root_ttl = 5; @@ -494,46 +503,46 @@ static char *guess_defbranch(void) } /* The caller must free filename and ref after calling this. */ -static inline void parse_readme(const char *readme, char **filename, char **ref, struct cgit_repo *repo) +static inline void parse_info_file(const char *file, char **filename, char **ref, struct cgit_repo *repo) { const char *colon; *filename = NULL; *ref = NULL; - if (!readme || !readme[0]) + if (!file || !file[0]) return; - /* Check if the readme is tracked in the git repo. */ - colon = strchr(readme, ':'); + /* Check if the file is tracked in the git repo. */ + colon = strchr(file, ':'); if (colon && strlen(colon) > 1) { /* If it starts with a colon, we want to use * the default branch */ - if (colon == readme && repo->defbranch) + if (colon == file && repo->defbranch) *ref = xstrdup(repo->defbranch); else - *ref = xstrndup(readme, colon - readme); - readme = colon + 1; + *ref = xstrndup(file, colon - file); + file = colon + 1; } - /* Prepend repo path to relative readme path unless tracked. */ - if (!(*ref) && readme[0] != '/') - *filename = fmtalloc("%s/%s", repo->path, readme); + /* Prepend repo path to relative file path unless tracked. */ + if (!(*ref) && file[0] != '/') + *filename = fmtalloc("%s/%s", repo->path, file); else - *filename = xstrdup(readme); + *filename = xstrdup(file); } -static void choose_readme(struct cgit_repo *repo) +static void choose_string_list_item(struct cgit_repo *repo, struct string_list *file) { int found; char *filename, *ref; struct string_list_item *entry; - if (!repo->readme.nr) + if (!file->nr) return; found = 0; - for_each_string_list_item(entry, &repo->readme) { - parse_readme(entry->string, &filename, &ref, repo); + for_each_string_list_item(entry, file) { + parse_info_file(entry->string, &filename, &ref, repo); if (!filename) { free(filename); free(ref); @@ -552,11 +561,11 @@ static void choose_readme(struct cgit_repo *repo) free(filename); free(ref); } - repo->readme.strdup_strings = 1; - string_list_clear(&repo->readme, 0); - repo->readme.strdup_strings = 0; + file->strdup_strings = 1; + string_list_clear(file, 0); + file->strdup_strings = 0; if (found) - string_list_append(&repo->readme, filename)->util = ref; + string_list_append(file, filename)->util = ref; } static void print_no_repo_clone_urls(const char *url) @@ -636,7 +645,8 @@ static int prepare_repo_cmd(int nongit) } string_list_sort(&ctx.repo->submodules); cgit_prepare_repo_env(ctx.repo); - choose_readme(ctx.repo); + choose_string_list_item(ctx.repo, &ctx.repo->readme); + choose_string_list_item(ctx.repo, &ctx.repo->license); return 0; } @@ -804,6 +814,12 @@ static void print_repo(FILE *f, struct cgit_repo *repo) else fprintf(f, "repo.readme=%s\n", item->string); } + for_each_string_list_item(item, &repo->license) { + if (item->util) + fprintf(f, "repo.license=%s:%s\n", (char *)item->util, item->string); + else + fprintf(f, "repo.license=%s\n", item->string); + } if (repo->defbranch) fprintf(f, "repo.defbranch=%s\n", repo->defbranch); if (repo->extra_head_content) @@ -1034,6 +1050,9 @@ static int calc_ttl(void) if (!strcmp(ctx.qry.page, "about")) return ctx.cfg.cache_about_ttl; + if (!strcmp(ctx.qry.page, "license")) + return ctx.cfg.cache_license_ttl; + if (!strcmp(ctx.qry.page, "snapshot")) return ctx.cfg.cache_snapshot_ttl; diff --git a/cgit.h b/cgit.h index 69b5c13..f0ad595 100644 --- a/cgit.h +++ b/cgit.h @@ -88,6 +88,7 @@ struct cgit_repo { char *defbranch; char *module_link; struct string_list readme; + struct string_list license; char *section; char *clone_url; char *logo; @@ -206,6 +207,7 @@ struct cgit_config { char *module_link; char *project_list; struct string_list readme; + struct string_list license; char *robots; char *root_title; char *root_desc; @@ -223,6 +225,7 @@ struct cgit_config { int cache_scanrc_ttl; int cache_static_ttl; int cache_about_ttl; + int cache_license_ttl; int cache_snapshot_ttl; int case_sensitive_sort; int embedded; diff --git a/cgitrc.5.txt b/cgitrc.5.txt index 33a6a8c..5a0e422 100644 --- a/cgitrc.5.txt +++ b/cgitrc.5.txt @@ -331,6 +331,12 @@ readme:: in this list. This is useful in conjunction with scan-path. Default value: none. See also: scan-path, repo.readme. +license:: + Text which will be used as default value for "repo.license". Multiple + config keys may be specified, and cgit will use the first found file + in this list. This is useful in conjunction with scan-path. Default + value: none. See also: scan-path, repo.license. + remove-suffix:: If set to "1" and scan-path is enabled, if any repositories are found with a suffix of ".git", this suffix will be removed for the url and @@ -585,6 +591,17 @@ repo.readme:: are no non-public files located in the same directory as the readme file. Default value: . +repo.license:: + A path (relative to ) which specifies a file to include + verbatim as the "license" page for this repo. You may also specify a + git refspec by head or by hash by prepending the refspec followed by + a colon. For example, "master:LICENSE". If the value begins + with a colon, i.e. ":COPYING", the default branch of the + repository will be used. Sharing any file will expose that entire + directory tree to the "/license/PATH" endpoints, so be sure that there + are no non-public files located in the same directory as the license + file. Default value: . + repo.section:: Override the current section name for this repository. Default value: none. @@ -669,7 +686,7 @@ Parameters are provided to filters as follows. about filter:: This filter is given a single parameter: the filename of the source file to filter. The filter can use the filename to determine (for - example) the type of syntax to follow when formatting the readme file. + example) the type of syntax to follow when formatting the readme/license file. The about text that is to be filtered is available on standard input and the filtered text is expected on standard output. @@ -930,6 +947,10 @@ readme=:install.txt readme=:INSTALL readme=:install +license=:LICENSE.md +license=:LICENSE +license=:COPYING.md +license=:COPYING ## ## List of repositories. @@ -946,6 +967,7 @@ repo.path=/pub/git/foo.git repo.desc=the master foo repository repo.owner=fooman at example.com repo.readme=info/web/about.html +repo.license=GPLv3.html repo.url=bar diff --git a/cmd.c b/cmd.c index 0eb75b1..fb1ccc0 100644 --- a/cmd.c +++ b/cmd.c @@ -50,7 +50,7 @@ static void about_fn(void) free(currenturl); free(redirect); } else if (ctx.repo->readme.nr) - cgit_print_repo_readme(ctx.qry.path); + cgit_print_repo_info_file(ctx.repo->readme, ctx.qry.path); else if (ctx.repo->homepage) cgit_redirect(ctx.repo->homepage, false); else { @@ -97,6 +97,30 @@ static void info_fn(void) cgit_clone_info(); } +static void license_fn(void) +{ + if (ctx.repo) { + size_t path_info_len = ctx.env.path_info ? strlen(ctx.env.path_info) : 0; + if (!ctx.qry.path && + ctx.qry.url[strlen(ctx.qry.url) - 1] != '/' && + (!path_info_len || ctx.env.path_info[path_info_len - 1] != '/')) { + char *currenturl = cgit_currenturl(); + char *redirect = fmtalloc("%s/", currenturl); + cgit_redirect(redirect, true); + free(currenturl); + free(redirect); + } else if (ctx.repo->license.nr) + cgit_print_repo_info_file(ctx.repo->license, ctx.qry.path); + else { + char *currenturl = cgit_currenturl(); + char *redirect = fmtalloc("%s../", currenturl); + cgit_redirect(redirect, false); + free(currenturl); + free(redirect); + } + } +} + static void log_fn(void) { cgit_print_log(ctx.qry.oid, ctx.qry.ofs, ctx.cfg.max_commit_count, @@ -178,6 +202,7 @@ struct cgit_cmd *cgit_get_cmd(void) def_cmd(commit, 1, 1, 0), def_cmd(diff, 1, 1, 0), def_cmd(info, 1, 0, 1), + def_cmd(license, 1, 1, 0), def_cmd(log, 1, 1, 0), def_cmd(ls_cache, 0, 0, 0), def_cmd(objects, 1, 0, 1), diff --git a/shared.c b/shared.c index 8115469..c7b98cc 100644 --- a/shared.c +++ b/shared.c @@ -70,6 +70,7 @@ struct cgit_repo *cgit_add_repo(const char *url) ret->commit_sort = ctx.cfg.commit_sort; ret->module_link = ctx.cfg.module_link; ret->readme = ctx.cfg.readme; + ret->license = ctx.cfg.license; ret->mtime = -1; ret->about_filter = ctx.cfg.about_filter; ret->commit_filter = ctx.cfg.commit_filter; diff --git a/ui-shared.c b/ui-shared.c index acd8ab5..207bf69 100644 --- a/ui-shared.c +++ b/ui-shared.c @@ -1056,6 +1056,10 @@ void cgit_print_pageheader(void) if (ctx.repo->max_stats) cgit_stats_link("stats", NULL, hc("stats"), ctx.qry.head, ctx.qry.vpath); + if (ctx.repo->license.nr) + reporevlink("license", "license", NULL, + hc("license"), ctx.qry.head, NULL, + NULL); if (ctx.repo->homepage) { html(""); diff --git a/ui-summary.h b/ui-summary.h index cba696a..9592802 100644 --- a/ui-summary.h +++ b/ui-summary.h @@ -1,7 +1,9 @@ #ifndef UI_SUMMARY_H #define UI_SUMMARY_H +#include + extern void cgit_print_summary(void); -extern void cgit_print_repo_readme(const char *path); +extern void cgit_print_repo_info_file(struct string_list file, const char *path); #endif /* UI_SUMMARY_H */ -- 2.31.1