;;; GNU Guix --- Functional package management for GNU ;;; Copyright © 2018 Mark H Weaver ;;; ;;; This file is part of GNU Guix. ;;; ;;; GNU Guix is free software; you can redistribute it and/or modify it ;;; under the terms of the GNU General Public License as published by ;;; the Free Software Foundation; either version 3 of the License, or (at ;;; your option) any later version. ;;; ;;; GNU Guix is distributed in the hope that it will be useful, but ;;; WITHOUT ANY WARRANTY; without even the implied warranty of ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;;; GNU General Public License for more details. ;;; ;;; You should have received a copy of the GNU General Public License ;;; along with GNU Guix. If not, see . ;;; This is very preliminary work. (use-modules (guix) (guix derivations) (gnu) (ice-9 match) (srfi srfi-1)) (define proc-returns-t? (match-lambda (((or 'lambda 'lambda*) formals bodies ... last) (returns-t? last)) (((or 'let 'let* 'letrec 'letrec* 'with-fluids) (bindings ...) bodies ... last) (proc-returns-t? last)) (('begin exprs ... last) (proc-returns-t? last)) (('const expr) (returns-t? expr)) ('invoke #t) (_ #f))) (define returns-t? (match-lambda (#t #t) (('begin exprs ... last) (returns-t? last)) (((or 'let 'let* 'letrec 'letrec* 'with-fluids) (bindings ...) bodies ... last) (returns-t? last)) (('match expr (pattern bodies ... last) ...) (every returns-t? last)) (('with-directory-excursion dir bodies ... last) (returns-t? last)) (((or 'call-with-input-file 'call-with-output-file 'with-input-to-file 'with-output-to-file 'with-atomic-file-replacement) file-name proc) (proc-returns-t? proc)) (('apply proc args ... tail) (proc-returns-t? proc)) ((proc args ...) (proc-returns-t? proc)) (_ #f))) (define mod-spec-returns-t? (match-lambda (((or 'add-before 'add-after) _ _ proc) (proc-returns-t? proc)) (('replace _ proc) (proc-returns-t? proc)) (('delete _) #t))) (define phases-return-t? (match-lambda (#f #t) ('%standard-phases #t) (('modify-phases orig mod-specs ...) (and (every mod-spec-returns-t? mod-specs) (phases-return-t? orig))) (((or 'alist-cons-before 'alist-cons-after) _ _ proc orig) (and (proc-returns-t? proc) (phases-return-t? orig))) (('alist-replace _ proc orig) (and (proc-returns-t? proc) (phases-return-t? orig))) (('alist-delete _ orig) (phases-return-t? orig)) (_ #f))) (define (package-snippet pkg) (and=> (package-source pkg) origin-snippet)) (define (snippet-returns-t? snippet) (or (not snippet) (returns-t? snippet))) (define (possible-snippet-problem-pkgs) (fold-packages cons '() #:select? (negate (compose snippet-returns-t? package-snippet)))) (define (arguments->phases arguments) (apply (lambda* (#:key phases #:allow-other-keys) phases) arguments)) (define (package-phases pkg) (and=> (package-arguments pkg) arguments->phases)) (define (possible-phase-problem-pkgs) (fold-packages cons '() #:select? (negate (compose phases-return-t? package-phases)))) (define (arguments->builder arguments) (apply (lambda* (#:key builder #:allow-other-keys) builder) arguments)) (define (package-builder pkg) (and=> (package-arguments pkg) arguments->builder)) (define (builder-returns-t? builder) (or (not builder) (returns-t? builder))) (define (possible-builder-problem-pkgs) (fold-packages cons '() #:select? (negate (compose builder-returns-t? package-builder)))) (define (package-namephases arguments))) (not (phases-return-t? phases)))) (_ #f))))) (_ #f))))) drv-files))