Comparar commits

..

12 Commits

Autor SHA1 Mensagem Data
Max Brunsfeld 6430bbb460 Wait for chromedriver's startup message on stdout 2015-02-05 22:40:17 -08:00
Max Brunsfeld 362ff963fd ⬆️ grunt-download-atom-shell 2015-02-05 13:07:05 -08:00
Max Brunsfeld 61ca2e14dc Run integration tests on CI 2015-02-05 13:02:25 -08:00
Max Brunsfeld 56677e71e4 Enable integration tests with environment var
I think this makes more sense then running them via a separate command,
since that command would only make sense for atom-core, unlike the
current 'run-package-specs' command, which works for any atom package.

This way, they won't run by default, but you can opt in to running them
on the command line by setting an env var, or in the spec runner by
temporarily editing the code, like we do for focused tests anyway.
2015-02-05 13:02:08 -08:00
Max Brunsfeld c927101bb2 Download chromedriver along with atom-shell 2015-02-05 12:59:48 -08:00
Max Brunsfeld 28f280183e Use which(1), not bash's type function 2015-02-04 15:22:51 -08:00
Max Brunsfeld f1df254a66 Use varargs in integration-test helper fn 2015-02-04 15:20:44 -08:00
Max Brunsfeld af28083a6f Add integration test coverage for reusing windows w/ the same dir 2015-02-04 15:07:08 -08:00
Max Brunsfeld 495caa7316 🎨 Rename DEFAULT_SOCKET_PATH -> DefaultSocketPath 2015-02-04 13:12:41 -08:00
Max Brunsfeld d0757c87c8 Move selenium-webdriver dependency to build/package.json 2015-02-04 13:11:33 -08:00
Max Brunsfeld c19d99e9e2 Add integration test for starting atom w/ different arguments 2015-02-04 12:59:26 -08:00
Max Brunsfeld ab43b08739 Add hidden --socket-path flag
This will allow integration tests to control which atom application
instance they use when creating atom windows
2015-02-04 11:47:29 -08:00
27 arquivos alterados com 243 adições e 223 exclusões
+12 -2
Ver Arquivo
@@ -24,8 +24,18 @@ Atom will automatically update when a new release is available.
You can also download an `atom-windows.zip` file from the [releases page](https://github.com/atom/atom/releases/latest).
The `.zip` version will not automatically update.
Using [chocolatey](https://chocolatey.org/)? Run `cinst Atom` to install
the latest version of Atom.
#### Uninstalling Chocolatey Version
The recommended installation of Atom on Windows used to be using [Chocolatey](https://chocolatey.org/packages/Atom/).
This is no longer recommended now that the Atom Windows installer & auto-updater
exists.
To switch from Chocolatey to the new installer:
* Upgrade to Atom 0.155 or above by running `cup Atom`
* Run `cuninst Atom` to uninstall the Chocolatey version of Atom
* This will not delete any of your installed packages or Atom config files.
* Download the latest [AtomSetup.exe installer](https://github.com/atom/atom/releases/latest).
* Double-click the downloaded file to install Atom
### Debian Linux (Ubuntu)
+2 -2
Ver Arquivo
@@ -222,7 +222,7 @@ module.exports = (grunt) ->
grunt.registerTask('test', ['shell:kill-atom', 'run-specs'])
grunt.registerTask('docs', ['markdown:guides', 'build-docs'])
ciTasks = ['output-disk-space', 'download-atom-shell', 'build']
ciTasks = ['output-disk-space', 'download-atom-shell', 'download-atom-shell-chromedriver', 'build']
ciTasks.push('dump-symbols') if process.platform isnt 'win32'
ciTasks.push('set-version', 'check-licenses', 'lint')
ciTasks.push('mkdeb') if process.platform is 'linux'
@@ -232,6 +232,6 @@ module.exports = (grunt) ->
ciTasks.push('publish-build')
grunt.registerTask('ci', ciTasks)
defaultTasks = ['download-atom-shell', 'build', 'set-version']
defaultTasks = ['download-atom-shell', 'download-atom-shell-chromedriver', 'build', 'set-version']
defaultTasks.push 'install' unless process.platform is 'linux'
grunt.registerTask('default', defaultTasks)
+2 -1
Ver Arquivo
@@ -19,7 +19,7 @@
"grunt-contrib-csslint": "~0.1.2",
"grunt-contrib-less": "~0.8.0",
"grunt-cson": "0.14.0",
"grunt-download-atom-shell": "~0.11.0",
"grunt-download-atom-shell": "~0.12.0",
"grunt-lesslint": "0.13.0",
"grunt-peg": "~1.1.0",
"grunt-shell": "~0.3.1",
@@ -31,6 +31,7 @@
"request": "~2.27.0",
"rimraf": "~2.2.2",
"runas": "~1.0.1",
"selenium-webdriver": "^2.44.0",
"tello": "1.0.4",
"temp": "~0.8.1",
"underscore-plus": "1.x",
+2 -2
Ver Arquivo
@@ -47,9 +47,9 @@ module.exports = (grunt) ->
{description} = grunt.file.readJSON('package.json')
iconName = path.join(shareDir, 'resources', 'app', 'resources', 'atom.png')
executable = path.join(shareDir, 'atom')
installDir = path.join(installDir, '.') # To prevent "Exec=/usr/local//share/atom/atom"
template = _.template(String(fs.readFileSync(desktopFile)))
filled = template({description, iconName, executable})
filled = template({description, installDir, iconName})
grunt.file.write(desktopInstallFile, filled)
+12
Ver Arquivo
@@ -85,15 +85,27 @@ module.exports = (grunt) ->
appPath = getAppPath()
resourcePath = process.cwd()
coreSpecsPath = path.resolve('spec')
chromedriverPath = path.join(resourcePath, "atom-shell", "chromedriver")
if process.platform in ['darwin', 'linux']
options =
cmd: appPath
args: ['--test', "--resource-path=#{resourcePath}", "--spec-directory=#{coreSpecsPath}"]
opts:
env: _.extend({}, process.env,
ATOM_INTEGRATION_TESTS_ENABLED: true
PATH: [process.env.path, chromedriverPath].join(":")
)
else if process.platform is 'win32'
options =
cmd: process.env.comspec
args: ['/c', appPath, '--test', "--resource-path=#{resourcePath}", "--spec-directory=#{coreSpecsPath}", "--log-file=ci.log"]
opts:
env: _.extend({}, process.env,
ATOM_INTEGRATION_TESTS_ENABLED: true
PATH: [process.env.path, chromedriverPath].join(";")
)
spawn options, (error, results, code) ->
if process.platform is 'win32'
+1 -1
Ver Arquivo
@@ -63,7 +63,7 @@ When you are deprecation free and all done converting, upgrade the `engines` fie
```json
{
"engines": {
"atom": ">=0.174.0 <2.0.0"
"atom": ">=0.174.0, <2.0.0"
}
}
```
+3 -4
Ver Arquivo
@@ -31,7 +31,7 @@
"emissary": "^1.3.1",
"event-kit": "^1.0.2",
"first-mate": "^3.0.0",
"fs-plus": "^2.5",
"fs-plus": "^2.3.2",
"fstream": "0.1.24",
"fuzzaldrin": "^2.1",
"git-utils": "^3.0.0",
@@ -103,7 +103,7 @@
"incompatible-packages": "0.21.0",
"keybinding-resolver": "0.27.0",
"link": "0.30.0",
"markdown-preview": "0.134.0",
"markdown-preview": "0.133.0",
"metrics": "0.42.0",
"notifications": "0.26.0",
"open-on-github": "0.32.0",
@@ -116,7 +116,7 @@
"styleguide": "0.43.0",
"symbols-view": "0.81.0",
"tabs": "0.64.0",
"timecop": "0.29.0",
"timecop": "0.28.0",
"tree-view": "0.154.0",
"update-package-dependencies": "0.8.0",
"welcome": "0.21.0",
@@ -125,7 +125,6 @@
"language-c": "0.38.0",
"language-clojure": "0.10.0",
"language-coffee-script": "0.39.0",
"language-csharp": "0.5.0",
"language-css": "0.27.0",
"language-gfm": "0.63.0",
"language-git": "0.10.0",
-39
Ver Arquivo
@@ -1,39 +0,0 @@
path = require 'path'
BufferedNodeProcess = require '../src/buffered-node-process'
describe "BufferedNodeProcess", ->
it "executes the script in a new process", ->
exit = jasmine.createSpy('exitCallback')
output = ''
stdout = (lines) -> output += lines
error = ''
stderr = (lines) -> error += lines
args = ['hi']
command = path.join(__dirname, 'fixtures', 'script.js')
new BufferedNodeProcess({command, args, stdout, stderr, exit})
waitsFor ->
exit.callCount is 1
runs ->
expect(output).toBe 'hi'
expect(error).toBe ''
expect(args).toEqual ['hi']
it "suppresses deprecations in the new process", ->
exit = jasmine.createSpy('exitCallback')
output = ''
stdout = (lines) -> output += lines
error = ''
stderr = (lines) -> error += lines
command = path.join(__dirname, 'fixtures', 'script-with-deprecations.js')
new BufferedNodeProcess({command, stdout, stderr, exit})
waitsFor ->
exit.callCount is 1
runs ->
expect(output).toBe 'hi'
expect(error).toBe ''
-17
Ver Arquivo
@@ -666,23 +666,6 @@ describe "Config", ->
foo:
bar: 'coffee'
describe "when an error is thrown writing the file to disk", ->
addErrorHandler = null
beforeEach ->
atom.notifications.onDidAddNotification addErrorHandler = jasmine.createSpy()
it "creates a notification", ->
jasmine.unspy CSON, 'writeFileSync'
spyOn(CSON, 'writeFileSync').andCallFake ->
error = new Error()
error.code = 'EPERM'
error.path = atom.config.getUserConfigPath()
throw error
save = -> atom.config.save()
expect(save).not.toThrow()
expect(addErrorHandler.callCount).toBe 1
describe ".loadUserConfig()", ->
beforeEach ->
expect(fs.existsSync(atom.config.configDirPath)).toBeFalsy()
-2
Ver Arquivo
@@ -1,2 +0,0 @@
require('fs').existsSync('hi');
process.stdout.write('hi');
-1
Ver Arquivo
@@ -1 +0,0 @@
process.stdout.write(process.argv[2]);
+36
Ver Arquivo
@@ -0,0 +1,36 @@
#!/bin/bash
# This script wraps the `Atom` binary, allowing the `chromedriver` server to
# execute it with positional arguments. `chromedriver` only allows 'switches'
# to be specified when starting a browser, not positional arguments, so this
# script accepts two special switches:
#
# * `atom-path` The path to the `Atom` binary
# * `atom-args` A space-separated list of positional arguments to pass to Atom.
#
# Any other switches will be passed through to `Atom`.
atom_path=""
atom_switches=()
atom_args=()
for arg in "$@"; do
case $arg in
--atom-path=*)
atom_path="${arg#*=}"
;;
--atom-args=*)
atom_args_string="${arg#*=}"
for atom_arg in $atom_args_string; do
atom_args+=($atom_arg)
done
;;
*)
atom_switches+=($arg)
;;
esac
done
exec $atom_path "${atom_switches[@]}" "${atom_args[@]}"
+107
Ver Arquivo
@@ -0,0 +1,107 @@
# These tests are excluded by default. To run them from the command line:
#
# ATOM_INTEGRATION_TESTS_ENABLED=true apm test
return unless process.env.ATOM_INTEGRATION_TESTS_ENABLED
os = require "os"
fs = require "fs"
path = require "path"
remote = require "remote"
temp = require("temp").track()
{spawn, spawnSync} = require "child_process"
{Builder, By} = require "../../build/node_modules/selenium-webdriver"
AtomPath = remote.process.argv[0]
AtomLauncherPath = path.join(__dirname, "helpers", "atom-launcher.sh")
SocketPath = path.join(os.tmpdir(), "atom-integration-test.sock")
ChromeDriverPort = 9515
describe "Starting Atom", ->
[chromeDriver, driver, tempDirPath] = []
beforeEach ->
tempDirPath = temp.mkdirSync("empty-dir")
waitsFor "chromedriver to start", (done) ->
chromeDriver = spawn "chromedriver", ["--verbose", "--port=#{ChromeDriverPort}"]
chromeDriver.on "error", (error) ->
throw new Error("chromedriver failed to start: #{error.message}")
chromeDriver.stdout.on "data", -> done()
afterEach ->
waitsForPromise -> driver.quit().thenFinally(-> chromeDriver.kill())
startAtom = (args...) ->
driver = new Builder()
.usingServer("http://localhost:#{ChromeDriverPort}")
.withCapabilities(
chromeOptions:
binary: AtomLauncherPath
args: [
"atom-path=#{AtomPath}"
"atom-args=#{args.join(" ")}"
"dev"
"safe"
"user-data-dir=#{temp.mkdirSync('integration-spec-')}"
"socket-path=#{SocketPath}"
]
)
.forBrowser('atom')
.build()
waitsForPromise ->
driver.wait ->
driver.getTitle().then (title) -> title.indexOf("Atom") >= 0
startAnotherAtom = (args...) ->
spawnSync(AtomPath, args.concat([
"--dev",
"--safe",
"--socket-path=#{SocketPath}"
]))
describe "when given the name of a file that doesn't exist", ->
tempFilePath = null
beforeEach ->
tempFilePath = path.join(tempDirPath, "an-existing-file")
fs.writeFileSync(tempFilePath, "This was already here.")
startAtom(path.join(tempDirPath, "new-file"))
it "opens a new window with an empty text editor", ->
waitsForPromise ->
driver.getAllWindowHandles().then (handles) ->
expect(handles.length).toBe 1
driver.executeScript(-> atom.workspace.getActivePane().getItems().length).then (length) ->
expect(length).toBe 1
driver.executeScript(-> atom.workspace.getActiveTextEditor().getText()).then (text) ->
expect(text).toBe("")
driver.findElement(By.tagName("atom-text-editor")).sendKeys("Hello world!")
driver.executeScript(-> atom.workspace.getActiveTextEditor().getText()).then (text) ->
expect(text).toBe "Hello world!"
# Opening another existing file in the same directory reuses the window,
# and opens a new tab for the file.
waitsForPromise ->
startAnotherAtom(tempFilePath)
driver.wait ->
driver.executeScript(-> atom.workspace.getActivePane().getItems().length).then (length) ->
length is 2
driver.executeScript(-> atom.workspace.getActiveTextEditor().getText()).then (text) ->
expect(text).toBe "This was already here."
# Opening a different directory creates a new window.
waitsForPromise ->
startAnotherAtom(temp.mkdirSync("another-empty-dir"))
driver.wait ->
driver.getAllWindowHandles().then (handles) ->
handles.length is 2
describe "when given the name of a directory that exists", ->
beforeEach ->
startAtom(tempDirPath)
it "opens a new window no text editors open", ->
waitsForPromise ->
driver.executeScript(-> atom.workspace.getActiveTextEditor()).then (editor) ->
expect(editor).toBeNull()
-38
Ver Arquivo
@@ -383,25 +383,6 @@ describe "Pane", ->
pane.saveActiveItem()
expect(atom.showSaveDialogSync).not.toHaveBeenCalled()
describe "when the item's saveAs method throws a well-known IO error", ->
notificationSpy = null
beforeEach ->
atom.notifications.onDidAddNotification notificationSpy = jasmine.createSpy()
it "creates a notification", ->
pane.getActiveItem().saveAs = ->
error = new Error("EACCES, permission denied '/foo'")
error.path = '/foo'
error.code = 'EACCES'
throw error
pane.saveActiveItem()
expect(notificationSpy).toHaveBeenCalled()
notification = notificationSpy.mostRecentCall.args[0]
expect(notification.getType()).toBe 'warning'
expect(notification.getMessage()).toContain 'Permission denied'
expect(notification.getMessage()).toContain '/foo'
describe "::saveActiveItemAs()", ->
pane = null
@@ -423,25 +404,6 @@ describe "Pane", ->
pane.saveActiveItemAs()
expect(atom.showSaveDialogSync).not.toHaveBeenCalled()
describe "when the item's saveAs method throws a well-known IO error", ->
notificationSpy = null
beforeEach ->
atom.notifications.onDidAddNotification notificationSpy = jasmine.createSpy()
it "creates a notification", ->
pane.getActiveItem().saveAs = ->
error = new Error("EACCES, permission denied '/foo'")
error.path = '/foo'
error.code = 'EACCES'
throw error
pane.saveActiveItemAs()
expect(notificationSpy).toHaveBeenCalled()
notification = notificationSpy.mostRecentCall.args[0]
expect(notification.getType()).toBe 'warning'
expect(notification.getMessage()).toContain 'Permission denied'
expect(notification.getMessage()).toContain '/foo'
describe "::itemForURI(uri)", ->
it "returns the item for which a call to .getURI() returns the given uri", ->
pane = new Pane(items: [new Item("A"), new Item("B"), new Item("C"), new Item("D")])
+2 -2
Ver Arquivo
@@ -305,13 +305,13 @@ window.waitsForPromise = (args...) ->
window.waitsFor timeout, (moveOn) ->
promise = fn()
if shouldReject
promise.catch(moveOn)
(promise.catch ? promise.thenCatch).call(promise, moveOn)
promise.then ->
jasmine.getEnv().currentSpec.fail("Expected promise to be rejected, but it was resolved")
moveOn()
else
promise.then(moveOn)
promise.catch (error) ->
(promise.catch ? promise.thenCatch).call promise, (error) ->
jasmine.getEnv().currentSpec.fail("Expected promise to be resolved, but it was rejected with #{jasmine.pp(error)}")
moveOn()
+1 -22
Ver Arquivo
@@ -1,7 +1,5 @@
{$, $$} = require '../src/space-pen-extensions'
path = require 'path'
fs = require 'fs-plus'
temp = require 'temp'
TextEditor = require '../src/text-editor'
WindowEventHandler = require '../src/window-event-handler'
@@ -56,7 +54,7 @@ describe "Window", ->
jasmine.unspy(TextEditor.prototype, "shouldPromptToSave")
beforeUnloadEvent = $.Event(new Event('beforeunload'))
describe "when pane items are modified", ->
describe "when pane items are are modified", ->
it "prompts user to save and calls atom.workspace.confirmClose", ->
editor = null
spyOn(atom.workspace, 'confirmClose').andCallThrough()
@@ -94,25 +92,6 @@ describe "Window", ->
$(window).trigger(beforeUnloadEvent)
expect(atom.confirm).toHaveBeenCalled()
describe "when the same path is modified in multiple panes", ->
it "prompts to save the item", ->
editor = null
filePath = path.join(temp.mkdirSync('atom-file'), 'file.txt')
fs.writeFileSync(filePath, 'hello')
spyOn(atom.workspace, 'confirmClose').andCallThrough()
spyOn(atom, 'confirm').andReturn(0)
waitsForPromise ->
atom.workspace.open(filePath).then (o) -> editor = o
runs ->
atom.workspace.getActivePane().splitRight(copyActiveItem: true)
editor.setText('world')
$(window).trigger(beforeUnloadEvent)
expect(atom.workspace.confirmClose).toHaveBeenCalled()
expect(atom.confirm.callCount).toBe 1
expect(fs.readFileSync(filePath, 'utf8')).toBe 'world'
describe ".unloadEditorWindow()", ->
it "saves the serialized state of the window so it can be deserialized after reload", ->
workspaceState = atom.workspace.serialize()
+7 -12
Ver Arquivo
@@ -955,14 +955,9 @@ describe "Workspace", ->
expect(editor.isModified()).toBeTruthy()
describe "::saveActivePaneItem()", ->
editor = null
beforeEach ->
waitsForPromise ->
atom.workspace.open('sample.js').then (o) -> editor = o
describe "when there is an error", ->
it "emits a warning notification when the file cannot be saved", ->
spyOn(editor, 'save').andCallFake ->
spyOn(Pane::, 'saveActiveItem').andCallFake ->
throw new Error("'/some/file' is a directory")
atom.notifications.onDidAddNotification addedSpy = jasmine.createSpy()
@@ -971,7 +966,7 @@ describe "Workspace", ->
expect(addedSpy.mostRecentCall.args[0].getType()).toBe 'warning'
it "emits a warning notification when the directory cannot be written to", ->
spyOn(editor, 'save').andCallFake ->
spyOn(Pane::, 'saveActiveItem').andCallFake ->
throw new Error("ENOTDIR, not a directory '/Some/dir/and-a-file.js'")
atom.notifications.onDidAddNotification addedSpy = jasmine.createSpy()
@@ -980,7 +975,7 @@ describe "Workspace", ->
expect(addedSpy.mostRecentCall.args[0].getType()).toBe 'warning'
it "emits a warning notification when the user does not have permission", ->
spyOn(editor, 'save').andCallFake ->
spyOn(Pane::, 'saveActiveItem').andCallFake ->
error = new Error("EACCES, permission denied '/Some/dir/and-a-file.js'")
error.code = 'EACCES'
error.path = '/Some/dir/and-a-file.js'
@@ -992,14 +987,14 @@ describe "Workspace", ->
expect(addedSpy.mostRecentCall.args[0].getType()).toBe 'warning'
it "emits a warning notification when the operation is not permitted", ->
spyOn(editor, 'save').andCallFake ->
spyOn(Pane::, 'saveActiveItem').andCallFake ->
error = new Error("EPERM, operation not permitted '/Some/dir/and-a-file.js'")
error.code = 'EPERM'
error.path = '/Some/dir/and-a-file.js'
throw error
it "emits a warning notification when the file is already open by another app", ->
spyOn(editor, 'save').andCallFake ->
spyOn(Pane::, 'saveActiveItem').andCallFake ->
error = new Error("EBUSY, resource busy or locked '/Some/dir/and-a-file.js'")
error.code = 'EBUSY'
error.path = '/Some/dir/and-a-file.js'
@@ -1014,7 +1009,7 @@ describe "Workspace", ->
expect(notificaiton.getMessage()).toContain 'Unable to save'
it "emits a warning notification when the file system is read-only", ->
spyOn(editor, 'save').andCallFake ->
spyOn(Pane::, 'saveActiveItem').andCallFake ->
error = new Error("EROFS, read-only file system '/Some/dir/and-a-file.js'")
error.code = 'EROFS'
error.path = '/Some/dir/and-a-file.js'
@@ -1029,7 +1024,7 @@ describe "Workspace", ->
expect(notification.getMessage()).toContain 'Unable to save'
it "emits a warning notification when the file cannot be saved", ->
spyOn(editor, 'save').andCallFake ->
spyOn(Pane::, 'saveActiveItem').andCallFake ->
throw new Error("no one knows")
save = -> atom.workspace.saveActivePaneItem()
+12 -9
Ver Arquivo
@@ -5,7 +5,7 @@ AutoUpdateManager = require './auto-update-manager'
BrowserWindow = require 'browser-window'
Menu = require 'menu'
app = require 'app'
fs = require 'fs-plus'
fs = require 'fs'
ipc = require 'ipc'
path = require 'path'
os = require 'os'
@@ -14,7 +14,7 @@ url = require 'url'
{EventEmitter} = require 'events'
_ = require 'underscore-plus'
socketPath =
DefaultSocketPath =
if process.platform is 'win32'
'\\\\.\\pipe\\atom-sock'
else
@@ -31,17 +31,20 @@ class AtomApplication
# Public: The entry point into the Atom application.
@open: (options) ->
options.socketPath ?= DefaultSocketPath
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 socketPath) or options.test
if (process.platform isnt 'win32' and not fs.existsSync options.socketPath) or options.test
createAtomApplication()
return
client = net.connect {path: socketPath}, ->
client = net.connect {path: options.socketPath}, ->
client.write JSON.stringify(options), ->
client.end()
app.terminate()
@@ -57,7 +60,7 @@ class AtomApplication
exit: (status) -> app.exit(status)
constructor: (options) ->
{@resourcePath, @version, @devMode, @safeMode} = options
{@resourcePath, @version, @devMode, @safeMode, @socketPath} = options
# Normalize to make sure drive letter case is consistent on Windows
@resourcePath = path.normalize(@resourcePath) if @resourcePath
@@ -119,15 +122,15 @@ class AtomApplication
connection.on 'data', (data) =>
@openWithOptions(JSON.parse(data))
server.listen socketPath
server.listen @socketPath
server.on 'error', (error) -> console.error 'Application server failed', error
deleteSocketFile: ->
return if process.platform is 'win32'
if fs.existsSync(socketPath)
if fs.existsSync(@socketPath)
try
fs.unlinkSync(socketPath)
fs.unlinkSync(@socketPath)
catch error
# Ignore ENOENT errors in case the file was deleted between the exists
# check and the call to unlink sync. This occurred occasionally on CI
@@ -342,7 +345,6 @@ class AtomApplication
# :window - {AtomWindow} to open file paths in.
openPath: ({pathToOpen, pidToKillWhenClosed, newWindow, devMode, safeMode, windowDimensions, window}={}) ->
{pathToOpen, initialLine, initialColumn} = @locationForPathToOpen(pathToOpen)
pathToOpen = fs.normalize(pathToOpen)
unless pidToKillWhenClosed or newWindow
pathToOpenStat = fs.statSyncNoException(pathToOpen)
@@ -415,6 +417,7 @@ class AtomApplication
openUrl: ({urlToOpen, devMode, safeMode}) ->
unless @packages?
PackageManager = require '../package-manager'
fs = require 'fs-plus'
@packages = new PackageManager
configDirPath: process.env.ATOM_HOME
devMode: devMode
+11 -6
Ver Arquivo
@@ -2,7 +2,7 @@ global.shellStartTime = Date.now()
crashReporter = require 'crash-reporter'
app = require 'app'
fs = require 'fs-plus'
fs = require 'fs'
path = require 'path'
optimist = require 'optimist'
nslog = require 'nslog'
@@ -43,11 +43,10 @@ start = ->
cwd = args.executedFrom?.toString() or process.cwd()
args.pathsToOpen = args.pathsToOpen.map (pathToOpen) ->
pathToOpen = fs.normalize(pathToOpen)
if cwd
path.resolve(cwd, pathToOpen)
path.resolve(cwd, pathToOpen.toString())
else
path.resolve(pathToOpen)
path.resolve(pathToOpen.toString())
setupCoffeeScript()
if args.devMode
@@ -78,7 +77,11 @@ setupCoffeeScript = ->
setupAtomHome = ->
return if process.env.ATOM_HOME
atomHome = path.join(app.getHomeDir(), '.atom')
if process.platform is 'win32'
home = process.env.USERPROFILE
else
home = process.env.HOME
atomHome = path.join(home, '.atom')
try
atomHome = fs.realpathSync(atomHome)
process.env.ATOM_HOME = atomHome
@@ -117,6 +120,7 @@ parseCommandLine = ->
options.alias('t', 'test').boolean('t').describe('t', 'Run the specified specs and exit with error code on failures.')
options.alias('v', 'version').boolean('v').describe('v', 'Print the version.')
options.alias('w', 'wait').boolean('w').describe('w', 'Wait for window to be closed before returning.')
options.string('socket-path')
args = options.argv
if args.help
@@ -137,6 +141,7 @@ parseCommandLine = ->
newWindow = args['new-window']
pidToKillWhenClosed = args['pid'] if args['wait']
logFile = args['log-file']
socketPath = args['socket-path']
if args['resource-path']
devMode = true
@@ -161,6 +166,6 @@ parseCommandLine = ->
# explicitly pass it by command line, see http://git.io/YC8_Ew.
process.env.PATH = args['path-environment'] if args['path-environment']
{resourcePath, pathsToOpen, executedFrom, test, version, pidToKillWhenClosed, devMode, safeMode, newWindow, specDirectory, logFile}
{resourcePath, pathsToOpen, executedFrom, test, version, pidToKillWhenClosed, devMode, safeMode, newWindow, specDirectory, logFile, socketPath}
start()
-3
Ver Arquivo
@@ -48,8 +48,5 @@ class BufferedNodeProcess extends BufferedProcess
options.env ?= Object.create(process.env)
options.env['ATOM_SHELL_INTERNAL_RUN_AS_NODE'] = 1
args = args?.slice() ? []
args.unshift(command)
args.unshift('--no-deprecation')
super({command: node, args, options, stdout, stderr, exit})
+1 -6
Ver Arquivo
@@ -868,12 +868,7 @@ class Config
save: ->
allSettings = {'*': @settings}
allSettings = _.extend allSettings, @scopedSettingsStore.propertiesForSource(@getUserConfigPath())
try
CSON.writeFileSync(@configFilePath, allSettings)
catch error
message = "Failed to save `#{path.basename(@configFilePath)}`"
detail = error.message
@notifyFailure(message, detail)
CSON.writeFileSync(@configFilePath, allSettings)
###
Section: Private methods managing global settings
+2 -2
Ver Arquivo
@@ -152,12 +152,12 @@ class PaneContainer extends Model
saveAll: ->
pane.saveItems() for pane in @getPanes()
confirmClose: (options) ->
confirmClose: ->
allSaved = true
for pane in @getPanes()
for item in pane.getItems()
unless pane.promptToSaveItem(item, options)
unless pane.promptToSaveItem(item)
allSaved = false
break
+4 -25
Ver Arquivo
@@ -437,8 +437,8 @@ class Pane extends Model
destroyInactiveItems: ->
@destroyItem(item) for item in @getItems() when item isnt @activeItem
promptToSaveItem: (item, options={}) ->
return true unless item.shouldPromptToSave?(options)
promptToSaveItem: (item) ->
return true unless item.shouldPromptToSave?()
if typeof item.getURI is 'function'
uri = item.getURI()
@@ -481,10 +481,7 @@ class Pane extends Model
itemURI = item.getUri()
if itemURI?
try
item.save?()
catch error
@handleSaveError(error)
item.save?()
nextAction?()
else
@saveItemAs(item, nextAction)
@@ -501,10 +498,7 @@ class Pane extends Model
itemPath = item.getPath?()
newItemPath = atom.showSaveDialogSync(itemPath)
if newItemPath
try
item.saveAs(newItemPath)
catch error
@handleSaveError(error)
item.saveAs(newItemPath)
nextAction?()
# Public: Save all items.
@@ -673,18 +667,3 @@ class Pane extends Model
for item in @getItems()
return false unless @promptToSaveItem(item)
true
handleSaveError: (error) ->
if error.message.endsWith('is a directory')
atom.notifications.addWarning("Unable to save file: #{error.message}")
else if error.code is 'EACCES' and error.path?
atom.notifications.addWarning("Unable to save file: Permission denied '#{error.path}'")
else if error.code in ['EPERM', 'EBUSY', 'UNKNOWN'] and error.path?
atom.notifications.addWarning("Unable to save file '#{error.path}'", detail: error.message)
else if error.code is 'EROFS' and error.path?
atom.notifications.addWarning("Unable to save file: Read-only file system '#{error.path}'")
else if errorMatch = /ENOTDIR, not a directory '([^']+)'/.exec(error.message)
fileName = errorMatch[1]
atom.notifications.addWarning("Unable to save file: A directory in the path '#{fileName}' could not be written to")
else
throw error
+1 -5
Ver Arquivo
@@ -641,11 +641,7 @@ class TextEditor extends Model
# Determine whether the user should be prompted to save before closing
# this editor.
shouldPromptToSave: ({windowCloseRequested}={}) ->
if windowCloseRequested
@isModified()
else
@isModified() and not @buffer.hasMultipleEditors()
shouldPromptToSave: -> @isModified() and not @buffer.hasMultipleEditors()
###
Section: Reading Text
+1 -1
Ver Arquivo
@@ -52,7 +52,7 @@ class WindowEventHandler
@subscribe $(window), 'blur', -> document.body.classList.add('is-blurred')
@subscribe $(window), 'beforeunload', =>
confirmed = atom.workspace?.confirmClose(windowCloseRequested: true)
confirmed = atom.workspace?.confirmClose()
atom.hide() if confirmed and not @reloadRequested and atom.getCurrentWindow().isWebViewFocused()
@reloadRequested = false
+24 -4
Ver Arquivo
@@ -599,8 +599,8 @@ class Workspace extends Model
saveAll: ->
@paneContainer.saveAll()
confirmClose: (options) ->
@paneContainer.confirmClose(options)
confirmClose: ->
@paneContainer.confirmClose()
# Save the active pane item.
#
@@ -609,7 +609,7 @@ class Workspace extends Model
# {::saveActivePaneItemAs} # will be called instead. This method does nothing
# if the active item does not implement a `.save` method.
saveActivePaneItem: ->
@getActivePane().saveActiveItem()
@saveActivePaneItemAndReportErrors('saveActiveItem')
# Prompt the user for a path and save the active pane item to it.
#
@@ -617,7 +617,27 @@ class Workspace extends Model
# `.saveAs` on the item with the selected path. This method does nothing if
# the active item does not implement a `.saveAs` method.
saveActivePaneItemAs: ->
@getActivePane().saveActiveItemAs()
@saveActivePaneItemAndReportErrors('saveActiveItemAs')
saveActivePaneItemAndReportErrors: (method) ->
try
@getActivePane()[method]()
catch error
if error.message.endsWith('is a directory')
atom.notifications.addWarning("Unable to save file: #{error.message}")
else if error.code is 'EACCES' and error.path?
atom.notifications.addWarning("Unable to save file: Permission denied '#{error.path}'")
else if error.code is 'EPERM' and error.path?
atom.notifications.addWarning("Unable to save file '#{error.path}'", detail: error.message)
else if error.code is 'EBUSY' and error.path?
atom.notifications.addWarning("Unable to save file '#{error.path}'", detail: error.message)
else if error.code is 'EROFS' and error.path?
atom.notifications.addWarning("Unable to save file: Read-only file system '#{error.path}'")
else if errorMatch = /ENOTDIR, not a directory '([^']+)'/.exec(error.message)
fileName = errorMatch[1]
atom.notifications.addWarning("Unable to save file: A directory in the path '#{fileName}' could not be written to")
else
throw error
# Destroy (close) the active pane item.
#
-17
Ver Arquivo
@@ -13,23 +13,6 @@ window.onload = function() {
var fs = require('fs');
var path = require('path');
// Ensure ATOM_HOME is always set before anything else is required
if (!process.env.ATOM_HOME) {
var home;
if (process.platform === 'win32') {
home = process.env.USERPROFILE;
} else {
home = process.env.HOME;
}
var atomHome = path.join(home, '.atom');
try {
atomHome = fs.realpathSync(atomHome);
} catch (error) {
// Ignore since the path might just not exist yet.
}
process.env.ATOM_HOME = atomHome;
}
// Skip "?loadSettings=".
var rawLoadSettings = decodeURIComponent(location.search.substr(14));
var loadSettings;