[6a3a178] | 1 | 'use strict'
|
---|
| 2 |
|
---|
| 3 | const path = require('path')
|
---|
| 4 | const fs = require('graceful-fs')
|
---|
| 5 | const pathExists = require('../path-exists').pathExists
|
---|
| 6 |
|
---|
| 7 | /**
|
---|
| 8 | * Function that returns two types of paths, one relative to symlink, and one
|
---|
| 9 | * relative to the current working directory. Checks if path is absolute or
|
---|
| 10 | * relative. If the path is relative, this function checks if the path is
|
---|
| 11 | * relative to symlink or relative to current working directory. This is an
|
---|
| 12 | * initiative to find a smarter `srcpath` to supply when building symlinks.
|
---|
| 13 | * This allows you to determine which path to use out of one of three possible
|
---|
| 14 | * types of source paths. The first is an absolute path. This is detected by
|
---|
| 15 | * `path.isAbsolute()`. When an absolute path is provided, it is checked to
|
---|
| 16 | * see if it exists. If it does it's used, if not an error is returned
|
---|
| 17 | * (callback)/ thrown (sync). The other two options for `srcpath` are a
|
---|
| 18 | * relative url. By default Node's `fs.symlink` works by creating a symlink
|
---|
| 19 | * using `dstpath` and expects the `srcpath` to be relative to the newly
|
---|
| 20 | * created symlink. If you provide a `srcpath` that does not exist on the file
|
---|
| 21 | * system it results in a broken symlink. To minimize this, the function
|
---|
| 22 | * checks to see if the 'relative to symlink' source file exists, and if it
|
---|
| 23 | * does it will use it. If it does not, it checks if there's a file that
|
---|
| 24 | * exists that is relative to the current working directory, if does its used.
|
---|
| 25 | * This preserves the expectations of the original fs.symlink spec and adds
|
---|
| 26 | * the ability to pass in `relative to current working direcotry` paths.
|
---|
| 27 | */
|
---|
| 28 |
|
---|
| 29 | function symlinkPaths (srcpath, dstpath, callback) {
|
---|
| 30 | if (path.isAbsolute(srcpath)) {
|
---|
| 31 | return fs.lstat(srcpath, (err) => {
|
---|
| 32 | if (err) {
|
---|
| 33 | err.message = err.message.replace('lstat', 'ensureSymlink')
|
---|
| 34 | return callback(err)
|
---|
| 35 | }
|
---|
| 36 | return callback(null, {
|
---|
| 37 | 'toCwd': srcpath,
|
---|
| 38 | 'toDst': srcpath
|
---|
| 39 | })
|
---|
| 40 | })
|
---|
| 41 | } else {
|
---|
| 42 | const dstdir = path.dirname(dstpath)
|
---|
| 43 | const relativeToDst = path.join(dstdir, srcpath)
|
---|
| 44 | return pathExists(relativeToDst, (err, exists) => {
|
---|
| 45 | if (err) return callback(err)
|
---|
| 46 | if (exists) {
|
---|
| 47 | return callback(null, {
|
---|
| 48 | 'toCwd': relativeToDst,
|
---|
| 49 | 'toDst': srcpath
|
---|
| 50 | })
|
---|
| 51 | } else {
|
---|
| 52 | return fs.lstat(srcpath, (err) => {
|
---|
| 53 | if (err) {
|
---|
| 54 | err.message = err.message.replace('lstat', 'ensureSymlink')
|
---|
| 55 | return callback(err)
|
---|
| 56 | }
|
---|
| 57 | return callback(null, {
|
---|
| 58 | 'toCwd': srcpath,
|
---|
| 59 | 'toDst': path.relative(dstdir, srcpath)
|
---|
| 60 | })
|
---|
| 61 | })
|
---|
| 62 | }
|
---|
| 63 | })
|
---|
| 64 | }
|
---|
| 65 | }
|
---|
| 66 |
|
---|
| 67 | function symlinkPathsSync (srcpath, dstpath) {
|
---|
| 68 | let exists
|
---|
| 69 | if (path.isAbsolute(srcpath)) {
|
---|
| 70 | exists = fs.existsSync(srcpath)
|
---|
| 71 | if (!exists) throw new Error('absolute srcpath does not exist')
|
---|
| 72 | return {
|
---|
| 73 | 'toCwd': srcpath,
|
---|
| 74 | 'toDst': srcpath
|
---|
| 75 | }
|
---|
| 76 | } else {
|
---|
| 77 | const dstdir = path.dirname(dstpath)
|
---|
| 78 | const relativeToDst = path.join(dstdir, srcpath)
|
---|
| 79 | exists = fs.existsSync(relativeToDst)
|
---|
| 80 | if (exists) {
|
---|
| 81 | return {
|
---|
| 82 | 'toCwd': relativeToDst,
|
---|
| 83 | 'toDst': srcpath
|
---|
| 84 | }
|
---|
| 85 | } else {
|
---|
| 86 | exists = fs.existsSync(srcpath)
|
---|
| 87 | if (!exists) throw new Error('relative srcpath does not exist')
|
---|
| 88 | return {
|
---|
| 89 | 'toCwd': srcpath,
|
---|
| 90 | 'toDst': path.relative(dstdir, srcpath)
|
---|
| 91 | }
|
---|
| 92 | }
|
---|
| 93 | }
|
---|
| 94 | }
|
---|
| 95 |
|
---|
| 96 | module.exports = {
|
---|
| 97 | symlinkPaths,
|
---|
| 98 | symlinkPathsSync
|
---|
| 99 | }
|
---|