summaryrefslogtreecommitdiff
path: root/deps/npm/node_modules/gentle-fs/lib/link.js
diff options
context:
space:
mode:
Diffstat (limited to 'deps/npm/node_modules/gentle-fs/lib/link.js')
-rw-r--r--deps/npm/node_modules/gentle-fs/lib/link.js66
1 files changed, 66 insertions, 0 deletions
diff --git a/deps/npm/node_modules/gentle-fs/lib/link.js b/deps/npm/node_modules/gentle-fs/lib/link.js
new file mode 100644
index 0000000000..246d801479
--- /dev/null
+++ b/deps/npm/node_modules/gentle-fs/lib/link.js
@@ -0,0 +1,66 @@
+'use strict'
+
+const path = require('path')
+const fs = require('graceful-fs')
+const chain = require('slide').chain
+const mkdir = require('mkdirp')
+const rm = require('./rm.js')
+
+exports = module.exports = {
+ link: link,
+ linkIfExists: linkIfExists
+}
+
+function linkIfExists (from, to, opts, cb) {
+ fs.stat(from, function (er) {
+ if (er) return cb()
+ fs.readlink(to, function (er, fromOnDisk) {
+ // if the link already exists and matches what we would do,
+ // we don't need to do anything
+ if (!er) {
+ var toDir = path.dirname(to)
+ var absoluteFrom = path.resolve(toDir, from)
+ var absoluteFromOnDisk = path.resolve(toDir, fromOnDisk)
+ if (absoluteFrom === absoluteFromOnDisk) return cb()
+ }
+ link(from, to, opts, cb)
+ })
+ })
+}
+
+function resolveIfSymlink (maybeSymlinkPath, cb) {
+ fs.lstat(maybeSymlinkPath, function (err, stat) {
+ if (err) return cb.apply(this, arguments)
+ if (!stat.isSymbolicLink()) return cb(null, maybeSymlinkPath)
+ fs.readlink(maybeSymlinkPath, cb)
+ })
+}
+
+function ensureFromIsNotSource (from, to, cb) {
+ resolveIfSymlink(from, function (err, fromDestination) {
+ if (err) return cb.apply(this, arguments)
+ if (path.resolve(path.dirname(from), fromDestination) === path.resolve(to)) {
+ return cb(new Error('Link target resolves to the same directory as link source: ' + to))
+ }
+ cb.apply(this, arguments)
+ })
+}
+
+function link (from, to, opts, cb) {
+ to = path.resolve(to)
+ opts.base = path.dirname(to)
+ var absTarget = path.resolve(opts.base, from)
+ var relativeTarget = path.relative(opts.base, absTarget)
+ var target = opts.absolute ? absTarget : relativeTarget
+
+ chain(
+ [
+ [ensureFromIsNotSource, absTarget, to],
+ [fs, 'stat', absTarget],
+ [rm, to, opts],
+ [mkdir, path.dirname(to)],
+ [fs, 'symlink', target, to, 'junction']
+ ],
+ cb
+ )
+}