file/unzip: change to call-with-unzip and call-with-unzip-entry

Use `call-with-` instead of `with-`, since it's a function instead
of a syntactic form. (This is a weak convention, but one to try to
follow with new functions and forms.)

Fix up the contracts and change the documentation to match the
usual style.

Create the temporary directory in `(find-system-path 'temp-dir)`
instead of the current directory.
This commit is contained in:
Matthew Flatt 2014-04-30 17:46:26 -06:00
parent f592cf6e35
commit 61d717fd07
3 changed files with 60 additions and 58 deletions

View File

@ -7,7 +7,7 @@
@defmodule[file/unzip]{The @racketmodname[file/unzip] library provides @defmodule[file/unzip]{The @racketmodname[file/unzip] library provides
a function to extract items from a @exec{zip} archive.} a function to extract items from a @exec{zip} archive.}
@defproc[(unzip [in (or/c path-string? input-port)] @defproc[(unzip [in (or/c path-string? input-port?)]
[entry-reader (if preserve-timestamps? [entry-reader (if preserve-timestamps?
(bytes? boolean? input-port? (or/c #f exact-integer?) (bytes? boolean? input-port? (or/c #f exact-integer?)
. -> . any) . -> . any)
@ -30,19 +30,16 @@ aspects of the unpacking, such as the destination directory.
@history[#:changed "6.0.0.3" @elem{Added the @racket[#:preserve-timestamps?] argument.}]} @history[#:changed "6.0.0.3" @elem{Added the @racket[#:preserve-timestamps?] argument.}]}
@defproc[(with-unzip [zip_file path-string?] @defproc[(call-with-unzip [in (or/c path-string? input-port?)]
[user_proc (-> path-string? any)]) [proc (-> path-string? any)])
void?]{ any]{
A helper func to wrap unzip with clean temporay unzip files. Unpacks @racket[in] to a temporary directory, calls @racket[proc] on
the temporary directory's path, and then deletes the temporary
directory while returning the result of @racket[proc].
Unzips an entire @exec{zip} archive from file path @racket[zip_file] to a temporary directory. @history[#:added "6.0.1.6"]}
The temporary directory is created in the @racket[zip_file]'s directory.
@racket[user_proc] has this temporary directory path as its parameter.
When done, delete temporay unzip files and directories.}
@defproc[(make-filesystem-entry-reader @defproc[(make-filesystem-entry-reader
[#:dest dest-path (or/c path-string? #f) #f] [#:dest dest-path (or/c path-string? #f) #f]
@ -151,20 +148,17 @@ If @racket[entry] is not in @racket[zipdir], an
@history[#:changed "6.0.0.3" @elem{Added the @racket[#:preserve-timestamps?] argument.}]} @history[#:changed "6.0.0.3" @elem{Added the @racket[#:preserve-timestamps?] argument.}]}
@defproc[(with-unzip-entry [zip_file path-string?] @defproc[(call-with-unzip-entry [in path-string? input-port]
[entry_file path-string?] [entry path-string?]
[user_proc (-> path-string? any)]) [proc (-> path-string? any)])
void?]{ any]{
A helper func to wrap unzip-entry with clean temporay unzip file. Unpacks @racket[entry] within @racket[in] to a temporary directory,
calls @racket[proc] on the unpacked file's path, and then
deletes the temporary directory while returning the result of
@racket[proc].
Unzip an specific entry from @racket[zip_file] to a temporary directory, @racket[entry_file] is a entry path in @racket[zip_file]. @history[#:added "6.0.1.6"]}
The temporary directory is created in the @racket[zip_file]'s directory.
@racket[user_proc] has this unzipped temporary file path as its parameter.
When done, delete temporay unzip file.}
@defproc[(path->zip-path [path path-string?]) bytes?]{ @defproc[(path->zip-path [path path-string?]) bytes?]{

View File

@ -1,24 +1,29 @@
#lang racket/base #lang racket/base
(require file/unzip tests/eli-tester) (require file/unzip
racket/runtime-path
tests/eli-tester)
(define-runtime-path unzip-me.zip "unzip-me.zip")
;; test-me.zip's directory structure is test-zip/1/data.dat ;; test-me.zip's directory structure is test-zip/1/data.dat
(define (test-with-unzip) (define (test-with-unzip in)
(with-unzip "unzip-me.zip" (call-with-unzip in
(lambda (tmp_dir) (lambda (tmp_dir)
(with-input-from-file (build-path tmp_dir "test-zip" "1" "data.dat") (with-input-from-file (build-path tmp_dir "test-zip" "1" "data.dat")
(lambda () (lambda ()
(test (read-line) => "chenxiao")))))) (test (read-line) => "chenxiao"))))))
(define (test-with-unzip-entry) (define (test-with-unzip-entry)
(with-unzip-entry "unzip-me.zip" (call-with-unzip-entry unzip-me.zip
(build-path "test-zip" "1" "data.dat") (build-path "test-zip" "1" "data.dat")
(lambda (tmp_file) (lambda (tmp_file)
(with-input-from-file tmp_file (with-input-from-file tmp_file
(lambda () (lambda ()
(test (read-line) => "chenxiao")))))) (test (read-line) => "chenxiao"))))))
(define (run-tests) (define (run-tests)
(test-with-unzip) (test-with-unzip unzip-me.zip)
(call-with-input-file* unzip-me.zip test-with-unzip)
(test-with-unzip-entry)) (test-with-unzip-entry))
(provide tests) (provide tests)

View File

@ -43,10 +43,15 @@
. ->* . . ->* .
any)] any)]
[with-unzip-entry (-> path-string? path-string? (-> path-string? any) any)] [call-with-unzip (-> (or/c path-string? input-port?)
[with-unzip (-> path-string? (-> path-string? any) any)] (-> path-string? any)
any)]
[call-with-unzip-entry (-> (or/c path-string? input-port?)
path-string?
(-> path-string? any)
any)]
[path->zip-path ((or/c string? path?) . -> . bytes?)])) [path->zip-path (path-string? . -> . bytes?)]))
;; =========================================================================== ;; ===========================================================================
;; CONSTANTS ;; CONSTANTS
@ -363,30 +368,28 @@
base base
(current-directory))) (current-directory)))
;; use dynamic-wind to clean temporary files (define (call-with-unzip-entry zip-file entry-file user-proc)
(define (with-unzip-entry zip_file entry_file user_proc) (let ([temp-dir #f])
(let ([temp_dir #f])
(dynamic-wind (dynamic-wind
(lambda () (lambda ()
(set! temp_dir (make-temporary-file "ziptmp~a" 'directory "."))) (set! temp-dir (make-temporary-file "ziptmp~a" 'directory)))
(lambda () (lambda ()
(let ([directory_entries (read-zip-directory zip_file)]) (let ([directory-entries (read-zip-directory zip-file)])
(unzip-entry (unzip-entry zip-file
zip_file directory-entries
directory_entries (path->zip-path entry-file)
(path->zip-path entry_file) (make-filesystem-entry-reader #:dest temp-dir #:exists 'replace))
(make-filesystem-entry-reader #:dest temp_dir #:exists 'replace)) (user-proc (build-path temp-dir entry-file))))
(user_proc (build-path temp_dir entry_file))))
(lambda () (lambda ()
(delete-directory/files temp_dir))))) (delete-directory/files temp-dir)))))
(define (with-unzip zip_file user_proc) (define (call-with-unzip zip-file user-proc)
(let ([temp_dir #f]) (let ([temp-dir #f])
(dynamic-wind (dynamic-wind
(lambda () (lambda ()
(set! temp_dir (make-temporary-file "ziptmp~a" 'directory "."))) (set! temp-dir (make-temporary-file "ziptmp~a" 'directory)))
(lambda () (lambda ()
(unzip zip_file (make-filesystem-entry-reader #:dest temp_dir #:exists 'replace)) (unzip zip-file (make-filesystem-entry-reader #:dest temp-dir #:exists 'replace))
(user_proc temp_dir)) (user-proc temp-dir))
(lambda () (lambda ()
(delete-directory/files temp_dir))))) (delete-directory/files temp-dir)))))