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 }}