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.
This commit is contained in:
pho4cexa 2022-12-18 09:59:59 -08:00
parent bd18246b08
commit 917788e29f
3 changed files with 73 additions and 46 deletions

1
.gitattributes vendored Normal file
View File

@ -0,0 +1 @@
main.scm ident

100
main.scm
View File

@ -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)

View File

@ -1,7 +1,7 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>{{ forge_title }} - {{ repository_name }}</title>
<title>git.example.com - {{ repository_name }}</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale-1.0, user-scalable=yes" />
<link rel="icon" href="data:," />
@ -18,15 +18,15 @@
</style>
</head>
<body>
<h1>{{ h1 }}</h1>
<h1>git.example.com</h1>
<h2>{{ repository_name }}</h2>
<p>clone url:{{ clone_url_prefix }}/{{ repository_name }}</p>
<p>clone url: git://git.example.com/{{ repository_name }}</p>
<nav>
{% if readme_file %}
<a href="{{ relative_root }}index.html">about</a>
<a href="{{ relative_root }}{{ readme_file }}.html">about</a>
<a href="{{ relative_root }}files.html">files</a>
{% else %}
<a href="{{ relative_root }}index.html">files</a>
<a href="{{ relative_root }}files.html">files</a>
{% endif %}
{% if license_file %}
<a href="{{ relative_root }}{{ license_file }}.html">license</a>
@ -41,4 +41,10 @@
{{ content|safe }}
<hr />
<footer>
<p>Generated by <a href="https://git.m455.casa/repo2html/">repo2html</a> using ersatz templates</p></footer></html>
<p>Generated by
<a href="https://git.m455.casa/repo2html/"
title="the repo2html git repo static renderer by m455 and pho4cexa">repo2html</a>
{{ repo2html_version }} using
<a href="http://wiki.call-cc.org/eggref/5/ersatz"
title="the ersatz Jinja2-like templating library by Ivan Raikov"
>ersatz</a> templates</p></footer></html>