@@ -187,6 +187,101 @@ object ZipOpTests extends TestSuite {
187187 assert(os.list(sources).toSet == expected)
188188 }
189189
190+ test(" symLinkAndPermissions" ) {
191+ def prepare (
192+ wd : os.Path ,
193+ zipStream : Boolean = false ,
194+ unzipStream : Boolean = false
195+ ) = {
196+ val zipFileName = " zipped.zip"
197+ val source = wd / " folder2"
198+ os.perms.set(source / " nestedA" / " a.txt" , os.PermSet .fromString(" rw-rw-rw-" ))
199+ os.symlink(source / " nestedA" / " link.txt" , os.rel / " a.txt" )
200+
201+ val zipped =
202+ if (zipStream) {
203+ os.write(
204+ wd / zipFileName,
205+ os.zip.stream(sources = List (source))
206+ )
207+ wd / zipFileName
208+ } else {
209+ os.zip(
210+ dest = wd / zipFileName,
211+ sources = List (source)
212+ )
213+ }
214+
215+ val unzipped =
216+ if (unzipStream) {
217+ os.unzip.stream(
218+ source = os.read.inputStream(zipped),
219+ dest = wd / " unzipped"
220+ )
221+ wd / " unzipped"
222+ } else {
223+ os.unzip(
224+ dest = wd / " unzipped" ,
225+ source = zipped
226+ )
227+ }
228+
229+ (source, unzipped)
230+ }
231+
232+ def walkRel (p : os.Path ) = os.walk(p).map(_.relativeTo(p))
233+
234+ test(" zip" ) - prep { wd =>
235+ val (source, unzipped) = prepare(wd)
236+
237+ assert(walkRel(source).toSet == walkRel(unzipped).toSet)
238+ assert(os.walk.stream(source)
239+ .filter(! os.isLink(_))
240+ .forall(p => os.perms(p) == os.perms(unzipped / p.relativeTo(source))))
241+ assert(
242+ os.walk.stream(source)
243+ .filter(os.isLink(_))
244+ .forall { p =>
245+ val unzippedLink = unzipped / p.relativeTo(source)
246+ os.isLink(unzippedLink) &&
247+ os.readLink(p) == os.readLink(unzippedLink)
248+ }
249+ )
250+ }
251+
252+ test(" zipStream" ) - prep { wd =>
253+ val (source, unzipped) = prepare(wd, zipStream = true )
254+
255+ assert(walkRel(source).toSet == walkRel(unzipped).toSet)
256+ assert(os.walk.stream(source)
257+ .filter(! os.isLink(_))
258+ .forall(p => os.perms(p) == os.perms(unzipped / p.relativeTo(source))))
259+ assert(
260+ os.walk.stream(source)
261+ .filter(os.isLink(_))
262+ .forall { p =>
263+ val unzippedLink = unzipped / p.relativeTo(source)
264+ os.isLink(unzippedLink) &&
265+ os.readLink(p) == os.readLink(unzippedLink)
266+ }
267+ )
268+ }
269+
270+ test(" unzipStream" ) - prep { wd =>
271+ val (source, unzipped) = prepare(wd, zipStream = true )
272+
273+ assert(walkRel(source).toSet == walkRel(unzipped).toSet)
274+ assert(
275+ os.walk.stream(source)
276+ .filter(os.isLink(_))
277+ .forall { p =>
278+ val unzippedLink = unzipped / p.relativeTo(source)
279+ os.read(p) == os.read(unzippedLink)
280+ }
281+ )
282+ }
283+ }
284+
190285 test(" unzipStream" ) - prep { wd =>
191286 // Step 1: Create an in-memory ZIP file as a stream
192287 val zipStreamOutput = new ByteArrayOutputStream ()
0 commit comments