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