mirror of
https://github.com/atom/atom.git
synced 2026-04-06 03:02:13 -04:00
Merge pull request #16845 from atom/fb-pw-simple-project-config
Add the concept of an `atomproject` file to atom.
This commit is contained in:
@@ -1,7 +1,3 @@
|
||||
const path = require('path')
|
||||
const temp = require('temp').track()
|
||||
const fs = require('fs-plus')
|
||||
|
||||
describe('Config', () => {
|
||||
let savedSettings
|
||||
|
||||
@@ -490,7 +486,6 @@ describe('Config', () => {
|
||||
atom.config.set('foo.bar.baz', 'value 2')
|
||||
expect(observeHandler).toHaveBeenCalledWith({newValue: 'value 2', oldValue: 'value 1'})
|
||||
observeHandler.reset()
|
||||
|
||||
observeHandler.andCallFake(() => { throw new Error('oops') })
|
||||
expect(() => atom.config.set('foo.bar.baz', 'value 1')).toThrow('oops')
|
||||
expect(observeHandler).toHaveBeenCalledWith({newValue: 'value 1', oldValue: 'value 2'})
|
||||
@@ -1840,4 +1835,86 @@ describe('Config', () => {
|
||||
expect(atom.config.get('do.ray')).toBe('me')
|
||||
})
|
||||
})
|
||||
|
||||
describe('project specific settings', () => {
|
||||
describe('config.resetProjectSettings', () => {
|
||||
it('gracefully handles invalid config objects', () => {
|
||||
atom.config.resetProjectSettings({})
|
||||
expect(atom.config.get('foo.bar')).toBeUndefined()
|
||||
})
|
||||
})
|
||||
|
||||
describe('config.get', () => {
|
||||
const dummyPath = '/Users/dummy/path.json'
|
||||
describe('project settings', () => {
|
||||
it('returns a deep clone of the property value', () => {
|
||||
atom.config.resetProjectSettings({'*': {'value': {array: [1, {b: 2}, 3]}}}, dummyPath)
|
||||
const retrievedValue = atom.config.get('value')
|
||||
retrievedValue.array[0] = 4
|
||||
retrievedValue.array[1].b = 2.1
|
||||
expect(atom.config.get('value')).toEqual({array: [1, {b: 2}, 3]})
|
||||
})
|
||||
|
||||
it('properly gets project settings', () => {
|
||||
atom.config.resetProjectSettings({'*': {'foo': 'wei'}}, dummyPath)
|
||||
expect(atom.config.get('foo')).toBe('wei')
|
||||
atom.config.resetProjectSettings({'*': {'foo': {'bar': 'baz'}}}, dummyPath)
|
||||
expect(atom.config.get('foo.bar')).toBe('baz')
|
||||
})
|
||||
|
||||
it('gets project settings with higher priority than regular settings', () => {
|
||||
atom.config.set('foo', 'bar')
|
||||
atom.config.resetProjectSettings({'*': {'foo': 'baz'}}, dummyPath)
|
||||
expect(atom.config.get('foo')).toBe('baz')
|
||||
})
|
||||
|
||||
it('correctly gets nested and scoped properties for project settings', () => {
|
||||
expect(atom.config.set('foo.bar.str', 'global')).toBe(true)
|
||||
expect(atom.config.set('foo.bar.str', 'scoped', {scopeSelector: '.source.js'})).toBe(true)
|
||||
expect(atom.config.get('foo.bar.str')).toBe('global')
|
||||
expect(atom.config.get('foo.bar.str', {scope: ['.source.js']})).toBe('scoped')
|
||||
})
|
||||
|
||||
it('returns a deep clone of the property value', () => {
|
||||
atom.config.set('value', {array: [1, {b: 2}, 3]})
|
||||
const retrievedValue = atom.config.get('value')
|
||||
retrievedValue.array[0] = 4
|
||||
retrievedValue.array[1].b = 2.1
|
||||
expect(atom.config.get('value')).toEqual({array: [1, {b: 2}, 3]})
|
||||
})
|
||||
|
||||
it('gets scoped values correctly', () => {
|
||||
atom.config.set('foo', 'bam', {scope: ['second']})
|
||||
expect(atom.config.get('foo', {'scopeSelector': 'second'})).toBe('bam')
|
||||
atom.config.resetProjectSettings({'*': {'foo': 'baz'}, 'second': {'foo': 'bar'}}, dummyPath)
|
||||
expect(atom.config.get('foo', {'scopeSelector': 'second'})).toBe('baz')
|
||||
atom.config.clearProjectSettings()
|
||||
expect(atom.config.get('foo', {'scopeSelector': 'second'})).toBe('bam')
|
||||
})
|
||||
|
||||
it('clears project settings correctly', () => {
|
||||
atom.config.set('foo', 'bar')
|
||||
expect(atom.config.get('foo')).toBe('bar')
|
||||
atom.config.resetProjectSettings({'*': {'foo': 'baz'}, 'second': {'foo': 'bar'}}, dummyPath)
|
||||
expect(atom.config.get('foo')).toBe('baz')
|
||||
expect(atom.config.getSources().length).toBe(1)
|
||||
atom.config.clearProjectSettings()
|
||||
expect(atom.config.get('foo')).toBe('bar')
|
||||
expect(atom.config.getSources().length).toBe(0)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('config.getAll', () => {
|
||||
const dummyPath = '/Users/dummy/path.json'
|
||||
it('gets settings in the same way .get would return them', () => {
|
||||
atom.config.resetProjectSettings({'*': {'a': 'b'}}, dummyPath)
|
||||
atom.config.set('a', 'f')
|
||||
expect(atom.config.getAll('a')).toEqual([{
|
||||
scopeSelector: '*',
|
||||
value: 'b'
|
||||
}])
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -274,6 +274,51 @@ describe('Project', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('.replace', () => {
|
||||
let projectSpecification, projectPath1, projectPath2
|
||||
beforeEach(() => {
|
||||
atom.project.replace(null)
|
||||
projectPath1 = temp.mkdirSync('project-path1')
|
||||
projectPath2 = temp.mkdirSync('project-path2')
|
||||
projectSpecification = {
|
||||
paths: [projectPath1, projectPath2],
|
||||
originPath: 'originPath',
|
||||
config: {
|
||||
'baz': 'buzz'
|
||||
}
|
||||
}
|
||||
})
|
||||
it('sets a project specification', () => {
|
||||
expect(atom.config.get('baz')).toBeUndefined()
|
||||
atom.project.replace(projectSpecification)
|
||||
expect(atom.project.getPaths()).toEqual([projectPath1, projectPath2])
|
||||
expect(atom.config.get('baz')).toBe('buzz')
|
||||
})
|
||||
|
||||
it('clears a project through replace with no params', () => {
|
||||
expect(atom.config.get('baz')).toBeUndefined()
|
||||
atom.project.replace(projectSpecification)
|
||||
expect(atom.config.get('baz')).toBe('buzz')
|
||||
expect(atom.project.getPaths()).toEqual([projectPath1, projectPath2])
|
||||
atom.project.replace()
|
||||
expect(atom.config.get('baz')).toBeUndefined()
|
||||
expect(atom.project.getPaths()).toEqual([])
|
||||
})
|
||||
|
||||
it('responds to change of project specification', () => {
|
||||
let wasCalled = false
|
||||
const callback = () => {
|
||||
wasCalled = true
|
||||
}
|
||||
atom.project.onDidReplace(callback)
|
||||
atom.project.replace(projectSpecification)
|
||||
expect(wasCalled).toBe(true)
|
||||
wasCalled = false
|
||||
atom.project.replace()
|
||||
expect(wasCalled).toBe(true)
|
||||
})
|
||||
})
|
||||
|
||||
describe('before and after saving a buffer', () => {
|
||||
let buffer
|
||||
beforeEach(() =>
|
||||
|
||||
@@ -50,7 +50,6 @@ let nextId = 0
|
||||
//
|
||||
// An instance of this class is always available as the `atom` global.
|
||||
class AtomEnvironment {
|
||||
|
||||
/*
|
||||
Section: Properties
|
||||
*/
|
||||
@@ -210,7 +209,7 @@ class AtomEnvironment {
|
||||
this.blobStore = params.blobStore
|
||||
this.configDirPath = params.configDirPath
|
||||
|
||||
const {devMode, safeMode, resourcePath, userSettings} = this.getLoadSettings()
|
||||
const {devMode, safeMode, resourcePath, userSettings, projectSpecification} = this.getLoadSettings()
|
||||
|
||||
ConfigSchema.projectHome = {
|
||||
type: 'string',
|
||||
@@ -224,6 +223,10 @@ class AtomEnvironment {
|
||||
})
|
||||
this.config.resetUserSettings(userSettings)
|
||||
|
||||
if (projectSpecification != null && projectSpecification.config != null) {
|
||||
this.project.replace(projectSpecification)
|
||||
}
|
||||
|
||||
this.menu.initialize({resourcePath})
|
||||
this.contextMenu.initialize({resourcePath, devMode})
|
||||
|
||||
@@ -788,6 +791,7 @@ class AtomEnvironment {
|
||||
this.disposables.add(this.applicationDelegate.onDidFailToReadUserSettings(message =>
|
||||
this.notifications.addError(message)
|
||||
))
|
||||
|
||||
this.disposables.add(this.applicationDelegate.onDidOpenLocations(this.openLocations.bind(this)))
|
||||
this.disposables.add(this.applicationDelegate.onApplicationMenuCommand(this.dispatchApplicationMenuCommand.bind(this)))
|
||||
this.disposables.add(this.applicationDelegate.onContextMenuCommand(this.dispatchContextMenuCommand.bind(this)))
|
||||
|
||||
@@ -422,8 +422,12 @@ class Config {
|
||||
type: 'object',
|
||||
properties: {}
|
||||
}
|
||||
|
||||
this.defaultSettings = {}
|
||||
this.settings = {}
|
||||
this.projectSettings = {}
|
||||
this.projectFile = null
|
||||
|
||||
this.scopedSettingsStore = new ScopedPropertyStore()
|
||||
|
||||
this.settingsLoaded = false
|
||||
@@ -621,10 +625,10 @@ class Config {
|
||||
legacyScopeDescriptor = this.getLegacyScopeDescriptorForNewScopeDescriptor(scopeDescriptor)
|
||||
if (legacyScopeDescriptor) {
|
||||
result.push(...Array.from(this.scopedSettingsStore.getAll(
|
||||
legacyScopeDescriptor.getScopeChain(),
|
||||
keyPath,
|
||||
options
|
||||
) || []))
|
||||
legacyScopeDescriptor.getScopeChain(),
|
||||
keyPath,
|
||||
options
|
||||
) || []))
|
||||
}
|
||||
} else {
|
||||
result = []
|
||||
@@ -691,7 +695,7 @@ class Config {
|
||||
let source = options.source
|
||||
const shouldSave = options.save != null ? options.save : true
|
||||
|
||||
if (source && !scopeSelector) {
|
||||
if (source && !scopeSelector && source !== this.projectFile) {
|
||||
throw new Error("::set with a 'source' and no 'sourceSelector' is not yet implemented!")
|
||||
}
|
||||
|
||||
@@ -708,7 +712,7 @@ class Config {
|
||||
if (scopeSelector != null) {
|
||||
this.setRawScopedValue(keyPath, value, source, scopeSelector)
|
||||
} else {
|
||||
this.setRawValue(keyPath, value)
|
||||
this.setRawValue(keyPath, value, {source})
|
||||
}
|
||||
|
||||
if (source === this.mainSource && shouldSave && this.settingsLoaded) {
|
||||
@@ -943,7 +947,12 @@ class Config {
|
||||
Section: Private methods managing global settings
|
||||
*/
|
||||
|
||||
resetUserSettings (newSettings) {
|
||||
resetUserSettings (newSettings, options = {}) {
|
||||
this._resetSettings(newSettings, options)
|
||||
}
|
||||
|
||||
_resetSettings (newSettings, options = {}) {
|
||||
const source = options.source
|
||||
newSettings = Object.assign({}, newSettings)
|
||||
if (newSettings.global != null) {
|
||||
newSettings['*'] = newSettings.global
|
||||
@@ -954,13 +963,16 @@ class Config {
|
||||
const scopedSettings = newSettings
|
||||
newSettings = newSettings['*']
|
||||
delete scopedSettings['*']
|
||||
this.resetUserScopedSettings(scopedSettings)
|
||||
this.resetScopedSettings(scopedSettings, {source})
|
||||
}
|
||||
|
||||
return this.transact(() => {
|
||||
this.settings = {}
|
||||
this._clearUnscopedSettingsForSource(source)
|
||||
this.settingsLoaded = true
|
||||
for (let key in newSettings) { const value = newSettings[key]; this.set(key, value, {save: false}) }
|
||||
for (let key in newSettings) {
|
||||
const value = newSettings[key]
|
||||
this.set(key, value, {save: false, source})
|
||||
}
|
||||
if (this.pendingOperations.length) {
|
||||
for (let op of this.pendingOperations) { op() }
|
||||
this.pendingOperations = []
|
||||
@@ -968,10 +980,39 @@ class Config {
|
||||
})
|
||||
}
|
||||
|
||||
_clearUnscopedSettingsForSource (source) {
|
||||
if (source === this.projectFile) {
|
||||
this.projectSettings = {}
|
||||
} else {
|
||||
this.settings = {}
|
||||
}
|
||||
}
|
||||
|
||||
resetProjectSettings (newSettings, projectFile) {
|
||||
// Sets the scope and source of all project settings to `path`.
|
||||
newSettings = Object.assign({}, newSettings)
|
||||
const oldProjectFile = this.projectFile
|
||||
this.projectFile = projectFile
|
||||
if (this.projectFile != null) {
|
||||
this._resetSettings(newSettings, {source: this.projectFile})
|
||||
} else {
|
||||
this.scopedSettingsStore.removePropertiesForSource(oldProjectFile)
|
||||
this.projectSettings = {}
|
||||
}
|
||||
}
|
||||
|
||||
clearProjectSettings () {
|
||||
this.resetProjectSettings({}, null)
|
||||
}
|
||||
|
||||
getRawValue (keyPath, options = {}) {
|
||||
let value
|
||||
if (!options.excludeSources || !options.excludeSources.includes(this.mainSource)) {
|
||||
value = getValueAtKeyPath(this.settings, keyPath)
|
||||
if (this.projectFile != null) {
|
||||
const projectValue = getValueAtKeyPath(this.projectSettings, keyPath)
|
||||
value = (projectValue === undefined) ? value : projectValue
|
||||
}
|
||||
}
|
||||
|
||||
let defaultValue
|
||||
@@ -990,19 +1031,22 @@ class Config {
|
||||
}
|
||||
}
|
||||
|
||||
setRawValue (keyPath, value) {
|
||||
setRawValue (keyPath, value, options = {}) {
|
||||
const source = options.source ? options.source : undefined
|
||||
const settingsToChange = source === this.projectFile ? 'projectSettings' : 'settings'
|
||||
const defaultValue = getValueAtKeyPath(this.defaultSettings, keyPath)
|
||||
|
||||
if (_.isEqual(defaultValue, value)) {
|
||||
if (keyPath != null) {
|
||||
deleteValueAtKeyPath(this.settings, keyPath)
|
||||
deleteValueAtKeyPath(this[settingsToChange], keyPath)
|
||||
} else {
|
||||
this.settings = null
|
||||
this[settingsToChange] = null
|
||||
}
|
||||
} else {
|
||||
if (keyPath != null) {
|
||||
setValueAtKeyPath(this.settings, keyPath, value)
|
||||
setValueAtKeyPath(this[settingsToChange], keyPath, value)
|
||||
} else {
|
||||
this.settings = value
|
||||
this[settingsToChange] = value
|
||||
}
|
||||
}
|
||||
return this.emitChangeEvent()
|
||||
@@ -1168,15 +1212,22 @@ class Config {
|
||||
*/
|
||||
|
||||
priorityForSource (source) {
|
||||
return (source === this.mainSource) ? 1000 : 0
|
||||
switch (source) {
|
||||
case this.mainSource:
|
||||
return 1000
|
||||
case this.projectFile:
|
||||
return 2000
|
||||
default:
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
emitChangeEvent () {
|
||||
if (this.transactDepth <= 0) { return this.emitter.emit('did-change') }
|
||||
}
|
||||
|
||||
resetUserScopedSettings (newScopedSettings) {
|
||||
const source = this.mainSource
|
||||
resetScopedSettings (newScopedSettings, options = {}) {
|
||||
const source = options.source == null ? this.mainSource : options.source
|
||||
const priority = this.priorityForSource(source)
|
||||
this.scopedSettingsStore.removePropertiesForSource(source)
|
||||
|
||||
|
||||
@@ -93,7 +93,6 @@ class AtomApplication extends EventEmitter {
|
||||
this.quitting = false
|
||||
this.getAllWindows = this.getAllWindows.bind(this)
|
||||
this.getLastFocusedWindow = this.getLastFocusedWindow.bind(this)
|
||||
|
||||
this.resourcePath = options.resourcePath
|
||||
this.devResourcePath = options.devResourcePath
|
||||
this.version = options.version
|
||||
@@ -203,6 +202,7 @@ class AtomApplication extends EventEmitter {
|
||||
|
||||
openWithOptions (options) {
|
||||
const {
|
||||
projectSpecification,
|
||||
initialPaths,
|
||||
pathsToOpen,
|
||||
executedFrom,
|
||||
@@ -257,6 +257,7 @@ class AtomApplication extends EventEmitter {
|
||||
profileStartup,
|
||||
clearWindowState,
|
||||
addToLastWindow,
|
||||
projectSpecification,
|
||||
env
|
||||
})
|
||||
} else if (urlsToOpen.length > 0) {
|
||||
@@ -820,6 +821,7 @@ class AtomApplication extends EventEmitter {
|
||||
window,
|
||||
clearWindowState,
|
||||
addToLastWindow,
|
||||
projectSpecification,
|
||||
env
|
||||
} = {}) {
|
||||
if (!pathsToOpen || pathsToOpen.length === 0) return
|
||||
@@ -853,7 +855,7 @@ class AtomApplication extends EventEmitter {
|
||||
}
|
||||
|
||||
let openedWindow
|
||||
if (existingWindow) {
|
||||
if (existingWindow && (projectSpecification == null || projectSpecification.config == null)) {
|
||||
openedWindow = existingWindow
|
||||
openedWindow.openLocations(locationsToOpen)
|
||||
if (openedWindow.isMinimized()) {
|
||||
@@ -878,6 +880,7 @@ class AtomApplication extends EventEmitter {
|
||||
}
|
||||
if (!resourcePath) resourcePath = this.resourcePath
|
||||
if (!windowDimensions) windowDimensions = this.getDimensionsForNewWindow()
|
||||
|
||||
openedWindow = new AtomWindow(this, this.fileRecoveryService, {
|
||||
initialPaths,
|
||||
locationsToOpen,
|
||||
@@ -888,6 +891,7 @@ class AtomApplication extends EventEmitter {
|
||||
windowDimensions,
|
||||
profileStartup,
|
||||
clearWindowState,
|
||||
projectSpecification,
|
||||
env
|
||||
})
|
||||
this.addWindow(openedWindow)
|
||||
|
||||
@@ -22,6 +22,7 @@ class AtomWindow extends EventEmitter {
|
||||
this.safeMode = settings.safeMode
|
||||
this.devMode = settings.devMode
|
||||
this.resourcePath = settings.resourcePath
|
||||
this.projectSpecification = settings.projectSpecification
|
||||
|
||||
let {pathToOpen, locationsToOpen} = settings
|
||||
if (!locationsToOpen && pathToOpen) locationsToOpen = [{pathToOpen}]
|
||||
@@ -59,9 +60,9 @@ class AtomWindow extends EventEmitter {
|
||||
get: () => JSON.stringify(Object.assign({
|
||||
userSettings: !this.isSpec
|
||||
? this.atomApplication.configFile.get()
|
||||
: null
|
||||
}, this.loadSettings)),
|
||||
configurable: true
|
||||
: null,
|
||||
projectSpecification: this.projectSpecification
|
||||
}, this.loadSettings))
|
||||
})
|
||||
|
||||
this.handleEvents()
|
||||
|
||||
@@ -5,6 +5,7 @@ const yargs = require('yargs')
|
||||
const {app} = require('electron')
|
||||
const path = require('path')
|
||||
const fs = require('fs-plus')
|
||||
const CSON = require('season')
|
||||
|
||||
module.exports = function parseCommandLine (processArgs) {
|
||||
const options = yargs(processArgs).wrap(yargs.terminalWidth())
|
||||
@@ -52,6 +53,7 @@ module.exports = function parseCommandLine (processArgs) {
|
||||
'When in test mode, waits until the specified time (in minutes) and kills the process (exit code: 130).'
|
||||
)
|
||||
options.alias('v', 'version').boolean('v').describe('v', 'Print the version information.')
|
||||
options.alias('p', 'project').describe('p', 'Start Atom with a project specification file.')
|
||||
options.alias('w', 'wait').boolean('w').describe('w', 'Wait for window to be closed before returning.')
|
||||
options.alias('a', 'add').boolean('a').describe('add', 'Open path as a new project in last used window.')
|
||||
options.string('socket-path')
|
||||
@@ -91,6 +93,7 @@ module.exports = function parseCommandLine (processArgs) {
|
||||
const benchmark = args['benchmark']
|
||||
const benchmarkTest = args['benchmark-test']
|
||||
const test = args['test']
|
||||
const projectSpecificationFile = args['project']
|
||||
const mainProcess = args['main-process']
|
||||
const timeout = args['timeout']
|
||||
const newWindow = args['new-window']
|
||||
@@ -125,6 +128,7 @@ module.exports = function parseCommandLine (processArgs) {
|
||||
}
|
||||
}
|
||||
|
||||
// Check to see if project flag is set, then add all paths from the .atomproject.
|
||||
if (args['resource-path']) {
|
||||
devMode = true
|
||||
devResourcePath = args['resource-path']
|
||||
@@ -134,6 +138,28 @@ module.exports = function parseCommandLine (processArgs) {
|
||||
devMode = true
|
||||
}
|
||||
|
||||
let projectSpecification = {}
|
||||
if (projectSpecificationFile) {
|
||||
const readPath = path.isAbsolute(projectSpecificationFile)
|
||||
? projectSpecificationFile
|
||||
: path.join(executedFrom, projectSpecificationFile)
|
||||
|
||||
const contents = Object.assign({}, readProjectSpecificationSync(readPath, executedFrom))
|
||||
const pathToProjectFile = path.join(executedFrom, projectSpecificationFile)
|
||||
|
||||
const base = path.dirname(pathToProjectFile)
|
||||
pathsToOpen.push(path.dirname(projectSpecificationFile))
|
||||
const paths = (contents.paths == null)
|
||||
? undefined
|
||||
: contents.paths.map(curPath => path.resolve(base, curPath))
|
||||
|
||||
projectSpecification = {
|
||||
originPath: pathToProjectFile,
|
||||
paths,
|
||||
config: contents.config
|
||||
}
|
||||
}
|
||||
|
||||
if (devMode) {
|
||||
resourcePath = devResourcePath
|
||||
}
|
||||
@@ -152,6 +178,7 @@ module.exports = function parseCommandLine (processArgs) {
|
||||
devResourcePath = normalizeDriveLetterName(devResourcePath)
|
||||
|
||||
return {
|
||||
projectSpecification,
|
||||
resourcePath,
|
||||
devResourcePath,
|
||||
pathsToOpen,
|
||||
@@ -177,6 +204,18 @@ module.exports = function parseCommandLine (processArgs) {
|
||||
}
|
||||
}
|
||||
|
||||
function readProjectSpecificationSync (filepath, executedFrom) {
|
||||
let contents
|
||||
try {
|
||||
contents = CSON.readFileSync(filepath)
|
||||
} catch (e) {
|
||||
throw new Error('Unable to read supplied project specification file.')
|
||||
}
|
||||
|
||||
contents.config = (contents.config == null) ? {} : contents.config
|
||||
return contents
|
||||
}
|
||||
|
||||
function normalizeDriveLetterName (filePath) {
|
||||
if (process.platform === 'win32') {
|
||||
return filePath.replace(/^([a-z]):/, ([driveLetter]) => driveLetter.toUpperCase() + ':')
|
||||
|
||||
@@ -77,6 +77,31 @@ class Project extends Model {
|
||||
}
|
||||
}
|
||||
|
||||
// Layers the contents of a project's file's config
|
||||
// on top of the current global config.
|
||||
replace (projectSpecification) {
|
||||
if (projectSpecification == null) {
|
||||
atom.config.clearProjectSettings()
|
||||
this.setPaths([])
|
||||
} else {
|
||||
if (projectSpecification.originPath == null) {
|
||||
return
|
||||
}
|
||||
|
||||
// If no path is specified, set to directory of originPath.
|
||||
if (!Array.isArray(projectSpecification.paths)) {
|
||||
projectSpecification.paths = [path.dirname(projectSpecification.originPath)]
|
||||
}
|
||||
atom.config.resetProjectSettings(projectSpecification.config, projectSpecification.originPath)
|
||||
this.setPaths(projectSpecification.paths)
|
||||
}
|
||||
this.emitter.emit('did-replace', projectSpecification)
|
||||
}
|
||||
|
||||
onDidReplace (callback) {
|
||||
return this.emitter.on('did-replace', callback)
|
||||
}
|
||||
|
||||
/*
|
||||
Section: Serialization
|
||||
*/
|
||||
@@ -323,7 +348,6 @@ class Project extends Model {
|
||||
// a file or does not exist, its parent directory will be added instead.
|
||||
addPath (projectPath, options = {}) {
|
||||
const directory = this.getDirectoryForProjectPath(projectPath)
|
||||
|
||||
let ok = true
|
||||
if (options.exact === true) {
|
||||
ok = (directory.getPath() === projectPath)
|
||||
@@ -353,6 +377,7 @@ class Project extends Model {
|
||||
this.emitter.emit('did-change-files', events)
|
||||
}
|
||||
}
|
||||
|
||||
// We'll use the directory's custom onDidChangeFiles callback, if available.
|
||||
// CustomDirectory::onDidChangeFiles should match the signature of
|
||||
// Project::onDidChangeFiles below (although it may resolve asynchronously)
|
||||
|
||||
Reference in New Issue
Block a user