1 var path = require('path')
2 // path.isAbsolute shim for Node.js 0.10 support
3 path.isAbsolute = (path.isAbsolute) ? path.isAbsolute : require('path-is-absolute')
4 var fs = require('graceful-fs')
7 * Function that returns two types of paths, one relative to symlink, and one
8 * relative to the current working directory. Checks if path is absolute or
9 * relative. If the path is relative, this function checks if the path is
10 * relative to symlink or relative to current working directory. This is an
11 * initiative to find a smarter `srcpath` to supply when building symlinks.
12 * This allows you to determine which path to use out of one of three possible
13 * types of source paths. The first is an absolute path. This is detected by
14 * `path.isAbsolute()`. When an absolute path is provided, it is checked to
15 * see if it exists. If it does it's used, if not an error is returned
16 * (callback)/ thrown (sync). The other two options for `srcpath` are a
17 * relative url. By default Node's `fs.symlink` works by creating a symlink
18 * using `dstpath` and expects the `srcpath` to be relative to the newly
19 * created symlink. If you provide a `srcpath` that does not exist on the file
20 * system it results in a broken symlink. To minimize this, the function
21 * checks to see if the 'relative to symlink' source file exists, and if it
22 * does it will use it. If it does not, it checks if there's a file that
23 * exists that is relative to the current working directory, if does its used.
24 * This preserves the expectations of the original fs.symlink spec and adds
25 * the ability to pass in `relative to current working direcotry` paths.
28 function symlinkPaths (srcpath, dstpath, callback) {
29 if (path.isAbsolute(srcpath)) {
30 return fs.lstat(srcpath, function (err, stat) {
32 err.message = err.message.replace('lstat', 'ensureSymlink')
35 return callback(null, {
41 var dstdir = path.dirname(dstpath)
42 var relativeToDst = path.join(dstdir, srcpath)
43 return fs.exists(relativeToDst, function (exists) {
45 return callback(null, {
46 'toCwd': relativeToDst,
50 return fs.lstat(srcpath, function (err, stat) {
52 err.message = err.message.replace('lstat', 'ensureSymlink')
55 return callback(null, {
57 'toDst': path.relative(dstdir, srcpath)
65 function symlinkPathsSync (srcpath, dstpath) {
67 if (path.isAbsolute(srcpath)) {
68 exists = fs.existsSync(srcpath)
69 if (!exists) throw new Error('absolute srcpath does not exist')
75 var dstdir = path.dirname(dstpath)
76 var relativeToDst = path.join(dstdir, srcpath)
77 exists = fs.existsSync(relativeToDst)
80 'toCwd': relativeToDst,
84 exists = fs.existsSync(srcpath)
85 if (!exists) throw new Error('relative srcpath does not exist')
88 'toDst': path.relative(dstdir, srcpath)
95 'symlinkPaths': symlinkPaths,
96 'symlinkPathsSync': symlinkPathsSync