symlink-or-copy
Advanced tools
Comparing version 1.0.1 to 1.1.0
# master | ||
# 1.1.0 | ||
* Use junctions when possible on Windows if symlinks are not available | ||
# 1.0.1 | ||
@@ -4,0 +8,0 @@ |
14
index.js
var fs = require('fs') | ||
var tmpdir = require('os').tmpdir(); | ||
var path = require('path') | ||
var copyDereferenceSync = require('copy-dereference').sync | ||
var spawn = require('child_process').spawn | ||
var isWindows = process.platform === 'win32' | ||
@@ -11,3 +9,2 @@ // These can be overridden for testing | ||
isWindows: isWindows, | ||
copyDereferenceSync: copyDereferenceSync, | ||
canSymlink: testCanSymlink(), | ||
@@ -87,10 +84,15 @@ fs: fs | ||
function symlinkWindows(srcPath, destPath) { | ||
var stat = options.fs.statSync(srcPath) | ||
var isDir = stat.isDirectory() | ||
if (options.canSymlink) { | ||
srcPath = options.fs.realpathSync(srcPath) | ||
var lstat = options.fs.lstatSync(srcPath) | ||
var isDir = lstat.isDirectory() | ||
options.fs.symlinkSync(srcPath, destPath, isDir ? 'dir' : 'file') | ||
} else if (isDir) { | ||
srcPath = options.fs.realpathSync(srcPath) | ||
options.fs.symlinkSync(srcPath, destPath, 'junction'); | ||
} else { | ||
options.copyDereferenceSync(srcPath, destPath) | ||
options.fs.writeFileSync(destPath, options.fs.readFileSync(srcPath), { flag: 'wx', mode: stat.mode }) | ||
options.fs.utimesSync(destPath, stat.atime, stat.mtime) | ||
} | ||
} |
{ | ||
"name": "symlink-or-copy", | ||
"description": "Symlink files or directories, falling back to copying on Windows", | ||
"version": "1.0.1", | ||
"version": "1.1.0", | ||
"author": "Jo Liss <joliss42@gmail.com>", | ||
@@ -12,11 +12,9 @@ "main": "index.js", | ||
}, | ||
"dependencies": { | ||
"copy-dereference": "^1.0.0" | ||
}, | ||
"scripts": { | ||
"test": "mocha tests/" | ||
"test": "mocha tests/", | ||
"test:debug": "mocha debug tests" | ||
}, | ||
"devDependencies": { | ||
"mocha": "^1.21.4" | ||
"mocha": "^2.2.4" | ||
} | ||
} |
# node-symlink-or-copy | ||
[![Build Status](https://travis-ci.org/broccolijs/node-symlink-or-copy.svg?branch=master)](https://travis-ci.org/broccolijs/node-symlink-or-copy) | ||
[![Build status](https://ci.appveyor.com/api/projects/status/rilxgmo21j3qth3v/branch/master?svg=true)](https://ci.appveyor.com/project/joliss/node-symlink-or-copy/branch/master) | ||
Symlink a file or directory to another place. Fall back to copying on Windows. | ||
@@ -60,10 +63,9 @@ Made for use with Broccoli plugins, for "do what I mean" behavior. | ||
* Symlinks could technically work on Windows, but they require special rights. | ||
There are also junctions, but it's not clear whether they are useful. We might | ||
want to be smarter about using symlinks on Windows when we can, but at the | ||
moment we opt for the simplest solution (always copying), even though it | ||
sacrifices performance on Windows. | ||
* Symlinks technically work on Windows, but they require special rights. For | ||
users with those rights, symlinks are used, but when not available, a | ||
combination of junctions and copying is used to mimic the behavior somewhat | ||
performantly. | ||
* There intentionally isn't an asynchronous version. It's not clear that we | ||
need or want one. Before sending a patch to add an async version, please share | ||
your use case on the issue tracker. | ||
* There intentionally isn't an asynchronoukks version. It's not clear that we | ||
need or want one. Before sending a patch to add an async version, please | ||
share your use case on the issue tracker. |
@@ -9,4 +9,6 @@ var assert = require('assert'); | ||
it('windows falls back to copy', function() { | ||
it('windows falls back to junction for dir', function() { | ||
var count = 0; | ||
var lsStatSyncCount = 0; | ||
var isDirectoryCount = 0; | ||
symLinkOrCopy.setOptions({ | ||
@@ -17,8 +19,76 @@ isWindows: true, | ||
}, | ||
canSymLink: false | ||
canSymLink: false, | ||
fs: { | ||
statSync: function() { | ||
lsStatSyncCount++; | ||
return { | ||
isSymbolicLink: function() { | ||
return true; | ||
}, | ||
isDirectory: function() { | ||
isDirectoryCount++; | ||
return true; | ||
} | ||
} | ||
}, | ||
realpathSync: function() {count++}, | ||
symlinkSync: function() {count++;} | ||
} | ||
}); | ||
symLinkOrCopy.sync(); | ||
assert.equal(count, 1); | ||
symLinkOrCopy.sync('foo', 'bar'); | ||
assert.equal(count, 2); | ||
assert.equal(lsStatSyncCount, 1); | ||
assert.equal(isDirectoryCount, 1); | ||
}); | ||
it('windows falls back to copy for file', function() { | ||
var count = 0 | ||
var lsStatSyncCount = 0 | ||
var isDirectoryCount = 0 | ||
var readFileSyncCount = 0 | ||
var writeFileSyncCount = 0 | ||
var utimesSyncCount = 0 | ||
symLinkOrCopy.setOptions({ | ||
isWindows: true, | ||
copyDereferenceSync: function() { | ||
count++ | ||
}, | ||
canSymLink: false, | ||
fs: { | ||
statSync: function() { | ||
lsStatSyncCount++ | ||
return { | ||
isSymbolicLink: function() { | ||
return true | ||
}, | ||
isDirectory: function() { | ||
isDirectoryCount++ | ||
return false | ||
} | ||
}; | ||
}, | ||
readFileSync: function() { | ||
readFileSyncCount++ | ||
return 'foo'; | ||
}, | ||
writeFileSync: function() { | ||
writeFileSyncCount++ | ||
return 'foo'; | ||
}, | ||
realpathSync: function() {count++}, | ||
symlinkSync: function() {count++}, | ||
utimesSync: function() {utimesSyncCount++} | ||
} | ||
}); | ||
symLinkOrCopy.sync('foo', 'bar'); | ||
assert.equal(count, 0); | ||
assert.equal(lsStatSyncCount, 1); | ||
assert.equal(isDirectoryCount, 1); | ||
assert.equal(writeFileSyncCount, 1); | ||
assert.equal(readFileSyncCount, 1); | ||
assert.equal(utimesSyncCount, 1); | ||
}); | ||
it('windows symlinks when has permission', function() { | ||
@@ -28,3 +98,3 @@ var count = 0; | ||
fs: { | ||
lstatSync: function() { | ||
statSync: function() { | ||
return { | ||
@@ -43,6 +113,7 @@ isSymbolicLink: function() { | ||
}, | ||
canSymlink: true | ||
canSymlink: true, | ||
isWindows: true | ||
}); | ||
symLinkOrCopy.sync(); | ||
assert.equal(count, 3); | ||
assert.equal(count, 2); | ||
}) | ||
@@ -49,0 +120,0 @@ }); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Shell access
Supply chain riskThis module accesses the system shell. Accessing the system shell increases the risk of executing arbitrary code.
Found 1 instance in 1 package
11234
0
9
219
71
- Removedcopy-dereference@^1.0.0
- Removedcopy-dereference@1.0.0(transitive)