100 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			100 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| 'use strict'
 | |
| 
 | |
| const path = require('path')
 | |
| const fs = require('graceful-fs')
 | |
| const pathExists = require('../path-exists').pathExists
 | |
| 
 | |
| /**
 | |
|  * Function that returns two types of paths, one relative to symlink, and one
 | |
|  * relative to the current working directory. Checks if path is absolute or
 | |
|  * relative. If the path is relative, this function checks if the path is
 | |
|  * relative to symlink or relative to current working directory. This is an
 | |
|  * initiative to find a smarter `srcpath` to supply when building symlinks.
 | |
|  * This allows you to determine which path to use out of one of three possible
 | |
|  * types of source paths. The first is an absolute path. This is detected by
 | |
|  * `path.isAbsolute()`. When an absolute path is provided, it is checked to
 | |
|  * see if it exists. If it does it's used, if not an error is returned
 | |
|  * (callback)/ thrown (sync). The other two options for `srcpath` are a
 | |
|  * relative url. By default Node's `fs.symlink` works by creating a symlink
 | |
|  * using `dstpath` and expects the `srcpath` to be relative to the newly
 | |
|  * created symlink. If you provide a `srcpath` that does not exist on the file
 | |
|  * system it results in a broken symlink. To minimize this, the function
 | |
|  * checks to see if the 'relative to symlink' source file exists, and if it
 | |
|  * does it will use it. If it does not, it checks if there's a file that
 | |
|  * exists that is relative to the current working directory, if does its used.
 | |
|  * This preserves the expectations of the original fs.symlink spec and adds
 | |
|  * the ability to pass in `relative to current working direcotry` paths.
 | |
|  */
 | |
| 
 | |
| function symlinkPaths (srcpath, dstpath, callback) {
 | |
|   if (path.isAbsolute(srcpath)) {
 | |
|     return fs.lstat(srcpath, (err) => {
 | |
|       if (err) {
 | |
|         err.message = err.message.replace('lstat', 'ensureSymlink')
 | |
|         return callback(err)
 | |
|       }
 | |
|       return callback(null, {
 | |
|         'toCwd': srcpath,
 | |
|         'toDst': srcpath
 | |
|       })
 | |
|     })
 | |
|   } else {
 | |
|     const dstdir = path.dirname(dstpath)
 | |
|     const relativeToDst = path.join(dstdir, srcpath)
 | |
|     return pathExists(relativeToDst, (err, exists) => {
 | |
|       if (err) return callback(err)
 | |
|       if (exists) {
 | |
|         return callback(null, {
 | |
|           'toCwd': relativeToDst,
 | |
|           'toDst': srcpath
 | |
|         })
 | |
|       } else {
 | |
|         return fs.lstat(srcpath, (err) => {
 | |
|           if (err) {
 | |
|             err.message = err.message.replace('lstat', 'ensureSymlink')
 | |
|             return callback(err)
 | |
|           }
 | |
|           return callback(null, {
 | |
|             'toCwd': srcpath,
 | |
|             'toDst': path.relative(dstdir, srcpath)
 | |
|           })
 | |
|         })
 | |
|       }
 | |
|     })
 | |
|   }
 | |
| }
 | |
| 
 | |
| function symlinkPathsSync (srcpath, dstpath) {
 | |
|   let exists
 | |
|   if (path.isAbsolute(srcpath)) {
 | |
|     exists = fs.existsSync(srcpath)
 | |
|     if (!exists) throw new Error('absolute srcpath does not exist')
 | |
|     return {
 | |
|       'toCwd': srcpath,
 | |
|       'toDst': srcpath
 | |
|     }
 | |
|   } else {
 | |
|     const dstdir = path.dirname(dstpath)
 | |
|     const relativeToDst = path.join(dstdir, srcpath)
 | |
|     exists = fs.existsSync(relativeToDst)
 | |
|     if (exists) {
 | |
|       return {
 | |
|         'toCwd': relativeToDst,
 | |
|         'toDst': srcpath
 | |
|       }
 | |
|     } else {
 | |
|       exists = fs.existsSync(srcpath)
 | |
|       if (!exists) throw new Error('relative srcpath does not exist')
 | |
|       return {
 | |
|         'toCwd': srcpath,
 | |
|         'toDst': path.relative(dstdir, srcpath)
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| }
 | |
| 
 | |
| module.exports = {
 | |
|   symlinkPaths,
 | |
|   symlinkPathsSync
 | |
| }
 |