Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 20 additions & 11 deletions file.carp
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,10 @@ You can also ask about the modes of the file, using the functions `readable?`,
(is-dir lres)
(do
(when @(WalkOptions.recursive? spec)
(walk-recur &f op spec))
(let [rec (walk-recur &f op spec)]
(when-do (Result.error? &rec)
(set! res rec)
(break))))
(when @(WalkOptions.match-dirs? spec) (~op &f)))
(~op &f))))))
(Dir.close dir)
Expand All @@ -146,23 +149,29 @@ or dotfiles.")

(doc walk-with "walks a directory with a custom [walk mode](#walk-mode).

Returns a result containing either nothing, or an error if the directory
couldn’t be opened due to permission errors or if the user tried to open a
nonexistant directory.")
Returns a result containing either nothing, or an error if a directory couldn’t
be opened due to permission errors or if the user tried to open a nonexistant
directory.

The walk aborts at the first subdirectory it can’t descend into and returns that
error, so a success means the entire tree was visited.")
(defn walk-with [s callback options] (walk-recur s callback options))

(doc walk "walks a directory with the default walk mode (see also
[`default-walk`](#default-walk)).

Returns a result containing either nothing, or an error if the directory
couldn’t be opened due to permission errors or if the user tried to open a
nonexistant directory.")
Returns a result containing either nothing, or an error if a directory couldn’t
be opened due to permission errors or if the user tried to open a nonexistant
directory.

The walk aborts at the first subdirectory it can’t descend into and returns that
error, so a success means the entire tree was visited.")
(defn walk [s callback] (walk-with s callback &default-walk))

(doc map-with "walks a directory with a custom [walk mode](#walk-mode).

Returns a result containing either the results of the walker function as an
array or an error if the directory couldn’t be opened due to permission errors
array or an error if a directory couldn’t be opened due to permission errors
or if the user tried to open a nonexistant directory.")
(defn map-with [s callback options]
(let [res []
Expand All @@ -175,13 +184,13 @@ or if the user tried to open a nonexistant directory.")
[`default-walk`](#default-walk)).

Returns a result containing either the results of the walker function as an
array or an error if the directory couldn’t be opened due to permission errors
array or an error if a directory couldn’t be opened due to permission errors
or if the user tried to open a nonexistant directory.")
(defn map [s callback] (map-with s callback &default-walk))

(doc contents-with "walks a directory with a custom [walk mode](#walk-mode).

Returns a result containing either the directory contents or an error if the
Returns a result containing either the directory contents or an error if a
directory couldn’t be opened due to permission errors or if the user tried to
open a nonexistant directory.")
(defn contents-with [s options] (map-with s &copy options))
Expand All @@ -190,7 +199,7 @@ open a nonexistant directory.")
[`default-walk`](#default-walk)).

Returns a result containing either the contents of that directory or an error
if the directory couldn’t be opened due to permission errors or if the user
if a directory couldn’t be opened due to permission errors or if the user
tried to open a nonexistant directory.")
(defn contents [s] (contents-with s &default-walk))

Expand Down
36 changes: 36 additions & 0 deletions test/file.carp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,24 @@

(def test-acc 0)

(defn- clean-walk-fixture []
(do
(ignore (System.system "chmod -R u+rwx walk-fixture 2> /dev/null"))
(ignore (System.system "rm -rf walk-fixture"))))

(defn- make-walk-fixture []
(do
(clean-walk-fixture)
(ignore (System.system "mkdir -p walk-fixture/readable walk-fixture/locked"))
(ignore
(System.system
"touch walk-fixture/top walk-fixture/readable/inner walk-fixture/locked/deep"))))

; chmod 000 does not stop root, so probe the directory instead of assuming
(defn- locked-dir-unreadable? []
(let [d (Dir.open (cstr "walk-fixture/locked"))]
(if (null? d) true (do (Dir.close d) false))))

(defn main []
(with-test test
(assert-equal test
Expand Down Expand Up @@ -88,6 +106,24 @@
&(Array.sorted &[@"test/nested/fixture" @"test/file.carp"])
&(Array.sorted &(Result.from-success (File.contents "test") []))
"contents works on directory")
(do (make-walk-fixture) @test)
(assert-equal test
&(Array.sorted
&[@"walk-fixture/locked/deep"
@"walk-fixture/readable/inner"
@"walk-fixture/top"])
&(Array.sorted &(Result.from-success (File.contents "walk-fixture") []))
"walk visits every file of a readable tree")
(assert-true test
(do
(ignore (System.system "chmod 000 walk-fixture/locked"))
(if (locked-dir-unreadable?)
(error? &(File.walk "walk-fixture" &(fn [_] ())))
(do
(IO.println "\t(skipped, unreadable directories are not enforced)")
true)))
"walk reports an error for an unreadable subdirectory")
(do (clean-walk-fixture) @test)
(let-do [f (unsafe-from-success (File.open "example"))]
(File.remove &f)
@test)))