From 917788e29f3bda6388d45f2b927818048136a23c Mon Sep 17 00:00:00 2001 From: pho4cexa Date: Sun, 18 Dec 2022 09:59:59 -0800 Subject: [PATCH] remove some env vars; make output land in html/ CLONE-URL, TITLE, and H1 are no longer processed. instead, the user should modify the templates/default.html to their liking. the output used to be structured like this: target-html-directory/ +-- index.html +-- files.html +-- README.md.html +-- (all the other files) the output is now structured like this: target-html-directory/ +-- index.html +-- html/ +-- files.html +-- README.md.html +-- (all the other files...) this makes it so people who are hosting bare repos for cloning on static webservers will have only two new directory entries (index.html and html) in the bare repo directory, reducing the risk of clobbering something. finally, i tried something hacky with gitattributes to get an automatic version idenifier to show up. but it turns out this is not the git hash of the commit, but instead the hash of the blob for main.scm, which could remain the same across releases. doesn't hurt, so i'll look for a better approach in the future. --- .gitattributes | 1 + main.scm | 100 ++++++++++++++++++++++++----------------- templates/default.html | 18 +++++--- 3 files changed, 73 insertions(+), 46 deletions(-) create mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..362d359 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +main.scm ident diff --git a/main.scm b/main.scm index f7d5788..865166e 100755 --- a/main.scm +++ b/main.scm @@ -21,13 +21,9 @@ utf8 ) -(define CLONE-URL (or (get-environment-variable "REPO2HTML_CLONE_URL") "git://git.example.com")) -(define TITLE (or (get-environment-variable "REPO2HTML_TITLE") "git.example.com")) -(define DESCRIPTION (or (get-environment-variable "REPO2HTML_DESCRIPTION") "my git repositories")) -(define H1 (or (get-environment-variable "REPO2HTML_H1") "git.example.com")) - ;; small utilities --------------------------------- + ;; (bail [message [exit-status]]) ;; end the program immediately. ;; if a message is provided, print it to the screen. @@ -166,12 +162,12 @@ (plaintext) (binary)))))) -(define (filelist->sxml source-files-list) +(define (filelist->sxml source-files-list relative-root) `((h1 "Files") ((ul ,(map (lambda (source-file) - `(li (a (@ href ,source-file ".html") ,source-file))) + `(li (a (@ href ,(make-pathname relative-root source-file ".html")) ,source-file))) source-files-list))))) (define (commits->sxml) @@ -241,32 +237,51 @@ ;; main program ------------------------------------------------------------------------------ (define (generate-html-files html-repo-path templates-directory) - (let* ((source-files-list (git-repository->paths-list)) - (repository-name (pathname-strip-directory (string-chomp html-repo-path "/"))) - (template-alist `(;; variables provided to template at all times - (source_files_list . ,source-files-list) - (clone_url_prefix . ,CLONE-URL) - (forge_title . ,TITLE) - (h1 . ,H1) - (repository_description . ,DESCRIPTION) - (repository_name . ,repository-name) - (readme_file - . ,(find (lambda (x) (member x source-files-list)) - '("README" "README.md" "README.txt"))) - (license_file - . ,(find (lambda (x) (member x source-files-list)) - '("LICENSE" "LICENSE.md" "LICENSE.txt"))) - (issues_file - . ,(and (find (lambda (x) (string-prefix? "ISSUES/" x)) source-files-list) "ISSUES")) - )) + (let* ((version-ident "$Id$") + (source-files-list (git-repository->paths-list)) + (template-alist + `(;; variables provided to template at all times. beware: ersatz + ;; templates break if you attempt to use a variable with a hyphen. + + ;; the list of all files in the git repo + (source_files_list . ,source-files-list) + ;; the description of the repo, taken from env, falling back to + ;; description file + (repository_description + . ,(or (get-environment-variable "REPO2HTML_DESCRIPTION") + (if-let (f (file-exists? "description")) + (with-input-from-file f read-lines) + #f) + "")) + ;; the repository name, which we detect from the output directory + ;; name. TODO: more heuristics if this doesn't work well + (repository_name + . ,(pathname-strip-directory (string-chomp html-repo-path "/"))) + ;; the first README file found, if any. + (readme_file + . ,(find (lambda (x) (member x source-files-list)) + '("README" "README.md" "README.txt"))) + ;; the first LICENSE file found, if any. + (license_file + . ,(find (lambda (x) (member x source-files-list)) + '("LICENSE" "LICENSE.md" "LICENSE.txt"))) + ;; the string "ISSUES" if any files exist in ISSUES/ + (issues_file + . ,(and (find (lambda (x) (string-prefix? "ISSUES/" x)) source-files-list) "ISSUES")) + (repo2html_version + . ,(if (equal? version-ident (list->string '(#\$ #\I #\d #\$))) + "" + (substring* version-ident 5 12))) + )) (write-with-template (make-template-writer-ersatz templates-directory template-alist))) + (define html-path (make-pathname html-repo-path "html")) (create-directory html-repo-path #t) ;; special files - (write-with-template (make-pathname html-repo-path "files" "html") (filelist->sxml source-files-list)) - (write-with-template (make-pathname html-repo-path "contributors" "html") (contributors->sxml)) - (write-with-template (make-pathname html-repo-path "commits" "html") (commits->sxml)) + (write-with-template (make-pathname html-path "files" "html") (filelist->sxml source-files-list "")) + (write-with-template (make-pathname html-path "contributors" "html") (contributors->sxml)) + (write-with-template (make-pathname html-path "commits" "html") (commits->sxml)) ;; htmlified repo contents (for-each (lambda (source-file) @@ -274,7 +289,7 @@ (pathparts) (define-values (root elements basename extension relative-root))) (write-with-template - (make-pathname html-repo-path source-file "html") + (make-pathname html-path source-file "html") (source->sxml source-file) `(;; additional per-page variables provided to template (source_file . ,source-file) @@ -284,24 +299,29 @@ (extension . ,extension) (relative_root . ,relative-root) )) - ;; if it's an image also copy it verbatim to output directory + ;; if it's an image, also write it verbatim to output directory (case (string->symbol (or (pathname-extension source-file) "")) ((jpg jpeg png gif webp webm svg apng avif svgz ico) (system (format "git show HEAD:~a > ~a" source-file - (make-pathname html-repo-path source-file)))))) + (make-pathname html-path source-file)))))) source-files-list) - ;; if (the output version of) README.md, README, or README.txt exists, copy - ;; that to index.html. otherwise copy files.html to index.html. - (->> - '("README.md" "README" "README.txt" "files") - (map (lambda (x) (make-pathname html-repo-path x "html"))) - (find file-exists?) - ((lambda (x) (copy-file x (make-pathname html-repo-path "index" "html") #t)))) + ;; if README.md, README, or README.txt exists, regenerate it as index.html. + ;; otherwise regenerate files.html as index.html. + (write-with-template + (make-pathname html-repo-path "index" "html") + (if-let (readme-file + (alist-ref 'readme_file template-alist)) + (source->sxml readme-file) + (filelist->sxml source-files-list "html")) + ;; TODO: do we need the full set of template variables defined here? + ;; if so maybe this and the set above should be lifted out somewhere + `((relative_root . "html/"))) + ;; if the ISSUES directory got created, write out an index file for the ;; stuff in there. - (when (file-exists? (make-pathname html-repo-path "ISSUES")) - (write-with-template (make-pathname html-repo-path "ISSUES" "html") (issueslist->sxml source-files-list))))) + (when (file-exists? (make-pathname html-path "ISSUES")) + (write-with-template (make-pathname html-path "ISSUES" "html") (issueslist->sxml source-files-list))))) (define (main #!optional html-repo-path templates-directory) diff --git a/templates/default.html b/templates/default.html index cceea88..9ecd0d1 100644 --- a/templates/default.html +++ b/templates/default.html @@ -1,7 +1,7 @@ -{{ forge_title }} - {{ repository_name }} +git.example.com - {{ repository_name }} @@ -18,15 +18,15 @@ -

{{ h1 }}

+

git.example.com

{{ repository_name }}

-

clone url:{{ clone_url_prefix }}/{{ repository_name }}

+

clone url: git://git.example.com/{{ repository_name }}