@@ -76,6 +76,13 @@ func (p *Path) Stat() (os.FileInfo, error) {
76
76
return os .Stat (p .path )
77
77
}
78
78
79
+ // Lstat returns a FileInfo describing the named file.
80
+ // If the file is a symbolic link, the returned FileInfo
81
+ // describes the symbolic link. Lstat makes no attempt to follow the link.
82
+ func (p * Path ) Lstat () (os.FileInfo , error ) {
83
+ return os .Lstat (p .path )
84
+ }
85
+
79
86
// Clone create a copy of the Path object
80
87
func (p * Path ) Clone () * Path {
81
88
return New (p .path )
@@ -311,6 +318,16 @@ func (p *Path) IsDirCheck() (bool, error) {
311
318
return false , err
312
319
}
313
320
321
+ // IsDirCheck return true if the path exists and is a symlink. In all the other
322
+ // cases (and also in case of any error) false is returned.
323
+ func (p * Path ) IsSymlink () (bool , error ) {
324
+ info , err := p .Lstat ()
325
+ if err != nil {
326
+ return false , fmt .Errorf ("getting lstat info for %s: %s" , p .path , err )
327
+ }
328
+ return info .Mode ()& os .ModeSymlink != 0 , nil
329
+ }
330
+
314
331
// CopyTo copies the contents of the file named src to the file named
315
332
// by dst. The file will be created if it does not already exist. If the
316
333
// destination file exists, all it's contents will be replaced by the contents
@@ -382,22 +399,30 @@ func (p *Path) CopyDirTo(dst *Path) error {
382
399
}
383
400
384
401
for _ , srcPath := range srcFiles {
385
- srcPathInfo , err := srcPath . Stat ( )
402
+ srcPathInfo , err := os . Lstat ( srcPath . path )
386
403
if err != nil {
387
- return fmt .Errorf ("getting stat info for %s: %s" , srcPath , err )
404
+ return fmt .Errorf ("getting lstat info for %s: %s" , srcPath , err )
388
405
}
389
406
dstPath := dst .Join (srcPath .Base ())
390
407
391
- if srcPathInfo .IsDir () {
392
- if err := srcPath .CopyDirTo (dstPath ); err != nil {
393
- return fmt .Errorf ("copying %s to %s: %s" , srcPath , dstPath , err )
408
+ // In case is a symlink, copy the symlink
409
+ if srcPathInfo .Mode ()& os .ModeSymlink != 0 {
410
+ namedLink , err := os .Readlink (srcPath .path )
411
+ if err != nil {
412
+ return fmt .Errorf ("could not read symlink: %s" , err .Error ())
413
+ }
414
+
415
+ if err := os .Symlink (namedLink , dstPath .path ); err != nil {
416
+ return fmt .Errorf ("creating symlink (%s) of %s to %s: %s" , namedLink , srcPath , dstPath , err )
394
417
}
418
+
395
419
continue
396
420
}
397
421
398
- // Skip symlinks.
399
- if srcPathInfo .Mode ()& os .ModeSymlink != 0 {
400
- // TODO
422
+ if srcPathInfo .IsDir () {
423
+ if err := srcPath .CopyDirTo (dstPath ); err != nil {
424
+ return fmt .Errorf ("copying %s to %s: %s" , srcPath , dstPath , err )
425
+ }
401
426
continue
402
427
}
403
428
0 commit comments