Merge branch 'master' into ns-use-display-layers

This commit is contained in:
Antonio Scandurra
2016-03-22 12:01:07 +01:00
16 changed files with 423 additions and 81 deletions

View File

@@ -6,6 +6,6 @@
"url": "https://github.com/atom/atom.git"
},
"dependencies": {
"atom-package-manager": "1.7.1"
"atom-package-manager": "1.9.1"
}
}

View File

@@ -1,7 +1,7 @@
{
"name": "atom",
"productName": "Atom",
"version": "1.7.0-dev",
"version": "1.8.0-dev",
"description": "A hackable text editor for the 21st Century.",
"main": "./src/browser/main.js",
"repository": {
@@ -72,7 +72,7 @@
"one-light-syntax": "1.2.0",
"solarized-dark-syntax": "1.0.0",
"solarized-light-syntax": "1.0.0",
"about": "1.4.0",
"about": "1.4.2",
"archive-view": "0.61.1",
"autocomplete-atom-api": "0.10.0",
"autocomplete-css": "0.11.0",
@@ -91,36 +91,36 @@
"exception-reporting": "0.37.0",
"find-and-replace": "0.197.4",
"fuzzy-finder": "1.0.3",
"git-diff": "1.0.0",
"git-diff": "1.0.1",
"go-to-line": "0.30.0",
"grammar-selector": "0.48.1",
"image-view": "0.57.0",
"incompatible-packages": "0.25.1",
"incompatible-packages": "0.26.1",
"keybinding-resolver": "0.35.0",
"line-ending-selector": "0.3.1",
"link": "0.31.0",
"markdown-preview": "0.157.3",
"line-ending-selector": "0.4.1",
"link": "0.31.1",
"markdown-preview": "0.158.0",
"metrics": "0.53.1",
"notifications": "0.62.3",
"open-on-github": "1.0.0",
"package-generator": "0.41.1",
"settings-view": "0.232.4",
"notifications": "0.63.1",
"open-on-github": "1.0.1",
"package-generator": "1.0.0",
"settings-view": "0.235.1",
"snippets": "1.0.1",
"spell-check": "0.67.0",
"status-bar": "1.1.0",
"status-bar": "1.2.0",
"styleguide": "0.45.2",
"symbols-view": "0.112.0",
"tabs": "0.91.3",
"tabs": "0.92.0",
"timecop": "0.33.1",
"tree-view": "0.203.0",
"tree-view": "0.203.2",
"update-package-dependencies": "0.10.0",
"welcome": "0.34.0",
"whitespace": "0.32.2",
"wrap-guide": "0.38.1",
"language-c": "0.51.1",
"language-clojure": "0.19.1",
"language-clojure": "0.20.0",
"language-coffee-script": "0.46.1",
"language-csharp": "0.11.0",
"language-csharp": "0.12.0",
"language-css": "0.36.0",
"language-gfm": "0.85.0",
"language-git": "0.12.1",
@@ -129,7 +129,7 @@
"language-hyperlink": "0.16.0",
"language-java": "0.17.0",
"language-javascript": "0.110.0",
"language-json": "0.17.5",
"language-json": "0.17.6",
"language-less": "0.29.0",
"language-make": "0.21.0",
"language-mustache": "0.13.0",
@@ -138,9 +138,9 @@
"language-php": "0.37.0",
"language-property-list": "0.8.0",
"language-python": "0.43.0",
"language-ruby": "0.68.1",
"language-ruby": "0.68.3",
"language-ruby-on-rails": "0.25.0",
"language-sass": "0.45.0",
"language-sass": "0.46.0",
"language-shellscript": "0.21.0",
"language-source": "0.9.0",
"language-sql": "0.20.0",

View File

@@ -97,7 +97,7 @@ describe "BufferedProcess", ->
expect(ChildProcess.spawn.argsForCall[0][1][1]).toBe '/c'
expect(ChildProcess.spawn.argsForCall[0][1][2]).toBe '"dir"'
it "calls the specified stdout, stderr, and exit callbacks ", ->
it "calls the specified stdout, stderr, and exit callbacks", ->
stdout = ''
stderr = ''
exitCallback = jasmine.createSpy('exit callback')
@@ -114,3 +114,30 @@ describe "BufferedProcess", ->
runs ->
expect(stderr).toContain 'apm - Atom Package Manager'
expect(stdout).toEqual ''
it "calls the specified stdout callback only with whole lines", ->
exitCallback = jasmine.createSpy('exit callback')
baseContent = "There are dozens of us! Dozens! It's as Ann as the nose on Plain's face. Can you believe that the only reason the club is going under is because it's in a terrifying neighborhood? She calls it a Mayonegg. Waiting for the Emmys. BTW did you know won 6 Emmys and was still canceled early by Fox? COME ON. I'll buy you a hundred George Michaels that you can teach to drive! Never once touched my per diem. I'd go to Craft Service, get some raw veggies, bacon, Cup-A-Soup…baby, I got a stew goin'"
content = (baseContent for _ in [1..200]).join('\n')
stdout = ''
endLength = 10
outputAlwaysEndsWithStew = true
process = new BufferedProcess
command: '/bin/echo'
args: [content]
options: {}
stdout: (lines) ->
stdout += lines
end = baseContent.substr(baseContent.length - endLength, endLength)
lineEndsWithStew = lines.substr(lines.length - endLength, endLength) is end
expect(lineEndsWithStew).toBeTrue
outputAlwaysEndsWithStew = outputAlwaysEndsWithStew and lineEndsWithStew
exit: exitCallback
waitsFor -> exitCallback.callCount is 1
runs ->
expect(outputAlwaysEndsWithStew).toBeTrue
expect(stdout).toBe content += '\n'

View File

@@ -0,0 +1,160 @@
'use babel'
/* eslint-env jasmine */
import child_process from 'child_process'
import environmentHelpers from '../src/environment-helpers'
import os from 'os'
describe('Environment handling', () => {
let originalEnv
let options
beforeEach(() => {
originalEnv = process.env
delete process._originalEnv
options = {
platform: process.platform,
env: Object.assign({}, process.env)
}
})
afterEach(() => {
process.env = originalEnv
delete process._originalEnv
})
describe('on OSX, when PWD is not set', () => {
beforeEach(() => {
options.platform = 'darwin'
})
describe('needsPatching', () => {
it('returns true if PWD is unset', () => {
delete options.env.PWD
expect(environmentHelpers.needsPatching(options)).toBe(true)
options.env.PWD = undefined
expect(environmentHelpers.needsPatching(options)).toBe(true)
options.env.PWD = null
expect(environmentHelpers.needsPatching(options)).toBe(true)
options.env.PWD = false
expect(environmentHelpers.needsPatching(options)).toBe(true)
})
it('returns false if PWD is set', () => {
options.env.PWD = 'xterm'
expect(environmentHelpers.needsPatching(options)).toBe(false)
})
})
describe('normalize', () => {
it('changes process.env if PWD is unset', () => {
if (process.platform === 'win32') {
return
}
delete options.env.PWD
environmentHelpers.normalize(options)
expect(process._originalEnv).toBeDefined()
expect(process._originalEnv).toBeTruthy()
expect(process.env).toBeDefined()
expect(process.env).toBeTruthy()
expect(process.env.PWD).toBeDefined()
expect(process.env.PWD).toBeTruthy()
expect(process.env.PATH).toBeDefined()
expect(process.env.PATH).toBeTruthy()
expect(process.env.ATOM_HOME).toBeDefined()
expect(process.env.ATOM_HOME).toBeTruthy()
})
})
})
describe('on a platform other than OSX', () => {
beforeEach(() => {
options.platform = 'penguin'
})
describe('needsPatching', () => {
it('returns false if PWD is set or unset', () => {
delete options.env.PWD
expect(environmentHelpers.needsPatching(options)).toBe(false)
options.env.PWD = undefined
expect(environmentHelpers.needsPatching(options)).toBe(false)
options.env.PWD = null
expect(environmentHelpers.needsPatching(options)).toBe(false)
options.env.PWD = false
expect(environmentHelpers.needsPatching(options)).toBe(false)
options.env.PWD = '/'
expect(environmentHelpers.needsPatching(options)).toBe(false)
})
it('returns false for linux', () => {
options.platform = 'linux'
options.PWD = '/'
expect(environmentHelpers.needsPatching(options)).toBe(false)
})
it('returns false for windows', () => {
options.platform = 'win32'
options.PWD = 'c:\\'
expect(environmentHelpers.needsPatching(options)).toBe(false)
})
})
describe('normalize', () => {
it('does not change the environment', () => {
if (process.platform === 'win32') {
return
}
delete options.env.PWD
environmentHelpers.normalize(options)
expect(process._originalEnv).toBeUndefined()
expect(process.env).toBeDefined()
expect(process.env).toBeTruthy()
expect(process.env.PATH).toBeDefined()
expect(process.env.PATH).toBeTruthy()
expect(process.env.PWD).toBeUndefined()
expect(process.env.PATH).toBe(originalEnv.PATH)
expect(process.env.ATOM_HOME).toBeDefined()
expect(process.env.ATOM_HOME).toBeTruthy()
})
})
})
describe('getFromShell', () => {
describe('when things are configured properly', () => {
beforeEach(() => {
spyOn(child_process, 'spawnSync').andReturn({
stdout: 'FOO=BAR' + os.EOL + 'TERM=xterm-something' + os.EOL +
'PATH=/usr/bin:/bin:/usr/sbin:/sbin:/crazy/path'
})
})
it('returns an object containing the information from the user\'s shell environment', () => {
let env = environmentHelpers.getFromShell()
expect(env.FOO).toEqual('BAR')
expect(env.TERM).toEqual('xterm-something')
expect(env.PATH).toEqual('/usr/bin:/bin:/usr/sbin:/sbin:/crazy/path')
})
})
describe('when an error occurs launching the shell', () => {
beforeEach(() => {
spyOn(child_process, 'spawnSync').andReturn({
error: new Error('testing when an error occurs')
})
})
it('returns undefined', () => {
expect(environmentHelpers.getFromShell()).toBeUndefined()
})
it('leaves the environment as-is when normalize() is called', () => {
options.platform = 'darwin'
delete options.env.PWD
expect(environmentHelpers.needsPatching(options)).toBe(true)
environmentHelpers.normalize(options)
expect(process.env).toBeDefined()
expect(process._originalEnv).toBeUndefined()
})
})
})
})

View File

@@ -17,6 +17,20 @@ describe "PackageManager", ->
beforeEach ->
workspaceElement = atom.views.getView(atom.workspace)
describe "::getApmPath()", ->
it "returns the path to the apm command", ->
apmPath = path.join(process.resourcesPath, "app", "apm", "bin", "apm")
if process.platform is 'win32'
apmPath += ".cmd"
expect(atom.packages.getApmPath()).toBe apmPath
describe "when the core.apmPath setting is set", ->
beforeEach ->
atom.config.set("core.apmPath", "/path/to/apm")
it "returns the value of the core.apmPath config setting", ->
expect(atom.packages.getApmPath()).toBe "/path/to/apm"
describe "::loadPackage(name)", ->
beforeEach ->
atom.config.set("core.disabledPackages", [])

View File

@@ -5,25 +5,25 @@ path = require 'path'
temp = require 'temp'
SquirrelUpdate = require '../src/browser/squirrel-update'
describe "Windows squirrel updates", ->
describe "Windows Squirrel Update", ->
tempHomeDirectory = null
originalSpawn = ChildProcess.spawn
harmlessSpawn = ->
# Just spawn something that won't actually modify the host
if process.platform is 'win32'
originalSpawn('dir')
else
originalSpawn('ls')
beforeEach ->
# Prevent the actually home directory from being manipulated
# Prevent the actual home directory from being manipulated
tempHomeDirectory = temp.mkdirSync('atom-temp-home-')
spyOn(fs, 'getHomeDirectory').andReturn(tempHomeDirectory)
# Prevent any commands from actually running and affecting the host
originalSpawn = ChildProcess.spawn
spyOn(ChildProcess, 'spawn').andCallFake (command, args) ->
if path.basename(command) is 'Update.exe' and args?[0] is '--createShortcut'
fs.writeFileSync(path.join(tempHomeDirectory, 'Desktop', 'Atom.lnk'), '')
# Just spawn something that won't actually modify the host
if process.platform is 'win32'
originalSpawn('dir')
else
originalSpawn('ls')
harmlessSpawn()
it "ignores errors spawning Squirrel", ->
jasmine.unspy(ChildProcess, 'spawn')
@@ -67,28 +67,55 @@ describe "Windows squirrel updates", ->
runs ->
expect(SquirrelUpdate.handleStartupEvent(app, '--not-squirrel')).toBe false
it "keeps the desktop shortcut deleted on updates if it was previously deleted after install", ->
desktopShortcutPath = path.join(tempHomeDirectory, 'Desktop', 'Atom.lnk')
expect(fs.existsSync(desktopShortcutPath)).toBe false
app = quit: jasmine.createSpy('quit')
expect(SquirrelUpdate.handleStartupEvent(app, '--squirrel-install')).toBe true
waitsFor ->
app.quit.callCount is 1
runs ->
app.quit.reset()
expect(fs.existsSync(desktopShortcutPath)).toBe true
fs.removeSync(desktopShortcutPath)
expect(fs.existsSync(desktopShortcutPath)).toBe false
expect(SquirrelUpdate.handleStartupEvent(app, '--squirrel-updated')).toBe true
waitsFor ->
app.quit.callCount is 1
runs ->
describe "Desktop shortcut", ->
desktopShortcutPath = '/non/existing/path'
beforeEach ->
desktopShortcutPath = path.join(tempHomeDirectory, 'Desktop', 'Atom.lnk')
jasmine.unspy(ChildProcess, 'spawn')
spyOn(ChildProcess, 'spawn').andCallFake (command, args) ->
if path.basename(command) is 'Update.exe' and args?[0] is '--createShortcut'
fs.writeFileSync(path.join(tempHomeDirectory, 'Desktop', 'Atom.lnk'), '')
harmlessSpawn()
else
throw new Error("API not mocked")
it "does not exist before install", ->
expect(fs.existsSync(desktopShortcutPath)).toBe false
describe "on install", ->
beforeEach ->
app = quit: jasmine.createSpy('quit')
SquirrelUpdate.handleStartupEvent(app, '--squirrel-install')
waitsFor ->
app.quit.callCount is 1
it "creates desktop shortcut", ->
expect(fs.existsSync(desktopShortcutPath)).toBe true
describe "when shortcut is deleted and then app is updated", ->
beforeEach ->
fs.removeSync(desktopShortcutPath)
expect(fs.existsSync(desktopShortcutPath)).toBe false
app = quit: jasmine.createSpy('quit')
SquirrelUpdate.handleStartupEvent(app, '--squirrel-updated')
waitsFor ->
app.quit.callCount is 1
it "does not recreate shortcut", ->
expect(fs.existsSync(desktopShortcutPath)).toBe false
describe "when shortcut is kept and app is updated", ->
beforeEach ->
app = quit: jasmine.createSpy('quit')
SquirrelUpdate.handleStartupEvent(app, '--squirrel-updated')
waitsFor ->
app.quit.callCount is 1
it "still has desktop shortcut", ->
expect(fs.existsSync(desktopShortcutPath)).toBe true
describe ".restartAtom", ->
it "quits the app and spawns a new one", ->

View File

@@ -624,7 +624,7 @@ describe "Workspace", ->
expect(pane.getItems()).toEqual [editor1, editor2]
describe "when replacing a pending item which is the last item in a second pane", ->
it "does not destory the pane even if core.destroyEmptyPanes is on", ->
it "does not destroy the pane even if core.destroyEmptyPanes is on", ->
atom.config.set('core.destroyEmptyPanes', true)
editor1 = null
editor2 = null

View File

@@ -85,16 +85,16 @@ class AtomApplication
else
@loadState(options) or @openPath(options)
openWithOptions: ({initialPaths, pathsToOpen, executedFrom, urlsToOpen, test, pidToKillWhenClosed, devMode, safeMode, newWindow, logFile, profileStartup, timeout, clearWindowState, addToLastWindow}) ->
openWithOptions: ({initialPaths, pathsToOpen, executedFrom, urlsToOpen, test, pidToKillWhenClosed, devMode, safeMode, newWindow, logFile, profileStartup, timeout, clearWindowState, addToLastWindow, env}) ->
if test
@runTests({headless: true, devMode, @resourcePath, executedFrom, pathsToOpen, logFile, timeout})
@runTests({headless: true, devMode, @resourcePath, executedFrom, pathsToOpen, logFile, timeout, env})
else if pathsToOpen.length > 0
@openPaths({initialPaths, pathsToOpen, executedFrom, pidToKillWhenClosed, newWindow, devMode, safeMode, profileStartup, clearWindowState, addToLastWindow})
@openPaths({initialPaths, pathsToOpen, executedFrom, pidToKillWhenClosed, newWindow, devMode, safeMode, profileStartup, clearWindowState, addToLastWindow, env})
else if urlsToOpen.length > 0
@openUrl({urlToOpen, devMode, safeMode}) for urlToOpen in urlsToOpen
@openUrl({urlToOpen, devMode, safeMode, env}) for urlToOpen in urlsToOpen
else
# Always open a editor window if this is the first instance of Atom.
@openPath({initialPaths, pidToKillWhenClosed, newWindow, devMode, safeMode, profileStartup, clearWindowState, addToLastWindow})
@openPath({initialPaths, pidToKillWhenClosed, newWindow, devMode, safeMode, profileStartup, clearWindowState, addToLastWindow, env})
# Public: Removes the {AtomWindow} from the global window list.
removeWindow: (window) ->
@@ -134,7 +134,8 @@ class AtomApplication
@deleteSocketFile()
server = net.createServer (connection) =>
connection.on 'data', (data) =>
@openWithOptions(JSON.parse(data))
options = JSON.parse(data)
@openWithOptions(options)
server.listen @socketPath
server.on 'error', (error) -> console.error 'Application server failed', error
@@ -418,8 +419,8 @@ class AtomApplication
# :profileStartup - Boolean to control creating a profile of the startup time.
# :window - {AtomWindow} to open file paths in.
# :addToLastWindow - Boolean of whether this should be opened in last focused window.
openPath: ({initialPaths, pathToOpen, pidToKillWhenClosed, newWindow, devMode, safeMode, profileStartup, window, clearWindowState, addToLastWindow} = {}) ->
@openPaths({initialPaths, pathsToOpen: [pathToOpen], pidToKillWhenClosed, newWindow, devMode, safeMode, profileStartup, window, clearWindowState, addToLastWindow})
openPath: ({initialPaths, pathToOpen, pidToKillWhenClosed, newWindow, devMode, safeMode, profileStartup, window, clearWindowState, addToLastWindow, env} = {}) ->
@openPaths({initialPaths, pathsToOpen: [pathToOpen], pidToKillWhenClosed, newWindow, devMode, safeMode, profileStartup, window, clearWindowState, addToLastWindow, env})
# Public: Opens multiple paths, in existing windows if possible.
#
@@ -432,7 +433,7 @@ class AtomApplication
# :windowDimensions - Object with height and width keys.
# :window - {AtomWindow} to open file paths in.
# :addToLastWindow - Boolean of whether this should be opened in last focused window.
openPaths: ({initialPaths, pathsToOpen, executedFrom, pidToKillWhenClosed, newWindow, devMode, safeMode, windowDimensions, profileStartup, window, clearWindowState, addToLastWindow}={}) ->
openPaths: ({initialPaths, pathsToOpen, executedFrom, pidToKillWhenClosed, newWindow, devMode, safeMode, windowDimensions, profileStartup, window, clearWindowState, addToLastWindow, env}={}) ->
devMode = Boolean(devMode)
safeMode = Boolean(safeMode)
clearWindowState = Boolean(clearWindowState)
@@ -469,7 +470,7 @@ class AtomApplication
windowInitializationScript ?= require.resolve('../initialize-application-window')
resourcePath ?= @resourcePath
windowDimensions ?= @getDimensionsForNewWindow()
openedWindow = new AtomWindow({initialPaths, locationsToOpen, windowInitializationScript, resourcePath, devMode, safeMode, windowDimensions, profileStartup, clearWindowState})
openedWindow = new AtomWindow({initialPaths, locationsToOpen, windowInitializationScript, resourcePath, devMode, safeMode, windowDimensions, profileStartup, clearWindowState, env})
if pidToKillWhenClosed?
@pidsToOpenWindows[pidToKillWhenClosed] = openedWindow
@@ -532,7 +533,7 @@ class AtomApplication
# :urlToOpen - The atom:// url to open.
# :devMode - Boolean to control the opened window's dev mode.
# :safeMode - Boolean to control the opened window's safe mode.
openUrl: ({urlToOpen, devMode, safeMode}) ->
openUrl: ({urlToOpen, devMode, safeMode, env}) ->
unless @packages?
PackageManager = require '../package-manager'
@packages = new PackageManager
@@ -547,7 +548,7 @@ class AtomApplication
packagePath = @packages.resolvePackagePath(packageName)
windowInitializationScript = path.resolve(packagePath, pack.urlMain)
windowDimensions = @getDimensionsForNewWindow()
new AtomWindow({windowInitializationScript, @resourcePath, devMode, safeMode, urlToOpen, windowDimensions})
new AtomWindow({windowInitializationScript, @resourcePath, devMode, safeMode, urlToOpen, windowDimensions, env})
else
console.log "Package '#{pack.name}' does not have a url main: #{urlToOpen}"
else
@@ -562,7 +563,7 @@ class AtomApplication
# :specPath - The directory to load specs from.
# :safeMode - A Boolean that, if true, won't run specs from ~/.atom/packages
# and ~/.atom/dev/packages, defaults to false.
runTests: ({headless, resourcePath, executedFrom, pathsToOpen, logFile, safeMode, timeout}) ->
runTests: ({headless, resourcePath, executedFrom, pathsToOpen, logFile, safeMode, timeout, env}) ->
if resourcePath isnt @resourcePath and not fs.existsSync(resourcePath)
resourcePath = @resourcePath
@@ -592,7 +593,7 @@ class AtomApplication
devMode = true
isSpec = true
safeMode ?= false
new AtomWindow({windowInitializationScript, resourcePath, headless, isSpec, devMode, testRunnerPath, legacyTestRunnerPath, testPaths, logFile, safeMode})
new AtomWindow({windowInitializationScript, resourcePath, headless, isSpec, devMode, testRunnerPath, legacyTestRunnerPath, testPaths, logFile, safeMode, env})
resolveTestRunnerPath: (testPath) ->
FindParentDir ?= require 'find-parent-dir'

View File

@@ -13,6 +13,7 @@ console.log = require 'nslog'
start = ->
args = parseCommandLine()
args.env = process.env
setupAtomHome(args)
setupCompileCache()
return if handleStartupEventWithSquirrel()

View File

@@ -111,11 +111,13 @@ class BufferedProcess
stream.on 'data', (data) =>
return if @killed
bufferedLength = buffered.length
buffered += data
lastNewlineIndex = buffered.lastIndexOf('\n')
lastNewlineIndex = data.lastIndexOf('\n')
if lastNewlineIndex isnt -1
onLines(buffered.substring(0, lastNewlineIndex + 1))
buffered = buffered.substring(lastNewlineIndex + 1)
lineLength = lastNewlineIndex + bufferedLength + 1
onLines(buffered.substring(0, lineLength))
buffered = buffered.substring(lineLength)
stream.on 'close', =>
return if @killed

View File

@@ -0,0 +1,94 @@
'use babel'
import {spawnSync} from 'child_process'
import os from 'os'
// Gets a dump of the user's configured shell environment.
//
// Returns the output of the `env` command or `undefined` if there was an error.
function getRawShellEnv () {
let shell = getUserShell()
// The `-ilc` set of options was tested to work with the OS X v10.11
// default-installed versions of bash, zsh, sh, and ksh. It *does not*
// work with csh or tcsh.
let results = spawnSync(shell, ['-ilc', 'env'], {encoding: 'utf8'})
if (results.error || !results.stdout || results.stdout.length <= 0) {
return
}
return results.stdout
}
function getUserShell () {
if (process.env.SHELL) {
return process.env.SHELL
}
return '/bin/bash'
}
// Gets the user's configured shell environment.
//
// Returns a copy of the user's shell enviroment.
function getFromShell () {
let shellEnvText = getRawShellEnv()
if (!shellEnvText) {
return
}
let env = {}
for (let line of shellEnvText.split(os.EOL)) {
if (line.includes('=')) {
let components = line.split('=')
if (components.length === 2) {
env[components[0]] = components[1]
} else {
let k = components.shift()
let v = components.join('=')
env[k] = v
}
}
}
return env
}
function needsPatching (options = { platform: process.platform, env: process.env }) {
if (options.platform === 'darwin' && !options.env.PWD) {
let shell = getUserShell()
if (shell.endsWith('csh') || shell.endsWith('tcsh')) {
return false
}
return true
}
return false
}
function normalize (options = {}) {
if (options && options.env) {
process.env = options.env
}
if (!options.env) {
options.env = process.env
}
if (!options.platform) {
options.platform = process.platform
}
if (needsPatching(options)) {
// Patch the `process.env` on startup to fix the problem first documented
// in #4126. Retain the original in case someone needs it.
let shellEnv = getFromShell()
if (shellEnv && shellEnv.PATH) {
process._originalEnv = process.env
process.env = shellEnv
}
}
}
export default { getFromShell, needsPatching, normalize }

View File

@@ -15,6 +15,12 @@ const submoduleMode = 57344 // TODO: compose this from libgit2 constants
// Just using this for _.isEqual and _.object, we should impl our own here
import _ from 'underscore-plus'
// For the most part, this class behaves the same as `GitRepository`, with a few
// notable differences:
// * Errors are generally propagated out to the caller instead of being
// swallowed within `GitRepositoryAsync`.
// * Methods accepting a path shouldn't be given a null path, unless it is
// specifically allowed as noted in the method's documentation.
export default class GitRepositoryAsync {
static open (path, options = {}) {
// QUESTION: Should this wrap Git.Repository and reject with a nicer message?
@@ -152,8 +158,7 @@ export default class GitRepositoryAsync {
if (!this.projectAtRoot) {
this.projectAtRoot = this.getRepo()
.then(repo => this.project.relativize(repo.workdir()))
.then(relativePath => relativePath === '')
.then(repo => this.project.relativize(repo.workdir()) === '')
}
return this.projectAtRoot

View File

@@ -1,10 +1,14 @@
# Like sands through the hourglass, so are the days of our lives.
module.exports = ({blobStore}) ->
environmentHelpers = require('./environment-helpers')
path = require 'path'
require './window'
{getWindowLoadSettings} = require './window-load-settings-helpers'
{resourcePath, isSpec, devMode} = getWindowLoadSettings()
{resourcePath, isSpec, devMode, env} = getWindowLoadSettings()
# Set baseline environment
environmentHelpers.normalize({env: env})
# Add application-specific exports to module search path.
exportsPath = path.join(resourcePath, 'exports')
@@ -21,6 +25,7 @@ module.exports = ({blobStore}) ->
applicationDelegate: new ApplicationDelegate,
configDirPath: process.env.ATOM_HOME
enablePersistence: true
env: env
})
atom.startEditorWindow().then ->

View File

@@ -128,8 +128,12 @@ class PackageManager
# Public: Get the path to the apm command.
#
# Uses the value of the `core.apmPath` config setting if it exists.
#
# Return a {String} file path to apm.
getApmPath: ->
configPath = atom.config.get('core.apmPath')
return configPath if configPath
return @apmPath if @apmPath?
commandName = 'apm'

View File

@@ -88,8 +88,9 @@ class TextEditor extends Model
state.assert = atomEnvironment.assert.bind(atomEnvironment)
state.applicationDelegate = atomEnvironment.applicationDelegate
editor = new this(state)
disposable = atomEnvironment.textEditors.add(editor)
editor.onDidDestroy -> disposable.dispose()
if state.registered
disposable = atomEnvironment.textEditors.add(editor)
editor.onDidDestroy -> disposable.dispose()
editor
constructor: (params={}) ->
@@ -167,6 +168,7 @@ class TextEditor extends Model
firstVisibleScreenColumn: @getFirstVisibleScreenColumn()
displayBuffer: @displayBuffer.serialize()
selectionsMarkerLayerId: @selectionsMarkerLayer.id
registered: atom.textEditors.editors.has this
subscribeToBuffer: ->
@buffer.retain()

View File

@@ -548,7 +548,10 @@ class Workspace extends Model
throw error
@project.bufferForPath(filePath, options).then (buffer) =>
@buildTextEditor(_.extend({buffer, largeFileMode}, options))
editor = @buildTextEditor(_.extend({buffer, largeFileMode}, options))
disposable = atom.textEditors.add(editor)
editor.onDidDestroy -> disposable.dispose()
editor
# Public: Returns a {Boolean} that is `true` if `object` is a `TextEditor`.
#
@@ -564,10 +567,7 @@ class Workspace extends Model
@config, @notificationManager, @packageManager, @clipboard, @viewRegistry,
@grammarRegistry, @project, @assert, @applicationDelegate
}, params)
editor = new TextEditor(params)
disposable = atom.textEditors.add(editor)
editor.onDidDestroy -> disposable.dispose()
editor
new TextEditor(params)
# Public: Asynchronously reopens the last-closed item's URI if it hasn't already been
# reopened.