| 1 | 'use strict'
|
|---|
| 2 |
|
|---|
| 3 | const u = require('universalify').fromCallback
|
|---|
| 4 | const path = require('path')
|
|---|
| 5 | const fs = require('graceful-fs')
|
|---|
| 6 | const mkdir = require('../mkdirs')
|
|---|
| 7 | const pathExists = require('../path-exists').pathExists
|
|---|
| 8 | const { areIdentical } = require('../util/stat')
|
|---|
| 9 |
|
|---|
| 10 | function createLink (srcpath, dstpath, callback) {
|
|---|
| 11 | function makeLink (srcpath, dstpath) {
|
|---|
| 12 | fs.link(srcpath, dstpath, err => {
|
|---|
| 13 | if (err) return callback(err)
|
|---|
| 14 | callback(null)
|
|---|
| 15 | })
|
|---|
| 16 | }
|
|---|
| 17 |
|
|---|
| 18 | fs.lstat(dstpath, (_, dstStat) => {
|
|---|
| 19 | fs.lstat(srcpath, (err, srcStat) => {
|
|---|
| 20 | if (err) {
|
|---|
| 21 | err.message = err.message.replace('lstat', 'ensureLink')
|
|---|
| 22 | return callback(err)
|
|---|
| 23 | }
|
|---|
| 24 | if (dstStat && areIdentical(srcStat, dstStat)) return callback(null)
|
|---|
| 25 |
|
|---|
| 26 | const dir = path.dirname(dstpath)
|
|---|
| 27 | pathExists(dir, (err, dirExists) => {
|
|---|
| 28 | if (err) return callback(err)
|
|---|
| 29 | if (dirExists) return makeLink(srcpath, dstpath)
|
|---|
| 30 | mkdir.mkdirs(dir, err => {
|
|---|
| 31 | if (err) return callback(err)
|
|---|
| 32 | makeLink(srcpath, dstpath)
|
|---|
| 33 | })
|
|---|
| 34 | })
|
|---|
| 35 | })
|
|---|
| 36 | })
|
|---|
| 37 | }
|
|---|
| 38 |
|
|---|
| 39 | function createLinkSync (srcpath, dstpath) {
|
|---|
| 40 | let dstStat
|
|---|
| 41 | try {
|
|---|
| 42 | dstStat = fs.lstatSync(dstpath)
|
|---|
| 43 | } catch {}
|
|---|
| 44 |
|
|---|
| 45 | try {
|
|---|
| 46 | const srcStat = fs.lstatSync(srcpath)
|
|---|
| 47 | if (dstStat && areIdentical(srcStat, dstStat)) return
|
|---|
| 48 | } catch (err) {
|
|---|
| 49 | err.message = err.message.replace('lstat', 'ensureLink')
|
|---|
| 50 | throw err
|
|---|
| 51 | }
|
|---|
| 52 |
|
|---|
| 53 | const dir = path.dirname(dstpath)
|
|---|
| 54 | const dirExists = fs.existsSync(dir)
|
|---|
| 55 | if (dirExists) return fs.linkSync(srcpath, dstpath)
|
|---|
| 56 | mkdir.mkdirsSync(dir)
|
|---|
| 57 |
|
|---|
| 58 | return fs.linkSync(srcpath, dstpath)
|
|---|
| 59 | }
|
|---|
| 60 |
|
|---|
| 61 | module.exports = {
|
|---|
| 62 | createLink: u(createLink),
|
|---|
| 63 | createLinkSync
|
|---|
| 64 | }
|
|---|