distro: Add GNU Shishi.
[jackhill/guix/guix.git] / distro.scm
CommitLineData
6b1891b0
LC
1;;; Guix --- Nix package management from Guile. -*- coding: utf-8 -*-
2;;; Copyright (C) 2012 Ludovic Courtès <ludo@gnu.org>
3;;;
4;;; This file is part of Guix.
5;;;
6;;; Guix is free software; you can redistribute it and/or modify it
7;;; under the terms of the GNU General Public License as published by
8;;; the Free Software Foundation; either version 3 of the License, or (at
9;;; your option) any later version.
10;;;
11;;; Guix is distributed in the hope that it will be useful, but
12;;; WITHOUT ANY WARRANTY; without even the implied warranty of
13;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14;;; GNU General Public License for more details.
15;;;
16;;; You should have received a copy of the GNU General Public License
17;;; along with Guix. If not, see <http://www.gnu.org/licenses/>.
18
19(define-module (distro)
20 #:use-module (guix packages)
800cdeef 21 #:use-module (guix utils)
6b1891b0
LC
22 #:use-module (ice-9 ftw)
23 #:use-module (srfi srfi-1)
24 #:use-module (srfi srfi-26)
800cdeef
LC
25 #:use-module (srfi srfi-39)
26 #:export (search-patch
ac5aa288 27 search-bootstrap-binary
800cdeef 28 %patch-directory
ba326ce4 29 fold-packages
800cdeef 30 find-packages-by-name))
6b1891b0
LC
31
32;;; Commentary:
33;;;
34;;; General utilities for the software distribution---i.e., the modules under
35;;; (distro ...).
36;;;
37;;; Code:
38
39(define _ (cut gettext <> "guix"))
40
a9f60c42
LC
41(define not-colon
42 ;; The char set that contains all the characters but `:'.
43 (char-set-complement (char-set #\:)))
44
45(define %patch-path
800cdeef 46 (make-parameter
a9f60c42
LC
47 (or (and=> (getenv "DISTRO_PATCH_PATH")
48 (cut string-tokenize <> not-colon))
49 (compile-time-value
50 (list (getenv "DISTRO_INSTALLED_PATCH_DIRECTORY"))))))
800cdeef 51
a9f60c42 52(define %bootstrap-binaries-path
ac5aa288 53 (make-parameter
a9f60c42
LC
54 (or (and=> (getenv "DISTRO_BOOTSTRAP_PATH")
55 (cut string-tokenize <> not-colon))
56 (compile-time-value
57 (list (getenv "DISTRO_INSTALLED_BOOTSTRAP_DIRECTORY"))))))
ac5aa288 58
800cdeef
LC
59(define (search-patch file-name)
60 "Search the patch FILE-NAME."
a9f60c42 61 (search-path (%patch-path) file-name))
800cdeef 62
ac5aa288
LC
63(define (search-bootstrap-binary file-name system)
64 "Search the bootstrap binary FILE-NAME for SYSTEM."
a9f60c42 65 (search-path (%bootstrap-binaries-path)
ac5aa288
LC
66 (string-append system "/" file-name)))
67
6b1891b0
LC
68(define %distro-module-directory
69 ;; Absolute path of the (distro ...) module root.
70 (string-append (dirname (search-path %load-path "distro.scm"))
1f455fdc 71 "/distro/packages"))
6b1891b0
LC
72
73(define (package-files)
74 "Return the list of files that implement distro modules."
75 (define prefix-len
1722d680 76 (string-length (dirname (search-path %load-path "distro.scm"))))
6b1891b0
LC
77
78 (file-system-fold (const #t) ; enter?
79 (lambda (path stat result) ; leaf
80 (if (string-suffix? ".scm" path)
81 (cons (substring path prefix-len) result)
82 result))
83 (lambda (path stat result) ; down
84 result)
85 (lambda (path stat result) ; up
86 result)
87 (const #f) ; skip
88 (lambda (path stat errno result)
89 (format (current-error-port)
49feac7a 90 (_ "warning: cannot access `~a': ~a~%")
6b1891b0
LC
91 path (strerror errno))
92 result)
93 '()
94 %distro-module-directory
95 stat))
96
97(define (package-modules)
98 "Return the list of modules that provide packages for the distribution."
99 (define not-slash
100 (char-set-complement (char-set #\/)))
101
102 (filter-map (lambda (path)
103 (let ((name (map string->symbol
104 (string-tokenize (string-drop-right path 4)
105 not-slash))))
106 (false-if-exception (resolve-interface name))))
107 (package-files)))
108
ba326ce4
LC
109(define (fold-packages proc init)
110 "Call (PROC PACKAGE RESULT) for each available package, using INIT as
111the initial value of RESULT."
112 (fold (lambda (module result)
113 (fold (lambda (var result)
114 (if (package? var)
115 (proc var result)
116 result))
117 result
118 (module-map (lambda (sym var)
119 (false-if-exception (variable-ref var)))
120 module)))
121 init
122 (package-modules)))
123
6b1891b0
LC
124(define* (find-packages-by-name name #:optional version)
125 "Return the list of packages with the given NAME. If VERSION is not #f,
126then only return packages whose version is equal to VERSION."
127 (define right-package?
128 (if version
129 (lambda (p)
ba326ce4 130 (and (string=? (package-name p) name)
6b1891b0
LC
131 (string=? (package-version p) version)))
132 (lambda (p)
ba326ce4
LC
133 (string=? (package-name p) name))))
134
135 (fold-packages (lambda (package result)
136 (if (right-package? package)
137 (cons package result)
138 result))
139 '()))