stagit

custom fork of stagit
Index Commits Files Refs README LICENSE
commit d098f7b7080de228f1738528df82a3670127eb19
parent 277c80e02f4805f7b3b6d7d0a3e1cbc4399c2a92
Author: mjkloeckner <martin.cachari@gmail.com>
Date:   Thu,  8 Dec 2022 00:26:51 -0300

show folders first on repo files view

now if a repo contains one or more folders they are printed before
regular files (similar to gnu's ls option --group-directories-first)
this is accomplished by iterating through the files on the tree two
times, the first one matching only folders and printing them to the final file
and on the second iteration matching everything else, skipping folders.

Diffstat:
Mstagit.c | 80++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------
1 file changed, 61 insertions(+), 19 deletions(-)
diff --git a/stagit.c b/stagit.c
@@ -1119,9 +1119,6 @@ writefilestree(FILE *fp, git_tree *tree, const char *path)
             else
                 ++parent;
         }
-        /* fputs("<tr><td>d---------</td><td><a class=\"dir\" href=\"../", fp); */
-        /* xmlencode(fp, parent, strlen(parent)); */
-
         fprintf(fp, "<tr style=\"cursor: pointer; cursor: hand;\" onclick=\"window.location.href=\'../");
         percentencode(fp, parent, strlen(parent));
         fputs(".html\'\">", fp);
@@ -1129,15 +1126,16 @@ writefilestree(FILE *fp, git_tree *tree, const char *path)
         fputs("<td id=\"file-mode\">d---------</td><td><a class=\"dir\" href=\"../", fp);
         xmlencode(fp, parent, strlen(parent));
 
-        /* fputs(".html\">..</a></td><td class=\"num\" align=\"right\"></td></tr>\n", fp); */
         fputs(".html\">..</a></td><td class=\"num\" align=\"right\"></td></tr>\n", fp);
     }
 
     count = git_tree_entrycount(tree);
+
     for (i = 0; i < count; i++) {
         if (!(entry = git_tree_entry_byindex(tree, i)) ||
             !(entryname = git_tree_entry_name(entry)))
             return -1;
+
         joinpath(entrypath, sizeof(entrypath), path, entryname);
 
         r = snprintf(filepath, sizeof(filepath), "file/%s.html",
@@ -1149,15 +1147,8 @@ writefilestree(FILE *fp, git_tree *tree, const char *path)
         if (rf < 0 || (size_t)rf >= sizeof(rawpath))
             errx(1, "path truncated: 'raw/%s'", entrypath);
 
-        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);
-                break;
-            case GIT_OBJ_TREE:
+        if (!git_tree_entry_to_object(&obj, repo, entry))
+            if (git_object_type(obj) == GIT_OBJ_TREE) {
                 mkdirfile(filepath);
 
                 if (strlcpy(tmp, relpath, sizeof(tmp)) >= sizeof(tmp))
@@ -1181,16 +1172,70 @@ writefilestree(FILE *fp, git_tree *tree, const char *path)
                 is_obj_tree = 1;
                 if (ret)
                     return ret;
+
+                fputs("<tr><td id=\"file-mode\">", fp);
+
+                /* make entire table row clickable */
+                fprintf(fp, "<tr style=\"cursor: pointer; cursor: hand;\" onclick=\"\
+                        window.location.href=\'%s", relpath);
+                percentencode(fp, filepath, strlen(filepath));
+                fputs("\'\"><td id=\"file-mode\">", fp);
+                fputs(filemode(git_tree_entry_filemode(entry)), fp);
+                fprintf(fp, "</td>");
+
+
+                if (git_object_type(obj) == GIT_OBJ_TREE)
+                    fprintf(fp, "<td id=\"dir-name\"><a href=\"%s", relpath);
+                else
+                    fprintf(fp, "<td id=\"file-name\"><a href=\"%s", relpath);
+
+                percentencode(fp, filepath, strlen(filepath));
+                fputs("\">", fp);
+
+                xmlencode(fp, entryname, strlen(entryname));
+
+                fputs("</a></td><td id=\"file-size\" class=\"num\" align=\"right\">", fp);
+
+                if (lc > 0)
+                    fprintf(fp, "%zuL", lc);
+                else if (!is_obj_tree)
+                    fprintf(fp, "%zuB", filesize);
+                fputs("</td></tr>\n", fp);
+                git_object_free(obj);
+            }
+    }
+
+    for (i = 0; i < count; i++) {
+        if (!(entry = git_tree_entry_byindex(tree, i)) ||
+            !(entryname = git_tree_entry_name(entry)))
+            return -1;
+        joinpath(entrypath, sizeof(entrypath), path, entryname);
+
+        r = snprintf(filepath, sizeof(filepath), "file/%s.html",
+                 entrypath);
+        if (r < 0 || (size_t)r >= sizeof(filepath))
+            errx(1, "path truncated: 'file/%s.html'", entrypath);
+        rf = snprintf(rawpath, sizeof(rawpath), "raw/%s",
+                 entrypath);
+        if (rf < 0 || (size_t)rf >= sizeof(rawpath))
+            errx(1, "path truncated: 'raw/%s'", entrypath);
+
+        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);
                 break;
+            case GIT_OBJ_TREE:
+                continue;
             default:
                 git_object_free(obj);
                 continue;
             }
             fputs("<tr><td id=\"file-mode\">", fp);
 
-            /* fputs("<tr style=\"cursor: pointer; cursor: hand;\" onclick=\"\ */
-            /*         window.location='",fp); */
-
             /* make entire table row clickable */
             fprintf(fp, "<tr style=\"cursor: pointer; cursor: hand;\" onclick=\"\
                     window.location.href=\'%s", relpath);
@@ -1204,9 +1249,6 @@ writefilestree(FILE *fp, git_tree *tree, const char *path)
                 fprintf(fp, "<td id=\"dir-name\"><a href=\"%s", relpath);
             else
                 fprintf(fp, "<td id=\"file-name\"><a href=\"%s", relpath);
-                /* fputs("id=\"files-dir\" ", fp); */
-
-            /* fprintf(fp, "href=\"%s", relpath); */
 
             percentencode(fp, filepath, strlen(filepath));
             fputs("\">", fp);