createLink.js 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. var fs = require('graceful-fs');
  2. var path = require('path');
  3. var Q = require('q');
  4. var mkdirp = require('mkdirp');
  5. var createError = require('./createError');
  6. var isWin = process.platform === 'win32';
  7. function createLink(src, dst, type) {
  8. var dstDir = path.dirname(dst);
  9. // Create directory
  10. return Q.nfcall(mkdirp, dstDir)
  11. // Check if source exists
  12. .then(function () {
  13. return Q.nfcall(fs.stat, src)
  14. .fail(function (error) {
  15. if (error.code === 'ENOENT') {
  16. throw createError('Failed to create link to ' + path.basename(src), 'ENOENT', {
  17. details: src + ' does not exist or points to a non-existent file'
  18. });
  19. }
  20. throw error;
  21. });
  22. })
  23. // Create symlink
  24. .then(function (stat) {
  25. type = type || (stat.isDirectory() ? 'dir' : 'file');
  26. return Q.nfcall(fs.symlink, src, dst, type)
  27. .fail(function (err) {
  28. if (!isWin || err.code !== 'EPERM') {
  29. throw err;
  30. }
  31. // Try with type "junction" on Windows
  32. // Junctions behave equally to true symlinks and can be created in
  33. // non elevated terminal (well, not always..)
  34. return Q.nfcall(fs.symlink, src, dst, 'junction')
  35. .fail(function (err) {
  36. throw createError('Unable to create link to ' + path.basename(src), err.code, {
  37. details: err.message.trim() + '\n\nTry running this command in an elevated terminal (run as root/administrator).'
  38. });
  39. });
  40. });
  41. });
  42. }
  43. module.exports = createLink;