mirror of
https://github.com/atom/atom.git
synced 2026-04-28 03:01:47 -04:00
Merge pull request #12394 from atom/ns-as-switch-offset-test-to-mocha
Replace ChromeDriver integration tests main process Mocha tests
This commit is contained in:
@@ -1,6 +1,16 @@
|
||||
var ipcRenderer = null
|
||||
var ipcMain = null
|
||||
var BrowserWindow = null
|
||||
'use strict'
|
||||
|
||||
const Disposable = require('event-kit').Disposable
|
||||
let ipcRenderer = null
|
||||
let ipcMain = null
|
||||
let BrowserWindow = null
|
||||
|
||||
exports.on = function (emitter, eventName, callback) {
|
||||
emitter.on(eventName, callback)
|
||||
return new Disposable(function () {
|
||||
emitter.removeListener(eventName, callback)
|
||||
})
|
||||
}
|
||||
|
||||
exports.call = function (methodName, ...args) {
|
||||
if (!ipcRenderer) {
|
||||
@@ -28,7 +38,7 @@ exports.respondTo = function (methodName, callback) {
|
||||
|
||||
var responseChannel = getResponseChannel(methodName)
|
||||
|
||||
ipcMain.on(methodName, function (event, ...args) {
|
||||
return exports.on(ipcMain, methodName, function (event, ...args) {
|
||||
var browserWindow = BrowserWindow.fromWebContents(event.sender)
|
||||
var result = callback(browserWindow, ...args)
|
||||
event.sender.send(responseChannel, result)
|
||||
|
||||
@@ -7,6 +7,7 @@ Config = require '../config'
|
||||
FileRecoveryService = require './file-recovery-service'
|
||||
ipcHelpers = require '../ipc-helpers'
|
||||
{BrowserWindow, Menu, app, dialog, ipcMain, shell} = require 'electron'
|
||||
{CompositeDisposable} = require 'event-kit'
|
||||
fs = require 'fs-plus'
|
||||
path = require 'path'
|
||||
os = require 'os'
|
||||
@@ -36,14 +37,12 @@ class AtomApplication
|
||||
else
|
||||
options.socketPath = path.join(os.tmpdir(), "atom-#{options.version}-#{process.env.USER}.sock")
|
||||
|
||||
createAtomApplication = -> new AtomApplication(options)
|
||||
|
||||
# FIXME: Sometimes when socketPath doesn't exist, net.connect would strangely
|
||||
# take a few seconds to trigger 'error' event, it could be a bug of node
|
||||
# or atom-shell, before it's fixed we check the existence of socketPath to
|
||||
# speedup startup.
|
||||
if (process.platform isnt 'win32' and not fs.existsSync options.socketPath) or options.test
|
||||
createAtomApplication()
|
||||
new AtomApplication(options).initialize(options)
|
||||
return
|
||||
|
||||
client = net.connect {path: options.socketPath}, ->
|
||||
@@ -51,7 +50,7 @@ class AtomApplication
|
||||
client.end()
|
||||
app.quit()
|
||||
|
||||
client.on 'error', createAtomApplication
|
||||
client.on 'error', -> new AtomApplication(options).initialize(options)
|
||||
|
||||
windows: null
|
||||
applicationMenu: null
|
||||
@@ -64,32 +63,46 @@ class AtomApplication
|
||||
|
||||
constructor: (options) ->
|
||||
{@resourcePath, @devResourcePath, @version, @devMode, @safeMode, @socketPath, timeout, clearWindowState} = options
|
||||
|
||||
@socketPath = null if options.test
|
||||
|
||||
global.atomApplication = this
|
||||
|
||||
@pidsToOpenWindows = {}
|
||||
@windows = []
|
||||
|
||||
@config = new Config({configDirPath: process.env.ATOM_HOME, @resourcePath, enablePersistence: true})
|
||||
@config.setSchema null, {type: 'object', properties: _.clone(require('../config-schema'))}
|
||||
@config.load()
|
||||
@fileRecoveryService = new FileRecoveryService(path.join(process.env.ATOM_HOME, "recovery"))
|
||||
@storageFolder = new StorageFolder(process.env.ATOM_HOME)
|
||||
|
||||
@disposable = new CompositeDisposable
|
||||
@handleEvents()
|
||||
|
||||
# This stuff was previously done in the constructor, but we want to be able to construct this object
|
||||
# for testing purposes without booting up the world. As you add tests, feel free to move instantiation
|
||||
# of these various sub-objects into the constructor, but you'll need to remove the side-effects they
|
||||
# perform during their construction, adding an initialize method that you call here.
|
||||
initialize: (options) ->
|
||||
global.atomApplication = this
|
||||
|
||||
@config.onDidChange 'core.useCustomTitleBar', @promptForRelaunch
|
||||
|
||||
@autoUpdateManager = new AutoUpdateManager(@version, options.test, @resourcePath, @config)
|
||||
@applicationMenu = new ApplicationMenu(@version, @autoUpdateManager)
|
||||
@atomProtocolHandler = new AtomProtocolHandler(@resourcePath, @safeMode)
|
||||
@fileRecoveryService = new FileRecoveryService(path.join(process.env.ATOM_HOME, "recovery"))
|
||||
|
||||
@listenForArgumentsFromNewProcess()
|
||||
@setupJavaScriptArguments()
|
||||
@handleEvents()
|
||||
@setupDockMenu()
|
||||
@storageFolder = new StorageFolder(process.env.ATOM_HOME)
|
||||
|
||||
@launch(options)
|
||||
|
||||
destroy: ->
|
||||
@disposable.dispose()
|
||||
windowsClosePromises = @windows.map (window) ->
|
||||
window.close()
|
||||
window.closedPromise
|
||||
Promise.all(windowsClosePromises)
|
||||
|
||||
launch: (options) ->
|
||||
if options.pathsToOpen?.length > 0 or options.urlsToOpen?.length > 0 or options.test
|
||||
@openWithOptions(options)
|
||||
else
|
||||
@@ -121,7 +134,7 @@ class AtomApplication
|
||||
@windows.push window
|
||||
@applicationMenu?.addWindow(window.browserWindow)
|
||||
window.once 'window:loaded', =>
|
||||
@autoUpdateManager.emitUpdateAvailableEvent(window)
|
||||
@autoUpdateManager?.emitUpdateAvailableEvent(window)
|
||||
|
||||
unless window.isSpec
|
||||
focusHandler = => @lastFocusedWindow = window
|
||||
@@ -218,27 +231,27 @@ class AtomApplication
|
||||
@openPathOnEvent('application:open-your-stylesheet', 'atom://.atom/stylesheet')
|
||||
@openPathOnEvent('application:open-license', path.join(process.resourcesPath, 'LICENSE.md'))
|
||||
|
||||
app.on 'before-quit', =>
|
||||
@disposable.add ipcHelpers.on app, 'before-quit', =>
|
||||
@quitting = true
|
||||
|
||||
app.on 'will-quit', =>
|
||||
@disposable.add ipcHelpers.on app, 'will-quit', =>
|
||||
@killAllProcesses()
|
||||
@deleteSocketFile()
|
||||
|
||||
app.on 'open-file', (event, pathToOpen) =>
|
||||
@disposable.add ipcHelpers.on app, 'open-file', (event, pathToOpen) =>
|
||||
event.preventDefault()
|
||||
@openPath({pathToOpen})
|
||||
|
||||
app.on 'open-url', (event, urlToOpen) =>
|
||||
@disposable.add ipcHelpers.on app, 'open-url', (event, urlToOpen) =>
|
||||
event.preventDefault()
|
||||
@openUrl({urlToOpen, @devMode, @safeMode})
|
||||
|
||||
app.on 'activate-with-no-open-windows', (event) =>
|
||||
@disposable.add ipcHelpers.on app, 'activate-with-no-open-windows', (event) =>
|
||||
event?.preventDefault()
|
||||
@emit('application:new-window')
|
||||
|
||||
# A request from the associated render process to open a new render process.
|
||||
ipcMain.on 'open', (event, options) =>
|
||||
@disposable.add ipcHelpers.on ipcMain, 'open', (event, options) =>
|
||||
window = @windowForEvent(event)
|
||||
if options?
|
||||
if typeof options.pathsToOpen is 'string'
|
||||
@@ -247,21 +260,21 @@ class AtomApplication
|
||||
options.window = window
|
||||
@openPaths(options)
|
||||
else
|
||||
new AtomWindow(@fileRecoveryService, options)
|
||||
new AtomWindow(this, @fileRecoveryService, options)
|
||||
else
|
||||
@promptForPathToOpen('all', {window})
|
||||
|
||||
ipcMain.on 'update-application-menu', (event, template, keystrokesByCommand) =>
|
||||
@disposable.add ipcHelpers.on ipcMain, 'update-application-menu', (event, template, keystrokesByCommand) =>
|
||||
win = BrowserWindow.fromWebContents(event.sender)
|
||||
@applicationMenu.update(win, template, keystrokesByCommand)
|
||||
@applicationMenu?.update(win, template, keystrokesByCommand)
|
||||
|
||||
ipcMain.on 'run-package-specs', (event, packageSpecPath) =>
|
||||
@disposable.add ipcHelpers.on ipcMain, 'run-package-specs', (event, packageSpecPath) =>
|
||||
@runTests({resourcePath: @devResourcePath, pathsToOpen: [packageSpecPath], headless: false})
|
||||
|
||||
ipcMain.on 'command', (event, command) =>
|
||||
@disposable.add ipcHelpers.on ipcMain, 'command', (event, command) =>
|
||||
@emit(command)
|
||||
|
||||
ipcMain.on 'open-command', (event, command, args...) =>
|
||||
@disposable.add ipcHelpers.on ipcMain, 'open-command', (event, command, args...) =>
|
||||
defaultPath = args[0] if args.length > 0
|
||||
switch command
|
||||
when 'application:open' then @promptForPathToOpen('all', getLoadSettings(), defaultPath)
|
||||
@@ -269,72 +282,72 @@ class AtomApplication
|
||||
when 'application:open-folder' then @promptForPathToOpen('folder', getLoadSettings(), defaultPath)
|
||||
else console.log "Invalid open-command received: " + command
|
||||
|
||||
ipcMain.on 'window-command', (event, command, args...) ->
|
||||
@disposable.add ipcHelpers.on ipcMain, 'window-command', (event, command, args...) ->
|
||||
win = BrowserWindow.fromWebContents(event.sender)
|
||||
win.emit(command, args...)
|
||||
|
||||
ipcMain.on 'call-window-method', (event, method, args...) ->
|
||||
@disposable.add ipcHelpers.on ipcMain, 'call-window-method', (event, method, args...) ->
|
||||
win = BrowserWindow.fromWebContents(event.sender)
|
||||
win[method](args...)
|
||||
|
||||
ipcMain.on 'pick-folder', (event, responseChannel) =>
|
||||
@disposable.add ipcHelpers.on ipcMain, 'pick-folder', (event, responseChannel) =>
|
||||
@promptForPath "folder", (selectedPaths) ->
|
||||
event.sender.send(responseChannel, selectedPaths)
|
||||
|
||||
ipcHelpers.respondTo 'set-window-size', (win, width, height) ->
|
||||
@disposable.add ipcHelpers.respondTo 'set-window-size', (win, width, height) ->
|
||||
win.setSize(width, height)
|
||||
|
||||
ipcHelpers.respondTo 'set-window-position', (win, x, y) ->
|
||||
@disposable.add ipcHelpers.respondTo 'set-window-position', (win, x, y) ->
|
||||
win.setPosition(x, y)
|
||||
|
||||
ipcHelpers.respondTo 'center-window', (win) ->
|
||||
@disposable.add ipcHelpers.respondTo 'center-window', (win) ->
|
||||
win.center()
|
||||
|
||||
ipcHelpers.respondTo 'focus-window', (win) ->
|
||||
@disposable.add ipcHelpers.respondTo 'focus-window', (win) ->
|
||||
win.focus()
|
||||
|
||||
ipcHelpers.respondTo 'show-window', (win) ->
|
||||
@disposable.add ipcHelpers.respondTo 'show-window', (win) ->
|
||||
win.show()
|
||||
|
||||
ipcHelpers.respondTo 'hide-window', (win) ->
|
||||
@disposable.add ipcHelpers.respondTo 'hide-window', (win) ->
|
||||
win.hide()
|
||||
|
||||
ipcHelpers.respondTo 'get-temporary-window-state', (win) ->
|
||||
@disposable.add ipcHelpers.respondTo 'get-temporary-window-state', (win) ->
|
||||
win.temporaryState
|
||||
|
||||
ipcHelpers.respondTo 'set-temporary-window-state', (win, state) ->
|
||||
@disposable.add ipcHelpers.respondTo 'set-temporary-window-state', (win, state) ->
|
||||
win.temporaryState = state
|
||||
|
||||
ipcMain.on 'did-cancel-window-unload', =>
|
||||
@disposable.add ipcHelpers.on ipcMain, 'did-cancel-window-unload', =>
|
||||
@quitting = false
|
||||
|
||||
clipboard = require '../safe-clipboard'
|
||||
ipcMain.on 'write-text-to-selection-clipboard', (event, selectedText) ->
|
||||
@disposable.add ipcHelpers.on ipcMain, 'write-text-to-selection-clipboard', (event, selectedText) ->
|
||||
clipboard.writeText(selectedText, 'selection')
|
||||
|
||||
ipcMain.on 'write-to-stdout', (event, output) ->
|
||||
@disposable.add ipcHelpers.on ipcMain, 'write-to-stdout', (event, output) ->
|
||||
process.stdout.write(output)
|
||||
|
||||
ipcMain.on 'write-to-stderr', (event, output) ->
|
||||
@disposable.add ipcHelpers.on ipcMain, 'write-to-stderr', (event, output) ->
|
||||
process.stderr.write(output)
|
||||
|
||||
ipcMain.on 'add-recent-document', (event, filename) ->
|
||||
@disposable.add ipcHelpers.on ipcMain, 'add-recent-document', (event, filename) ->
|
||||
app.addRecentDocument(filename)
|
||||
|
||||
ipcMain.on 'execute-javascript-in-dev-tools', (event, code) ->
|
||||
@disposable.add ipcHelpers.on ipcMain, 'execute-javascript-in-dev-tools', (event, code) ->
|
||||
event.sender.devToolsWebContents?.executeJavaScript(code)
|
||||
|
||||
ipcMain.on 'get-auto-update-manager-state', (event) =>
|
||||
@disposable.add ipcHelpers.on ipcMain, 'get-auto-update-manager-state', (event) =>
|
||||
event.returnValue = @autoUpdateManager.getState()
|
||||
|
||||
ipcMain.on 'get-auto-update-manager-error', (event) =>
|
||||
@disposable.add ipcHelpers.on ipcMain, 'get-auto-update-manager-error', (event) =>
|
||||
event.returnValue = @autoUpdateManager.getErrorMessage()
|
||||
|
||||
ipcMain.on 'will-save-path', (event, path) =>
|
||||
@disposable.add ipcHelpers.on ipcMain, 'will-save-path', (event, path) =>
|
||||
@fileRecoveryService.willSavePath(@windowForEvent(event), path)
|
||||
event.returnValue = true
|
||||
|
||||
ipcMain.on 'did-save-path', (event, path) =>
|
||||
@disposable.add ipcHelpers.on ipcMain, 'did-save-path', (event, path) =>
|
||||
@fileRecoveryService.didSavePath(@windowForEvent(event), path)
|
||||
event.returnValue = true
|
||||
|
||||
@@ -498,7 +511,7 @@ class AtomApplication
|
||||
windowInitializationScript ?= require.resolve('../initialize-application-window')
|
||||
resourcePath ?= @resourcePath
|
||||
windowDimensions ?= @getDimensionsForNewWindow()
|
||||
openedWindow = new AtomWindow(@fileRecoveryService, {initialPaths, locationsToOpen, windowInitializationScript, resourcePath, devMode, safeMode, windowDimensions, profileStartup, clearWindowState, env})
|
||||
openedWindow = new AtomWindow(this, @fileRecoveryService, {initialPaths, locationsToOpen, windowInitializationScript, resourcePath, devMode, safeMode, windowDimensions, profileStartup, clearWindowState, env})
|
||||
|
||||
if pidToKillWhenClosed?
|
||||
@pidsToOpenWindows[pidToKillWhenClosed] = openedWindow
|
||||
@@ -506,6 +519,8 @@ class AtomApplication
|
||||
openedWindow.browserWindow.once 'closed', =>
|
||||
@killProcessForWindow(openedWindow)
|
||||
|
||||
openedWindow
|
||||
|
||||
# Kill all processes associated with opened windows.
|
||||
killAllProcesses: ->
|
||||
@killProcess(pid) for pid of @pidsToOpenWindows
|
||||
@@ -548,9 +563,8 @@ class AtomApplication
|
||||
devMode: @devMode
|
||||
safeMode: @safeMode
|
||||
}))
|
||||
true
|
||||
else
|
||||
false
|
||||
null
|
||||
|
||||
# Open an atom:// url.
|
||||
#
|
||||
@@ -577,7 +591,7 @@ class AtomApplication
|
||||
packagePath = @packages.resolvePackagePath(packageName)
|
||||
windowInitializationScript = path.resolve(packagePath, pack.urlMain)
|
||||
windowDimensions = @getDimensionsForNewWindow()
|
||||
new AtomWindow(@fileRecoveryService, {windowInitializationScript, @resourcePath, devMode, safeMode, urlToOpen, windowDimensions, env})
|
||||
new AtomWindow(this, @fileRecoveryService, {windowInitializationScript, @resourcePath, devMode, safeMode, urlToOpen, windowDimensions, env})
|
||||
else
|
||||
console.log "Package '#{pack.name}' does not have a url main: #{urlToOpen}"
|
||||
else
|
||||
@@ -622,7 +636,7 @@ class AtomApplication
|
||||
devMode = true
|
||||
isSpec = true
|
||||
safeMode ?= false
|
||||
new AtomWindow(@fileRecoveryService, {windowInitializationScript, resourcePath, headless, isSpec, devMode, testRunnerPath, legacyTestRunnerPath, testPaths, logFile, safeMode, env})
|
||||
new AtomWindow(this, @fileRecoveryService, {windowInitializationScript, resourcePath, headless, isSpec, devMode, testRunnerPath, legacyTestRunnerPath, testPaths, logFile, safeMode, env})
|
||||
|
||||
resolveTestRunnerPath: (testPath) ->
|
||||
FindParentDir ?= require 'find-parent-dir'
|
||||
@@ -720,4 +734,3 @@ class AtomApplication
|
||||
# once we're using electron v.1.2.2
|
||||
# app.relaunch()
|
||||
app.quit()
|
||||
|
||||
|
||||
@@ -15,11 +15,14 @@ class AtomWindow
|
||||
loaded: null
|
||||
isSpec: null
|
||||
|
||||
constructor: (@fileRecoveryService, settings={}) ->
|
||||
constructor: (@atomApplication, @fileRecoveryService, settings={}) ->
|
||||
{@resourcePath, initialPaths, pathToOpen, locationsToOpen, @isSpec, @headless, @safeMode, @devMode} = settings
|
||||
locationsToOpen ?= [{pathToOpen}] if pathToOpen
|
||||
locationsToOpen ?= []
|
||||
|
||||
@loadedPromise = new Promise((@resolveLoadedPromise) =>)
|
||||
@closedPromise = new Promise((@resolveClosedPromise) =>)
|
||||
|
||||
options =
|
||||
show: false
|
||||
title: 'Atom'
|
||||
@@ -44,7 +47,7 @@ class AtomWindow
|
||||
options.titleBarStyle = 'hidden'
|
||||
|
||||
@browserWindow = new BrowserWindow options
|
||||
global.atomApplication.addWindow(this)
|
||||
@atomApplication.addWindow(this)
|
||||
|
||||
@handleEvents()
|
||||
|
||||
@@ -72,8 +75,9 @@ class AtomWindow
|
||||
@browserWindow.loadSettings = loadSettings
|
||||
|
||||
@browserWindow.once 'window:loaded', =>
|
||||
@emit 'window:loaded'
|
||||
@loaded = true
|
||||
@emit 'window:loaded'
|
||||
@resolveLoadedPromise()
|
||||
|
||||
@setLoadSettings(loadSettings)
|
||||
@env = loadSettings.env if loadSettings.env?
|
||||
@@ -124,12 +128,13 @@ class AtomWindow
|
||||
false
|
||||
|
||||
handleEvents: ->
|
||||
@browserWindow.on 'close', ->
|
||||
global.atomApplication.saveState(false)
|
||||
@browserWindow.on 'close', =>
|
||||
@atomApplication.saveState(false)
|
||||
|
||||
@browserWindow.on 'closed', =>
|
||||
@fileRecoveryService.didCloseWindow(this)
|
||||
global.atomApplication.removeWindow(this)
|
||||
@atomApplication.removeWindow(this)
|
||||
@resolveClosedPromise()
|
||||
|
||||
@browserWindow.on 'unresponsive', =>
|
||||
return if @isSpec
|
||||
@@ -142,7 +147,7 @@ class AtomWindow
|
||||
@browserWindow.destroy() if chosen is 0
|
||||
|
||||
@browserWindow.webContents.on 'crashed', =>
|
||||
global.atomApplication.exit(100) if @headless
|
||||
@atomApplication.exit(100) if @headless
|
||||
|
||||
@fileRecoveryService.didCrashWindow(this)
|
||||
chosen = dialog.showMessageBox @browserWindow,
|
||||
@@ -182,7 +187,7 @@ class AtomWindow
|
||||
|
||||
sendCommand: (command, args...) ->
|
||||
if @isSpecWindow()
|
||||
unless global.atomApplication.sendCommandToFirstResponder(command)
|
||||
unless @atomApplication.sendCommandToFirstResponder(command)
|
||||
switch command
|
||||
when 'window:reload' then @reload()
|
||||
when 'window:toggle-dev-tools' then @toggleDevTools()
|
||||
@@ -190,7 +195,7 @@ class AtomWindow
|
||||
else if @isWebViewFocused()
|
||||
@sendCommandToBrowserWindow(command, args...)
|
||||
else
|
||||
unless global.atomApplication.sendCommandToFirstResponder(command)
|
||||
unless @atomApplication.sendCommandToFirstResponder(command)
|
||||
@sendCommandToBrowserWindow(command, args...)
|
||||
|
||||
sendCommandToBrowserWindow: (command, args...) ->
|
||||
@@ -205,7 +210,7 @@ class AtomWindow
|
||||
shouldHideTitleBar: ->
|
||||
not @isSpec and
|
||||
process.platform is 'darwin' and
|
||||
global.atomApplication.config.get('core.useCustomTitleBar')
|
||||
@atomApplication.config.get('core.useCustomTitleBar')
|
||||
|
||||
close: -> @browserWindow.close()
|
||||
|
||||
|
||||
@@ -14,21 +14,20 @@ const {app} = require('electron')
|
||||
const fs = require('fs-plus')
|
||||
const path = require('path')
|
||||
const temp = require('temp')
|
||||
const yargs = require('yargs')
|
||||
const dedent = require('dedent')
|
||||
const parseCommandLine = require('./parse-command-line')
|
||||
const startCrashReporter = require('../crash-reporter-start')
|
||||
const previousConsoleLog = console.log
|
||||
console.log = require('nslog')
|
||||
|
||||
function start () {
|
||||
const args = parseCommandLine()
|
||||
args.env = process.env
|
||||
const args = parseCommandLine(process.argv.slice(1))
|
||||
setupAtomHome(args)
|
||||
setupCompileCache()
|
||||
|
||||
if (handleStartupEventWithSquirrel()) {
|
||||
return
|
||||
} else if (args.test && args.mainProcess) {
|
||||
app.setPath('userData', temp.mkdirSync('atom-user-data-dir-for-main-process-tests'))
|
||||
console.log = previousConsoleLog
|
||||
app.on('ready', function () {
|
||||
const testRunner = require(path.join(args.resourcePath, 'spec/main-process/mocha-test-runner'))
|
||||
@@ -72,14 +71,6 @@ function start () {
|
||||
})
|
||||
}
|
||||
|
||||
function normalizeDriveLetterName (filePath) {
|
||||
if (process.platform === 'win32') {
|
||||
return filePath.replace(/^([a-z]):/, ([driveLetter]) => driveLetter.toUpperCase() + ':')
|
||||
} else {
|
||||
return filePath
|
||||
}
|
||||
}
|
||||
|
||||
function handleStartupEventWithSquirrel () {
|
||||
if (process.platform !== 'win32') {
|
||||
return false
|
||||
@@ -125,141 +116,4 @@ function setupCompileCache () {
|
||||
CompileCache.setAtomHomeDirectory(process.env.ATOM_HOME)
|
||||
}
|
||||
|
||||
function writeFullVersion () {
|
||||
process.stdout.write(
|
||||
`Atom : ${app.getVersion()}\n` +
|
||||
`Electron: ${process.versions.electron}\n` +
|
||||
`Chrome : ${process.versions.chrome}\n` +
|
||||
`Node : ${process.versions.node}\n`
|
||||
)
|
||||
}
|
||||
|
||||
function parseCommandLine () {
|
||||
const options = yargs(process.argv.slice(1)).wrap(100)
|
||||
const version = app.getVersion()
|
||||
options.usage(
|
||||
dedent`Atom Editor v${version}
|
||||
|
||||
Usage: atom [options] [path ...]
|
||||
|
||||
One or more paths to files or folders may be specified. If there is an
|
||||
existing Atom window that contains all of the given folders, the paths
|
||||
will be opened in that window. Otherwise, they will be opened in a new
|
||||
window.
|
||||
|
||||
Environment Variables:
|
||||
|
||||
ATOM_DEV_RESOURCE_PATH The path from which Atom loads source code in dev mode.
|
||||
Defaults to \`~/github/atom\`.
|
||||
|
||||
ATOM_HOME The root path for all configuration files and folders.
|
||||
Defaults to \`~/.atom\`.`
|
||||
)
|
||||
// Deprecated 1.0 API preview flag
|
||||
options.alias('1', 'one').boolean('1').describe('1', 'This option is no longer supported.')
|
||||
options.boolean('include-deprecated-apis').describe('include-deprecated-apis', 'This option is not currently supported.')
|
||||
options.alias('d', 'dev').boolean('d').describe('d', 'Run in development mode.')
|
||||
options.alias('f', 'foreground').boolean('f').describe('f', 'Keep the main process in the foreground.')
|
||||
options.alias('h', 'help').boolean('h').describe('h', 'Print this usage message.')
|
||||
options.alias('l', 'log-file').string('l').describe('l', 'Log all output to file.')
|
||||
options.alias('n', 'new-window').boolean('n').describe('n', 'Open a new window.')
|
||||
options.boolean('profile-startup').describe('profile-startup', 'Create a profile of the startup execution time.')
|
||||
options.alias('r', 'resource-path').string('r').describe('r', 'Set the path to the Atom source directory and enable dev-mode.')
|
||||
options.boolean('safe').describe(
|
||||
'safe',
|
||||
'Do not load packages from ~/.atom/packages or ~/.atom/dev/packages.'
|
||||
)
|
||||
options.boolean('portable').describe(
|
||||
'portable',
|
||||
'Set portable mode. Copies the ~/.atom folder to be a sibling of the installed Atom location if a .atom folder is not already there.'
|
||||
)
|
||||
options.alias('t', 'test').boolean('t').describe('t', 'Run the specified specs and exit with error code on failures.')
|
||||
options.alias('m', 'main-process').boolean('m').describe('m', 'Run the specified specs in the main process.')
|
||||
options.string('timeout').describe(
|
||||
'timeout',
|
||||
'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('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')
|
||||
options.string('user-data-dir')
|
||||
options.boolean('clear-window-state').describe('clear-window-state', 'Delete all Atom environment state.')
|
||||
|
||||
const args = options.argv
|
||||
|
||||
if (args.help) {
|
||||
process.stdout.write(options.help())
|
||||
process.exit(0)
|
||||
}
|
||||
|
||||
if (args.version) {
|
||||
writeFullVersion()
|
||||
process.exit(0)
|
||||
}
|
||||
|
||||
const addToLastWindow = args['add']
|
||||
const safeMode = args['safe']
|
||||
const pathsToOpen = args._
|
||||
const test = args['test']
|
||||
const mainProcess = args['main-process']
|
||||
const timeout = args['timeout']
|
||||
const newWindow = args['new-window']
|
||||
let executedFrom = null
|
||||
if (args['executed-from'] && args['executed-from'].toString()) {
|
||||
executedFrom = args['executed-from'].toString()
|
||||
} else {
|
||||
executedFrom = process.cwd()
|
||||
}
|
||||
|
||||
let pidToKillWhenClosed = null
|
||||
if (args['wait']) {
|
||||
pidToKillWhenClosed = args['pid']
|
||||
}
|
||||
|
||||
const logFile = args['log-file']
|
||||
const socketPath = args['socket-path']
|
||||
const userDataDir = args['user-data-dir']
|
||||
const profileStartup = args['profile-startup']
|
||||
const clearWindowState = args['clear-window-state']
|
||||
const urlsToOpen = []
|
||||
const setPortable = args.portable
|
||||
let devMode = args['dev']
|
||||
let devResourcePath = process.env.ATOM_DEV_RESOURCE_PATH || path.join(app.getPath('home'), 'github', 'atom')
|
||||
let resourcePath = null
|
||||
|
||||
if (args['resource-path']) {
|
||||
devMode = true
|
||||
resourcePath = args['resource-path']
|
||||
}
|
||||
|
||||
if (test) {
|
||||
devMode = true
|
||||
}
|
||||
|
||||
if (devMode && !resourcePath) {
|
||||
resourcePath = devResourcePath
|
||||
}
|
||||
|
||||
if (!fs.statSyncNoException(resourcePath)) {
|
||||
resourcePath = path.dirname(path.dirname(__dirname))
|
||||
}
|
||||
|
||||
if (args['path-environment']) {
|
||||
// On Yosemite the $PATH is not inherited by the "open" command, so we have to
|
||||
// explicitly pass it by command line, see http://git.io/YC8_Ew.
|
||||
process.env.PATH = args['path-environment']
|
||||
}
|
||||
|
||||
resourcePath = normalizeDriveLetterName(resourcePath)
|
||||
devResourcePath = normalizeDriveLetterName(devResourcePath)
|
||||
|
||||
return {
|
||||
resourcePath, devResourcePath, pathsToOpen, urlsToOpen, executedFrom, test,
|
||||
version, pidToKillWhenClosed, devMode, safeMode, newWindow, logFile, socketPath,
|
||||
userDataDir, profileStartup, timeout, setPortable, clearWindowState,
|
||||
addToLastWindow, mainProcess
|
||||
}
|
||||
}
|
||||
|
||||
start()
|
||||
|
||||
148
src/main-process/parse-command-line.js
Normal file
148
src/main-process/parse-command-line.js
Normal file
@@ -0,0 +1,148 @@
|
||||
'use strict'
|
||||
|
||||
const dedent = require('dedent')
|
||||
const yargs = require('yargs')
|
||||
const {app} = require('electron')
|
||||
const path = require('path')
|
||||
const fs = require('fs-plus')
|
||||
|
||||
module.exports = function parseCommandLine (processArgs) {
|
||||
const options = yargs(processArgs).wrap(100)
|
||||
const version = app.getVersion()
|
||||
options.usage(
|
||||
dedent`Atom Editor v${version}
|
||||
|
||||
Usage: atom [options] [path ...]
|
||||
|
||||
One or more paths to files or folders may be specified. If there is an
|
||||
existing Atom window that contains all of the given folders, the paths
|
||||
will be opened in that window. Otherwise, they will be opened in a new
|
||||
window.
|
||||
|
||||
Environment Variables:
|
||||
|
||||
ATOM_DEV_RESOURCE_PATH The path from which Atom loads source code in dev mode.
|
||||
Defaults to \`~/github/atom\`.
|
||||
|
||||
ATOM_HOME The root path for all configuration files and folders.
|
||||
Defaults to \`~/.atom\`.`
|
||||
)
|
||||
// Deprecated 1.0 API preview flag
|
||||
options.alias('1', 'one').boolean('1').describe('1', 'This option is no longer supported.')
|
||||
options.boolean('include-deprecated-apis').describe('include-deprecated-apis', 'This option is not currently supported.')
|
||||
options.alias('d', 'dev').boolean('d').describe('d', 'Run in development mode.')
|
||||
options.alias('f', 'foreground').boolean('f').describe('f', 'Keep the main process in the foreground.')
|
||||
options.alias('h', 'help').boolean('h').describe('h', 'Print this usage message.')
|
||||
options.alias('l', 'log-file').string('l').describe('l', 'Log all output to file.')
|
||||
options.alias('n', 'new-window').boolean('n').describe('n', 'Open a new window.')
|
||||
options.boolean('profile-startup').describe('profile-startup', 'Create a profile of the startup execution time.')
|
||||
options.alias('r', 'resource-path').string('r').describe('r', 'Set the path to the Atom source directory and enable dev-mode.')
|
||||
options.boolean('safe').describe(
|
||||
'safe',
|
||||
'Do not load packages from ~/.atom/packages or ~/.atom/dev/packages.'
|
||||
)
|
||||
options.boolean('portable').describe(
|
||||
'portable',
|
||||
'Set portable mode. Copies the ~/.atom folder to be a sibling of the installed Atom location if a .atom folder is not already there.'
|
||||
)
|
||||
options.alias('t', 'test').boolean('t').describe('t', 'Run the specified specs and exit with error code on failures.')
|
||||
options.alias('m', 'main-process').boolean('m').describe('m', 'Run the specified specs in the main process.')
|
||||
options.string('timeout').describe(
|
||||
'timeout',
|
||||
'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('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')
|
||||
options.string('user-data-dir')
|
||||
options.boolean('clear-window-state').describe('clear-window-state', 'Delete all Atom environment state.')
|
||||
|
||||
const args = options.argv
|
||||
|
||||
if (args.help) {
|
||||
process.stdout.write(options.help())
|
||||
process.exit(0)
|
||||
}
|
||||
|
||||
if (args.version) {
|
||||
process.stdout.write(
|
||||
`Atom : ${app.getVersion()}\n` +
|
||||
`Electron: ${process.versions.electron}\n` +
|
||||
`Chrome : ${process.versions.chrome}\n` +
|
||||
`Node : ${process.versions.node}\n`
|
||||
)
|
||||
process.exit(0)
|
||||
}
|
||||
|
||||
const addToLastWindow = args['add']
|
||||
const safeMode = args['safe']
|
||||
const pathsToOpen = args._
|
||||
const test = args['test']
|
||||
const mainProcess = args['main-process']
|
||||
const timeout = args['timeout']
|
||||
const newWindow = args['new-window']
|
||||
let executedFrom = null
|
||||
if (args['executed-from'] && args['executed-from'].toString()) {
|
||||
executedFrom = args['executed-from'].toString()
|
||||
} else {
|
||||
executedFrom = process.cwd()
|
||||
}
|
||||
|
||||
let pidToKillWhenClosed = null
|
||||
if (args['wait']) {
|
||||
pidToKillWhenClosed = args['pid']
|
||||
}
|
||||
|
||||
const logFile = args['log-file']
|
||||
const socketPath = args['socket-path']
|
||||
const userDataDir = args['user-data-dir']
|
||||
const profileStartup = args['profile-startup']
|
||||
const clearWindowState = args['clear-window-state']
|
||||
const urlsToOpen = []
|
||||
const setPortable = args.portable
|
||||
let devMode = args['dev']
|
||||
let devResourcePath = process.env.ATOM_DEV_RESOURCE_PATH || path.join(app.getPath('home'), 'github', 'atom')
|
||||
let resourcePath = null
|
||||
|
||||
if (args['resource-path']) {
|
||||
devMode = true
|
||||
resourcePath = args['resource-path']
|
||||
}
|
||||
|
||||
if (test) {
|
||||
devMode = true
|
||||
}
|
||||
|
||||
if (devMode && !resourcePath) {
|
||||
resourcePath = devResourcePath
|
||||
}
|
||||
|
||||
if (!fs.statSyncNoException(resourcePath)) {
|
||||
resourcePath = path.dirname(path.dirname(__dirname))
|
||||
}
|
||||
|
||||
if (args['path-environment']) {
|
||||
// On Yosemite the $PATH is not inherited by the "open" command, so we have to
|
||||
// explicitly pass it by command line, see http://git.io/YC8_Ew.
|
||||
process.env.PATH = args['path-environment']
|
||||
}
|
||||
|
||||
resourcePath = normalizeDriveLetterName(resourcePath)
|
||||
devResourcePath = normalizeDriveLetterName(devResourcePath)
|
||||
|
||||
return {
|
||||
resourcePath, devResourcePath, pathsToOpen, urlsToOpen, executedFrom, test,
|
||||
version, pidToKillWhenClosed, devMode, safeMode, newWindow, logFile, socketPath,
|
||||
userDataDir, profileStartup, timeout, setPortable, clearWindowState,
|
||||
addToLastWindow, mainProcess, env: process.env
|
||||
}
|
||||
}
|
||||
|
||||
function normalizeDriveLetterName (filePath) {
|
||||
if (process.platform === 'win32') {
|
||||
return filePath.replace(/^([a-z]):/, ([driveLetter]) => driveLetter.toUpperCase() + ':')
|
||||
} else {
|
||||
return filePath
|
||||
}
|
||||
}
|
||||
@@ -26,7 +26,7 @@ class StateStore {
|
||||
save (key, value) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.dbPromise.then(db => {
|
||||
if (db == null) resolve()
|
||||
if (db == null) return resolve()
|
||||
|
||||
var request = db.transaction(['states'], 'readwrite')
|
||||
.objectStore('states')
|
||||
|
||||
@@ -12,6 +12,7 @@ class WindowEventHandler
|
||||
|
||||
@previousOnbeforeunloadHandler = @window.onbeforeunload
|
||||
@window.onbeforeunload = @handleWindowBeforeunload
|
||||
@addEventListener(@window, 'unload', @handleWindowUnload)
|
||||
@addEventListener(@window, 'focus', @handleWindowFocus)
|
||||
@addEventListener(@window, 'blur', @handleWindowBlur)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user