commit ecd0f6fb42cc6ca1ed4d9756a1e1cd4f04f8df0a
parent ea2f8521c49df0f10de5e6d8a97842c0df7c47b0
Author: Miquel Ortega <miquel.ortega9@gmail.com>
Date: Thu, 10 Sep 2020 15:37:50 +0100
Add separate listing page for every directory
Instead of listing all the files in files.html, add dir.html at
file/path/to/dir.html, which lists files in directory, for every
directory. This generates a possible conflict with a directory with path
path/to/dir.html.
Diffstat:
M | stagit.c | | | 82 | ++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------- |
1 file changed, 54 insertions(+), 28 deletions(-)
diff --git a/stagit.c b/stagit.c
@@ -398,6 +398,20 @@ mkdirp(const char *path)
return 0;
}
+int
+mkdirfile(const char *path)
+{
+ char *d;
+ char tmp[PATH_MAX];
+ if (strlcpy(tmp, path, sizeof(tmp)) >= sizeof(tmp))
+ errx(1, "path truncated: '%s'", path);
+ if (!(d = dirname(tmp)))
+ err(1, "dirname");
+ if (mkdirp(d))
+ return -1;
+ return 0;
+}
+
void
printtimez(FILE *fp, const git_time *intime)
{
@@ -893,16 +907,15 @@ writeatom(FILE *fp, int all)
void
writeblobraw(const git_blob *blob, const char *fpath, const char *filename, git_off_t filesize)
{
- char tmp[PATH_MAX] = "", *d;
+ char tmp[PATH_MAX] = "";
const char *p;
int lc = 0;
FILE *fp;
+ mkdirfile(fpath);
+
if (strlcpy(tmp, fpath, sizeof(tmp)) >= sizeof(tmp))
errx(1, "path truncated: '%s'", fpath);
- if (!(d = dirname(tmp)))
- err(1, "dirname");
- mkdirp(d);
for (p = fpath, tmp[0] = '\0'; *p; p++) {
if (*p == '/' && strlcat(tmp, "../", sizeof(tmp)) >= sizeof(tmp))
@@ -917,22 +930,22 @@ writeblobraw(const git_blob *blob, const char *fpath, const char *filename, git_
int
writeblob(git_object *obj, const char *fpath, const char *rpath, const char *filename, git_off_t filesize)
{
- char tmp[PATH_MAX] = "", *d;
- const char *p;
+ char tmp[PATH_MAX] = "";
+ const char *p, *oldrelpath;
int lc = 0;
FILE *fp;
+ mkdirfile(fpath);
+
if (strlcpy(tmp, fpath, sizeof(tmp)) >= sizeof(tmp))
errx(1, "path truncated: '%s'", fpath);
- if (!(d = dirname(tmp)))
- err(1, "dirname");
- if (mkdirp(d))
- return -1;
for (p = fpath, tmp[0] = '\0'; *p; p++) {
if (*p == '/' && strlcat(tmp, "../", sizeof(tmp)) >= sizeof(tmp))
errx(1, "path truncated: '../%s'", tmp);
}
+
+ oldrelpath = relpath;
relpath = tmp;
fp = efopen(fpath, "w");
@@ -952,7 +965,7 @@ writeblob(git_object *obj, const char *fpath, const char *rpath, const char *fil
writefooter(fp);
fclose(fp);
- relpath = "";
+ relpath = oldrelpath;
return lc;
}
@@ -1005,11 +1018,17 @@ writefilestree(FILE *fp, git_tree *tree, const char *path)
const git_tree_entry *entry = NULL;
git_object *obj = NULL;
git_off_t filesize;
- const char *entryname;
- char filepath[PATH_MAX], rawpath[PATH_MAX], entrypath[PATH_MAX];
+ FILE *fp_subtree;
+ const char *entryname, *oldrelpath;
+ char filepath[PATH_MAX], rawpath[PATH_MAX], entrypath[PATH_MAX], tmp[PATH_MAX];
size_t count, i;
int lc, r, rf, ret;
+ fputs("<table id=\"files\"><thead>\n<tr>"
+ "<td><b>Mode</b></td><td><b>Name</b></td>"
+ "<td class=\"num\" align=\"right\"><b>Size</b></td>"
+ "</tr>\n</thead><tbody>\n", fp);
+
count = git_tree_entrycount(tree);
for (i = 0; i < count; i++) {
if (!(entry = git_tree_entry_byindex(tree, i)) ||
@@ -1029,34 +1048,47 @@ 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:
+ filesize = git_blob_rawsize((git_blob *)obj);
+ lc = writeblob(obj, filepath, rawpath, entryname, filesize);
+ writeblobraw((git_blob *)obj, rawpath, entryname, filesize);
break;
case GIT_OBJ_TREE:
+ mkdirfile(filepath);
+
+ if (strlcpy(tmp, relpath, sizeof(tmp)) >= sizeof(tmp))
+ errx(1, "path truncated: '%s'", relpath);
+ if (strlcat(tmp, "../", sizeof(tmp)) >= sizeof(tmp))
+ errx(1, "path truncated: '../%s'", tmp);
+
+ oldrelpath = relpath;
+ relpath = tmp;
+ fp_subtree = efopen(filepath, "w");
+ writeheader(fp_subtree, "Files");
/* NOTE: recurses */
- ret = writefilestree(fp, (git_tree *)obj,
+ ret = writefilestree(fp_subtree, (git_tree *)obj,
entrypath);
+ writefooter(fp_subtree);
+ relpath = oldrelpath;
git_object_free(obj);
+ lc = -1;
if (ret)
return ret;
- continue;
+ break;
default:
git_object_free(obj);
continue;
}
- filesize = git_blob_rawsize((git_blob *)obj);
- lc = writeblob(obj, filepath, rawpath, entryname, filesize);
- writeblobraw((git_blob *)obj, rawpath, entryname, filesize);
-
fputs("<tr><td>", fp);
fputs(filemode(git_tree_entry_filemode(entry)), fp);
fprintf(fp, "</td><td><a href=\"%s", relpath);
xmlencode(fp, filepath, strlen(filepath));
fputs("\">", fp);
- xmlencode(fp, entrypath, strlen(entrypath));
+ xmlencode(fp, entryname, strlen(entryname));
fputs("</a></td><td class=\"num\" align=\"right\">", fp);
if (lc > 0)
fprintf(fp, "%dL", lc);
- else
+ else if (lc == 0)
fprintf(fp, "%juB", (uintmax_t)filesize);
fputs("</td></tr>\n", fp);
git_object_free(obj);
@@ -1074,6 +1106,7 @@ writefilestree(FILE *fp, git_tree *tree, const char *path)
}
}
+ fputs("</tbody></table>", fp);
return 0;
}
@@ -1084,17 +1117,10 @@ writefiles(FILE *fp, const git_oid *id)
git_commit *commit = NULL;
int ret = -1;
- fputs("<table id=\"files\"><thead>\n<tr>"
- "<td><b>Mode</b></td><td><b>Name</b></td>"
- "<td class=\"num\" align=\"right\"><b>Size</b></td>"
- "</tr>\n</thead><tbody>\n", fp);
-
if (!git_commit_lookup(&commit, repo, id) &&
!git_commit_tree(&tree, commit))
ret = writefilestree(fp, tree, "");
- fputs("</tbody></table>", fp);
-
git_commit_free(commit);
git_tree_free(tree);