Merge branch 'master' into as-faster-style-recalculation

This commit is contained in:
Antonio Scandurra
2015-09-09 20:53:58 +02:00
5 changed files with 146 additions and 40 deletions

View File

@@ -17,7 +17,7 @@ Ubuntu LTS 12.04 64-bit is the recommended platform.
### Ubuntu / Debian
* `sudo apt-get install build-essential git libgnome-keyring-dev fakeroot`
* Instructions for [Node.js](https://github.com/joyent/node/wiki/Installing-Node.js-via-package-manager#ubuntu-mint-elementary-os).
* Instructions for [Node.js](https://github.com/nodejs/node-v0.x-archive/wiki/Installing-Node.js-via-package-manager#debian-and-ubuntu-based-linux-distributions).
* Make sure the command `node` is available after Node.js installation (some systems install it as `nodejs`).
* Use `which node` to check if it is available.
* Use `sudo update-alternatives --install /usr/bin/node node /usr/bin/nodejs 10` to update it.
@@ -25,7 +25,7 @@ Ubuntu LTS 12.04 64-bit is the recommended platform.
### Fedora / CentOS / RHEL
* `sudo dnf --assumeyes install make gcc gcc-c++ glibc-devel git-core libgnome-keyring-devel rpmdevtools`
* Instructions for [Node.js](https://github.com/joyent/node/wiki/Installing-Node.js-via-package-manager#fedora).
* Instructions for [Node.js](https://github.com/nodejs/node-v0.x-archive/wiki/Installing-Node.js-via-package-manager#enterprise-linux-and-fedora).
### Arch

View File

@@ -69,10 +69,10 @@
"atom-light-ui": "0.43.0",
"base16-tomorrow-dark-theme": "0.27.0",
"base16-tomorrow-light-theme": "0.9.0",
"one-dark-ui": "1.0.3",
"one-dark-ui": "1.0.4",
"one-dark-syntax": "1.1.0",
"one-light-syntax": "1.1.0",
"one-light-ui": "1.0.3",
"one-light-ui": "1.0.4",
"solarized-dark-syntax": "0.38.1",
"solarized-light-syntax": "0.22.1",
"about": "1.1.0",
@@ -85,7 +85,7 @@
"autoflow": "0.25.0",
"autosave": "0.22.0",
"background-tips": "0.26.0",
"bookmarks": "0.36.0",
"bookmarks": "0.37.0",
"bracket-matcher": "0.76.0",
"command-palette": "0.36.0",
"deprecation-cop": "0.54.0",
@@ -94,11 +94,11 @@
"exception-reporting": "0.36.0",
"find-and-replace": "0.180.0",
"fuzzy-finder": "0.88.0",
"git-diff": "0.55.0",
"git-diff": "0.56.0",
"go-to-line": "0.30.0",
"grammar-selector": "0.47.0",
"image-view": "0.54.0",
"incompatible-packages": "0.24.1",
"incompatible-packages": "0.25.0",
"keybinding-resolver": "0.33.0",
"line-ending-selector": "0.0.5",
"link": "0.30.0",
@@ -116,7 +116,7 @@
"symbols-view": "0.104.0",
"tabs": "0.84.0",
"timecop": "0.31.0",
"tree-view": "0.186.0",
"tree-view": "0.187.0",
"update-package-dependencies": "0.10.0",
"welcome": "0.30.0",
"whitespace": "0.31.0",

View File

@@ -7,6 +7,10 @@ describe "Package", ->
describe "when the package contains incompatible native modules", ->
beforeEach ->
spyOn(atom, 'inDevMode').andReturn(false)
items = {}
spyOn(global.localStorage, 'setItem').andCallFake (key, item) -> items[key] = item; undefined
spyOn(global.localStorage, 'getItem').andCallFake (key) -> items[key] ? null
spyOn(global.localStorage, 'removeItem').andCallFake (key) -> delete items[key]; undefined
it "does not activate it", ->
packagePath = atom.project.getDirectories()[0]?.resolve('packages/package-with-incompatible-native-module')
@@ -17,14 +21,6 @@ describe "Package", ->
it "caches the incompatible native modules in local storage", ->
packagePath = atom.project.getDirectories()[0]?.resolve('packages/package-with-incompatible-native-module')
cacheKey = null
cacheItem = null
spyOn(global.localStorage, 'setItem').andCallFake (key, item) ->
cacheKey = key
cacheItem = item
spyOn(global.localStorage, 'getItem').andCallFake (key) ->
return cacheItem if cacheKey is key
expect(new Package(packagePath).isCompatible()).toBe false
expect(global.localStorage.getItem.callCount).toBe 1
@@ -34,6 +30,71 @@ describe "Package", ->
expect(global.localStorage.getItem.callCount).toBe 2
expect(global.localStorage.setItem.callCount).toBe 1
describe "::rebuild()", ->
beforeEach ->
spyOn(atom, 'inDevMode').andReturn(false)
items = {}
spyOn(global.localStorage, 'setItem').andCallFake (key, item) -> items[key] = item; undefined
spyOn(global.localStorage, 'getItem').andCallFake (key) -> items[key] ? null
spyOn(global.localStorage, 'removeItem').andCallFake (key) -> delete items[key]; undefined
it "returns a promise resolving to the results of `apm rebuild`", ->
packagePath = atom.project.getDirectories()[0]?.resolve('packages/package-with-index')
pack = new Package(packagePath)
rebuildCallbacks = []
spyOn(pack, 'runRebuildProcess').andCallFake ((callback) -> rebuildCallbacks.push(callback))
promise = pack.rebuild()
rebuildCallbacks[0]({code: 0, stdout: 'stdout output', stderr: 'stderr output'})
waitsFor (done) ->
promise.then (result) ->
expect(result).toEqual {code: 0, stdout: 'stdout output', stderr: 'stderr output'}
done()
it "persists build failures in local storage", ->
packagePath = atom.project.getDirectories()[0]?.resolve('packages/package-with-index')
pack = new Package(packagePath)
expect(pack.isCompatible()).toBe true
expect(pack.getBuildFailureOutput()).toBeNull()
rebuildCallbacks = []
spyOn(pack, 'runRebuildProcess').andCallFake ((callback) -> rebuildCallbacks.push(callback))
pack.rebuild()
rebuildCallbacks[0]({code: 13, stderr: 'It is broken'})
expect(pack.getBuildFailureOutput()).toBe 'It is broken'
expect(pack.getIncompatibleNativeModules()).toEqual []
expect(pack.isCompatible()).toBe false
# A different package instance has the same failure output (simulates reload)
pack2 = new Package(packagePath)
expect(pack2.getBuildFailureOutput()).toBe 'It is broken'
expect(pack2.isCompatible()).toBe false
# Clears the build failure after a successful build
pack.rebuild()
rebuildCallbacks[1]({code: 0, stdout: 'It worked'})
expect(pack.getBuildFailureOutput()).toBeNull()
expect(pack2.getBuildFailureOutput()).toBeNull()
it "sets cached incompatible modules to an empty array when the rebuild completes (there may be a build error, but rebuilding *deletes* native modules)", ->
packagePath = atom.project.getDirectories()[0]?.resolve('packages/package-with-incompatible-native-module')
pack = new Package(packagePath)
expect(pack.getIncompatibleNativeModules().length).toBeGreaterThan(0)
rebuildCallbacks = []
spyOn(pack, 'runRebuildProcess').andCallFake ((callback) -> rebuildCallbacks.push(callback))
pack.rebuild()
expect(pack.getIncompatibleNativeModules().length).toBeGreaterThan(0)
rebuildCallbacks[0]({code: 0, stdout: 'It worked'})
expect(pack.getIncompatibleNativeModules().length).toBe(0)
describe "theme", ->
theme = null

View File

@@ -11,6 +11,7 @@ Q = require 'q'
ModuleCache = require './module-cache'
ScopedProperties = require './scoped-properties'
BufferedProcess = require './buffered-process'
packagesCache = require('../package.json')?._atomPackages ? {}
@@ -603,6 +604,70 @@ class Package
traversePath(path.join(@path, 'node_modules'))
nativeModulePaths
###
Section: Native Module Compatibility
###
# Extended: Are all native modules depended on by this package correctly
# compiled against the current version of Atom?
#
# Incompatible packages cannot be activated.
#
# Returns a {Boolean}, true if compatible, false if incompatible.
isCompatible: ->
return @compatible if @compatible?
if @path.indexOf(path.join(atom.packages.resourcePath, 'node_modules') + path.sep) is 0
# Bundled packages are always considered compatible
@compatible = true
else if @getMainModulePath()
@incompatibleModules = @getIncompatibleNativeModules()
@compatible = @incompatibleModules.length is 0 and not @getBuildFailureOutput()?
else
@compatible = true
# Extended: Rebuild native modules in this package's dependencies for the
# current version of Atom.
#
# Returns a {Promise} that resolves with an object containing `code`,
# `stdout`, and `stderr` properties based on the results of running
# `apm rebuild` on the package.
rebuild: ->
new Promise (resolve) =>
@runRebuildProcess (result) =>
if result.code is 0
global.localStorage.removeItem(@getBuildFailureOutputStorageKey())
else
@compatible = false
global.localStorage.setItem(@getBuildFailureOutputStorageKey(), result.stderr)
global.localStorage.setItem(@getIncompatibleNativeModulesStorageKey(), '[]')
resolve(result)
# Extended: If a previous rebuild failed, get the contents of stderr.
#
# Returns a {String} or null if no previous build failure occurred.
getBuildFailureOutput: ->
global.localStorage.getItem(@getBuildFailureOutputStorageKey())
runRebuildProcess: (callback) ->
stderr = ''
stdout = ''
new BufferedProcess({
command: atom.packages.getApmPath()
args: ['rebuild', '--no-color']
options: {cwd: @path}
stderr: (output) -> stderr += output
stdout: (output) -> stdout += output
exit: (code) -> callback({code, stdout, stderr})
})
getBuildFailureOutputStorageKey: ->
"installed-packages:#{@name}:#{@metadata.version}:build-error"
getIncompatibleNativeModulesStorageKey: ->
electronVersion = process.versions['electron'] ? process.versions['atom-shell']
"installed-packages:#{@name}:#{@metadata.version}:electron-#{electronVersion}:incompatible-native-modules"
# Get the incompatible native modules that this package depends on.
# This recurses through all dependencies and requires all modules that
# contain a `.node` file.
@@ -610,11 +675,10 @@ class Package
# This information is cached in local storage on a per package/version basis
# to minimize the impact on startup time.
getIncompatibleNativeModules: ->
localStorageKey = "installed-packages:#{@name}:#{@metadata.version}"
unless atom.inDevMode()
try
{incompatibleNativeModules} = JSON.parse(global.localStorage.getItem(localStorageKey)) ? {}
return incompatibleNativeModules if incompatibleNativeModules?
if arrayAsString = global.localStorage.getItem(@getIncompatibleNativeModulesStorageKey())
return JSON.parse(arrayAsString)
incompatibleNativeModules = []
for nativeModulePath in @getNativeModuleDependencyPaths()
@@ -629,28 +693,9 @@ class Package
version: version
error: error.message
global.localStorage.setItem(localStorageKey, JSON.stringify({incompatibleNativeModules}))
global.localStorage.setItem(@getIncompatibleNativeModulesStorageKey(), JSON.stringify(incompatibleNativeModules))
incompatibleNativeModules
# Public: Is this package compatible with this version of Atom?
#
# Incompatible packages cannot be activated. This will include packages
# installed to ~/.atom/packages that were built against node 0.11.10 but
# now need to be upgrade to node 0.11.13.
#
# Returns a {Boolean}, true if compatible, false if incompatible.
isCompatible: ->
return @compatible if @compatible?
if @path.indexOf(path.join(atom.packages.resourcePath, 'node_modules') + path.sep) is 0
# Bundled packages are always considered compatible
@compatible = true
else if @getMainModulePath()
@incompatibleModules = @getIncompatibleNativeModules()
@compatible = @incompatibleModules.length is 0
else
@compatible = true
handleError: (message, error) ->
if error.filename and error.location and (error instanceof SyntaxError)
location = "#{error.filename}:#{error.location.first_line + 1}:#{error.location.first_column + 1}"

View File

@@ -82,4 +82,4 @@
// Other
@font-family: 'SF UI Text', 'Lucida Grande', 'Segoe UI', Ubuntu, Cantarell, sans-serif;
@font-family: '.SFNSText-Regular', 'SF UI Text', 'Lucida Grande', 'Segoe UI', Ubuntu, Cantarell, sans-serif;