command-installer.js 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. const path = require('path');
  2. const fs = require('fs-plus');
  3. module.exports = class CommandInstaller {
  4. constructor(applicationDelegate) {
  5. this.applicationDelegate = applicationDelegate;
  6. }
  7. initialize(appVersion) {
  8. this.appVersion = appVersion;
  9. }
  10. getInstallDirectory() {
  11. return '/usr/local/bin';
  12. }
  13. getResourcesDirectory() {
  14. return process.resourcesPath;
  15. }
  16. installShellCommandsInteractively() {
  17. const showErrorDialog = error => {
  18. this.applicationDelegate.confirm(
  19. {
  20. message: 'Failed to install shell commands',
  21. detail: error.message
  22. },
  23. () => {}
  24. );
  25. };
  26. this.installAtomCommand(true, (error, atomCommandName) => {
  27. if (error) return showErrorDialog(error);
  28. this.installApmCommand(true, (error, apmCommandName) => {
  29. if (error) return showErrorDialog(error);
  30. this.applicationDelegate.confirm(
  31. {
  32. message: 'Commands installed.',
  33. detail: `The shell commands \`${atomCommandName}\` and \`${apmCommandName}\` are installed.`
  34. },
  35. () => {}
  36. );
  37. });
  38. });
  39. }
  40. getCommandNameForChannel(commandName) {
  41. let channelMatch = this.appVersion.match(/beta|nightly/);
  42. let channel = channelMatch ? channelMatch[0] : '';
  43. switch (channel) {
  44. case 'beta':
  45. return `${commandName}-beta`;
  46. case 'nightly':
  47. return `${commandName}-nightly`;
  48. default:
  49. return commandName;
  50. }
  51. }
  52. installAtomCommand(askForPrivilege, callback) {
  53. this.installCommand(
  54. path.join(this.getResourcesDirectory(), 'pulsar.sh'),
  55. 'pulsar',
  56. askForPrivilege,
  57. callback
  58. );
  59. }
  60. installApmCommand(askForPrivilege, callback) {
  61. this.installCommand(
  62. path.join(
  63. this.getResourcesDirectory(),
  64. 'app',
  65. 'ppm',
  66. 'bin',
  67. 'apm'
  68. ),
  69. 'ppm',
  70. askForPrivilege,
  71. callback
  72. );
  73. }
  74. installCommand(commandPath, commandName, askForPrivilege, callback) {
  75. if (process.platform !== 'darwin') return callback();
  76. const destinationPath = path.join(this.getInstallDirectory(), commandName);
  77. fs.readlink(destinationPath, (error, realpath) => {
  78. if (error && error.code !== 'ENOENT') return callback(error);
  79. if (realpath === commandPath) return callback(null, commandName);
  80. this.createSymlink(fs, commandPath, destinationPath, error => {
  81. if (error && error.code === 'EACCES' && askForPrivilege) {
  82. const fsAdmin = require('fs-admin');
  83. this.createSymlink(fsAdmin, commandPath, destinationPath, error => {
  84. callback(error, commandName);
  85. });
  86. } else {
  87. callback(error);
  88. }
  89. });
  90. });
  91. }
  92. createSymlink(fs, sourcePath, destinationPath, callback) {
  93. fs.unlink(destinationPath, error => {
  94. if (error && error.code !== 'ENOENT') return callback(error);
  95. fs.makeTree(path.dirname(destinationPath), error => {
  96. if (error) return callback(error);
  97. fs.symlink(sourcePath, destinationPath, callback);
  98. });
  99. });
  100. }
  101. };