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 | }
|
---|