66 */
77package os
88
9+ import java .nio .file
910import java .nio .file .{Path => _ , _ }
1011import java .nio .file .attribute .{FileAttribute , PosixFilePermission , PosixFilePermissions }
1112
@@ -134,28 +135,34 @@ object copy {
134135 def matching (followLinks : Boolean = true ,
135136 replaceExisting : Boolean = false ,
136137 copyAttributes : Boolean = false ,
137- createFolders : Boolean = false )
138+ createFolders : Boolean = false ,
139+ mergeFolders : Boolean = false )
138140 (partialFunction : PartialFunction [Path , Path ]): PartialFunction [Path , Unit ] = {
139141 new PartialFunction [Path , Unit ] {
140142 def isDefinedAt (x : Path ) = partialFunction.isDefinedAt(x)
141143 def apply (from : Path ) = {
142144 val dest = partialFunction(from)
143145 makeDir.all(dest/ up)
144- os.copy(from, dest, followLinks, replaceExisting, copyAttributes, createFolders)
146+ os.copy(
147+ from, dest, followLinks, replaceExisting, copyAttributes, createFolders, mergeFolders
148+ )
145149 }
146150 }
147151
148152 }
149153 def matching (partialFunction : PartialFunction [Path , Path ]): PartialFunction [Path , Unit ] = {
150154 matching()(partialFunction)
151155 }
152- def apply (from : Path ,
153- to : Path ,
154- followLinks : Boolean = true ,
155- replaceExisting : Boolean = false ,
156- copyAttributes : Boolean = false ,
157- createFolders : Boolean = false ): Unit = {
158- if (createFolders) makeDir.all(to/ up)
156+ def apply (
157+ from : Path ,
158+ to : Path ,
159+ followLinks : Boolean = true ,
160+ replaceExisting : Boolean = false ,
161+ copyAttributes : Boolean = false ,
162+ createFolders : Boolean = false ,
163+ mergeFolders : Boolean = false
164+ ): Unit = {
165+ if (createFolders) makeDir.all(to / up)
159166 val opts1 =
160167 if (followLinks) Array [CopyOption ]()
161168 else Array [CopyOption ](LinkOption .NOFOLLOW_LINKS )
@@ -169,8 +176,15 @@ object copy {
169176 ! to.startsWith(from),
170177 s " Can't copy a directory into itself: $to is inside $from"
171178 )
172- def copyOne (p : Path ) = {
173- Files .copy(p.wrapped, (to/ (p relativeTo from)).wrapped, opts1 ++ opts2 ++ opts3:_* )
179+
180+ def copyOne (p : Path ): file.Path = {
181+ val target = to / p.relativeTo(from)
182+ if (mergeFolders && isDir(p, followLinks) && isDir(target, followLinks)) {
183+ // nothing to do
184+ target.wrapped
185+ } else {
186+ Files .copy(p.wrapped, target.wrapped, opts1 ++ opts2 ++ opts3 : _* )
187+ }
174188 }
175189
176190 copyOne(from)
@@ -187,8 +201,12 @@ object copy {
187201 followLinks : Boolean = true ,
188202 replaceExisting : Boolean = false ,
189203 copyAttributes : Boolean = false ,
190- createFolders : Boolean = false ): Unit = {
191- os.copy(from, to/ from.last, followLinks, replaceExisting, copyAttributes, createFolders)
204+ createFolders : Boolean = false ,
205+ mergeFolders : Boolean = false ): Unit = {
206+ os.copy(
207+ from, to/ from.last,
208+ followLinks, replaceExisting, copyAttributes, createFolders, mergeFolders
209+ )
192210 }
193211 }
194212
0 commit comments