aboutsummaryrefslogtreecommitdiff
path: root/gnu/home/services/vcs.scm
blob: 6ac7140d7031584913320a43d0a6f7cdf73674fc (about) (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
;;; SPDX-License-Identifier: CC0-1.0
;;;
;;; Copyright © 2023 Wojtek Kosior <koszko@koszko.org>

(define-module (gnu home services vcs)
  #:use-module ((guix gexp) #:select
                (gexp file-append mixed-text-file computed-file file-like?))
  #:use-module ((gnu services) #:select (service-type service-extension))
  #:use-module ((gnu services configuration) #:select
                (define-configuration/no-serialization alist?))
  #:use-module ((gnu home services shepherd) #:select
                (home-shepherd-service-type shepherd-service))
  #:use-module ((gnu packages version-control) #:select (git))
  #:use-module ((gnu packages web) #:select (lighttpd))
  #:export (home-localhost-repo-server-configuration
            home-localhost-repo-server-configuration?
            home-localhost-repo-server-configuration-lighttpd
            home-localhost-repo-server-configuration-git
            home-localhost-repo-server-configuration-port
            home-localhost-repo-server-configuration-repos

            home-localhost-repo-server-service-type))

(define-configuration/no-serialization
  home-localhost-repo-server-configuration
  (lighttpd
   (file-like lighttpd)
   "The Lighttpd package to use.")
  (git
   (file-like git)
   "The Git package to use.")
  (port
   (integer 8098)
   "TCP port to serve repositories on.")
  (repos
   (alist '())
   "Association list mapping repository names to their filesystm paths."))

(define (repositories-root repos)
  (computed-file "repos"
                 #~(begin
                     (mkdir #$output)
                     (chdir #$output)
                     (for-each (lambda (repo)
                                 (symlink (cdr repo) (car repo)))
                               '#$repos))))

(define (lighttpd-conf config)
  (let* ((repos (home-localhost-repo-server-configuration-repos config))
         (git (home-localhost-repo-server-configuration-git config))
         (port (home-localhost-repo-server-configuration-port config))
         (git-backend (file-append git "/libexec/git-core/git-http-backend")))
    (mixed-text-file "lighttpd.conf"
                   "\
server.document-root = \"/dev/null\"
server.modules = ( \"mod_alias\", \"mod_cgi\", \"mod_setenv\")
server.port = " (format #f "~a" port) "

alias.url = ( \"/\" => \"" git-backend "/\" )
cgi.assign = (\"\" => \"\")

setenv.add-environment = (
    \"GIT_PROJECT_ROOT\" => \"" (repositories-root repos) "\",
    \"GIT_HTTP_EXPORT_ALL\" => \"\"
)
")))

(define (home-localhost-repo-server-services config)
  (let ((lighttpd (home-localhost-repo-server-configuration-lighttpd config))
        (lighttpd-config-file (lighttpd-conf config)))
    (list (shepherd-service
           (provision '(localhost-repo-server))
           (modules '((shepherd support)))      ;for '%user-log-dir'
           (start #~(make-forkexec-constructor
                     '(#$(file-append lighttpd "/sbin/lighttpd") "-D"
                       "-f" #$lighttpd-config-file)
                     #:log-file (string-append
                                 %user-log-dir
                                 "/localhost-repo-server.log")))
           (stop #~(make-kill-destructor))
           (documentation "Start local Lighttpd process that will serve
cloneable git repositories on localhost.")))))

(define home-localhost-repo-server-service-type
  (service-type
   (name 'home-localhost-repo-server)
   (extensions
    (list (service-extension home-shepherd-service-type
                             home-localhost-repo-server-services)))
   (description "Serve local GIT repositories over HTTP so that they can be
easily cloneable using http://localhost URLs.")
   (default-value (home-localhost-repo-server-configuration))))