io.files.unique: change to create unique files and directories relative to the current-directory.

locals-and-roots
John Benediktsson 2016-03-18 10:57:54 -07:00
parent f5b31a85c0
commit baae677276
19 changed files with 352 additions and 352 deletions

View File

@ -59,26 +59,27 @@ M: windows scp-name "pscp" ;
] change-file-lines ;
: with-build-images ( quot -- )
[ boot-image-names [ absolute-path ] map ] dip
'[
! Copy boot images
boot-image-names current-temporary-directory get copy-files-into
! Copy checksums
checksums-path current-temporary-directory get copy-file-into
current-temporary-directory get [
[
! Copy boot images
_ "." copy-files-into
! Copy checksums
checksums-path "." copy-file-into
! Rewrite checksum lines with build number
checksum-lines-append-build
! Rename file to file.build-number
current-directory get directory-files [ dup append-build move-file ] each
! Run the quot in the current-directory, which is the unique directory
"." directory-files [ dup append-build move-file ] each
! Run the quot in the unique directory
@
] with-directory
] cleanup-unique-directory ; inline
] cleanup-unique-directory
] with-temp-directory ; inline
: upload-build-images ( -- )
[
[
\ scp-name get-global scp-name or ,
current-directory get directory-files %
"." directory-files %
build-destination ,
] { } make try-process
] with-build-images ;

View File

@ -79,14 +79,19 @@ IN: csv.tests
{ { { "writing" "some" "csv" "tests" } } }
[
"writing,some,csv,tests"
"csv-test1-" unique-file utf8
[ set-file-contents ] [ file>csv ] [ drop delete-file ] 2tri
[
"writing,some,csv,tests"
"csv-test1-" ".csv" unique-file utf8
[ set-file-contents ] [ file>csv ] [ drop delete-file ] 2tri
] with-temp-directory
] unit-test
{ t } [
{ { "writing,some,csv,tests" } } dup "csv-test2-"
unique-file utf8 [ csv>file ] [ file>csv ] 2bi =
[
{ { "writing,some,csv,tests" } } dup
"csv-test2-" ".csv" unique-file utf8
[ csv>file ] [ file>csv ] 2bi =
] with-temp-directory
] unit-test
{ { { "hello" "" "" "" "goodbye" "" } } }

View File

@ -1,26 +1,29 @@
! Copyright (C) 2009 Doug Coleman.
! See http://factorcode.org/license.txt for BSD license.
USING: accessors combinators.short-circuit db db.errors
db.errors.sqlite db.sqlite io.files.unique kernel namespaces
tools.test ;
db.errors.sqlite db.sqlite io.files.temp io.files.unique kernel
namespaces tools.test ;
IN: db.errors.sqlite.tests
: sqlite-error-test-db-path ( -- path )
"sqlite" "error-test" make-unique-file ;
[
"sqlite" "error-test" [
sqlite-error-test-db-path <sqlite-db> [
<sqlite-db> [
[
"insert into foo (id) values('1');" sql-command
] [
{ [ sql-table-missing? ] [ table>> "foo" = ] } 1&&
] must-fail-with
[
"insert into foo (id) values('1');" sql-command
] [
{ [ sql-table-missing? ] [ table>> "foo" = ] } 1&&
] must-fail-with
[
"create table foo(id);" sql-command
"create table foo(id);" sql-command
] [
{ [ sql-table-exists? ] [ table>> "foo" = ] } 1&&
] must-fail-with
"create table foo(id);" sql-command
] with-db
[
"create table foo(id);" sql-command
] [
{ [ sql-table-exists? ] [ table>> "foo" = ] } 1&&
] must-fail-with
] with-db
] cleanup-unique-file
] with-temp-directory

View File

@ -10,26 +10,30 @@ CONSTANT: test-file-contents "Files are so boring anymore."
: create-test-file ( -- path )
test-file-contents
"ftp.server" "test" make-unique-file
"ftp.server" "test" unique-file
[ ascii set-file-contents ] [ normalize-path ] bi ;
: test-ftp-server ( quot -- )
'[
current-temporary-directory get
0 <ftp-server> [
"ftp://localhost" >url insecure-addr set-url-addr
"ftp" >>protocol
create-test-file >>path
@
] with-threaded-server
] cleanup-unique-directory ; inline
[
'[
"." 0 <ftp-server> [
"ftp://localhost" >url insecure-addr set-url-addr
"ftp" >>protocol
create-test-file >>path
@
] with-threaded-server
] cleanup-unique-directory
] with-temp-directory ; inline
{ t }
[
[
[
[ ftp-get ] [ path>> file-name ascii file-contents ] bi
] cleanup-unique-working-directory
[
[ ftp-get ]
[ path>> file-name ascii file-contents ] bi
] cleanup-unique-directory
] with-temp-directory
] test-ftp-server test-file-contents =
] unit-test
@ -38,7 +42,10 @@ CONSTANT: test-file-contents "Files are so boring anymore."
[
"/" >>path
[
[ ftp-get ] [ path>> file-name ascii file-contents ] bi
] cleanup-unique-working-directory
[
[ ftp-get ]
[ path>> file-name ascii file-contents ] bi
] cleanup-unique-directory
] with-temp-directory
] test-ftp-server test-file-contents =
] must-fail

View File

@ -6,9 +6,11 @@ IN: io.directories.search.tests
{ t } [
[
10 [ "io.paths.test" "gogogo" make-unique-file ] replicate
current-temporary-directory get [ ] find-all-files
] cleanup-unique-directory [ natural-sort ] same?
[
10 [ "io.paths.test" "gogogo" unique-file ] replicate
"." [ ] find-all-files
] cleanup-unique-directory [ natural-sort ] same?
] with-temp-directory
] unit-test
{ f } [
@ -23,17 +25,22 @@ IN: io.directories.search.tests
{ t } [
[
current-temporary-directory get
"the-head" unique-file drop t
[ file-name "the-head" head? ] find-file string?
] cleanup-unique-directory
[
"the-head" "" unique-file drop
"." t [ file-name "the-head" head? ] find-file string?
] cleanup-unique-directory
] with-temp-directory
] unit-test
{ t } [
[ unique-directory unique-directory ] output>array
[ [ "abcd" append-path touch-file ] each ]
[ [ file-name "abcd" = ] find-all-in-directories length 2 = ]
[ [ delete-tree ] each ] tri
[
[
[ unique-directory unique-directory ] output>array
[ [ "abcd" append-path touch-file ] each ]
[ [ file-name "abcd" = ] find-all-in-directories length 2 = ]
[ [ delete-tree ] each ] tri
] cleanup-unique-directory
] with-temp-directory
] unit-test
{ t } [

View File

@ -9,30 +9,30 @@ IN: io.files.links.unix.tests
{ t } [
[
current-temporary-directory get [
[
5 "lol" make-test-links
"lol1" follow-links
current-temporary-directory get "lol5" append-path =
] with-directory
] cleanup-unique-directory
"lol5" absolute-path =
] cleanup-unique-directory
] with-temp-directory
] unit-test
[
[
current-temporary-directory get [
[
100 "laf" make-test-links "laf1" follow-links
] with-directory
] with-unique-directory
] with-unique-directory
] with-temp-directory
] [ too-many-symlinks? ] must-fail-with
{ t } [
110 symlink-depth [
[
current-temporary-directory get [
[
100 "laf" make-test-links
"laf1" follow-links
current-temporary-directory get "laf100" append-path =
] with-directory
] cleanup-unique-directory
"laf100" absolute-path =
] cleanup-unique-directory
] with-temp-directory
] with-variable
] unit-test

View File

@ -1,16 +1,9 @@
USING: help.markup help.syntax io.directories quotations strings ;
USING: help.markup help.syntax io.directories io.pathnames
quotations strings ;
IN: io.files.unique
HELP: default-temporary-directory
{ $values
{ "path" "a pathname string" }
}
{ $description "A hook that returns the path of the temporary directory in a platform-specific way. Does not guarantee that path is writable by your user." } ;
HELP: touch-unique-file
{ $values
{ "path" "a pathname string" }
}
{ $values { "path" "a pathname string" } }
{ $description "Creates a unique file in a platform-specific way. The file is guaranteed not to exist and is openable by your user." } ;
HELP: unique-length
@ -21,92 +14,46 @@ HELP: unique-retries
{ unique-length unique-retries } related-words
HELP: make-unique-file
{ $values { "prefix" string } { "suffix" string }
{ "path" "a pathname string" } }
{ $description "Creates a file that is guaranteed not to exist in the directory stored in " { $link current-temporary-directory } ". The file name is composed of a prefix, a number of random digits and letters, and the suffix. Returns the full pathname." }
{ $errors "Throws an error if a new unique file cannot be created after a number of tries. The most likely error is incorrect directory permissions on the temporary directory." } ;
HELP: unique-file
{ $values { "prefix" string } { "suffix" string } { "path" "a pathname string" } }
{ $description "Creates a file that is guaranteed not to exist in the " { $link current-directory } ". The file name is composed of a prefix, a " { $link unique-length } " number of random digits and letters, and the suffix. Returns the full pathname." }
{ $errors "Throws an error if a new unique file cannot be created after a " { $link unique-retries } " number of tries. The most likely error is incorrect directory permissions on the " { $link current-directory } "." } ;
{ unique-file make-unique-file cleanup-unique-file } related-words
{ unique-file cleanup-unique-file } related-words
HELP: cleanup-unique-file
{ $values { "prefix" string } { "suffix" string }
{ "quot" quotation } }
{ $description "Creates a file with " { $link make-unique-file } " and calls the quotation with the path name on the stack." }
{ $notes "The unique file will be deleted after calling this word." } ;
{ $values { "prefix" string } { "suffix" string } { "quot" { $quotation ( path -- ) } } }
{ $description "Creates a file with " { $link unique-file } " and calls the quotation with the path name on the stack." }
{ $notes "The unique file will be deleted after calling this word, even if an error is thrown in the quotation." } ;
HELP: unique-directory
{ $values { "path" "a pathname string" } }
{ $description "Creates a directory in " { $link current-temporary-directory } " that is guaranteed not to exist and return the full pathname. The mechanism for the guarantee of uniqueness is retrying with a randomly generated filename until " { $link make-directory } " does not fail." }
{ $errors "Throws an error if the directory cannot be created after a number of tries " { $link unique-retries } ". The most likely error is incorrect directory permissions on the temporary directory." } ;
{ $description "Creates a directory in the " { $link current-directory } " that is guaranteed not to exist and return the full pathname. The mechanism for the guarantee of uniqueness is retrying with a " { $link unique-length } " randomly generated filename until " { $link make-directory } " succeeds." }
{ $errors "Throws an error if the directory cannot be created after a " { $link unique-retries } " number of tries. The most likely error is incorrect directory permissions on the " { $link current-directory } "." } ;
HELP: with-unique-directory
{ $values { "quot" quotation } { "path" "a pathname string" } }
{ $description "Creates a directory with " { $link unique-directory } " and calls the quotation using " { $link with-directory } " to set it as the " { $link current-directory } "." } ;
HELP: cleanup-unique-directory
{ $values { "quot" quotation } }
{ $description "Creates a directory with " { $link unique-directory } " and calls the quotation with the pathname on the stack using the " { $link with-temporary-directory } " combinator. The quotation can access the " { $link current-temporary-directory } " symbol for the name of the temporary directory. Subsequent unique files will be created in this unique directory until the combinator returns." }
{ $notes "The directory will be deleted after calling this word, even if an error is thrown in the quotation. This combinator is like " { $link with-unique-directory } " but does not delete the directory." } ;
{ $description "Creates a directory with " { $link unique-directory } " and calls the quotation using " { $link with-directory } " to set it as the " { $link current-directory } "." }
{ $notes "The unique directory will be deleted after calling this word, even if an error is thrown in the quotation." } ;
HELP: with-unique-directory
{ $values
{ "quot" quotation }
{ "path" "a pathname string" }
}
{ $description "Creates a directory with " { $link unique-directory } " and calls the quotation with the pathname on the stack using the " { $link with-temporary-directory } " combinator. The quotation can access the " { $link current-temporary-directory } " symbol for the name of the temporary directory. Subsequent unique files will be created in this unique directory until the combinator returns." } ;
HELP: copy-file-unique
{ $values
{ "path" "a pathname string" } { "prefix" string } { "suffix" string }
{ "path'" "a pathname string" }
}
{ $description "Copies " { $snippet "path" } " to a new unique file in the directory stored in " { $link current-temporary-directory } ". Returns the new path." } ;
HELP: move-file-unique
{ $values
{ "path" "a pathname string" } { "prefix" string } { "suffix" string }
{ "path'" "a pathname string" }
}
{ $description "Moves " { $snippet "path" } " to a new unique file in the directory stored in " { $link current-temporary-directory } ". Returns the new path." } ;
HELP: current-temporary-directory
{ $values
{ "value" "a path" }
}
{ $description "The temporary directory used for creating unique files and directories." } ;
HELP: unique-file
{ $values
{ "prefix" string }
{ "path" "a pathname string" }
}
{ $description "Creates a temporary file in the directory stored in " { $link current-temporary-directory } " and outputs the path name." } ;
HELP: with-temporary-directory
{ $values
{ "path" "a pathname string" } { "quot" quotation }
}
{ $description "Sets " { $link current-temporary-directory } " to " { $snippet "path" } " and calls the quotation, restoring the previous temporary path after execution completes." } ;
{ unique-directory with-unique-directory cleanup-unique-directory } related-words
ARTICLE: "io.files.unique" "Unique files"
"The " { $vocab-link "io.files.unique" } " vocabulary implements cross-platform unique file creation in temporary directories in a high-level and secure way." $nl
"Changing the temporary path:"
{ $subsections current-temporary-directory }
"The " { $vocab-link "io.files.unique" } " vocabulary implements cross-platform unique file creation in a high-level and secure way." $nl
"Creating unique files:"
{ $subsections
unique-file
cleanup-unique-file
make-unique-file
}
"Creating unique directories:"
{ $subsections
unique-directory
with-unique-directory
cleanup-unique-directory
}
"Default temporary directory:"
{ $subsections default-temporary-directory }
"Copying and moving files to a new unique file:"
{ $subsections
copy-file-unique
move-file-unique
} ;
ABOUT: "io.files.unique"

View File

@ -1,41 +1,54 @@
USING: io.encodings.ascii sequences strings io io.files accessors
tools.test kernel io.files.unique namespaces continuations
io.files.info io.pathnames io.directories ;
USING: accessors continuations io.directories io.encodings.ascii
io.files io.files.info io.files.unique io.pathnames kernel
namespaces sequences strings tools.test ;
IN: io.files.unique.tests
{ 123 } [
"core" ".test" [
[ [ 123 CHAR: a <string> ] dip ascii set-file-contents ]
[ file-info size>> ] bi
] cleanup-unique-file
] unit-test
{ t } [
[ current-directory get file-info directory? ] cleanup-unique-directory
] unit-test
{ t } [
current-directory get
[ [ "FAILDOG" throw ] cleanup-unique-directory ] [ drop ] recover
current-directory get =
[
"core" ".test" [
[ [ 123 CHAR: a <string> ] dip ascii set-file-contents ]
[ file-info size>> ] bi
] cleanup-unique-file
] with-temp-directory
] unit-test
{ t } [
[
"asdf" unique-file drop
"asdf2" unique-file drop
current-temporary-directory get directory-files length 2 =
] cleanup-unique-directory
] unit-test
{ t } [
[ ] with-unique-directory >boolean
[ current-directory get file-info directory? ]
cleanup-unique-directory
] with-temp-directory
] unit-test
{ t } [
[
"asdf" unique-file drop
"asdf" unique-file drop
current-temporary-directory get directory-files length 2 =
] with-unique-directory drop
current-directory get
[ [ "FAILDOG" throw ] cleanup-unique-directory ] [ drop ] recover
current-directory get =
] with-temp-directory
] unit-test
{ t } [
[
[
"asdf" "" unique-file drop
"asdf2" "" unique-file drop
"." directory-files length 2 =
] cleanup-unique-directory
] with-temp-directory
] unit-test
{ t } [
[
[ ] with-unique-directory >boolean
] with-temp-directory
] unit-test
{ t } [
[
[
"asdf" "" unique-file drop
"asdf" "" unique-file drop
"." directory-files length 2 =
] with-unique-directory drop
] with-temp-directory
] unit-test

View File

@ -1,28 +1,25 @@
! Copyright (C) 2008 Doug Coleman.
! See http://factorcode.org/license.txt for BSD license.
USING: arrays combinators continuations fry io io.backend
io.directories io.directories.hierarchy io.files io.pathnames
kernel locals math math.bitwise math.parser namespaces random
sequences system vocabs random.data ;
USING: combinators continuations fry io.backend io.directories
io.directories.hierarchy io.pathnames kernel locals namespaces
random.data sequences system vocabs ;
IN: io.files.unique
<PRIVATE
HOOK: (touch-unique-file) io-backend ( path -- )
PRIVATE>
: touch-unique-file ( path -- )
normalize-path (touch-unique-file) ;
HOOK: default-temporary-directory io-backend ( -- path )
SYMBOL: current-temporary-directory
SYMBOL: unique-length
SYMBOL: unique-retries
10 unique-length set-global
10 unique-retries set-global
: with-temporary-directory ( path quot -- )
[ current-temporary-directory ] dip with-variable ; inline
<PRIVATE
: random-file-name ( -- string )
@ -31,54 +28,37 @@ SYMBOL: unique-retries
: retry ( quot: ( -- ? ) n -- )
iota swap [ drop ] prepose attempt-all ; inline
: (make-unique-file) ( path prefix suffix -- path )
PRIVATE>
: unique-file ( prefix suffix -- path )
'[
_ _ _ random-file-name glue append-path
current-directory get
_ _ random-file-name glue append-path
dup touch-unique-file
] unique-retries get retry ;
PRIVATE>
: make-unique-file ( prefix suffix -- path )
[ current-temporary-directory get ] 2dip (make-unique-file) ;
: cleanup-unique-file ( prefix suffix quot: ( path -- ) -- )
[ make-unique-file ] dip [ delete-file ] bi ; inline
:: cleanup-unique-file ( prefix suffix quot: ( path -- ) -- )
prefix suffix unique-file :> path
[ path quot call ] [ path delete-file ] [ ] cleanup ; inline
: unique-directory ( -- path )
[
current-temporary-directory get
current-directory get
random-file-name append-path
dup make-directory
] unique-retries get retry ;
: with-unique-directory ( quot -- path )
[ unique-directory ] dip
[ with-temporary-directory ] [ drop ] 2bi ; inline
: cleanup-unique-directory ( quot: ( -- ) -- )
[ unique-directory ] dip
'[ _ with-temporary-directory ] [ delete-tree ] bi ; inline
: unique-file ( prefix -- path )
"" make-unique-file ;
: move-file-unique ( path prefix suffix -- path' )
make-unique-file [ move-file ] keep ;
: copy-file-unique ( path prefix suffix -- path' )
make-unique-file [ copy-file ] keep ;
: temporary-file ( -- path ) "" unique-file ;
:: cleanup-unique-working-directory ( quot -- )
:: with-unique-directory ( quot -- path )
unique-directory :> path
path [ path quot with-temporary-directory ] with-directory
path delete-tree ; inline
path quot with-directory
path ; inline
:: cleanup-unique-directory ( quot -- )
unique-directory :> path
[ path quot with-directory ]
[ path delete-tree ] [ ] cleanup ; inline
{
{ [ os unix? ] [ "io.files.unique.unix" ] }
{ [ os windows? ] [ "io.files.unique.windows" ] }
} cond require
default-temporary-directory current-temporary-directory set-global

View File

@ -1,12 +1,10 @@
! Copyright (C) 2008 Doug Coleman.
! See http://factorcode.org/license.txt for BSD license.
USING: kernel io.ports io.backend.unix math.bitwise
unix system io.files.unique unix.ffi literals ;
USING: io.backend.unix io.files.unique.private literals system
unix unix.ffi ;
IN: io.files.unique.unix
CONSTANT: open-unique-flags flags{ O_RDWR O_CREAT O_EXCL }
M: unix (touch-unique-file) ( path -- )
open-unique-flags file-mode open-file close-file ;
M: unix default-temporary-directory ( -- path ) "/tmp" ;

View File

@ -1,9 +1,6 @@
USING: destructors environment io.files.unique io.files.windows
system windows.kernel32 ;
USING: destructors environment io.files.unique.private
io.files.windows system windows.kernel32 ;
IN: io.files.unique.windows
M: windows (touch-unique-file) ( path -- )
GENERIC_WRITE CREATE_NEW 0 open-file dispose ;
M: windows default-temporary-directory ( -- path )
"TEMP" os-env ;

View File

@ -82,7 +82,8 @@ SYMBOLS: out-path err-path ;
[ ] [
<process>
console-vm-path "-run=hello-world" 2array >>command
"out.txt" unique-file [ out-path set-global ] keep >>stdout
[ "out" ".txt" unique-file ] with-temp-directory
[ out-path set-global ] keep >>stdout
try-process
] unit-test
@ -105,8 +106,10 @@ SYMBOLS: out-path err-path ;
launcher-test-path [
<process>
console-vm-path "-script" "stderr.factor" 3array >>command
"out.txt" unique-file [ out-path set-global ] keep >>stdout
"err.txt" unique-file [ err-path set-global ] keep >>stderr
[ "out" ".txt" unique-file ] with-temp-directory
[ out-path set-global ] keep >>stdout
[ "err" ".txt" unique-file ] with-temp-directory
[ err-path set-global ] keep >>stderr
try-process
] with-directory
] unit-test
@ -123,7 +126,8 @@ SYMBOLS: out-path err-path ;
launcher-test-path [
<process>
console-vm-path "-script" "stderr.factor" 3array >>command
"out.txt" unique-file [ out-path set-global ] keep >>stdout
[ "out" ".txt" unique-file ] with-temp-directory
[ out-path set-global ] keep >>stdout
+stdout+ >>stderr
try-process
] with-directory
@ -137,7 +141,8 @@ SYMBOLS: out-path err-path ;
launcher-test-path [
<process>
console-vm-path "-script" "stderr.factor" 3array >>command
"err2.txt" unique-file [ err-path set-global ] keep >>stderr
[ "err2" ".txt" unique-file ] with-temp-directory
[ err-path set-global ] keep >>stderr
utf8 <process-reader> stream-lines first
] with-directory
] unit-test
@ -197,7 +202,8 @@ SYMBOLS: out-path err-path ;
[ ] [
<process>
"cmd.exe /c dir" >>command
"dir.txt" unique-file [ out-path set-global ] keep >>stdout
[ "dir" ".txt" unique-file ] with-temp-directory
[ out-path set-global ] keep >>stdout
try-process
] unit-test
@ -205,7 +211,7 @@ SYMBOLS: out-path err-path ;
] times
{ "Hello appender\r\nÖrjan ågren är åter\r\nHello appender\r\nÖrjan ågren är åter\r\n" } [
"append-test" unique-file out-path set-global
[ "append-test" "" unique-file ] with-temp-directory out-path set-global
2 [
launcher-test-path [
<process>

View File

@ -1,7 +1,7 @@
! Copyright (C) 2009 Doug Coleman.
! See http://factorcode.org/license.txt for BSD license.
USING: accessors assocs continuations fry http.server io
io.encodings.ascii io.files io.files.unique
io.encodings.ascii io.files io.files.temp io.files.unique
io.servers io.streams.duplex io.streams.string
kernel math.ranges mime.multipart multiline namespaces random
sequences sorting strings threads tools.test ;
@ -13,8 +13,8 @@ CONSTANT: upload1 "------WebKitFormBoundary6odjpVPXIighAE2L\r\nContent-Dispositi
: mime-test-stream ( -- stream )
upload1
"mime" "test" make-unique-file ascii
[ set-file-contents ] [ <file-reader> ] 2bi ;
[ "mime" "test" unique-file ] with-temp-directory
ascii [ set-file-contents ] [ <file-reader> ] 2bi ;
{ } [ mime-test-stream [ ] with-input-stream ] unit-test

View File

@ -2,8 +2,8 @@
! See http://factorcode.org/license.txt for BSD license.
USING: accessors ascii assocs byte-arrays combinators fry
hashtables http http.parsers io io.encodings.binary io.files
io.files.unique io.streams.string kernel math quoting sequences
splitting ;
io.files.temp io.files.unique io.streams.string kernel math
quoting sequences splitting ;
IN: mime.multipart
CONSTANT: buffer-size 65536
@ -94,7 +94,7 @@ C: <mime-variable> mime-variable
] with-output-stream ;
: dump-file ( multipart -- multipart )
"factor-" "-upload" make-unique-file
[ "factor-" "-upload" unique-file ] with-temp-directory
[ >>temp-file ] [ dump-mime-file ] bi ;
: parse-content-disposition-form-data ( string -- hashtable )

View File

@ -157,91 +157,116 @@ CONSTANT: pt-array-1
! File seeking tests
{ B{ 3 2 3 4 5 } }
[
"seek-test1" unique-file binary
[
[
B{ 1 2 3 4 5 } write
tell-output 5 assert=
0 seek-absolute seek-output
tell-output 0 assert=
B{ 3 } write
tell-output 1 assert=
] with-file-writer
] [
file-contents
] 2bi
"seek-test1" "" [
binary
[
[
B{ 1 2 3 4 5 } write
tell-output 5 assert=
0 seek-absolute seek-output
tell-output 0 assert=
B{ 3 } write
tell-output 1 assert=
] with-file-writer
] [
file-contents
] 2bi
] cleanup-unique-file
] with-temp-directory
] unit-test
{ B{ 1 2 3 4 3 } }
[
"seek-test2" unique-file binary
[
[
B{ 1 2 3 4 5 } write
tell-output 5 assert=
-1 seek-relative seek-output
tell-output 4 assert=
B{ 3 } write
tell-output 5 assert=
] with-file-writer
] [
file-contents
] 2bi
"seek-test2" "" [
binary
[
[
B{ 1 2 3 4 5 } write
tell-output 5 assert=
-1 seek-relative seek-output
tell-output 4 assert=
B{ 3 } write
tell-output 5 assert=
] with-file-writer
] [
file-contents
] 2bi
] cleanup-unique-file
] with-temp-directory
] unit-test
{ B{ 1 2 3 4 5 0 3 } }
[
"seek-test3" unique-file binary
[
[
B{ 1 2 3 4 5 } write
tell-output 5 assert=
1 seek-relative seek-output
tell-output 6 assert=
B{ 3 } write
tell-output 7 assert=
] with-file-writer
] [
file-contents
] 2bi
"seek-test3" "" [
binary
[
[
B{ 1 2 3 4 5 } write
tell-output 5 assert=
1 seek-relative seek-output
tell-output 6 assert=
B{ 3 } write
tell-output 7 assert=
] with-file-writer
] [
file-contents
] 2bi
] cleanup-unique-file
] with-temp-directory
] unit-test
{ B{ 3 } }
[
B{ 1 2 3 4 5 } "seek-test4" unique-file binary [
set-file-contents
] [
[
tell-input 0 assert=
-3 seek-end seek-input
tell-input 2 assert=
1 read
tell-input 3 assert=
] with-file-reader
] 2bi
[
"seek-test4" "" [
B{ 1 2 3 4 5 } swap binary
[
set-file-contents
] [
[
tell-input 0 assert=
-3 seek-end seek-input
tell-input 2 assert=
1 read
tell-input 3 assert=
] with-file-reader
] 2bi
] cleanup-unique-file
] with-temp-directory
] unit-test
{ B{ 2 } }
[
B{ 1 2 3 4 5 } "seek-test5" unique-file binary [
set-file-contents
] [
[
tell-input 0 assert=
3 seek-absolute seek-input
tell-input 3 assert=
-2 seek-relative seek-input
tell-input 1 assert=
1 read
tell-input 2 assert=
] with-file-reader
] 2bi
[
"seek-test5" "" [
B{ 1 2 3 4 5 } swap binary [
set-file-contents
] [
[
tell-input 0 assert=
3 seek-absolute seek-input
tell-input 3 assert=
-2 seek-relative seek-input
tell-input 1 assert=
1 read
tell-input 2 assert=
] with-file-reader
] 2bi
] cleanup-unique-file
] with-temp-directory
] unit-test
[
"seek-test6" unique-file binary [
-10 seek-absolute seek-input
] with-file-reader
[
"seek-test6" "" [
binary [
-10 seek-absolute seek-input
] with-file-reader
] cleanup-unique-file
] with-temp-directory
] must-fail
{ } [
@ -254,21 +279,29 @@ CONSTANT: pt-array-1
] unit-test
[
"non-string-error" unique-file ascii [
{ } write
] with-file-writer
[
"non-string-error" "" [
ascii [ { } write ] with-file-writer
] cleanup-unique-file
] with-temp-directory
] [ no-method? ] must-fail-with
[
"non-byte-array-error" unique-file binary [
"" write
] with-file-writer
[
"non-byte-array-error" "" [
binary [ "" write ] with-file-writer
] cleanup-unique-file
] with-temp-directory
] [ no-method? ] must-fail-with
! What happens if we close a file twice?
{ } [
"closing-twice" unique-file ascii <file-writer>
[ dispose ] [ dispose ] bi
[
"closing-twice" "" [
ascii <file-writer>
[ dispose ] [ dispose ] bi
] cleanup-unique-file
] with-temp-directory
] unit-test
! Test cwd, cd. You do not want to use with-cd, you want with-directory.

View File

@ -3,10 +3,10 @@ USING: accessors arrays assocs calendar calendar.format
combinators combinators.short-circuit fry io io.backend
io.directories io.directories.hierarchy io.encodings.binary
io.encodings.detect io.encodings.utf8 io.files io.files.info
io.files.types io.files.unique io.launcher io.pathnames kernel
locals math math.parser namespaces sequences sorting strings
system unicode.categories xml.syntax xml.writer xmode.catalog
xmode.marker xmode.tokens ;
io.files.temp io.files.types io.files.unique io.launcher
io.pathnames kernel locals math math.parser namespaces sequences
sorting strings system unicode.categories xml.syntax xml.writer
xmode.catalog xmode.marker xmode.tokens ;
IN: codebook
! Usage: "my/source/tree" codebook
@ -194,8 +194,8 @@ TUPLE: code-file
</guide>
</package> XML> ;
: write-dest-file ( xml dest-dir name ext -- )
append append-path utf8 [ write-xml ] with-file-writer ;
: write-dest-file ( xml name ext -- )
append utf8 [ write-xml ] with-file-writer ;
SYMBOL: kindlegen-path
kindlegen-path [ "kindlegen" ] initialize
@ -216,30 +216,31 @@ codebook-output-path [ "resource:codebooks" ] initialize
dest-dir make-directories
[
current-temporary-directory get :> temp-dir
src-dir file-name :> name
src-dir code-files :> files
[
src-dir file-name :> name
src-dir code-files :> files
src-dir name files code>opf
temp-dir name ".opf" write-dest-file
src-dir name files code>opf
name ".opf" write-dest-file
"vocab:codebook/cover.jpg" temp-dir copy-file-into
"vocab:codebook/cover.jpg" "." copy-file-into
src-dir name files code>ncx
temp-dir name ".ncx" write-dest-file
src-dir name files code>ncx
name ".ncx" write-dest-file
src-dir name files code>toc-html
temp-dir "_toc.html" "" write-dest-file
src-dir name files code>toc-html
"_toc.html" "" write-dest-file
files [| file |
src-dir file code>html
temp-dir file name>> file-html-name "" write-dest-file
] each
files [| file |
src-dir file code>html
file name>> file-html-name "" write-dest-file
] each
temp-dir name ".opf" kindle-path kindlegen
temp-dir name ".mobi" kindle-path dest-dir copy-file-into
"." name ".opf" kindle-path kindlegen
"." name ".mobi" kindle-path dest-dir copy-file-into
dest-dir name ".mobi" kindle-path :> mobi-path
dest-dir name ".mobi" kindle-path :> mobi-path
"Job's finished: " write mobi-path print flush
] cleanup-unique-working-directory ;
"Job's finished: " write mobi-path print flush
] cleanup-unique-directory
] with-temp-directory ;

View File

@ -1,8 +1,8 @@
! Copyright (C) 2010 Doug Coleman.
! See http://factorcode.org/license.txt for BSD license.
USING: assocs combinators fry grouping http.client io
io.encodings.binary io.files io.files.unique json.reader kernel
locals make namespaces sequences urls ;
io.encodings.binary io.files io.files.temp io.files.unique
json.reader kernel locals make namespaces sequences urls ;
IN: google.translate
CONSTANT: google-translate-url "http://ajax.googleapis.com/ajax/services/language/translate"
@ -53,8 +53,9 @@ TUPLE: response-error response error ;
: translate-tts ( text -- file )
"http://translate.google.com/translate_tts?tl=en" >url
swap "q" set-query-param "" ".mp3" make-unique-file
[ download-to ] keep ;
swap "q" set-query-param [
"" ".mp3" unique-file [ download-to ] keep
] with-temp-directory ;
! Example:
! "dog" "en" "de" translate .

View File

@ -116,13 +116,15 @@ PRIVATE>
} case ;
:: with-preview ( graph quot: ( path -- ) -- )
"preview" ".dot" [| code-file |
"preview" preview-extension [| image-file |
graph code-file ?encoding write-dot
code-file image-file try-preview-command
image-file quot call( path -- )
[
"preview" ".dot" [| code-file |
"preview" preview-extension [| image-file |
graph code-file ?encoding write-dot
code-file image-file try-preview-command
image-file quot call( path -- )
] cleanup-unique-file
] cleanup-unique-file
] cleanup-unique-file ;
] with-temp-directory ;
PRIVATE>

View File

@ -1,9 +1,9 @@
! Copyright (C) 2010 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: bootstrap.image bootstrap.image.download io
io.directories io.directories.hierarchy io.files.unique
io.launcher io.pathnames kernel namespaces sequences
mason.common mason.config webapps.mason.version.files ;
io.directories io.directories.hierarchy io.files.temp
io.files.unique io.launcher io.pathnames kernel namespaces
sequences mason.common mason.config webapps.mason.version.files ;
IN: webapps.mason.version.source
: clone-factor ( -- )
@ -34,13 +34,12 @@ IN: webapps.mason.version.source
[ suffix "factor" suffix try-process ] keep ;
: make-source-release ( version git-id -- path )
"Creating source release..." print flush
[
current-temporary-directory get [
"Creating source release..." print flush [
[
clone-factor prepare-source (make-source-release)
"Package created: " write absolute-path dup print
] with-directory
] with-unique-directory drop ;
] with-unique-directory drop
] with-temp-directory ;
: upload-source-release ( package version -- )
"Uploading source release..." print flush