Initial commit.
gitile/config.scm unknown status 1
| 1 | + | ;;;; Copyright (C) 2020 Julien Lepiller <julien@lepiller.eu> | |
| 2 | + | ;;;; | |
| 3 | + | ;;;; This library is free software; you can redistribute it and/or | |
| 4 | + | ;;;; modify it under the terms of the GNU Lesser General Public | |
| 5 | + | ;;;; License as published by the Free Software Foundation; either | |
| 6 | + | ;;;; version 3 of the License, or (at your option) any later version. | |
| 7 | + | ;;;; | |
| 8 | + | ;;;; This library is distributed in the hope that it will be useful, | |
| 9 | + | ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 10 | + | ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| 11 | + | ;;;; Lesser General Public License for more details. | |
| 12 | + | ;;;; | |
| 13 | + | ;;;; You should have received a copy of the GNU Lesser General Public | |
| 14 | + | ;;;; License along with this library; if not, write to the Free Software | |
| 15 | + | ;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
| 16 | + | ;;;; | |
| 17 | + | ||
| 18 | + | (define-module (gitile config) | |
| 19 | + | #:use-module (srfi srfi-9) | |
| 20 | + | #:export (make-config | |
| 21 | + | config? | |
| 22 | + | config-port | |
| 23 | + | config-host | |
| 24 | + | config-database | |
| 25 | + | config-repositories)) | |
| 26 | + | ||
| 27 | + | (define-record-type config | |
| 28 | + | (make-config port host database repositories) | |
| 29 | + | config? | |
| 30 | + | (port config-port) | |
| 31 | + | (host config-host) | |
| 32 | + | (database config-database) | |
| 33 | + | (repositories config-repositories)) |
gitile/handler.scm unknown status 1
| 1 | + | ;;;; Copyright (C) 2020 Julien Lepiller <julien@lepiller.eu> | |
| 2 | + | ;;;; | |
| 3 | + | ;;;; This library is free software; you can redistribute it and/or | |
| 4 | + | ;;;; modify it under the terms of the GNU Lesser General Public | |
| 5 | + | ;;;; License as published by the Free Software Foundation; either | |
| 6 | + | ;;;; version 3 of the License, or (at your option) any later version. | |
| 7 | + | ;;;; | |
| 8 | + | ;;;; This library is distributed in the hope that it will be useful, | |
| 9 | + | ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 10 | + | ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| 11 | + | ;;;; Lesser General Public License for more details. | |
| 12 | + | ;;;; | |
| 13 | + | ;;;; You should have received a copy of the GNU Lesser General Public | |
| 14 | + | ;;;; License along with this library; if not, write to the Free Software | |
| 15 | + | ;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
| 16 | + | ;;;; | |
| 17 | + | ||
| 18 | + | (define-module (gitile handler) | |
| 19 | + | #:use-module (fibers web server) | |
| 20 | + | #:use-module (git) | |
| 21 | + | #:use-module (gitile pages) | |
| 22 | + | #:use-module (ice-9 match) | |
| 23 | + | #:use-module (web request) | |
| 24 | + | #:use-module (web response) | |
| 25 | + | #:use-module (web uri) | |
| 26 | + | #:export (gitile-handler)) | |
| 27 | + | ||
| 28 | + | (define (request-path-components request) | |
| 29 | + | (split-and-decode-uri-path (uri-path (request-uri request)))) | |
| 30 | + | ||
| 31 | + | (define (not-found request) | |
| 32 | + | (format #t "Not found: ~a~%" (uri->string (request-uri request))) | |
| 33 | + | (values (build-response #:code 404) | |
| 34 | + | (string-append "Resource not found: " | |
| 35 | + | (uri->string (request-uri request))))) | |
| 36 | + | ||
| 37 | + | (define (style page project ref) | |
| 38 | + | `(html | |
| 39 | + | (head | |
| 40 | + | (meta (@ (charset "UTF-8"))) | |
| 41 | + | (meta (@ (name "viewport") (content "width=device-width, initial-scale=1"))) | |
| 42 | + | (link (@ (rel "stylesheet") (href "/css/gitile.css")))) | |
| 43 | + | (body | |
| 44 | + | (header | |
| 45 | + | (nav | |
| 46 | + | (ul | |
| 47 | + | (li (@ (class "first")) (a (@ (href "/")) "Projects")) | |
| 48 | + | (li (a (@ (href "/" project)) "Repository")) | |
| 49 | + | (li (a (@ (href "/" project "/tree/" ref)) "Files")) | |
| 50 | + | (li (a (@ (href "/" project "/ommits")) "Commits")) | |
| 51 | + | (li (a (@ (href "/" project "/tags")) "Tags"))))) | |
| 52 | + | (div (@ (id "content")) | |
| 53 | + | ,@page) | |
| 54 | + | (footer (p (a (@ (href "https://lepiller.eu")) "Who am I?")))))) | |
| 55 | + | ||
| 56 | + | (define (show page) | |
| 57 | + | (values '((content-type . (text/html))) | |
| 58 | + | (with-output-to-string (lambda _ (sxml->xml page))))) | |
| 59 | + | ||
| 60 | + | (define (show-raw page) | |
| 61 | + | (values '((content-type . (text/plain))) | |
| 62 | + | page)) | |
| 63 | + | ||
| 64 | + | (define (gitile-handler config) | |
| 65 | + | (define (get-repo name) | |
| 66 | + | (repository-open (string-append repositories "/" name ".git"))) | |
| 67 | + | ||
| 68 | + | (match config | |
| 69 | + | (($ config port host database repositories) | |
| 70 | + | (lambda (request body) | |
| 71 | + | (pk 'request request) | |
| 72 | + | (pk 'body (if body (utf8->string body) body)) | |
| 73 | + | (match (request-path-components request) | |
| 74 | + | ((project-name) (show (project-index project-name))) | |
| 75 | + | ((project-name "tree" ref path ...) | |
| 76 | + | (show (style (project-files (get-repo project-name) #:ref ref #:path path) | |
| 77 | + | project-name ref))) | |
| 78 | + | ((project-name "raw" ref path ...) | |
| 79 | + | (show-raw (project-file-raw (get-repo project-name) path #:ref ref))) | |
| 80 | + | ((project-name "commits") | |
| 81 | + | (style (show not-yet-page) project-name "-")) | |
| 82 | + | ((project-name "commits" ref) | |
| 83 | + | (show (style not-yet-page project-name ref))) | |
| 84 | + | ((project-name "tags") | |
| 85 | + | (show (style not-yet-page project-name "-")))))))) |
gitile/pages.scm unknown status 1
| 1 | + | ;;;; Copyright (C) 2020 Julien Lepiller <julien@lepiller.eu> | |
| 2 | + | ;;;; | |
| 3 | + | ;;;; This library is free software; you can redistribute it and/or | |
| 4 | + | ;;;; modify it under the terms of the GNU Lesser General Public | |
| 5 | + | ;;;; License as published by the Free Software Foundation; either | |
| 6 | + | ;;;; version 3 of the License, or (at your option) any later version. | |
| 7 | + | ;;;; | |
| 8 | + | ;;;; This library is distributed in the hope that it will be useful, | |
| 9 | + | ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 10 | + | ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| 11 | + | ;;;; Lesser General Public License for more details. | |
| 12 | + | ;;;; | |
| 13 | + | ;;;; You should have received a copy of the GNU Lesser General Public | |
| 14 | + | ;;;; License along with this library; if not, write to the Free Software | |
| 15 | + | ;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
| 16 | + | ;;;; | |
| 17 | + | ||
| 18 | + | (define-module (gitile pages) | |
| 19 | + | #:use-module (gitile repo) | |
| 20 | + | #:export (not-yet-page | |
| 21 | + | project-file-raw | |
| 22 | + | project-files)) | |
| 23 | + | ||
| 24 | + | (define not-yet-page | |
| 25 | + | `(p "Not yet available, sorry :/")) | |
| 26 | + | ||
| 27 | + | (define* (project-file-raw repo path #:key (ref #f)) | |
| 28 | + | (get-file-content repo path #:ref ref)) | |
| 29 | + | ||
| 30 | + | (define* (project-files repo #:key (ref #f) (path "")) | |
| 31 | + | (let ((files (get-files repo #:ref ref #:path path))) | |
| 32 | + | (if (and (string-null? path) (null? files)) | |
| 33 | + | `(p "Empty repository") | |
| 34 | + | (if (null? files) | |
| 35 | + | `((p "file content") | |
| 36 | + | (pre ,@(get-file-content repo path #:ref ref))) | |
| 37 | + | `((p "directory content") | |
| 38 | + | ,@(map | |
| 39 | + | (lambda (file) | |
| 40 | + | `(p ,file)) | |
| 41 | + | files)))))) |
gitile/repo.scm unknown status 1
| 1 | + | ;;;; Copyright (C) 2020 Julien Lepiller <julien@lepiller.eu> | |
| 2 | + | ;;;; | |
| 3 | + | ;;;; This library is free software; you can redistribute it and/or | |
| 4 | + | ;;;; modify it under the terms of the GNU Lesser General Public | |
| 5 | + | ;;;; License as published by the Free Software Foundation; either | |
| 6 | + | ;;;; version 3 of the License, or (at your option) any later version. | |
| 7 | + | ;;;; | |
| 8 | + | ;;;; This library is distributed in the hope that it will be useful, | |
| 9 | + | ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 10 | + | ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| 11 | + | ;;;; Lesser General Public License for more details. | |
| 12 | + | ;;;; | |
| 13 | + | ;;;; You should have received a copy of the GNU Lesser General Public | |
| 14 | + | ;;;; License along with this library; if not, write to the Free Software | |
| 15 | + | ;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
| 16 | + | ;;;; | |
| 17 | + | ||
| 18 | + | (define-module (gitile repo) | |
| 19 | + | #:use-module (git) | |
| 20 | + | #:export (get-branches | |
| 21 | + | get-tags | |
| 22 | + | get-files)) | |
| 23 | + | ||
| 24 | + | (define (get-branches repo) | |
| 25 | + | (map (lambda (ref) (cons (reference-shorthand ref) (reference-name ref))) | |
| 26 | + | (filter reference-branch? (reference-fold cons '() repo)))) | |
| 27 | + | ||
| 28 | + | (define (get-tags repo) | |
| 29 | + | (map (lambda (ref) (cons (reference-shorthand ref) (reference-name ref))) | |
| 30 | + | (filter reference-tag? (reference-fold cons '() repo)))) | |
| 31 | + | ||
| 32 | + | (define (search-reference repo name) | |
| 33 | + | (reference-fold (lambda (ref acc) | |
| 34 | + | (if (equal? name (reference-shorthand ref)) | |
| 35 | + | (reference-name ref) | |
| 36 | + | acc)) | |
| 37 | + | #f | |
| 38 | + | repo)) | |
| 39 | + | ||
| 40 | + | (define (ref->oid repo ref) | |
| 41 | + | (let ((ref-name (or ref | |
| 42 | + | (false-if-exception (reference-name (repository-head repo)))))) | |
| 43 | + | (or (false-if-exception (string->oid ref-name)) | |
| 44 | + | (false-if-exception (reference-name->oid repo ref-name)) | |
| 45 | + | (reference-name->oid (search-reference repo ref-name))))) | |
| 46 | + | ||
| 47 | + | (define* (get-files repo #:key (path "") (ref #f)) | |
| 48 | + | (let* ((oid (ref->oid repo ref)) | |
| 49 | + | (commit (commit-lookup repo oid)) | |
| 50 | + | (tree (commit-tree commit))) | |
| 51 | + | (let ((result '())) | |
| 52 | + | (tree-walk | |
| 53 | + | tree TREEWALK-PRE | |
| 54 | + | (lambda (root entry) | |
| 55 | + | (when (equal? root path) | |
| 56 | + | (set! result (cons (string-append root (tree-entry-name entry)) | |
| 57 | + | result))) | |
| 58 | + | 0))))) | |
| 59 | + | ||
| 60 | + | (define (find-tree-item tree name) | |
| 61 | + | (let ((result #f)) | |
| 62 | + | (tree-walk | |
| 63 | + | tree TREEWALK-PRE | |
| 64 | + | (lambda (root entry) | |
| 65 | + | (let ((filepath (string-append root (tree-entry-name entry)))) | |
| 66 | + | (when (equal? name filepath) | |
| 67 | + | (set! result entry)) | |
| 68 | + | 0))) | |
| 69 | + | result)) | |
| 70 | + | ||
| 71 | + | (define* (get-file-content repo path #:key (ref #f)) | |
| 72 | + | (let* ((oid (ref->oid ref)) | |
| 73 | + | (commit (commit-lookup repo oid)) | |
| 74 | + | (tree (commit-tree commit)) | |
| 75 | + | (entry (find-tree-item tree path)) | |
| 76 | + | (entry-oid (entry-id entry)) | |
| 77 | + | (blob (blob-lookup repo entry-oid))) | |
| 78 | + | (blob-content blob))) |