Merge pull request #9990 from scv119/test

Add a core config `core.automaticallyUpdate` to disable Atom autoupdate.
This commit is contained in:
Max Brunsfeld
2016-01-07 11:05:43 -08:00
9 changed files with 61 additions and 39 deletions

View File

@@ -38,7 +38,6 @@ module.exports = (grunt) ->
buildDir = grunt.option('build-dir')
buildDir ?= path.join(os.tmpdir(), 'atom-build')
buildDir = path.resolve(buildDir)
disableAutoUpdate = grunt.option('no-auto-update') ? false
channel = grunt.option('channel')
releasableBranches = ['stable', 'beta']
@@ -181,7 +180,7 @@ module.exports = (grunt) ->
pkg: grunt.file.readJSON('package.json')
atom: {
appName, channel, metadata, disableAutoUpdate,
appName, channel, metadata,
appFileName, apmFileName,
appDir, buildDir, contentsDir, installDir, shellAppDir, symbolsDir,
}

View File

@@ -186,5 +186,4 @@ module.exports = (grunt) ->
dependencies = ['compile', 'generate-license:save', 'generate-module-cache', 'compile-packages-slug']
dependencies.push('copy-info-plist') if process.platform is 'darwin'
dependencies.push('set-exe-icon') if process.platform is 'win32'
dependencies.push('disable-autoupdate') if grunt.config.get('atom.disableAutoUpdate')
grunt.task.run(dependencies...)

View File

@@ -1,12 +0,0 @@
fs = require 'fs'
path = require 'path'
module.exports = (grunt) ->
grunt.registerTask 'disable-autoupdate', 'Set up disableAutoUpdate field in package.json file', ->
appDir = fs.realpathSync(grunt.config.get('atom.appDir'))
metadata = grunt.file.readJSON(path.join(appDir, 'package.json'))
metadata._disableAutoUpdate = grunt.config.get('atom.disableAutoUpdate')
grunt.file.write(path.join(appDir, 'package.json'), JSON.stringify(metadata))

View File

@@ -872,6 +872,26 @@ describe "Config", ->
atom.config.loadUserConfig()
expect(atom.config.get("foo.bar")).toBe "baz"
describe "when the config file fails to load", ->
addErrorHandler = null
beforeEach ->
atom.notifications.onDidAddNotification addErrorHandler = jasmine.createSpy()
spyOn(fs, "existsSync").andCallFake ->
error = new Error()
error.code = 'EPERM'
throw error
it "creates a notification and does not try to save later changes to disk", ->
load = -> atom.config.loadUserConfig()
expect(load).not.toThrow()
expect(addErrorHandler.callCount).toBe 1
atom.config.set("foo.bar", "baz")
advanceClock(100)
expect(atom.config.save).not.toHaveBeenCalled()
expect(atom.config.get("foo.bar")).toBe "baz"
describe ".observeUserConfig()", ->
updatedHandler = null

View File

@@ -103,8 +103,6 @@ class ApplicationMenu
downloadingUpdateItem.visible = false
installUpdateItem.visible = false
return if @autoUpdateManager.isDisabled()
switch state
when 'idle', 'error', 'no-update-available'
checkForUpdateItem.visible = true
@@ -119,9 +117,10 @@ class ApplicationMenu
#
# Returns an Array of menu item Objects.
getDefaultTemplate: ->
template = [
[
label: "Atom"
submenu: [
{label: "Check for Update", metadata: {autoUpdate: true}}
{label: 'Reload', accelerator: 'Command+R', click: => @focusedWindow()?.reload()}
{label: 'Close Window', accelerator: 'Command+Shift+W', click: => @focusedWindow()?.close()}
{label: 'Toggle Dev Tools', accelerator: 'Command+Alt+I', click: => @focusedWindow()?.toggleDevTools()}
@@ -129,10 +128,6 @@ class ApplicationMenu
]
]
# Add `Check for Update` button if autoUpdateManager is enabled.
template[0].submenu.unshift({label: "Check for Update", metadata: {autoUpdate: true}}) unless @autoUpdateManager.isDisabled()
template
focusedWindow: ->
_.find global.atomApplication.windows, (atomWindow) -> atomWindow.isFocused()

View File

@@ -74,8 +74,7 @@ class AtomApplication
@pidsToOpenWindows = {}
@windows = []
disableAutoUpdate = require(path.join(@resourcePath, 'package.json'))._disableAutoUpdate ? false
@autoUpdateManager = new AutoUpdateManager(@version, options.test, disableAutoUpdate)
@autoUpdateManager = new AutoUpdateManager(@version, options.test, @resourcePath)
@applicationMenu = new ApplicationMenu(@version, @autoUpdateManager)
@atomProtocolHandler = new AtomProtocolHandler(@resourcePath, @safeMode)

View File

@@ -1,5 +1,6 @@
autoUpdater = null
_ = require 'underscore-plus'
Config = require '../config'
{EventEmitter} = require 'events'
path = require 'path'
@@ -15,10 +16,13 @@ module.exports =
class AutoUpdateManager
_.extend @prototype, EventEmitter.prototype
constructor: (@version, @testMode, @disabled) ->
constructor: (@version, @testMode, resourcePath) ->
@state = IdleState
@iconPath = path.resolve(__dirname, '..', '..', 'resources', 'atom.png')
@feedUrl = "https://atom.io/api/updates?version=#{@version}"
@config = new Config({configDirPath: process.env.ATOM_HOME, resourcePath, enablePersistence: true})
@config.setSchema null, {type: 'object', properties: _.clone(require('../config-schema'))}
@config.load()
process.nextTick => @setupAutoUpdater()
setupAutoUpdater: ->
@@ -46,9 +50,13 @@ class AutoUpdateManager
@setState(UpdateAvailableState)
@emitUpdateAvailableEvent(@getWindows()...)
# Only check for updates periodically if enabled and running in release
# version.
@scheduleUpdateCheck() unless /\w{7}/.test(@version) or @disabled
@config.onDidChange 'core.automaticallyUpdate', ({newValue}) =>
if newValue
@scheduleUpdateCheck()
else
@cancelScheduledUpdateCheck()
@scheduleUpdateCheck() if @config.get 'core.automaticallyUpdate'
switch process.platform
when 'win32'
@@ -56,9 +64,6 @@ class AutoUpdateManager
when 'linux'
@setState(UnsupportedState)
isDisabled: ->
@disabled
emitUpdateAvailableEvent: (windows...) ->
return unless @releaseVersion?
for atomWindow in windows
@@ -74,10 +79,18 @@ class AutoUpdateManager
@state
scheduleUpdateCheck: ->
checkForUpdates = => @check(hidePopups: true)
fourHours = 1000 * 60 * 60 * 4
setInterval(checkForUpdates, fourHours)
checkForUpdates()
# Only schedule update check periodically if running in release version and
# and there is no existing scheduled update check.
unless /\w{7}/.test(@version) or @checkForUpdatesIntervalID
checkForUpdates = => @check(hidePopups: true)
fourHours = 1000 * 60 * 60 * 4
@checkForUpdatesIntervalID = setInterval(checkForUpdates, fourHours)
checkForUpdates()
cancelScheduledUpdateCheck: ->
if @checkForUpdatesIntervalID
clearInterval(@checkForUpdatesIntervalID)
@checkForUpdatesIntervalID = null
check: ({hidePopups}={}) ->
unless hidePopups

View File

@@ -104,6 +104,10 @@ module.exports =
description: 'Automatically open an empty editor on startup.'
type: 'boolean'
default: true
automaticallyUpdate:
description: 'Automatically update Atom when a new release is available.'
type: 'boolean'
default: true
editor:
type: 'object'

View File

@@ -779,9 +779,14 @@ class Config
loadUserConfig: ->
return if @shouldNotAccessFileSystem()
unless fs.existsSync(@configFilePath)
fs.makeTreeSync(path.dirname(@configFilePath))
CSON.writeFileSync(@configFilePath, {})
try
unless fs.existsSync(@configFilePath)
fs.makeTreeSync(path.dirname(@configFilePath))
CSON.writeFileSync(@configFilePath, {})
catch error
@configFileHasErrors = true
@notifyFailure("Failed to initialize `#{path.basename(@configFilePath)}`", error.stack)
return
try
unless @savePending
@@ -820,7 +825,7 @@ class Config
@watchSubscription = null
notifyFailure: (errorMessage, detail) ->
@notificationManager.addError(errorMessage, {detail, dismissable: true})
@notificationManager?.addError(errorMessage, {detail, dismissable: true})
save: ->
return if @shouldNotAccessFileSystem()