Merge pull request #1011 from atom/no-root-tmp

Do not always use "/tmp" to represent system temporary directory
This commit is contained in:
Cheng Zhao
2013-10-21 17:37:04 -07:00
20 changed files with 115 additions and 63 deletions

View File

@@ -28,6 +28,13 @@
* Class methods (methods starting with a `@`)
* Instance variables
* Instance methods
* Be ware of platform differences
* The home directory is `process.env.USERPROFILE` on Windows, while on OS X
and Linux it's `process.env.HOME`
* Path separator is `\` on Windows, and is `/` on OS X and Linux, so use
`path.join` to concatenate filenames.
* Temporary directory is not `/tmp` on Windows, use `os.tmpdir()` when
possible
## Philosophy

View File

@@ -1,5 +1,6 @@
fs = require 'fs'
path = require 'path'
os = require 'os'
fm = require 'json-front-matter'
_ = require 'underscore-plus'
@@ -9,7 +10,8 @@ packageJson = require './package.json'
module.exports = (grunt) ->
appName = 'Atom.app'
[major, minor, patch] = packageJson.version.split('.')
buildDir = grunt.option('build-dir') ? '/tmp/atom-build'
tmpDir = if process.platform is 'win32' then os.tmpdir() else '/tmp'
buildDir = grunt.option('build-dir') ? path.join(tmpDir, 'atom-build')
shellAppDir = path.join(buildDir, appName)
contentsDir = path.join(shellAppDir, 'Contents')
appDir = path.join(contentsDir, 'Resources', 'app')

View File

@@ -1,10 +1,12 @@
{fs} = require 'atom'
path = require 'path'
temp = require 'temp'
installer = require '../src/command-installer'
describe "install(commandPath, callback)", ->
directory = '/tmp/install-atom-command/atom'
commandPath = "#{directory}/source"
destinationPath = "#{directory}/bin/source"
directory = path.join(temp.dir, 'install-atom-command', 'atom')
commandPath = path.join(directory, 'source')
destinationPath = path.join(directory, 'bin', 'source')
beforeEach ->
spyOn(installer, 'findInstallDirectory').andCallFake (callback) ->

View File

@@ -1,8 +1,11 @@
{fs} = require 'atom'
path = require 'path'
temp = require 'temp'
CSON = require 'season'
describe "Config", ->
dotAtomPath = path.join(temp.dir, 'dot-atom-dir')
describe ".get(keyPath)", ->
it "allows a key path's value to be read", ->
expect(config.set("foo.bar.baz", 42)).toBe 42
@@ -162,11 +165,11 @@ describe "Config", ->
describe ".initializeConfigDirectory()", ->
beforeEach ->
config.configDirPath = '/tmp/dot-atom-dir'
config.configDirPath = dotAtomPath
expect(fs.exists(config.configDirPath)).toBeFalsy()
afterEach ->
fs.remove('/tmp/dot-atom-dir') if fs.exists('/tmp/dot-atom-dir')
fs.remove(dotAtomPath) if fs.exists(dotAtomPath)
describe "when the configDirPath doesn't exist", ->
it "copies the contents of dot-atom to ~/.atom", ->
@@ -185,12 +188,12 @@ describe "Config", ->
describe ".loadUserConfig()", ->
beforeEach ->
config.configDirPath = '/tmp/dot-atom-dir'
config.configDirPath = dotAtomPath
config.configFilePath = path.join(config.configDirPath, "config.cson")
expect(fs.exists(config.configDirPath)).toBeFalsy()
afterEach ->
fs.remove('/tmp/dot-atom-dir') if fs.exists('/tmp/dot-atom-dir')
fs.remove(dotAtomPath) if fs.exists(dotAtomPath)
describe "when the config file contains valid cson", ->
beforeEach ->
@@ -222,7 +225,7 @@ describe "Config", ->
updatedHandler = null
beforeEach ->
config.configDirPath = '/tmp/dot-atom-dir'
config.configDirPath = dotAtomPath
config.configFilePath = path.join(config.configDirPath, "config.cson")
expect(fs.exists(config.configDirPath)).toBeFalsy()
fs.writeSync(config.configFilePath, "foo: bar: 'baz'")
@@ -233,7 +236,7 @@ describe "Config", ->
afterEach ->
config.unobserveUserConfig()
fs.remove('/tmp/dot-atom-dir') if fs.exists('/tmp/dot-atom-dir')
fs.remove(dotAtomPath) if fs.exists(dotAtomPath)
describe "when the config file changes to contain valid cson", ->
it "updates the config data", ->

View File

@@ -1,5 +1,6 @@
{_, $, $$, fs, Editor, Range, RootView} = require 'atom'
path = require 'path'
temp = require 'temp'
describe "Editor", ->
[buffer, editor, editSession, cachedLineHeight, cachedCharWidth] = []
@@ -86,7 +87,7 @@ describe "Editor", ->
describe "when the activeEditSession's file is modified on disk", ->
it "triggers an alert", ->
filePath = "/tmp/atom-changed-file.txt"
filePath = path.join(temp.dir, 'atom-changed-file.txt')
fs.writeSync(filePath, "")
editSession = project.openSync(filePath)
editor.edit(editSession)
@@ -151,7 +152,7 @@ describe "Editor", ->
expect(editor.lineElementForScreenRow(6).text()).toMatch /^ currentgoodbye/
it "triggers alert if edit session's buffer goes into conflict with changes on disk", ->
filePath = "/tmp/atom-changed-file.txt"
filePath = path.join(temp.dir, 'atom-changed-file.txt')
fs.writeSync(filePath, "")
tempEditSession = project.openSync(filePath)
editor.edit(tempEditSession)
@@ -247,7 +248,7 @@ describe "Editor", ->
filePath = null
beforeEach ->
filePath = "/tmp/something.txt"
filePath = path.join(temp.dir, 'something.txt')
fs.writeSync(filePath, filePath)
afterEach ->
@@ -274,11 +275,11 @@ describe "Editor", ->
expect(eventHandler).toHaveBeenCalled()
eventHandler.reset()
oldBuffer.saveAs("/tmp/atom-bad.txt")
oldBuffer.saveAs(path.join(temp.dir, 'atom-bad.txt'))
expect(eventHandler).not.toHaveBeenCalled()
eventHandler.reset()
editor.getBuffer().saveAs("/tmp/atom-new.txt")
editor.getBuffer().saveAs(path.join(temp.dir, 'atom-new.txt'))
expect(eventHandler).toHaveBeenCalled()
it "loads the grammar for the new path", ->
@@ -2296,7 +2297,8 @@ describe "Editor", ->
[filePath] = []
beforeEach ->
filePath = path.join(fs.absolute("/tmp"), "grammar-change.txt")
tmpdir = fs.absolute(temp.dir)
filePath = path.join(tmpdir, "grammar-change.txt")
fs.writeSync(filePath, "var i;")
afterEach ->
@@ -2648,10 +2650,11 @@ describe "Editor", ->
editor.trigger 'editor:save-debug-snapshot'
statePath = path.join(temp.dir, 'state')
expect(atom.showSaveDialog).toHaveBeenCalled()
saveDialogCallback('/tmp/state')
saveDialogCallback(statePath)
expect(fs.writeSync).toHaveBeenCalled()
expect(fs.writeSync.argsForCall[0][0]).toBe '/tmp/state'
expect(fs.writeSync.argsForCall[0][0]).toBe statePath
expect(typeof fs.writeSync.argsForCall[0][1]).toBe 'string'
describe "when the escape key is pressed on the editor", ->

View File

@@ -33,12 +33,15 @@ describe "fs", ->
expect(fs.exists(null)).toBe false
describe ".makeTree(path)", ->
aPath = path.join(temp.dir, 'a')
beforeEach ->
fs.remove("/tmp/a") if fs.exists("/tmp/a")
fs.remove(aPath) if fs.exists(aPath)
it "creates all directories in path including any missing parent directories", ->
fs.makeTree("/tmp/a/b/c")
expect(fs.exists("/tmp/a/b/c")).toBeTruthy()
abcPath = path.join(aPath, 'b', 'c')
fs.makeTree(abcPath)
expect(fs.exists(abcPath)).toBeTruthy()
describe ".traverseTreeSync(path, onFile, onDirectory)", ->
it "calls fn for every path in the tree at the given path", ->
@@ -131,6 +134,7 @@ describe "fs", ->
describe ".absolute(relativePath)", ->
it "converts a leading ~ segment to the HOME directory", ->
expect(fs.absolute('~')).toBe fs.realpathSync(process.env.HOME)
expect(fs.absolute(path.join('~', 'does', 'not', 'exist'))).toBe path.join(process.env.HOME, 'does', 'not', 'exist')
homeDir = atom.getHomeDirPath()
expect(fs.absolute('~')).toBe fs.realpathSync(homeDir)
expect(fs.absolute(path.join('~', 'does', 'not', 'exist'))).toBe path.join(homeDir, 'does', 'not', 'exist')
expect(fs.absolute('~test')).toBe '~test'

View File

@@ -8,18 +8,19 @@ describe "Git", ->
repo = null
beforeEach ->
fs.remove('/tmp/.git') if fs.isDirectorySync('/tmp/.git')
gitPath = path.join(temp.dir, '.git')
fs.remove(gitPath) if fs.isDirectorySync(gitPath)
afterEach ->
repo.destroy() if repo?.repo?
describe "@open(path)", ->
it "returns null when no repository is found", ->
expect(Git.open('/tmp/nogit.txt')).toBeNull()
expect(Git.open(path.join(temp.dir, 'nogit.txt'))).toBeNull()
describe "new Git(path)", ->
it "throws an exception when no repository is found", ->
expect(-> new Git('/tmp/nogit.txt')).toThrow()
expect(-> new Git(path.join(temp.dir, 'nogit.txt'))).toThrow()
describe ".getPath()", ->
it "returns the repository path for a .git directory path", ->

View File

@@ -1,3 +1,5 @@
path = require 'path'
temp = require 'temp'
{Site} = require 'telepath'
{View} = require 'atom'
PaneContainer = require '../src/pane-container'
@@ -13,7 +15,7 @@ describe "PaneContainer replication", ->
initialize: (@name) -> @text(@name)
serialize: -> { deserializer: 'TestView', @name }
getState: -> @serialize()
getUri: -> "/tmp/#{@name}"
getUri: -> path.join(temp.dir, @name)
isEqual: (other) -> @name is other.name
beforeEach ->

View File

@@ -1,3 +1,5 @@
path = require 'path'
temp = require 'temp'
PaneContainer = require '../src/pane-container'
Pane = require '../src/pane'
{_, $, View, $$} = require 'atom'
@@ -12,7 +14,7 @@ describe "PaneContainer", ->
@content: -> @div tabindex: -1
initialize: (@name) -> @text(@name)
serialize: -> { deserializer: 'TestView', @name }
getUri: -> "/tmp/#{@name}"
getUri: -> path.join(temp.dir, @name)
save: -> @saved = true
isEqual: (other) -> @name is other.name

View File

@@ -1,7 +1,8 @@
PaneContainer = require '../src/pane-container'
Pane = require '../src/pane'
{$, View} = require 'atom'
{dirname} = require 'path'
path = require 'path'
temp = require 'temp'
describe "Pane", ->
[container, view1, view2, editSession1, editSession2, pane] = []
@@ -372,7 +373,7 @@ describe "Pane", ->
pane.trigger 'core:save-as'
expect(atom.showSaveDialogSync).toHaveBeenCalledWith(dirname(editSession2.getPath()))
expect(atom.showSaveDialogSync).toHaveBeenCalledWith(path.dirname(editSession2.getPath()))
expect(editSession2.saveAs).toHaveBeenCalledWith('/selected/path')
describe "when the current item does not have a saveAs method", ->
@@ -679,7 +680,7 @@ describe "Pane", ->
expect(pane.saveItem).not.toHaveBeenCalled()
expect(pane.activeItem.save).not.toHaveBeenCalled()
initialActiveItemUri = '/tmp/hi'
initialActiveItemUri = path.join(temp.dir, 'hi')
pane.activeView.trigger 'focusout'
expect(pane.activeItem.save).toHaveBeenCalled()
@@ -697,7 +698,7 @@ describe "Pane", ->
expect(initialActiveItem.save).not.toHaveBeenCalled()
pane.showItem(initialActiveItem)
initialActiveItemUri = '/tmp/hi'
initialActiveItemUri = path.join(temp.dir, 'hi')
pane.showItem(view2)
expect(initialActiveItem.save).toHaveBeenCalled()
@@ -716,7 +717,7 @@ describe "Pane", ->
pane.destroyItem(view2)
expect(pane.saveItem).not.toHaveBeenCalled()
initialActiveItemUri = '/tmp/hi'
initialActiveItemUri = path.join(temp.dir, 'hi')
pane.destroyItem(initialActiveItem)
expect(initialActiveItem.save).toHaveBeenCalled()

View File

@@ -1,6 +1,7 @@
{$, $$, fs, RootView, View} = require 'atom'
Q = require 'q'
path = require 'path'
temp = require 'temp'
Pane = require '../src/pane'
describe "RootView", ->
@@ -162,7 +163,7 @@ describe "RootView", ->
describe "when the title of the active pane item changes", ->
it "updates the window title based on the item's new title", ->
editSession = rootView.getActivePaneItem()
editSession.buffer.setPath('/tmp/hi')
editSession.buffer.setPath(path.join(temp.dir, 'hi'))
expect(rootView.title).toBe "#{editSession.getTitle()} - #{project.getPath()}"
describe "when the active pane's item changes", ->

View File

@@ -1,4 +1,6 @@
{fs} = require 'atom'
path = require 'path'
temp = require 'temp'
TextMateGrammar = require '../src/text-mate-grammar'
describe "the `syntax` global", ->
@@ -10,19 +12,19 @@ describe "the `syntax` global", ->
describe "serialization", ->
it "remembers grammar overrides by path", ->
path = '/foo/bar/file.js'
expect(syntax.selectGrammar(path).name).not.toBe 'Ruby'
syntax.setGrammarOverrideForPath(path, 'source.ruby')
filePath = '/foo/bar/file.js'
expect(syntax.selectGrammar(filePath).name).not.toBe 'Ruby'
syntax.setGrammarOverrideForPath(filePath, 'source.ruby')
syntax2 = deserialize(syntax.serialize())
syntax2.addGrammar(grammar) for grammar in syntax.grammars when grammar isnt syntax.nullGrammar
expect(syntax2.selectGrammar(path).name).toBe 'Ruby'
expect(syntax2.selectGrammar(filePath).name).toBe 'Ruby'
describe ".selectGrammar(filePath)", ->
it "can use the filePath to load the correct grammar based on the grammar's filetype", ->
atom.activatePackage('git-tmbundle', sync: true)
expect(syntax.selectGrammar("file.js").name).toBe "JavaScript" # based on extension (.js)
expect(syntax.selectGrammar("/tmp/.git/config").name).toBe "Git Config" # based on end of the path (.git/config)
expect(syntax.selectGrammar(path.join(temp.dir, '.git', 'config')).name).toBe "Git Config" # based on end of the path (.git/config)
expect(syntax.selectGrammar("Rakefile").name).toBe "Ruby" # based on the file's basename (Rakefile)
expect(syntax.selectGrammar("curb").name).toBe "Null Grammar"
expect(syntax.selectGrammar("/hu.git/config").name).toBe "Null Grammar"
@@ -51,12 +53,12 @@ describe "the `syntax` global", ->
expect(fs.read).not.toHaveBeenCalled()
it "allows the default grammar to be overridden for a path", ->
path = '/foo/bar/file.js'
expect(syntax.selectGrammar(path).name).not.toBe 'Ruby'
syntax.setGrammarOverrideForPath(path, 'source.ruby')
expect(syntax.selectGrammar(path).name).toBe 'Ruby'
syntax.clearGrammarOverrideForPath(path)
expect(syntax.selectGrammar(path).name).not.toBe 'Ruby'
filePath = '/foo/bar/file.js'
expect(syntax.selectGrammar(filePath).name).not.toBe 'Ruby'
syntax.setGrammarOverrideForPath(filePath, 'source.ruby')
expect(syntax.selectGrammar(filePath).name).toBe 'Ruby'
syntax.clearGrammarOverrideForPath(filePath)
expect(syntax.selectGrammar(filePath).name).not.toBe 'Ruby'
describe "when multiple grammars have matching fileTypes", ->
it "selects the grammar with the longest fileType match", ->

View File

@@ -154,7 +154,7 @@ describe 'TextBuffer', ->
[filePath, bufferToDelete] = []
beforeEach ->
filePath = "/tmp/atom-file-to-delete.txt"
filePath = path.join(temp.dir, 'atom-file-to-delete.txt')
fs.writeSync(filePath, 'delete me')
bufferToDelete = project.bufferForPathSync(filePath)
filePath = bufferToDelete.getPath() # symlinks may have been converted
@@ -212,7 +212,7 @@ describe 'TextBuffer', ->
it "reports the modified status changing to true after the underlying file is deleted", ->
buffer.release()
filePath = "/tmp/atom-tmp-file"
filePath = path.join(temp.dir, 'atom-tmp-file')
fs.writeSync(filePath, 'delete me')
buffer = project.bufferForPathSync(filePath)
modifiedHandler = jasmine.createSpy("modifiedHandler")
@@ -224,7 +224,7 @@ describe 'TextBuffer', ->
runs -> expect(buffer.isModified()).toBe true
it "reports the modified status changing to false after a modified buffer is saved", ->
filePath = "/tmp/atom-tmp-file"
filePath = path.join(temp.dir, 'atom-tmp-file')
fs.writeSync(filePath, '')
buffer.release()
buffer = project.bufferForPathSync(filePath)
@@ -248,7 +248,7 @@ describe 'TextBuffer', ->
expect(buffer.isModified()).toBe true
it "reports the modified status changing to false after a modified buffer is reloaded", ->
filePath = "/tmp/atom-tmp-file"
filePath = path.join(temp.dir, 'atom-tmp-file')
fs.writeSync(filePath, '')
buffer.release()
buffer = project.bufferForPathSync(filePath)
@@ -271,7 +271,7 @@ describe 'TextBuffer', ->
expect(buffer.isModified()).toBe true
it "reports the modified status changing to false after a buffer to a non-existent file is saved", ->
filePath = "/tmp/atom-tmp-file"
filePath = path.join(temp.dir, 'atom-tmp-file')
fs.remove(filePath) if fs.exists(filePath)
expect(fs.exists(filePath)).toBeFalsy()
buffer.release()
@@ -464,7 +464,7 @@ describe 'TextBuffer', ->
filePath = null
beforeEach ->
filePath = '/tmp/temp.txt'
filePath = path.join(temp.dir, 'temp.txt')
fs.writeSync(filePath, "")
saveBuffer = project.bufferForPathSync(filePath)
saveBuffer.setText("blah")
@@ -521,7 +521,7 @@ describe 'TextBuffer', ->
saveAsBuffer.release()
it "saves the contents of the buffer to the path", ->
filePath = '/tmp/temp.txt'
filePath = path.join(temp.dir, 'temp.txt')
fs.remove filePath if fs.exists(filePath)
saveAsBuffer = project.bufferForPathSync(null).retain()
@@ -535,8 +535,8 @@ describe 'TextBuffer', ->
expect(eventHandler).toHaveBeenCalledWith(saveAsBuffer)
it "stops listening to events on previous path and begins listening to events on new path", ->
originalPath = "/tmp/original.txt"
newPath = "/tmp/new.txt"
originalPath = path.join(temp.dir, 'original.txt')
newPath = path.join(temp.dir, 'new.txt')
fs.writeSync(originalPath, "")
saveAsBuffer = project.bufferForPathSync(originalPath).retain()

View File

@@ -13,6 +13,7 @@ remote = require 'remote'
shell = require 'shell'
crypto = require 'crypto'
path = require 'path'
os = require 'os'
dialog = remote.require 'dialog'
app = remote.require 'app'
{Document} = require 'telepath'
@@ -229,7 +230,10 @@ class Atom
@getCurrentWindow().isFullScreen()
getHomeDirPath: ->
app.getHomeDir()
process.env[if process.platform is 'win32' then 'USERPROFILE' else 'HOME']
getTempDirPath: ->
if process.platform is 'win32' then os.tmpdir() else '/tmp'
# Public: Get the directory path to Atom's configuration area.
getConfigDirPath: ->

View File

@@ -8,13 +8,14 @@ dialog = require 'dialog'
fs = require 'fs'
ipc = require 'ipc'
path = require 'path'
os = require 'os'
net = require 'net'
shell = require 'shell'
url = require 'url'
{EventEmitter} = require 'events'
_ = require 'underscore-plus'
socketPath = '/tmp/atom.sock'
socketPath = path.join(os.tmpdir(), 'atom.sock')
# Private: The application's singleton class.
#

View File

@@ -1,12 +1,14 @@
crypto = require 'crypto'
fs = require 'fs'
path = require 'path'
os = require 'os'
CoffeeScript = require 'coffee-script'
CSON = require 'season'
mkdir = require('mkdirp').sync
cacheDir = '/tmp/atom-compile-cache'
tmpDir = if process.platform is 'win32' then os.tmpdir() else '/tmp'
cacheDir = path.join(tmpDir, 'atom-compile-cache')
coffeeCacheDir = path.join(cacheDir, 'coffee')
CSON.setCacheDir(path.join(cacheDir, 'cson'))

View File

@@ -13,10 +13,12 @@ fsExtensions =
absolute: (relativePath) ->
return null unless relativePath?
homeDir = process.env[if process.platform is 'win32' then 'USERPROFILE' else 'HOME']
if relativePath is '~'
relativePath = process.env.HOME
relativePath = homeDir
else if relativePath.indexOf('~/') is 0
relativePath = "#{process.env.HOME}#{relativePath.substring(1)}"
relativePath = "#{homeDir}#{relativePath.substring(1)}"
try
fs.realpathSync(relativePath)

View File

@@ -1,12 +1,15 @@
path = require 'path'
os = require 'os'
LessCache = require 'less-cache'
{Subscriber} = require 'emissary'
tmpDir = if process.platform is 'win32' then os.tmpdir() else '/tmp'
module.exports =
class LessCompileCache
Subscriber.includeInto(this)
@cacheDir: '/tmp/atom-compile-cache/less'
@cacheDir: path.join(tmpDir, 'atom-compile-cache', 'less')
constructor: ->
@cache = new LessCache

View File

@@ -1,16 +1,21 @@
path = require 'path'
os = require 'os'
module.exports = (grunt) ->
{rm} = require('./task-helpers')(grunt)
grunt.registerTask 'partial-clean', 'Delete some of the build files', ->
tmpdir = if process.platform is 'win32' then os.tmpdir() else '/tmp'
rm grunt.config.get('atom.buildDir')
rm require('../src/coffee-cache').cacheDir
rm require('../src/less-compile-cache').cacheDir
rm '/tmp/atom-cached-atom-shells'
rm path.join(tmpdir, 'atom-cached-atom-shells')
rm 'atom-shell'
grunt.registerTask 'clean', 'Delete all the build files', ->
homeDir = process.env[if process.platform is 'win32' then 'USERPROFILE' else 'HOME']
rm 'node_modules'
rm path.join(process.env.HOME, '.atom', '.node-gyp')
rm path.join(homeDir, '.atom', '.node-gyp')
grunt.task.run('partial-clean')

View File

@@ -1,5 +1,6 @@
fs = require 'fs'
path = require 'path'
os = require 'os'
request = require 'request'
formidable = require 'formidable'
@@ -70,7 +71,11 @@ module.exports = (grunt) ->
else
null
getCachePath = (version) -> "/tmp/atom-cached-atom-shells/#{version}"
getTempDir = ->
if process.platform is 'win32' then os.tmpdir() else '/tmp'
getCachePath = (version) ->
path.join(getTempDir(), 'atom-cached-atom-shells', version)
isAtomShellVersionCached = (version) ->
grunt.file.isFile(getCachePath(version), 'version')