1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889 |
- 'use strict';
- var os = require('os');
- var path = require('path');
- var through = require('through2');
- var fo = require('../file-operations');
- var isWindows = (os.platform() === 'win32');
- function linkStream(optResolver) {
- function linkFile(file, enc, callback) {
- var isRelative = optResolver.resolve('relativeSymlinks', file);
- var flags = fo.getFlags({
- overwrite: optResolver.resolve('overwrite', file),
- append: false,
- });
- if (!isWindows) {
- // On non-Windows, just use 'file'
- return createLinkWithType('file');
- }
- fo.reflectStat(file.symlink, file, onReflectTarget);
- function onReflectTarget(statErr) {
- if (statErr && statErr.code !== 'ENOENT') {
- return callback(statErr);
- }
- // If target doesn't exist, the vinyl will still carry the target stats.
- // Let's use those to determine which kind of dangling link to create.
- // 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 dirType = useJunctions ? 'junction' : 'dir';
- var type = !statErr && file.isDirectory() ? dirType : 'file';
- createLinkWithType(type);
- }
- function createLinkWithType(type) {
- // This is done after prepare() to use the adjusted file.base property
- if (isRelative && type !== 'junction') {
- file.symlink = path.relative(file.base, file.symlink);
- }
- var opts = {
- flags: flags,
- type: type,
- };
- fo.symlink(file.symlink, file.path, opts, onSymlink);
- }
- function onSymlink(symlinkErr) {
- if (symlinkErr) {
- return callback(symlinkErr);
- }
- fo.reflectLinkStat(file.path, file, onReflectLink);
- }
- function onReflectLink(reflectErr) {
- if (reflectErr) {
- return callback(reflectErr);
- }
- callback(null, file);
- }
- }
- return through.obj(linkFile);
- }
- module.exports = linkStream;
|