From 6568d2bd6e4e047dd95b00a7a6e7501a16491eb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20Court=C3=A8s?= Date: Mon, 4 May 2015 21:44:52 +0200 Subject: search-paths: Add 'evaluate-search-paths', from (guix scripts package). * guix/scripts/package.scm (with-null-error-port, evaluate-search-paths): Move to... * guix/search-paths.scm: ... here. * guix/utils.scm (string-tokenize*): Move to... * guix/search-paths.scm: ... here. * tests/utils.scm ("string-tokenize*"): Adjust accordingly. --- guix/search-paths.scm | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 71 insertions(+), 1 deletion(-) (limited to 'guix/search-paths.scm') diff --git a/guix/search-paths.scm b/guix/search-paths.scm index 147bfcae8c..b17f5acd5d 100644 --- a/guix/search-paths.scm +++ b/guix/search-paths.scm @@ -18,6 +18,9 @@ (define-module (guix search-paths) #:use-module (guix records) + #:use-module (guix build utils) + #:use-module (srfi srfi-1) + #:use-module (srfi srfi-26) #:use-module (ice-9 match) #:export ( search-path-specification @@ -29,7 +32,8 @@ search-path-specification-file-pattern search-path-specification->sexp - sexp->search-path-specification)) + sexp->search-path-specification + evaluate-search-paths)) ;;; Commentary: ;;; @@ -74,4 +78,70 @@ a object." (file-type type) (file-pattern pattern))))) +(define-syntax-rule (with-null-error-port exp) + "Evaluate EXP with the error port pointing to the bit bucket." + (with-error-to-port (%make-void-port "w") + (lambda () exp))) + +;; XXX: This procedure used to be in (guix utils) but since we want to be able +;; to use (guix search-paths) on the build side, we want to avoid the +;; dependency on (guix utils), and so this procedure is back here for now. +(define (string-tokenize* string separator) + "Return the list of substrings of STRING separated by SEPARATOR. This is +like `string-tokenize', but SEPARATOR is a string." + (define (index string what) + (let loop ((string string) + (offset 0)) + (cond ((string-null? string) + #f) + ((string-prefix? what string) + offset) + (else + (loop (string-drop string 1) (+ 1 offset)))))) + + (define len + (string-length separator)) + + (let loop ((string string) + (result '())) + (cond ((index string separator) + => + (lambda (offset) + (loop (string-drop string (+ offset len)) + (cons (substring string 0 offset) + result)))) + (else + (reverse (cons string result)))))) + +(define* (evaluate-search-paths search-paths directory + #:optional (getenv (const #f))) + "Evaluate SEARCH-PATHS, a list of search-path specifications, for DIRECTORY, +and return a list of variable/value pairs. Use GETENV to determine the +current settings and report only settings not already effective." + (define search-path-definition + (match-lambda + (($ variable files separator + type pattern) + (let* ((values (or (and=> (getenv variable) + (cut string-tokenize* <> separator)) + '())) + ;; Add a trailing slash to force symlinks to be treated as + ;; directories when 'find-files' traverses them. + (files (if pattern + (map (cut string-append <> "/") files) + files)) + + ;; XXX: Silence 'find-files' when it stumbles upon non-existent + ;; directories (see + ;; .) + (path (with-null-error-port + (search-path-as-list files (list directory) + #:type type + #:pattern pattern)))) + (if (every (cut member <> values) path) + #f ;VARIABLE is already set appropriately + (cons variable (string-join path separator))))))) + + (filter-map search-path-definition search-paths)) + ;;; search-paths.scm ends here -- cgit v1.2.3