Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Copy tree fix #123

Merged
merged 11 commits into from
Jan 12, 2024
Merged
Show file tree
Hide file tree
Changes from 9 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
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ For a list of breaking changes, check [here](#breaking-changes).

Babashka [fs](https://github.com/babashka/fs): file system utility library for Clojure

## Unreleased

- [#122](https://github.com/babashka/fs/issues/122): `fs/copy-tree`: fix copying read-only directories with children ([@sohalt](https://github.com/sohalt))

## v0.5.20 (2023-12-21)

- [#119](https://github.com/babashka/fs/issues/119): `fs/delete-tree`: add `:force` flag to delete read-only directories/files. Set the flag to true in `fs/with-temp-dir` ([@jlesquembre](https://github.com/jlesquembre))
Expand Down
21 changes: 17 additions & 4 deletions src/babashka/fs.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -209,8 +209,8 @@
(preVisitDirectory [_ dir attrs]
(-> (pre-visit-dir dir attrs)
file-visit-result))
(postVisitDirectory [_ dir attrs]
(-> (post-visit-dir dir attrs)
(postVisitDirectory [_ dir ex]
(-> (post-visit-dir dir ex)
file-visit-result))
(visitFile [_ path attrs]
(-> (visit-file path attrs)
Expand Down Expand Up @@ -424,6 +424,9 @@
([path {:keys [:posix-file-permissions]}]
(Files/createDirectories (as-path path) (posix->attrs posix-file-permissions))))

(declare posix-file-permissions)
(declare u+wx)
Sohalt marked this conversation as resolved.
Show resolved Hide resolved

(defn copy-tree
"Copies entire file tree from src to dest. Creates dest if needed
using `create-dirs`, passing it the `:posix-file-permissions`
Expand Down Expand Up @@ -453,7 +456,8 @@
(when-not (Files/exists to-dir link-options)
(Files/copy ^Path dir to-dir
^"[Ljava.nio.file.CopyOption;"
copy-options)))
copy-options)
(u+wx to-dir)))
Sohalt marked this conversation as resolved.
Show resolved Hide resolved
:continue)
:visit-file (fn [from-path _attrs]
(let [rel (relativize from from-path)
Expand All @@ -462,7 +466,16 @@
^"[Ljava.nio.file.CopyOption;"
copy-options)
:continue)
:continue)}))))
:continue)
:post-visit-dir (fn [dir _ex]
(let [rel (relativize from dir)
to-dir (path to rel)]
(if win?
Sohalt marked this conversation as resolved.
Show resolved Hide resolved
(when-not (.canWrite (file from))
(.setWritable (file dir) false))
(let [perms (posix-file-permissions (file dir))]
(Files/setPosixFilePermissions to-dir perms)))
:continue))}))))

(defn temp-dir
"Returns `java.io.tmpdir` property as path."
Expand Down
12 changes: 12 additions & 0 deletions test/babashka/fs_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,18 @@
(is (fs/exists? (fs/file tmp"foo2" "foo" "1"))
"The nested destination directory is not created when it doesn't exist")))

(deftest copy-tree-nested-ro-dir-test
(fs/with-temp-dir [tmp {}]
;; https://github.com/babashka/fs/issues/122
(fs/create-dirs (fs/path tmp "src" "foo" "bar"))
(.setReadOnly (fs/file tmp "src" "foo"))
(fs/copy-tree (fs/path tmp "src") (fs/path tmp "dst"))
(is (fs/exists? (fs/path tmp "dst" "foo" "bar")))
(when (not windows?)
;; you can always write to directories on Windows, even if they are read-only
;; https://answers.microsoft.com/en-us/windows/forum/all/all-folders-are-now-read-only-windows-10/0ca1880f-e997-46af-bd85-042a53fc078e
(is (not (fs/writable? (fs/path tmp "dst" "foo")))))))

(deftest components-test
(let [paths (map normalize (fs/components (fs/path (temp-dir) "foo")))]
(is (= "foo" (last paths)))
Expand Down