ctucx.git: stagit

ctucx' stagit fork

commit 7a058a7a07ffcf0131494522ad27ed3515a4dcbc
parent ed551de179e417b856040921003d4a5200b05a19
Author: Oscar Benedito <oscar@oscarbenedito.com>
Date: Thu, 18 Mar 2021 20:57:30 +0100

Merge tag '0.9.5'
8 files changed, 60 insertions(+), 48 deletions(-)
M
LICENSE
|
3
+--
M
Makefile
|
2
+-
M
README.md
|
3
++-
M
example_create.sh
|
2
+-
M
example_post-receive.sh
|
2
+-
M
stagit-index.c
|
2
+-
M
stagit.1
|
8
+++++++-
M
stagit.c
|
86
++++++++++++++++++++++++++++++++++++++++++-------------------------------------
diff --git a/LICENSE b/LICENSE
@@ -1,7 +1,6 @@
 MIT/X Consortium License
 
-(c) 2015-2019 Hiltjo Posthuma <hiltjo@codemadness.org>
-(c) 2015-2016 Dimitris Papastamos <sin@2f30.org>
+(c) 2015-2021 Hiltjo Posthuma <hiltjo@codemadness.org>
 
 Permission is hereby granted, free of charge, to any person obtaining a
 copy of this software and associated documentation files (the "Software"),
diff --git a/Makefile b/Makefile
@@ -1,7 +1,7 @@
 .POSIX:
 
 NAME = stagit
-VERSION = 0.9.4
+VERSION = 0.9.5
 
 # paths
 PREFIX = /usr/local
diff --git a/README.md b/README.md
@@ -152,7 +152,8 @@ Features
 - Show references: local branches and tags.
 - Detect README and LICENSE file from HEAD and link it as a webpage.
 - Detect submodules (.gitmodules file) from HEAD and link it as a webpage.
-- Atom feed log (atom.xml).
+- Atom feed of the commit log (atom.xml).
+- Atom feed of the tags/refs (tags.xml).
 - Make index page for multiple repositories with stagit-index.
 - After generating the pages (relatively slow) serving the files is very fast,
   simple and requires little resources (because the content is static), only a
diff --git a/example_create.sh b/example_create.sh
@@ -46,7 +46,7 @@ for dir in "$reposdir/"*.git/; do
 
     mkdir -p "$webdir/$d"
     cd "$webdir/$d" || continue
-    stagit -c ".stagit-build-cache" "$reposdir/$r"
+    stagit -c ".stagit-build-cache" -u "https://git.oscarbenedito.com/$d/" "$reposdir/$r"
 
     # symlinks
     [ -f "about.html" ] \
diff --git a/example_post-receive.sh b/example_post-receive.sh
@@ -59,7 +59,7 @@ mkdir -p "${destdir}/${d}"
 cd "${destdir}/${d}" || exit 1
 
 # make pages
-stagit -c "${cachefile}" "${reposdir}/${r}"
+stagit -c "${cachefile}" -u "https://git.oscarbenedito.com/$d/" "${reposdir}/${r}"
 [ -f "about.html" ] \
     && ln -sf "about.html" "index.html" \
     || ln -sf "log.html" "index.html"
diff --git a/stagit-index.c b/stagit-index.c
@@ -42,7 +42,7 @@ xmlencode(FILE *fp, const char *s, size_t len)
 		case '\'': fputs("&#39;" , fp); break;
 		case '&':  fputs("&amp;",  fp); break;
 		case '"':  fputs("&quot;", fp); break;
-		default:   fputc(*s, fp);
+		default:   putc(*s, fp);
 		}
 	}
 }
diff --git a/stagit.1 b/stagit.1
@@ -1,4 +1,4 @@
-.Dd July 19, 2020
+.Dd March 5, 2021
 .Dt STAGIT 1
 .Os
 .Sh NAME

@@ -8,6 +8,7 @@
 .Nm
 .Op Fl c Ar cachefile
 .Op Fl l Ar commits
+.Op Fl u Ar baseurl
 .Ar repodir
 .Sh DESCRIPTION
 .Nm

@@ -31,6 +32,9 @@ Write a maximum number of
 .Ar commits
 to the log.html file only.
 However the commit files are written as usual.
+.It Fl u Ar baseurl
+Base URL to make links in the Atom feeds absolute.
+For example: "https://git.codemadness.org/stagit/".
 .El
 .Pp
 The options

@@ -103,6 +107,8 @@ square logo.
 .It style.css
 CSS stylesheet.
 .El
+.Sh EXIT STATUS
+.Ex -std
 .Sh SEE ALSO
 .Xr stagit-index 1
 .Sh AUTHORS
diff --git a/stagit.c b/stagit.c
@@ -17,6 +17,8 @@
 
 #include "compat.h"
 
+#define LEN(s)    (sizeof(s)/sizeof(*s))
+
 struct deltainfo {
 	git_patch *patch;
 

@@ -57,6 +59,7 @@ struct referenceinfo {
 
 static git_repository *repo;
 
+static const char *baseurl = ""; /* base URL to make absolute RSS/Atom URI */
 static const char *relpath = "";
 static const char *repodir;
 

@@ -254,8 +257,7 @@ err:
 int
 refs_cmp(const void *v1, const void *v2)
 {
-	struct referenceinfo *r1 = (struct referenceinfo *)v1;
-	struct referenceinfo *r2 = (struct referenceinfo *)v2;
+	const struct referenceinfo *r1 = v1, *r2 = v2;
 	time_t t1, t2;
 	int r;
 

@@ -350,12 +352,12 @@ err:
 }
 
 FILE *
-efopen(const char *name, const char *flags)
+efopen(const char *filename, const char *flags)
 {
 	FILE *fp;
 
-	if (!(fp = fopen(name, flags)))
-		err(1, "fopen: '%s'", name);
+	if (!(fp = fopen(filename, flags)))
+		err(1, "fopen: '%s'", filename);
 
 	return fp;
 }

@@ -373,7 +375,7 @@ xmlencode(FILE *fp, const char *s, size_t len)
 		case '\'': fputs("&#39;",  fp); break;
 		case '&':  fputs("&amp;",  fp); break;
 		case '"':  fputs("&quot;", fp); break;
-		default:   fputc(*s, fp);
+		default:   putc(*s, fp);
 		}
 	}
 }

@@ -465,7 +467,7 @@ writeheader(FILE *fp, const char *title)
 	fputs("<!DOCTYPE html>\n"
 		"<html>\n<head>\n"
 		"<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />\n"
-		"<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n"
+		"<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n"
 		"<title>", fp);
 	xmlencode(fp, title, strlen(title));
 	if (title[0] && strippedname[0])

@@ -520,18 +522,18 @@ writefooter(FILE *fp)
 	fputs("</div>\n</body>\n</html>\n", fp);
 }
 
-int
+size_t
 writeblobhtml(FILE *fp, const git_blob *blob)
 {
-	size_t n = 0, i, prev;
-	const char *nfmt = "<a href=\"#l%d\" class=\"line\" id=\"l%d\">%7d</a> ";
+	size_t n = 0, i, len, prev;
+	const char *nfmt = "<a href=\"#l%zu\" class=\"line\" id=\"l%zu\">%7zu</a> ";
 	const char *s = git_blob_rawcontent(blob);
-	git_off_t len = git_blob_rawsize(blob);
 
+	len = git_blob_rawsize(blob);
 	fputs("<pre id=\"blob\">\n", fp);
 
 	if (len > 0) {
-		for (i = 0, prev = 0; i < (size_t)len; i++) {
+		for (i = 0, prev = 0; i < len; i++) {
 			if (s[i] != '\n')
 				continue;
 			n++;

@@ -571,12 +573,12 @@ printcommit(FILE *fp, struct commitinfo *ci)
 		xmlencode(fp, ci->author->email, strlen(ci->author->email));
 		fputs("</a>&gt;\n<b>Date:</b>   ", fp);
 		printtime(fp, &(ci->author->when));
-		fputc('\n', fp);
+		putc('\n', fp);
 	}
 	if (ci->msg) {
-		fputc('\n', fp);
+		putc('\n', fp);
 		xmlencode(fp, ci->msg, strlen(ci->msg));
-		fputc('\n', fp);
+		putc('\n', fp);
 	}
 }
 

@@ -695,7 +697,7 @@ printshowfile(FILE *fp, struct commitinfo *ci)
 					fprintf(fp, "<a href=\"#h%zu-%zu-%zu\" id=\"h%zu-%zu-%zu\" class=\"d\">-",
 						i, j, k, i, j, k);
 				else
-					fputc(' ', fp);
+					putc(' ', fp);
 				xmlencode(fp, line->content, line->content_len);
 				if (line->old_lineno == -1 || line->new_lineno == -1)
 					fputs("</a>", fp);

@@ -826,8 +828,8 @@ printcommitatom(FILE *fp, struct commitinfo *ci, const char *tag)
 		xmlencode(fp, ci->summary, strlen(ci->summary));
 		fputs("</title>\n", fp);
 	}
-	fprintf(fp, "<link rel=\"alternate\" type=\"text/html\" href=\"commit/%s.html\" />\n",
-	        ci->oid);
+	fprintf(fp, "<link rel=\"alternate\" type=\"text/html\" href=\"%scommit/%s.html\" />\n",
+	        baseurl, ci->oid);
 
 	if (ci->author) {
 		fputs("<author>\n<name>", fp);

@@ -848,10 +850,10 @@ printcommitatom(FILE *fp, struct commitinfo *ci, const char *tag)
 		xmlencode(fp, ci->author->email, strlen(ci->author->email));
 		fputs("&gt;\nDate:   ", fp);
 		printtime(fp, &(ci->author->when));
-		fputc('\n', fp);
+		putc('\n', fp);
 	}
 	if (ci->msg) {
-		fputc('\n', fp);
+		putc('\n', fp);
 		xmlencode(fp, ci->msg, strlen(ci->msg));
 	}
 	fputs("\n</content>\n</entry>\n", fp);

@@ -909,7 +911,7 @@ writeblobraw(const git_blob *blob, const char *fpath, const char *filename, git_
 {
 	char tmp[PATH_MAX] = "";
 	const char *p;
-	int lc = 0;
+	size_t lc = 0;
 	FILE *fp;
 
 	mkdirfile(fpath);

@@ -927,8 +929,8 @@ writeblobraw(const git_blob *blob, const char *fpath, const char *filename, git_
 	fclose(fp);
 }
 
-int
-writeblob(git_object *obj, const char *fpath, const char *rpath, const char *filename, git_off_t filesize)
+size_t
+writeblob(git_object *obj, const char *fpath, const char *rpath, const char *filename, size_t filesize)
 {
 	char tmp[PATH_MAX] = "";
 	const char *p, *oldrelpath;

@@ -952,7 +954,7 @@ writeblob(git_object *obj, const char *fpath, const char *rpath, const char *fil
 	writeheader(fp, filename);
 	fputs("<p> ", fp);
 	xmlencode(fp, filename, strlen(filename));
-	fprintf(fp, " (%juB)", (uintmax_t)filesize);
+	fprintf(fp, " (%zuB)", filesize);
 	fprintf(fp, " - <a href=\"%s%s\">raw</a></p><hr/>", relpath, rpath);
 
 	if (git_blob_is_binary((git_blob *)obj)) {

@@ -1017,13 +1019,12 @@ writefilestree(FILE *fp, git_tree *tree, const char *path)
 {
 	const git_tree_entry *entry = NULL;
 	git_object *obj = NULL;
-	git_off_t filesize;
 	FILE *fp_subtree;
 	const char *entryname, *oldrelpath;
-	char filepath[PATH_MAX], rawpath[PATH_MAX], entrypath[PATH_MAX], tmp[PATH_MAX], tmp2[PATH_MAX];
+	char filepath[PATH_MAX], rawpath[PATH_MAX], entrypath[PATH_MAX], tmp[PATH_MAX], tmp2[PATH_MAX], oid[8];
 	char* parent;
-	size_t count, i;
-	int lc, r, rf, ret;
+	size_t count, i, lc, filesize;
+	int r, rf, ret, is_obj_tree;
 
 	if (strlen(path) > 0) {
 		fputs("<h2>Directory: ", fp);

@@ -1074,6 +1075,7 @@ writefilestree(FILE *fp, git_tree *tree, const char *path)
 		if (!git_tree_entry_to_object(&obj, repo, entry)) {
 			switch (git_object_type(obj)) {
 			case GIT_OBJ_BLOB:
+				is_obj_tree = 0;
 				filesize = git_blob_rawsize((git_blob *)obj);
 				lc = writeblob(obj, filepath, rawpath, entryname, filesize);
 				writeblobraw((git_blob *)obj, rawpath, entryname, filesize);

@@ -1098,7 +1100,8 @@ writefilestree(FILE *fp, git_tree *tree, const char *path)
 				                     entrypath);
 				writefooter(fp_subtree);
 				relpath = oldrelpath;
-				lc = -1;
+				lc = 0;
+				is_obj_tree = 1;
 				if (ret)
 					return ret;
 				break;

@@ -1118,9 +1121,9 @@ writefilestree(FILE *fp, git_tree *tree, const char *path)
 			xmlencode(fp, entryname, strlen(entryname));
 			fputs("</a></td><td class=\"num\" align=\"right\">", fp);
 			if (lc > 0)
-				fprintf(fp, "%dL", lc);
-			else if (lc == 0)
-				fprintf(fp, "%juB", (uintmax_t)filesize);
+				fprintf(fp, "%zuL", lc);
+			else if (!is_obj_tree)
+				fprintf(fp, "%zuB", filesize);
 			fputs("</td></tr>\n", fp);
 			git_object_free(obj);
 		} else if (git_tree_entry_type(entry) == GIT_OBJ_COMMIT) {

@@ -1129,11 +1132,9 @@ writefilestree(FILE *fp, git_tree *tree, const char *path)
 				relpath);
 			xmlencode(fp, entrypath, strlen(entrypath));
 			fputs("</a> @ ", fp);
-			const git_oid* oid = git_tree_entry_id(entry);
-			char oidstr[8];
-			git_oid_tostr(oidstr, sizeof(oidstr), oid);
-			fprintf(fp, "%s</td><td class=\"num\" align=\"right\"></td></tr>\n",
-			        oidstr);
+			git_oid_tostr(oid, sizeof(oid), git_tree_entry_id(entry));
+			xmlencode(fp, oid, strlen(oid));
+			fputs("</td><td class=\"num\" align=\"right\"></td></tr>\n", fp);
 		}
 	}
 

@@ -1218,7 +1219,8 @@ writerefs(FILE *fp)
 void
 usage(char *argv0)
 {
-	fprintf(stderr, "%s [-c cachefile | -l commits] repodir\n", argv0);
+	fprintf(stderr, "%s [-c cachefile | -l commits] "
+	        "[-u baseurl] repodir\n", argv0);
 	exit(1);
 }
 

@@ -1257,6 +1259,10 @@ main(int argc, char *argv[])
 			if (argv[i][0] == '\0' || *p != '\0' ||
 			    nlogcommits <= 0 || errno)
 				usage(argv[0]);
+		} else if (argv[i][1] == 'u') {
+			if (i + 1 >= argc)
+				usage(argv[0]);
+			baseurl = argv[++i];
 		}
 	}
 	if (!repodir)

@@ -1342,7 +1348,7 @@ main(int argc, char *argv[])
 	}
 
 	/* check LICENSE */
-	for (i = 0; i < sizeof(licensefiles) / sizeof(*licensefiles) && !license; i++) {
+	for (i = 0; i < LEN(licensefiles) && !license; i++) {
 		if (!git_revparse_single(&obj, repo, licensefiles[i]) &&
 		    git_object_type(obj) == GIT_OBJ_BLOB)
 			license = licensefiles[i] + strlen("HEAD:");

@@ -1350,7 +1356,7 @@ main(int argc, char *argv[])
 	}
 
 	/* check README */
-	for (i = 0; i < sizeof(readmefiles) / sizeof(*readmefiles) && !readme; i++) {
+	for (i = 0; i < LEN(readmefiles) && !readme; i++) {
 		if (!git_revparse_single(&obj, repo, readmefiles[i]) &&
 		    git_object_type(obj) == GIT_OBJ_BLOB)
 			readme = readmefiles[i] + strlen("HEAD:");