diff --git a/lib/symlink/link-file.js b/lib/symlink/link-file.js index a8bbc8fa..425664f5 100644 --- a/lib/symlink/link-file.js +++ b/lib/symlink/link-file.js @@ -13,28 +13,16 @@ var isWindows = (os.platform() === 'win32'); function linkStream(optResolver) { function linkFile(file, enc, callback) { - // This option provides a way to create a Junction instead of a - // Directory symlink on Windows. This comes with the following caveats: - // * NTFS Junctions cannot be relative. - // * NTFS Junctions MUST be directories. - // * NTFS Junctions must be on the same file system. - // * Most products CANNOT detect a directory is a Junction: - // This has the side effect of possibly having a whole directory - // deleted when a product is deleting the Junction directory. - // For example, JetBrains product lines will delete the entire - // contents of the TARGET directory because the product does not - // realize it's a symlink as the JVM and Node return false for isSymlink. - var useJunctions = isWindows && optResolver.resolve('useJunctions', file); - var isRelative = optResolver.resolve('relativeSymlinks', file); var flag = optResolver.resolve('flag', file); - if (isWindows) { - fs.stat(file.symlink, onStat); - } else { - onStat(null, file.stat); + if (!isWindows) { + // On non-Windows, just use 'file' + return createLinkWithType('file'); } + fs.stat(file.symlink, onStat); + function onStat(statErr, stat) { if (statErr && statErr.code !== 'ENOENT') { return onWritten(statErr); @@ -45,9 +33,29 @@ function linkStream(optResolver) { stat = file.stat; } + // This option provides a way to create a Junction instead of a + // Directory symlink on Windows. This comes with the following caveats: + // * NTFS Junctions cannot be relative. + // * NTFS Junctions MUST be directories. + // * NTFS Junctions must be on the same file system. + // * Most products CANNOT detect a directory is a Junction: + // This has the side effect of possibly having a whole directory + // deleted when a product is deleting the Junction directory. + // For example, JetBrains product lines will delete the entire + // contents of the TARGET directory because the product does not + // realize it's a symlink as the JVM and Node return false for isSymlink. + + // This function is Windows only, so we don't need to check again + var useJunctions = optResolver.resolve('useJunctions', file); + var symDirType = useJunctions ? 'junction' : 'dir'; - var symType = stat && stat.isDirectory() ? symDirType : 'file'; + // Must check if isDirectory is defined + var symType = stat && stat.isDirectory && stat.isDirectory() ? symDirType : 'file'; + + createLinkWithType(symType); + } + function createLinkWithType(symType) { // This is done after prepare() to use the adjusted file.base property if (isRelative && symType !== 'junction') { file.symlink = path.relative(file.base, file.symlink); diff --git a/lib/symlink/prepare.js b/lib/symlink/prepare.js index 69134528..664c9de6 100644 --- a/lib/symlink/prepare.js +++ b/lib/symlink/prepare.js @@ -29,6 +29,7 @@ function prepareSymlink(folderResolver, optResolver) { file.stat.mode = LINK_MODE; file.cwd = cwd; file.base = basePath; + // This is the path we are linking *TO* file.symlink = file.path; file.path = writePath; // We have to set contents to null for a link