@@ -292,8 +292,11 @@ file.write = function(filepath, contents, options) {
292292// Read a file, optionally processing its content, then write the output.
293293// Or read a directory, recursively creating directories, reading files,
294294// processing content, writing output.
295+ // Handles symlinks by coping them as files or directories.
295296file . copy = function copy ( srcpath , destpath , options ) {
296- if ( file . isDir ( srcpath ) ) {
297+ if ( file . _isSymbolicLink ( srcpath ) ) {
298+ file . _copySymbolicLink ( srcpath , destpath ) ;
299+ } else if ( file . isDir ( srcpath ) ) {
297300 // Copy a directory, recursively.
298301 // Explicitly create new dest directory.
299302 file . mkdir ( destpath ) ;
@@ -449,6 +452,24 @@ file.isPathCwd = function() {
449452 }
450453} ;
451454
455+ file . _isSymbolicLink = function ( ) {
456+ var filepath = path . join . apply ( path , arguments ) ;
457+ return fs . lstatSync ( filepath ) . isSymbolicLink ( ) ;
458+ } ;
459+
460+ file . _copySymbolicLink = function ( srcpath , destpath ) {
461+ var destdir = path . join ( destpath , '..' ) ;
462+ var fileBase = path . basename ( srcpath ) ;
463+ // Use the correct relative path for the symlink
464+ if ( ! grunt . file . isPathAbsolute ( srcpath ) ) {
465+ srcpath = path . relative ( destdir , srcpath ) || '.' ;
466+ }
467+ file . mkdir ( destdir ) ;
468+ var mode = grunt . file . isDir ( srcpath ) ? 'dir' : 'file' ;
469+ var destpath = path . join ( destpath , fileBase ) ;
470+ return fs . symlinkSync ( srcpath , destpath , mode ) ;
471+ } ;
472+
452473// Test to see if a filepath is contained within the CWD.
453474file . isPathInCwd = function ( ) {
454475 var filepath = path . join . apply ( path , arguments ) ;
0 commit comments