mirror of
https://github.com/atom/atom.git
synced 2026-01-22 21:38:10 -05:00
Install apm command when Atom starts
This changes the command installation to use symlinks instead of copying over the contents of the file.
This commit is contained in:
@@ -154,23 +154,6 @@ describe "Window", ->
|
||||
window.unloadEditorWindow()
|
||||
expect(atom.saveWindowState.callCount).toBe 1
|
||||
|
||||
describe ".installAtomCommand(commandPath)", ->
|
||||
commandPath = '/tmp/installed-atom-command/atom'
|
||||
|
||||
afterEach ->
|
||||
fsUtils.remove(commandPath) if fsUtils.exists(commandPath)
|
||||
|
||||
describe "when the command path doesn't exist", ->
|
||||
it "copies atom.sh to the specified path", ->
|
||||
expect(fsUtils.exists(commandPath)).toBeFalsy()
|
||||
window.installAtomCommand(commandPath)
|
||||
|
||||
waitsFor ->
|
||||
fsUtils.exists(commandPath)
|
||||
|
||||
runs ->
|
||||
expect(fsUtils.read(commandPath).length).toBeGreaterThan 1
|
||||
|
||||
describe ".deserialize(state)", ->
|
||||
class Foo
|
||||
@deserialize: ({name}) -> new Foo(name)
|
||||
|
||||
34
spec/stdlib/command-installer-spec.coffee
Normal file
34
spec/stdlib/command-installer-spec.coffee
Normal file
@@ -0,0 +1,34 @@
|
||||
fs = require 'fs'
|
||||
fsUtils = require 'fs-utils'
|
||||
installer = require 'command-installer'
|
||||
|
||||
describe "install(commandPath, callback)", ->
|
||||
directory = '/tmp/install-atom-command/atom'
|
||||
commandPath = "#{directory}/source"
|
||||
destinationPath = "#{directory}/bin/source"
|
||||
|
||||
beforeEach ->
|
||||
spyOn(installer, 'findInstallDirectory').andCallFake (callback) ->
|
||||
callback(directory)
|
||||
|
||||
fsUtils.remove(directory) if fsUtils.exists(directory)
|
||||
|
||||
it "symlinks the command and makes it executable", ->
|
||||
fsUtils.write(commandPath, 'test')
|
||||
expect(fsUtils.isFile(commandPath)).toBeTruthy()
|
||||
expect(fsUtils.isExecutable(commandPath)).toBeFalsy()
|
||||
expect(fsUtils.isFile(destinationPath)).toBeFalsy()
|
||||
|
||||
installDone = false
|
||||
installError = null
|
||||
installer.install commandPath, (error) ->
|
||||
installDone = true
|
||||
installError = error
|
||||
|
||||
waitsFor -> installDone
|
||||
|
||||
runs ->
|
||||
expect(installError).toBeNull()
|
||||
expect(fsUtils.isFile(destinationPath)).toBeTruthy()
|
||||
expect(fs.realpathSync(destinationPath)).toBe fs.realpathSync(commandPath)
|
||||
expect(fsUtils.isExecutable(destinationPath)).toBeTruthy()
|
||||
@@ -35,11 +35,8 @@ window.setUpEnvironment = ->
|
||||
|
||||
# This method is only called when opening a real application window
|
||||
window.startEditorWindow = ->
|
||||
directory = _.find ['/opt/boxen', '/opt/github', '/usr/local'], (dir) -> fsUtils.isDirectory(dir)
|
||||
if directory
|
||||
installAtomCommand(fsUtils.join(directory, 'bin/atom'))
|
||||
else
|
||||
console.warn "Failed to install `atom` binary"
|
||||
installAtomCommand()
|
||||
installApmCommand()
|
||||
|
||||
atom.windowMode = 'editor'
|
||||
handleEvents()
|
||||
@@ -85,21 +82,13 @@ window.unloadEditorWindow = ->
|
||||
window.project = null
|
||||
window.git = null
|
||||
|
||||
window.installAtomCommand = (commandPath, done) ->
|
||||
fs.exists commandPath, (exists) ->
|
||||
return if exists
|
||||
window.installAtomCommand = (callback) ->
|
||||
commandPath = fsUtils.join(window.resourcePath, 'atom.sh')
|
||||
require('command-installer').install(commandPath, callback)
|
||||
|
||||
bundledCommandPath = fsUtils.resolve(window.resourcePath, 'atom.sh')
|
||||
if bundledCommandPath?
|
||||
fs.readFile bundledCommandPath, (error, data) ->
|
||||
if error?
|
||||
console.warn "Failed to install `atom` binary", error
|
||||
else
|
||||
fsUtils.writeAsync commandPath, data, (error) ->
|
||||
if error?
|
||||
console.warn "Failed to install `atom` binary", error
|
||||
else
|
||||
fs.chmod(commandPath, 0o755, commandPath)
|
||||
window.installApmCommand = (callback) ->
|
||||
commandPath = fsUtils.join(window.resourcePath, 'node_modules', '.bin', 'apm')
|
||||
require('command-installer').install(commandPath, callback)
|
||||
|
||||
window.unloadConfigWindow = ->
|
||||
return if not configView
|
||||
|
||||
50
src/stdlib/command-installer.coffee
Normal file
50
src/stdlib/command-installer.coffee
Normal file
@@ -0,0 +1,50 @@
|
||||
path = require 'path'
|
||||
fs = require 'fs'
|
||||
_ = require 'underscore'
|
||||
async = require 'async'
|
||||
mkdirp = require 'mkdirp'
|
||||
fsUtils = require 'fs-utils'
|
||||
|
||||
symlinkCommand = (sourcePath, destinationPath, callback) ->
|
||||
mkdirp fsUtils.directory(destinationPath), (error) ->
|
||||
if error?
|
||||
callback(error)
|
||||
else
|
||||
fs.symlink sourcePath, destinationPath, (error) ->
|
||||
if error?
|
||||
callback(error)
|
||||
else
|
||||
fs.chmod(destinationPath, 0o755, callback)
|
||||
|
||||
unlinkCommand = (destinationPath, callback) ->
|
||||
fs.exists destinationPath, (exists) ->
|
||||
if exists
|
||||
fs.unlink(destinationPath, callback)
|
||||
else
|
||||
callback()
|
||||
|
||||
module.exports =
|
||||
findInstallDirectory: (callback) ->
|
||||
directories = ['/opt/boxen','/opt/github','/usr/local']
|
||||
async.detect(directories, fsUtils.isDirectoryAsync, callback)
|
||||
|
||||
install: (commandPath, commandName, callback) ->
|
||||
if not commandName? or _.isFunction(commandName)
|
||||
callback = commandName
|
||||
commandName = path.basename(commandPath, path.extname(commandPath))
|
||||
|
||||
installCallback = (error) ->
|
||||
if error?
|
||||
console.warn "Failed to install `#{commandName}` binary", error
|
||||
callback?(error)
|
||||
|
||||
@findInstallDirectory (directory) ->
|
||||
if directory?
|
||||
destinationPath = path.join(directory, 'bin', commandName)
|
||||
unlinkCommand destinationPath, (error) ->
|
||||
if error?
|
||||
installCallback(error)
|
||||
else
|
||||
symlinkCommand(commandPath, destinationPath, installCallback)
|
||||
else
|
||||
installCallback(new Error("No destination directory exists to install"))
|
||||
@@ -73,8 +73,11 @@ module.exports =
|
||||
return done(false) unless path?.length > 0
|
||||
fs.exists path, (exists) ->
|
||||
if exists
|
||||
fs.stat path, (err, stat) ->
|
||||
done(stat?.isDirectory() ? false)
|
||||
fs.stat path, (error, stat) ->
|
||||
if error?
|
||||
done(false)
|
||||
else
|
||||
done(stat.isDirectory())
|
||||
else
|
||||
done(false)
|
||||
|
||||
@@ -87,6 +90,13 @@ module.exports =
|
||||
catch e
|
||||
false
|
||||
|
||||
# Returns true if the specified path is exectuable.
|
||||
isExecutable: (path) ->
|
||||
try
|
||||
(fs.statSync(path).mode & 0o777 & 1) isnt 0
|
||||
catch e
|
||||
false
|
||||
|
||||
# Returns an array with all the names of files contained
|
||||
# in the directory path.
|
||||
list: (rootPath, extensions) ->
|
||||
|
||||
Reference in New Issue
Block a user