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