From 81a03d59de401403c56c23a506a63d26b1904a11 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sun, 29 Dec 2013 08:35:21 -0600 Subject: [PATCH] raco test: add "info.rkt" field `test-omit-paths` Using an "info.rkt" field is a fallback for when a submodule won't do (e.g., because the module doesn't normally compile). --- .../compiler-lib/compiler/commands/test.rkt | 99 ++++++++++++++++--- .../racket-doc/scribblings/raco/test.scrbl | 19 ++++ 2 files changed, 107 insertions(+), 11 deletions(-) diff --git a/pkgs/compiler-pkgs/compiler-lib/compiler/commands/test.rkt b/pkgs/compiler-pkgs/compiler-lib/compiler/commands/test.rkt index a8f8310400..d71ae4e250 100644 --- a/pkgs/compiler-pkgs/compiler-lib/compiler/commands/test.rkt +++ b/pkgs/compiler-pkgs/compiler-lib/compiler/commands/test.rkt @@ -13,7 +13,9 @@ raco/command-name racket/system rackunit/log - pkg/lib) + pkg/lib + setup/collects + setup/getinfo) (define submodules '()) ; '() means "default" (define first-avail? #f) @@ -379,24 +381,33 @@ (set! ids (cons id ids)))))))) ;; Perform all tests in path `e`: -(define (test-files e [check-suffix? #f] #:sema continue-sema) +(define (test-files e + #:check-suffix? [check-suffix? #f] + #:sema continue-sema) (match e [(? string? s) - (test-files (string->path s) check-suffix? #:sema continue-sema)] + (test-files (string->path s) + #:check-suffix? check-suffix? + #:sema continue-sema)] [(? path? p) (cond [(directory-exists? p) (set! single-file? #f) - (with-summary - `(directory ,p) - (map/parallel - (λ (dp #:sema s) - (test-files (build-path p dp) #t #:sema s)) - (directory-list p) - #:sema continue-sema))] + (if (omit-path? (path->directory-path p)) + (summary 0 0 #f 0) + (with-summary + `(directory ,p) + (map/parallel + (λ (dp #:sema s) + (test-files (build-path p dp) + #:check-suffix? #t + #:sema s)) + (directory-list p) + #:sema continue-sema)))] [(and (file-exists? p) (or (not check-suffix?) - (regexp-match #rx#"\\.rkt$" (path->bytes p)))) + (regexp-match #rx#"\\.rkt$" (path->bytes p))) + (not (omit-path? p))) (parameterize ([current-directory (let-values ([(base name dir?) (split-path p)]) (if (path? base) base @@ -513,6 +524,72 @@ [else (test-files e #:sema continue-sema)])) +;; -------------------------------------------------- +;; Reading "info.rkt" files + +(define omit-paths (make-hash)) + +(define collects-cache (make-hash)) +(define info-done (make-hash)) + +(define (check-info p check-up?) + (define-values (base name dir?) (split-path p)) + (define dir (normalize-info-path + (if dir? + p + (if (path? base) + (path->complete-path base) + (current-directory))))) + + (when (and check-up? (not dir?)) + ;; Check enclosing collection + (define c (path->collects-relative p #:cache collects-cache)) + (when (list? c) + (check-info/parents dir + (apply build-path (map bytes->path (reverse (cdr (reverse (cdr c))))))))) + + (unless (hash-ref info-done dir #f) + (hash-set! info-done dir #t) + (define info (get-info/full dir)) + (when info + (define v (info 'test-omit-paths (lambda () '()))) + (define (bad) + (log-error "bad `test-omit-paths` in \"info.rkt\": ~e" v)) + (cond + [(eq? v 'all) + (hash-set! omit-paths dir #t)] + [(list? v) + (for ([i (in-list v)]) + (unless (path-string? i) (bad)) + (define p (normalize-info-path (path->complete-path i dir))) + (define dp (if (directory-exists? p) + (path->directory-path p) + p)) + (hash-set! omit-paths dp #t))] + [else (bad)])))) + +(define (check-info/parents dir subpath) + (let loop ([dir dir] [subpath subpath]) + (unless (hash-ref info-done dir #f) + (check-info dir #f) + (define-values (next-subpath subpath-name subpath-dir?) (split-path subpath)) + (define-values (next-dir dir-name dir-dir?) (split-path dir)) + (when (path? next-subpath) + (loop next-dir next-subpath))))) + +(define (normalize-info-path p) + (simplify-path (path->complete-path p) #f)) + +(define (omit-path? p) + (check-info p #t) + (let ([p (normalize-info-path p)]) + (or (hash-ref omit-paths p #f) + (let-values ([(base name dir?) (split-path p)]) + (and (path? base) + (omit-path? base)))))) + +;; -------------------------------------------------- + (define (string->number* what s check) (define n (string->number s)) (unless (check n) diff --git a/pkgs/racket-pkgs/racket-doc/scribblings/raco/test.scrbl b/pkgs/racket-pkgs/racket-doc/scribblings/raco/test.scrbl index 0b7a986a9c..a5c5e26d88 100644 --- a/pkgs/racket-pkgs/racket-doc/scribblings/raco/test.scrbl +++ b/pkgs/racket-pkgs/racket-doc/scribblings/raco/test.scrbl @@ -110,3 +110,22 @@ identifiers: @item{@racket[timeout] --- override the default timeout for the test} ] + +To prevent @exec{raco test} from running a particular file, normally +the file should contain a submodule that takes no action. In some +cases, however, adding a submodule is inconvenient or impossible +(e.g., because the file will not always compile). Thus, @exec{raco +test} also consults any @filepath{info.rkt} file in the candidate test +file's directory; in the case of a file within a collection, +@filepath{info.rkt} files from any enclosing collection directories +are also consulted. The following @filepath{info.rkt} fields are +recognized: + +@itemlist[ + + @item{@racket[test-omit-paths] --- a list of path strings (relative + to the enclosing directory) or @racket['all] to omit all files within + the enclosing directory. When a path string refers to a directory, + all files within the directory are omitted.} + +]