Never load config settings from disk when a save is pending

Fixes #5771

We load the user’s settings from disk when we detect a change to their
config.cson file. However, if there’s a save pending, doing this will
end up blowing away the values we intend to save.
This commit is contained in:
Nathan Sobo
2015-04-18 12:39:20 +12:00
parent 96b0938c7c
commit d1c44dcb54
2 changed files with 33 additions and 8 deletions

View File

@@ -486,6 +486,7 @@ describe "Config", ->
atom.config.set('foo.bar.baz', "value 1")
expect(observeHandler).toHaveBeenCalledWith("value 1")
advanceClock(100) # complete pending save that was requested in ::set
observeHandler.reset()
atom.config.loadUserConfig()
@@ -789,6 +790,22 @@ describe "Config", ->
expect(warnSpy).toHaveBeenCalled()
expect(warnSpy.mostRecentCall.args[0]).toContain "foo.int"
describe "when there is a pending save", ->
it "does not change the config settings", ->
fs.writeFileSync atom.config.configFilePath, "'*': foo: bar: 'baz'"
atom.config.set("foo.bar", "quux")
atom.config.loadUserConfig()
expect(atom.config.get("foo.bar")).toBe "quux"
advanceClock(100)
expect(atom.config.save.callCount).toBe 1
expect(atom.config.get("foo.bar")).toBe "quux"
atom.config.loadUserConfig()
expect(atom.config.get("foo.bar")).toBe "baz"
describe ".observeUserConfig()", ->
updatedHandler = null

View File

@@ -332,9 +332,16 @@ class Config
@configFilePath = fs.resolve(@configDirPath, 'config', ['json', 'cson'])
@configFilePath ?= path.join(@configDirPath, 'config.cson')
@transactDepth = 0
@savePending = false
@debouncedSave = _.debounce(@save, 100)
@debouncedLoad = _.debounce(@loadUserConfig, 100)
@requestLoad = _.debounce(@loadUserConfig, 100)
@requestSave = =>
@savePending = true
debouncedSave.call(this)
save = =>
@savePending = false
@save()
debouncedSave = _.debounce(save, 100)
###
Section: Config Subscription
@@ -605,7 +612,7 @@ class Config
else
@setRawValue(keyPath, value)
@debouncedSave() if source is @getUserConfigPath() and shouldSave and not @configFileHasErrors
@requestSave() if source is @getUserConfigPath() and shouldSave and not @configFileHasErrors
true
# Essential: Restore the setting at `keyPath` to its default value.
@@ -635,7 +642,7 @@ class Config
_.setValueForKeyPath(settings, keyPath, undefined)
settings = withoutEmptyObjects(settings)
@set(null, settings, {scopeSelector, source, priority: @priorityForSource(source)}) if settings?
@debouncedSave()
@requestSave()
else
@scopedSettingsStore.removePropertiesForSourceAndSelector(source, scopeSelector)
@emitChangeEvent()
@@ -757,9 +764,10 @@ class Config
CSON.writeFileSync(@configFilePath, {})
try
userConfig = CSON.readFileSync(@configFilePath)
@resetUserSettings(userConfig)
@configFileHasErrors = false
unless @savePending
userConfig = CSON.readFileSync(@configFilePath)
@resetUserSettings(userConfig)
@configFileHasErrors = false
catch error
@configFileHasErrors = true
message = "Failed to load `#{path.basename(@configFilePath)}`"
@@ -776,7 +784,7 @@ class Config
observeUserConfig: ->
try
@watchSubscription ?= pathWatcher.watch @configFilePath, (eventType) =>
@debouncedLoad() if eventType is 'change' and @watchSubscription?
@requestLoad() if eventType is 'change' and @watchSubscription?
catch error
@notifyFailure """
Unable to watch path: `#{path.basename(@configFilePath)}`. Make sure you have permissions to