avoid using directory-exists?
as part of a contract
Although a `directory-exists?` check is useful for providing better
error messages, it's fundentally a race condition, since an external
process can always remove a directory between the check and a use of
the directory. Because of that limitation of `directory-exists?`, we
normally avoid making it part of a contract. This commit adjust
937aa3cdb1
to follow that convention while preserving the helpful
check and documentation improvements.
This commit is contained in:
parent
6c0d193132
commit
2b9c0c4689
|
@ -215,21 +215,23 @@ with the same file/directory omissions and updates as
|
|||
@command-ref{create}.}
|
||||
|
||||
@defproc[(generate-stripped-directory [mode (or/c 'source 'binary 'binary-lib 'built)]
|
||||
[src-dir (and/c path-string? directory-exists?)]
|
||||
[dest-dir (and/c path-string? directory-exists?)])
|
||||
[src-dir path-string?]
|
||||
[dest-dir path-string?])
|
||||
void?]{
|
||||
|
||||
Copies @racket[src-dir] to @racket[dest-dir] with file/directory
|
||||
omissions and updates corresponding to the creation of a @tech{source
|
||||
package}, @tech{binary package}, @tech{binary library package}, or @tech{built package} as indicated
|
||||
by @racket[mode].} Note, @racket[generate-stripped-directory] does not compile or render source files
|
||||
by @racket[mode]. The given @racket[src-dir] and @racket[dest-dir] must both exist already.
|
||||
|
||||
Note that @racket[generate-stripped-directory] does not compile or render source files
|
||||
found in the @racket[src-dir]. To perform precompilation or rendering before stripping the source directory,
|
||||
use @exec{raco setup} or @exec{raco make}.
|
||||
use @exec{raco setup} or @exec{raco make}.}
|
||||
|
||||
|
||||
@defproc[(check-strip-compatible [mode (or/c 'source 'binary 'binary-lib 'built)]
|
||||
[pkg-name string?]
|
||||
[dir (and/c path-string? directory-exists?)]
|
||||
[dir path-string?]
|
||||
[error (string? . -> . any)])
|
||||
any]{
|
||||
|
||||
|
|
|
@ -14,35 +14,37 @@
|
|||
(define pkg-dest-path (build-path tmp-dir "pkg-strip"))
|
||||
(make-directory pkg-dest-path)
|
||||
|
||||
(define rx:does-not-exist #rx"directory does not exist")
|
||||
|
||||
;; Giving path to nonexistent directory should raise a contract exception.
|
||||
(check-exn #rx"expected: \\(and/c path-string\\? directory-exists\\?\\)" (lambda () (check-strip-compatible 'source "pkg-strip" "does not exist" error)))
|
||||
(check-exn rx:does-not-exist (lambda () (check-strip-compatible 'source "pkg-strip" "does not exist" error)))
|
||||
|
||||
(check-exn #rx"expected: \\(and/c path-string\\? directory-exists\\?\\)" (lambda () (check-strip-compatible 'binary "pkg-strip" "does not exist" error)))
|
||||
(check-exn rx:does-not-exist (lambda () (check-strip-compatible 'binary "pkg-strip" "does not exist" error)))
|
||||
|
||||
(check-exn #rx"expected: \\(and/c path-string\\? directory-exists\\?\\)" (lambda () (check-strip-compatible 'binary-lib "pkg-strip" "does not exist" error)))
|
||||
(check-exn rx:does-not-exist (lambda () (check-strip-compatible 'binary-lib "pkg-strip" "does not exist" error)))
|
||||
|
||||
(check-exn #rx"expected: \\(and/c path-string\\? directory-exists\\?\\)" (lambda () (check-strip-compatible 'built "pkg-strip" "does not exist" error)))
|
||||
(check-exn rx:does-not-exist (lambda () (check-strip-compatible 'built "pkg-strip" "does not exist" error)))
|
||||
|
||||
;; Path to existing directory should succeed.
|
||||
(check-not-exn (lambda () (check-strip-compatible 'source "pkg-strip" pkg-path error)))
|
||||
|
||||
;; Giving path to nonexistent src directory should raise a contract exception.
|
||||
(check-exn #rx"expected: \\(and/c path-string\\? directory-exists\\?\\)" (lambda () (generate-stripped-directory 'source 5 pkg-dest-path)))
|
||||
(check-exn exn:fail:contract? (lambda () (generate-stripped-directory 'source 5 pkg-dest-path)))
|
||||
|
||||
(check-exn #rx"expected: \\(and/c path-string\\? directory-exists\\?\\)" (lambda () (generate-stripped-directory 'binary "does not exist" pkg-dest-path)))
|
||||
(check-exn rx:does-not-exist (lambda () (generate-stripped-directory 'binary "does not exist" pkg-dest-path)))
|
||||
|
||||
(check-exn #rx"expected: \\(and/c path-string\\? directory-exists\\?\\)" (lambda () (generate-stripped-directory 'binary-lib "does not exist" pkg-dest-path)))
|
||||
(check-exn rx:does-not-exist (lambda () (generate-stripped-directory 'binary-lib "does not exist" pkg-dest-path)))
|
||||
|
||||
(check-exn #rx"expected: \\(and/c path-string\\? directory-exists\\?\\)" (lambda () (generate-stripped-directory 'built "does not exist" pkg-dest-path)))
|
||||
(check-exn rx:does-not-exist (lambda () (generate-stripped-directory 'built "does not exist" pkg-dest-path)))
|
||||
|
||||
;; Giving path to nonexistent dest directory should raise a contract exception.
|
||||
(check-exn #rx"expected: \\(and/c path-string\\? directory-exists\\?\\)" (lambda () (generate-stripped-directory 'source pkg-path "does not exist")))
|
||||
(check-exn rx:does-not-exist (lambda () (generate-stripped-directory 'source pkg-path "does not exist")))
|
||||
|
||||
(check-exn #rx"expected: \\(and/c path-string\\? directory-exists\\?\\)" (lambda () (generate-stripped-directory 'binary pkg-path "does not exist")))
|
||||
(check-exn rx:does-not-exist (lambda () (generate-stripped-directory 'binary pkg-path "does not exist")))
|
||||
|
||||
(check-exn #rx"expected: \\(and/c path-string\\? directory-exists\\?\\)" (lambda () (generate-stripped-directory 'binary-lib pkg-path "does not exist")))
|
||||
(check-exn rx:does-not-exist (lambda () (generate-stripped-directory 'binary-lib pkg-path "does not exist")))
|
||||
|
||||
(check-exn #rx"expected: \\(and/c path-string\\? directory-exists\\?\\)" (lambda () (generate-stripped-directory 'built pkg-path "does not exist")))
|
||||
(check-exn rx:does-not-exist (lambda () (generate-stripped-directory 'built pkg-path "does not exist")))
|
||||
|
||||
;; Paths to existing src and dest directories should succeed.
|
||||
(check-not-exn (lambda () (generate-stripped-directory 'source pkg-path pkg-dest-path)))
|
||||
|
|
|
@ -21,11 +21,9 @@
|
|||
(define strip-binary-compile-info (make-parameter #t))
|
||||
|
||||
(define (check-strip-compatible mode pkg dir error)
|
||||
(unless (and (path-string? dir) (directory-exists? dir))
|
||||
(raise-argument-error
|
||||
'check-strip-compatible
|
||||
"(and/c path-string? directory-exists?)"
|
||||
dir))
|
||||
(unless (path-string? dir)
|
||||
(raise-argument-error 'check-strip-compatible "path-string?" dir))
|
||||
(check-directory-exists 'check-strip-compatible "" dir)
|
||||
|
||||
(define i (get-info/full dir))
|
||||
(define raw-status (and i
|
||||
|
@ -64,17 +62,12 @@
|
|||
|
||||
(define (generate-stripped-directory mode dir dest-dir
|
||||
#:check-status? [check-status? #t])
|
||||
(unless (and (path-string? dir) (directory-exists? dir))
|
||||
(raise-argument-error
|
||||
'generate-stripped-directory
|
||||
"(and/c path-string? directory-exists?)"
|
||||
dir))
|
||||
|
||||
(unless (and (path-string? dest-dir) (directory-exists? dest-dir))
|
||||
(raise-argument-error
|
||||
'generate-stripped-directory
|
||||
"(and/c path-string? directory-exists?)"
|
||||
dest-dir))
|
||||
(unless (path-string? dir)
|
||||
(raise-argument-error 'generate-stripped-directory "path-string?" dir))
|
||||
(unless (path-string? dest-dir)
|
||||
(raise-argument-error 'generate-stripped-directory "path-string?" dest-dir))
|
||||
(check-directory-exists 'generate-stripped-directory "source " dir)
|
||||
(check-directory-exists 'generate-stripped-directory "destination " dest-dir)
|
||||
|
||||
(define drop-keep-ns (make-base-namespace))
|
||||
(define (add-drop+keeps dir base drops keeps)
|
||||
|
@ -487,3 +480,14 @@
|
|||
(for ([f (in-list (directory-list dest-dir #:build? #t))])
|
||||
(when (directory-exists? f)
|
||||
(create-info-as-needed mode f 'collection)))]))
|
||||
|
||||
(define (check-directory-exists who which dir)
|
||||
(unless (directory-exists? dir)
|
||||
(raise (exn:fail:filesystem
|
||||
(format (string-append
|
||||
"~a: destination ~adirectory does not exist\n"
|
||||
" path: ~a")
|
||||
who
|
||||
which
|
||||
dir)
|
||||
(current-continuation-marks)))))
|
||||
|
|
Loading…
Reference in New Issue
Block a user