mirror of
https://github.com/Foundry376/Mailspring.git
synced 2025-09-08 05:34:23 +08:00
fix(asar): Support ASAR, and running of specs in prod builds
Summary: fix(task-queue): Repair the findTask function Add "ship logs" and "open logs" to the developer menu Patches for Chromium 42 Test Plan: Run tests! Reviewers: evan Reviewed By: evan Differential Revision: https://phab.nylas.com/D1547
This commit is contained in:
parent
5e4fea01e5
commit
e198c4f6c4
32 changed files with 200 additions and 112 deletions
|
@ -2,7 +2,7 @@ fs = require 'fs'
|
|||
path = require 'path'
|
||||
os = require 'os'
|
||||
|
||||
# This is the main Gruntfile that manages building Edgehill distributions.
|
||||
# This is the main Gruntfile that manages building Nylas Mail distributions.
|
||||
# The reason it's inisde of the build/ folder is so everything can be
|
||||
# compiled against Node's v8 headers instead of Atom's v8 headers. All
|
||||
# packages in the root-level node_modules are compiled against Atom's v8
|
||||
|
@ -17,25 +17,25 @@ os = require 'os'
|
|||
#
|
||||
# tmpDir: /var/folders/xl/_qdlmc512sb6cpqryy_2tzzw0000gn/T/ (aka /tmp)
|
||||
#
|
||||
# buildDir = /tmp/edgehill-build
|
||||
# shellAppDir = /tmp/edgehill-build/Edgehill.app
|
||||
# contentsDir = /tmp/edgehill-build/Edgehill.app/Contents
|
||||
# appDir = /tmp/edgehill-build/Edgehill.app/Contents/Resources/app
|
||||
# buildDir = /tmp/nylas-build
|
||||
# shellAppDir = /tmp/nylas-build/Nylas.app
|
||||
# contentsDir = /tmp/nylas-build/Nylas.app/Contents
|
||||
# appDir = /tmp/nylas-build/Nylas.app/Contents/Resources/app
|
||||
#
|
||||
# installDir = /Applications/Edgehil.app
|
||||
# installDir = /Applications/Nylas.app
|
||||
#
|
||||
# And on Linux:
|
||||
#
|
||||
# tmpDir: /tmp/
|
||||
#
|
||||
# buildDir = /tmp/edgehill-build
|
||||
# shellAppDir = /tmp/edgehill-build/Edgehill
|
||||
# contentsDir = /tmp/edgehill-build/Edgehill
|
||||
# appDir = /tmp/edgehill-build/Edgehill/resources/app
|
||||
# buildDir = /tmp/nylas-build
|
||||
# shellAppDir = /tmp/nylas-build/Nylas
|
||||
# contentsDir = /tmp/nylas-build/Nylas
|
||||
# appDir = /tmp/nylas-build/Nylas/resources/app
|
||||
#
|
||||
# installDir = /usr/local OR $INSTALL_PREFIX
|
||||
# binDir = /usr/local/bin
|
||||
# shareDir = /usr/local/share/edgehill
|
||||
# shareDir = /usr/local/share/nylas
|
||||
|
||||
# Add support for obselete APIs of vm module so we can make some third-party
|
||||
# modules work under node v0.11.x.
|
||||
|
@ -99,7 +99,7 @@ module.exports = (grunt) ->
|
|||
contentsDir = shellAppDir
|
||||
appDir = path.join(shellAppDir, 'resources', 'app')
|
||||
installDir ?= process.env.INSTALL_PREFIX ? '/usr/local'
|
||||
killCommand ='pkill -9 nylas'
|
||||
killCommand = 'pkill -9 nylas'
|
||||
|
||||
installDir = path.resolve(installDir)
|
||||
|
||||
|
@ -166,18 +166,19 @@ module.exports = (grunt) ->
|
|||
dest: appDir
|
||||
ext: '.js'
|
||||
|
||||
for child in fs.readdirSync('node_modules') when child isnt '.bin'
|
||||
directory = path.join('node_modules', child)
|
||||
metadataPath = path.join(directory, 'package.json')
|
||||
continue unless grunt.file.isFile(metadataPath)
|
||||
for folder in ['node_modules', 'internal_packages']
|
||||
for child in fs.readdirSync(folder) when child isnt '.bin'
|
||||
directory = path.join(folder, child)
|
||||
metadataPath = path.join(directory, 'package.json')
|
||||
continue unless grunt.file.isFile(metadataPath)
|
||||
|
||||
{engines, theme} = grunt.file.readJSON(metadataPath)
|
||||
if engines?.atom?
|
||||
coffeeConfig.glob_to_multiple.src.push("#{directory}/**/*.coffee")
|
||||
lessConfig.glob_to_multiple.src.push("#{directory}/**/*.less")
|
||||
prebuildLessConfig.src.push("#{directory}/**/*.less") unless theme
|
||||
csonConfig.glob_to_multiple.src.push("#{directory}/**/*.cson")
|
||||
pegConfig.glob_to_multiple.src.push("#{directory}/**/*.pegjs")
|
||||
{engines, theme} = grunt.file.readJSON(metadataPath)
|
||||
if engines?.atom?
|
||||
coffeeConfig.glob_to_multiple.src.push("#{directory}/**/*.coffee")
|
||||
lessConfig.glob_to_multiple.src.push("#{directory}/**/*.less")
|
||||
prebuildLessConfig.src.push("#{directory}/**/*.less") unless theme
|
||||
csonConfig.glob_to_multiple.src.push("#{directory}/**/*.cson")
|
||||
pegConfig.glob_to_multiple.src.push("#{directory}/**/*.pegjs")
|
||||
|
||||
grunt.initConfig
|
||||
pkg: grunt.file.readJSON('package.json')
|
||||
|
@ -304,16 +305,16 @@ module.exports = (grunt) ->
|
|||
|
||||
ciTasks = ['output-disk-space', 'download-electron', 'build']
|
||||
ciTasks.push('dump-symbols') if process.platform isnt 'win32'
|
||||
ciTasks.push('set-version', 'lint')
|
||||
ciTasks.push('set-version', 'lint', 'generate-asar')
|
||||
ciTasks.push('mkdeb') if process.platform is 'linux'
|
||||
ciTasks.push('test') if process.platform is 'darwin'
|
||||
ciTasks.push('codesign')
|
||||
ciTasks.push('mkdmg') if process.platform is 'darwin'
|
||||
ciTasks.push('create-windows-installer') if process.platform is 'win32'
|
||||
ciTasks.push('publish-edgehill-build') if process.platform is 'darwin'
|
||||
ciTasks.push('publish-nylas-build') if process.platform is 'darwin'
|
||||
grunt.registerTask('ci', ciTasks)
|
||||
|
||||
defaultTasks = ['download-electron', 'build', 'set-version']
|
||||
defaultTasks = ['download-electron', 'build', 'set-version', 'generate-asar']
|
||||
# We don't run `install` on linux because you need to run `sudo`.
|
||||
# See docs/build-instructions/linux.md
|
||||
# `sudo script/grunt install`
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"name": "edgehill-build",
|
||||
"name": "nylas-build",
|
||||
"description": "Nylas Mail build",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
|
|
@ -110,8 +110,6 @@ module.exports = (grunt) ->
|
|||
'.gitkeep'
|
||||
]
|
||||
|
||||
packageNames.forEach (packageName) -> ignoredPaths.push(path.join(packageName, 'spec'))
|
||||
|
||||
ignoredPaths = ignoredPaths.map (ignoredPath) -> escapeRegExp(ignoredPath)
|
||||
|
||||
# Add .* to avoid matching hunspell_dictionaries.
|
||||
|
@ -141,19 +139,14 @@ module.exports = (grunt) ->
|
|||
|
||||
testFolderPattern = new RegExp("#{escapeRegExp(path.sep)}te?sts?#{escapeRegExp(path.sep)}")
|
||||
exampleFolderPattern = new RegExp("#{escapeRegExp(path.sep)}examples?#{escapeRegExp(path.sep)}")
|
||||
benchmarkFolderPattern = new RegExp("#{escapeRegExp(path.sep)}benchmarks?#{escapeRegExp(path.sep)}")
|
||||
|
||||
nodeModulesFilter = new RegExp(ignoredPaths.join('|'))
|
||||
filterNodeModule = (pathToCopy) ->
|
||||
return true if benchmarkFolderPattern.test(pathToCopy)
|
||||
|
||||
pathToCopy = path.resolve(pathToCopy)
|
||||
nodeModulesFilter.test(pathToCopy) or testFolderPattern.test(pathToCopy) or exampleFolderPattern.test(pathToCopy)
|
||||
|
||||
packageFilter = new RegExp("(#{ignoredPaths.join('|')})|(.+\\.(cson|coffee|cjsx|jsx)$)")
|
||||
filterPackage = (pathToCopy) ->
|
||||
return true if benchmarkFolderPattern.test(pathToCopy)
|
||||
|
||||
pathToCopy = path.resolve(pathToCopy)
|
||||
packageFilter.test(pathToCopy) or testFolderPattern.test(pathToCopy) or exampleFolderPattern.test(pathToCopy)
|
||||
|
||||
|
|
|
@ -43,12 +43,10 @@ module.exports = (grunt) ->
|
|||
for keymapPath in fs.listSync(path.join(moduleDirectory, 'keymaps'), ['.cson', '.json'])
|
||||
relativePath = path.relative(appDir, keymapPath)
|
||||
pack.keymaps[relativePath] = CSON.readFileSync(keymapPath)
|
||||
rm keymapPath
|
||||
|
||||
for menuPath in fs.listSync(path.join(moduleDirectory, 'menus'), ['.cson', '.json'])
|
||||
relativePath = path.relative(appDir, menuPath)
|
||||
pack.menus[relativePath] = CSON.readFileSync(menuPath)
|
||||
rm menuPath
|
||||
|
||||
packages[metadata.name] = pack
|
||||
|
||||
|
|
31
build/tasks/generate-asar-task.coffee
Normal file
31
build/tasks/generate-asar-task.coffee
Normal file
|
@ -0,0 +1,31 @@
|
|||
asar = require 'asar'
|
||||
fs = require 'fs'
|
||||
path = require 'path'
|
||||
|
||||
module.exports = (grunt) ->
|
||||
{cp, rm} = require('./task-helpers')(grunt)
|
||||
|
||||
grunt.registerTask 'generate-asar', 'Generate asar archive for the app', ->
|
||||
done = @async()
|
||||
|
||||
unpack = [
|
||||
'*.node'
|
||||
'**/vendor/**'
|
||||
'**/src/tasks/**'
|
||||
'**/node_modules/aws-sdk/**'
|
||||
'**/node_modules/spellchecker/**'
|
||||
]
|
||||
unpack = "{#{unpack.join(',')}}"
|
||||
|
||||
appDir = grunt.config.get('atom.appDir')
|
||||
unless fs.existsSync(appDir)
|
||||
grunt.log.error 'The app has to be built before generating asar archive.'
|
||||
return done(false)
|
||||
|
||||
asar.createPackageWithOptions appDir, path.resolve(appDir, '..', 'app.asar'), {unpack}, (err) ->
|
||||
return done(err) if err?
|
||||
|
||||
rm appDir
|
||||
fs.renameSync path.resolve(appDir, '..', 'new-app'), appDir
|
||||
|
||||
done()
|
|
@ -123,7 +123,7 @@ module.exports = (grunt) ->
|
|||
process.chdir(orig)
|
||||
reject(err)
|
||||
|
||||
grunt.registerTask "publish-edgehill-build", "Publish Edgehill build", ->
|
||||
grunt.registerTask "publish-nylas-build", "Publish Nylas build", ->
|
||||
done = @async()
|
||||
|
||||
dmgPath = path.join(grunt.config.get('atom.buildDir'), dmgName())
|
|
@ -15,8 +15,8 @@ FreeBSD -RELEASE 64-bit is the recommended platform.
|
|||
```sh
|
||||
git clone https://github.com/nylas/edgehill
|
||||
cd edgehill
|
||||
script/build # Creates application at $TMPDIR/edgehill-build/Edgehill
|
||||
sudo script/grunt install # Installs command to /usr/local/bin/edgehill
|
||||
script/build # Creates application at $TMPDIR/nylas-build/Nylas
|
||||
sudo script/grunt install # Installs command to /usr/local/bin/nylas
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
|
|
@ -61,7 +61,7 @@ If you have problems with permissions don't forget to prefix with `sudo`
|
|||
script/build
|
||||
```
|
||||
|
||||
This will create the Nylas Mail application at `$TMPDIR/edgehill-build/Edgehill`.
|
||||
This will create the Nylas Mail application at `$TMPDIR/nylas-build/Nylas`.
|
||||
|
||||
4. Install the `edgehill` and `apm` commands to `/usr/local/bin` by executing:
|
||||
|
||||
|
@ -71,7 +71,7 @@ If you have problems with permissions don't forget to prefix with `sudo`
|
|||
|
||||
To use the newly installed Nylas Mail, quit and restart all running Nylas Mail instances.
|
||||
|
||||
5. *Optionally*, you may generate distributable packages of Nylas Mail at `$TMPDIR/edgehill-build`. Currenty, `.deb` and `.rpm` package types are supported. To create a `.deb` package run:
|
||||
5. *Optionally*, you may generate distributable packages of Nylas Mail at `$TMPDIR/nylas-build`. Currenty, `.deb` and `.rpm` package types are supported. To create a `.deb` package run:
|
||||
|
||||
```sh
|
||||
script/grunt mkdeb
|
||||
|
|
|
@ -335,7 +335,7 @@ describe "populated composer", ->
|
|||
useFullDraft.apply(@)
|
||||
makeComposer.call(@)
|
||||
spyOn(@composer, "_sendDraft")
|
||||
NylasTestUtils.loadKeymap "internal_packages/composer/keymaps/composer.cson"
|
||||
NylasTestUtils.loadKeymap("internal_packages/composer/keymaps/composer")
|
||||
|
||||
it "sends the draft on cmd-enter", ->
|
||||
NylasTestUtils.keyPress("cmd-enter", React.findDOMNode(@composer))
|
||||
|
|
|
@ -35,7 +35,10 @@ class DeveloperBar extends React.Component
|
|||
@activityStoreUnsubscribe() if @activityStoreUnsubscribe
|
||||
|
||||
render: =>
|
||||
return <div></div> unless @state.visible
|
||||
# TODO WARNING: This 1px height is necessary to fix a redraw issue in the thread
|
||||
# list in Chrome 42 (Electron 0.26.0). Do not remove unless you've verified that
|
||||
# scrolling works fine now and repaints aren't visible.
|
||||
return <div style={height:1}></div> unless @state.visible
|
||||
|
||||
<ResizableRegion className="developer-bar"
|
||||
initialHeight={@state.height}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
NotificationsStore = require '../lib/notifications-store.coffee'
|
||||
NotificationsStore = require '../lib/notifications-store'
|
||||
Notification = NotificationsStore.Notification
|
||||
{Actions} = require 'nylas-exports'
|
||||
|
||||
|
|
|
@ -40,6 +40,9 @@
|
|||
background-color: @background-color-info;
|
||||
}
|
||||
}
|
||||
// TODO: Necessary for Chromium 42 to render `activity-item-leave` animation
|
||||
// properly. Removing position relative causes the div to remain visible
|
||||
position:relative;
|
||||
}
|
||||
|
||||
transition: height 0.4s;
|
||||
|
|
|
@ -4,7 +4,7 @@ ReactTestUtils = React.addons.TestUtils
|
|||
{Actions} = require 'nylas-exports'
|
||||
|
||||
SearchBar = require '../lib/search-bar'
|
||||
SearchSuggestionStore = require '../lib/search-suggestion-store.coffee'
|
||||
SearchSuggestionStore = require '../lib/search-suggestion-store'
|
||||
|
||||
describe 'SearchBar', ->
|
||||
beforeEach ->
|
||||
|
|
|
@ -219,7 +219,7 @@ describe "ThreadList", ->
|
|||
columns = [c1,c2,c3]
|
||||
|
||||
beforeEach ->
|
||||
NylasTestUtils.loadKeymap("internal_packages/thread-list/keymaps/thread-list.cson")
|
||||
NylasTestUtils.loadKeymap("internal_packages/thread-list/keymaps/thread-list")
|
||||
spyOn(ThreadStore, "_onNamespaceChanged")
|
||||
spyOn(DatabaseStore, "findAll").andCallFake ->
|
||||
new Promise (resolve, reject) -> resolve(test_threads())
|
||||
|
|
|
@ -54,6 +54,9 @@
|
|||
submenu: [
|
||||
{ label: 'Open In Dev Mode...', command: 'application:open-dev' }
|
||||
{ type: 'separator' }
|
||||
{ label: 'Open Detailed Logs', command: 'window:open-errorreporter-logs' }
|
||||
{ label: 'Ship Detailed Logs to Nylas', command: 'application:ship-logs' }
|
||||
{ type: 'separator' }
|
||||
{ label: 'Run Nylas Mail Specs', command: 'application:run-all-specs' }
|
||||
{ label: 'Run Package Specs', command: 'application:run-package-specs' }
|
||||
{ label: 'Toggle Developer Tools', command: 'window:toggle-dev-tools' }
|
||||
|
|
|
@ -37,6 +37,9 @@
|
|||
submenu: [
|
||||
{ label: 'Open In &Dev Mode...', command: 'application:open-dev' }
|
||||
{ type: 'separator' }
|
||||
{ label: 'Open Detailed Logs', command: 'window:open-errorreporter-logs' }
|
||||
{ label: 'Ship Detailed Logs to Nylas', command: 'application:ship-logs' }
|
||||
{ type: 'separator' }
|
||||
{ label: 'Run &Nylas Mail Specs', command: 'application:run-all-specs' }
|
||||
{ label: 'Run Package &Specs', command: 'application:run-package-specs' }
|
||||
{ label: 'Toggle Developer &Tools', command: 'window:toggle-dev-tools' }
|
||||
|
|
|
@ -39,6 +39,9 @@
|
|||
submenu: [
|
||||
{ label: 'Open In &Dev Mode...', command: 'application:open-dev' }
|
||||
{ type: 'separator' }
|
||||
{ label: 'Open Detailed Logs', command: 'window:open-errorreporter-logs' }
|
||||
{ label: 'Ship Detailed Logs to Nylas', command: 'application:ship-logs' }
|
||||
{ type: 'separator' }
|
||||
{ label: 'Run &Atom Specs', command: 'application:run-all-specs' }
|
||||
{ label: 'Run Package &Specs', command: 'application:run-package-specs' }
|
||||
{ label: 'Toggle Developer &Tools', command: 'window:toggle-dev-tools' }
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
[Desktop Entry]
|
||||
Name=Edgehill
|
||||
Name=Nylas
|
||||
Comment=<%= description %>
|
||||
GenericName=Email OS
|
||||
Exec=<%= installDir %>/share/edgehill/edgehill %U
|
||||
GenericName=Nylas
|
||||
Exec=<%= installDir %>/share/nylas/nylas %U
|
||||
Icon=<%= iconName %>
|
||||
Type=Application
|
||||
StartupNotify=true
|
||||
|
|
|
@ -6,8 +6,8 @@ ReactTestUtils = React.addons.TestUtils
|
|||
GeneratedForm,
|
||||
GeneratedFieldset} = require ('../../src/components/generated-form')
|
||||
|
||||
fixtureModule = 'internal_packages/salesforce'
|
||||
Adapter = require path.join('../../', fixtureModule, 'lib/salesforce-schema-adapter.coffee')
|
||||
fixtureModule = path.resolve(__dirname, '..', '..', 'internal_packages', 'salesforce')
|
||||
Adapter = require(path.join(fixtureModule, 'lib/salesforce-schema-adapter'))
|
||||
fpath = path.join(fixtureModule, 'spec/fixtures/opportunity-layouts.json')
|
||||
rawData = JSON.parse(fs.readFileSync(fpath, 'utf-8'))
|
||||
testData = Adapter.convertFullEditLayout("opportunity", rawData)
|
||||
|
|
|
@ -89,6 +89,27 @@ describe "TaskQueue", ->
|
|||
remoteSpy = (task) ->
|
||||
spyOn(task, "performRemote").andCallFake -> Promise.resolve()
|
||||
|
||||
describe "findTask", ->
|
||||
beforeEach ->
|
||||
@subclassA = new TaskSubclassA()
|
||||
@subclassB1 = new TaskSubclassB("B1")
|
||||
@subclassB2 = new TaskSubclassB("B2")
|
||||
TaskQueue._queue = [@subclassA, @subclassB1, @subclassB2]
|
||||
|
||||
it "accepts type as a string", ->
|
||||
expect(TaskQueue.findTask('TaskSubclassB', {bProp: 'B1'})).toEqual(@subclassB1)
|
||||
|
||||
it "accepts type as a class", ->
|
||||
expect(TaskQueue.findTask(TaskSubclassB, {bProp: 'B1'})).toEqual(@subclassB1)
|
||||
|
||||
it "works without a set of match criteria", ->
|
||||
expect(TaskQueue.findTask(TaskSubclassA)).toEqual(@subclassA)
|
||||
|
||||
it "only returns a task that matches the criteria", ->
|
||||
expect(TaskQueue.findTask(TaskSubclassB, {bProp: 'B1'})).toEqual(@subclassB1)
|
||||
expect(TaskQueue.findTask(TaskSubclassB, {bProp: 'B2'})).toEqual(@subclassB2)
|
||||
expect(TaskQueue.findTask(TaskSubclassB, {bProp: 'B3'})).toEqual(null)
|
||||
|
||||
describe "enqueue", ->
|
||||
it "makes sure you've queued a real task", ->
|
||||
expect( -> TaskQueue.enqueue("asamw")).toThrow()
|
||||
|
|
|
@ -4,10 +4,13 @@ KeymapManager = require 'atom-keymap'
|
|||
|
||||
NylasTestUtils =
|
||||
loadKeymap: (keymapPath) ->
|
||||
baseKeymaps = CSON.readFileSync("keymaps/base.cson")
|
||||
atom.keymaps.add("keymaps/base.cson", baseKeymaps)
|
||||
{resourcePath} = atom.getLoadSettings()
|
||||
basePath = CSON.resolve("#{resourcePath}/keymaps/base")
|
||||
baseKeymaps = CSON.readFileSync(basePath)
|
||||
atom.keymaps.add(basePath, baseKeymaps)
|
||||
|
||||
if keymapPath?
|
||||
keymapPath = CSON.resolve("#{resourcePath}/#{keymapPath}")
|
||||
keymapFile = CSON.readFileSync(keymapPath)
|
||||
atom.keymaps.add(keymapPath, keymapFile)
|
||||
|
||||
|
@ -16,4 +19,3 @@ NylasTestUtils =
|
|||
document.dispatchEvent(event)
|
||||
|
||||
module.exports = NylasTestUtils
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
# Start the crash reporter before anything else.
|
||||
require('crash-reporter').start(productName: 'Atom', companyName: 'GitHub')
|
||||
require('crash-reporter').start(productName: 'Nylas Mail', companyName: 'Nylas')
|
||||
|
||||
|
||||
path = require 'path'
|
||||
fs = require 'fs-plus'
|
||||
|
|
|
@ -119,7 +119,7 @@ class Application
|
|||
# return a promise that resolves after we've configured dblite for our platform
|
||||
return @dblitePromise = new Promise (resolve, reject) =>
|
||||
dblite = require('../../vendor/dblite-custom').withSQLite('3.8.6+')
|
||||
vendor = @resourcePath + "/vendor"
|
||||
vendor = path.join(@resourcePath.replace('app.asar', 'app.asar.unpacked'), '/vendor')
|
||||
|
||||
if process.platform is 'win32'
|
||||
dblite.bin = "#{vendor}/sqlite3-win32.exe"
|
||||
|
@ -192,9 +192,17 @@ class Application
|
|||
@on 'application:run-all-specs', ->
|
||||
@runSpecs
|
||||
exitWhenDone: false
|
||||
resourcePath: global.devResourcePath
|
||||
resourcePath: @resourcePath
|
||||
safeMode: @windowManager.focusedWindow()?.safeMode
|
||||
|
||||
@on 'application:ship-logs', ->
|
||||
global.errorReporter.shipLogs("User triggered.")
|
||||
dialog.showMessageBox
|
||||
type: 'warning'
|
||||
buttons: ['OK']
|
||||
message: 'Your local Nylas Mail logs have been sent to LogStash.'
|
||||
title: 'Logs Shipped'
|
||||
|
||||
@on 'application:run-package-specs', ->
|
||||
dialog.showOpenDialog {
|
||||
title: 'Choose a Package Directory'
|
||||
|
@ -204,7 +212,7 @@ class Application
|
|||
return if filenames.length is 0
|
||||
@runSpecs
|
||||
exitWhenDone: false
|
||||
resourcePath: global.devResourcePath
|
||||
resourcePath: @resourcePath
|
||||
specDirectory: filenames[0]
|
||||
|
||||
@on 'application:run-benchmarks', ->
|
||||
|
|
|
@ -2,7 +2,7 @@ var app, errorReporter, fs, lstatSyncNoException, optimist, parseCommandLine, pa
|
|||
|
||||
global.shellStartTime = Date.now();
|
||||
|
||||
errorReporter = new (require('../error-reporter'));
|
||||
global.errorReporter = new (require('../error-reporter'));
|
||||
|
||||
app = require('app');
|
||||
|
||||
|
|
|
@ -21,26 +21,14 @@ animationSupported = => true
|
|||
###
|
||||
|
||||
addClass = (element, className) =>
|
||||
if element.classList
|
||||
element.classList.add className
|
||||
else if !hasClass(element, className)
|
||||
element.className = element.className + ' ' + className
|
||||
element.classList.add(className)
|
||||
element
|
||||
|
||||
removeClass = (element, className) =>
|
||||
if hasClass(className)
|
||||
if element.classList
|
||||
element.classList.remove className
|
||||
else
|
||||
element.className = (' ' + element.className + ' ').replace(' ' + className + ' ', ' ').trim()
|
||||
if element.classList.contains(className)
|
||||
element.classList.remove(className)
|
||||
element
|
||||
|
||||
hasClass = (element, className) =>
|
||||
if element.classList
|
||||
element.classList.contains className
|
||||
else
|
||||
(' ' + element.className + ' ').indexOf(' ' + className + ' ') > -1
|
||||
|
||||
|
||||
###
|
||||
Public: TimeoutTransitionGroup applies a CSS transition to the components added
|
||||
|
|
|
@ -14,7 +14,14 @@ if (process.type === 'renderer') {
|
|||
app = require('app');
|
||||
}
|
||||
|
||||
tmpPath = app.getPath('temp');
|
||||
var tmpPath = app.getPath('temp');
|
||||
|
||||
var logpid = process.pid;
|
||||
if (process.type === 'renderer') {
|
||||
logpid = remote.process.pid + "." + process.pid;
|
||||
}
|
||||
var logpath = path.join(tmpPath, 'edgehill-' + logpid + '.log');
|
||||
|
||||
|
||||
module.exports = ErrorReporter = (function() {
|
||||
function ErrorReporter() {
|
||||
|
@ -55,11 +62,6 @@ module.exports = ErrorReporter = (function() {
|
|||
}
|
||||
|
||||
// Open a file write stream to log output from this process
|
||||
var pid = process.pid;
|
||||
if (process.type === 'renderer') {
|
||||
pid = remote.process.pid + "." + process.pid;
|
||||
}
|
||||
var logpath = path.join(tmpPath, 'edgehill-' + pid + '.log');
|
||||
console.log("Streaming log data to "+logpath);
|
||||
|
||||
this.loghost = os.hostname();
|
||||
|
@ -162,6 +164,11 @@ module.exports = ErrorReporter = (function() {
|
|||
}
|
||||
};
|
||||
|
||||
ErrorReporter.prototype.openLogs = function() {
|
||||
var shell = require('shell');
|
||||
shell.openItem(logpath);
|
||||
};
|
||||
|
||||
ErrorReporter.prototype.shipLogs = function(reason) {
|
||||
if (!this.shipLogsQueued) {
|
||||
var timeSinceLogShip = Date.now() - this.shipLogsTime;
|
||||
|
|
|
@ -98,10 +98,7 @@ class DraftStore
|
|||
# In popout windows the existance of the window is the sending state.
|
||||
isSendingDraft: (draftLocalId) ->
|
||||
if atom.isMainWindow()
|
||||
task = TaskQueue.findTask
|
||||
object: "SendDraftTask"
|
||||
matchKey: "draftLocalId"
|
||||
matchValue: draftLocalId
|
||||
task = TaskQueue.findTask(SendDraftTask, {draftLocalId})
|
||||
return task?
|
||||
else return false
|
||||
|
||||
|
@ -376,11 +373,10 @@ class DraftStore
|
|||
# edits and are destroying the session. If there are errors down
|
||||
# the line, we'll make a new session and handle them later
|
||||
@_doneWithSession(session)
|
||||
@trigger()
|
||||
|
||||
atom.close() if @_isPopout()
|
||||
|
||||
@trigger()
|
||||
|
||||
_isPopout: ->
|
||||
atom.getWindowType() is "composer"
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ FileUploadStore = Reflux.createStore
|
|||
for path in pathsToOpen
|
||||
# When this task runs, we expect to hear `uploadStateChanged` actions.
|
||||
Actions.attachFilePath({messageLocalId, path})
|
||||
|
||||
|
||||
_onAttachFilePath: ({messageLocalId, path}) ->
|
||||
@_verifyId(messageLocalId)
|
||||
@task = new FileUploadTask(path, messageLocalId)
|
||||
|
@ -63,9 +63,10 @@ FileUploadStore = Reflux.createStore
|
|||
|
||||
_onAbortUpload: (uploadData) ->
|
||||
Actions.dequeueMatchingTask({
|
||||
object: 'FileUploadTask',
|
||||
matchKey: "filePath"
|
||||
matchValue: uploadData.filePath
|
||||
type: 'FileUploadTask',
|
||||
matching: {
|
||||
filePath: uploadData.filePath
|
||||
}
|
||||
})
|
||||
|
||||
_onFileUploaded: ({file, uploadData}) ->
|
||||
|
|
|
@ -45,9 +45,10 @@ if @_thread && @_thread.isUnread()
|
|||
|
||||
```coffee
|
||||
Actions.dequeueMatchingTask({
|
||||
object: 'FileUploadTask',
|
||||
matchKey: "filePath"
|
||||
matchValue: uploadData.filePath
|
||||
type: 'FileUploadTask',
|
||||
matching: {
|
||||
filePath: uploadData.filePath
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
|
@ -103,11 +104,23 @@ class TaskQueue
|
|||
queue: =>
|
||||
@_queue
|
||||
|
||||
findTask: ({object, matchKey, matchValue}) ->
|
||||
for other in @_queue by -1
|
||||
if object is object and other[matchKey] is matchValue
|
||||
return other
|
||||
return null
|
||||
###
|
||||
Public: Returns an existing task in the queue that matches the type you provide,
|
||||
and any other match properties. Useful for checking to see if something, like
|
||||
a "SendDraft" task is in-flight.
|
||||
|
||||
- `type`: The string name of the task class, or the Task class itself. (ie:
|
||||
{SaveDraftTask} or 'SaveDraftTask')
|
||||
|
||||
- `matching`: Optional An {Object} with criteria to pass to _.isMatch. For a
|
||||
SaveDraftTask, this could be {draftLocalId: "123123"}
|
||||
|
||||
Returns a matching {Task}, or null.
|
||||
###
|
||||
findTask: (type, matching = {}) ->
|
||||
type = type.name unless _.isString(type)
|
||||
match = _.find @_queue, (task) -> task.constructor.name is type and _.isMatch(task, matching)
|
||||
match ? null
|
||||
|
||||
enqueue: (task, {silent}={}) =>
|
||||
if not (task instanceof Task)
|
||||
|
@ -135,8 +148,8 @@ class TaskQueue
|
|||
@dequeue(task, silent: true) if task?
|
||||
@_update()
|
||||
|
||||
dequeueMatching: (task) =>
|
||||
toDequeue = @findTask(task)
|
||||
dequeueMatching: ({type, matching}) =>
|
||||
toDequeue = @findTask(type, matching)
|
||||
|
||||
if not toDequeue
|
||||
console.warn("Could not find task: #{task?.object}", task)
|
||||
|
|
|
@ -31,9 +31,20 @@ module.exports = (dir, regexPattern) ->
|
|||
|
||||
console.log("Uploading #{logs} to S3")
|
||||
|
||||
# The AWS Module does some really interesting stuff - it loads it's configuration
|
||||
# from JSON files. Unfortunately, when the app is built into an ASAR bundle, child
|
||||
# processes forked from the main process can't seem to access files inside the archive,
|
||||
# so AWS can't find it's JSON config. (5/20)
|
||||
if __dirname.indexOf('app.asar') != -1
|
||||
AWSModulePath = path.join(__dirname, '..','..','..', 'app.asar.unpacked', 'node_modules', 'aws-sdk')
|
||||
else
|
||||
AWSModulePath = 'aws-sdk'
|
||||
|
||||
console.log("Load AWS module from #{AWSModulePath}")
|
||||
|
||||
# Note: These credentials are only good for uploading to this
|
||||
# specific bucket and can't be used for anything else.
|
||||
AWS = require 'aws-sdk'
|
||||
AWS = require(AWSModulePath)
|
||||
AWS.config.update
|
||||
accessKeyId: 'AKIAIEGVDSVLK3Z7UVFA',
|
||||
secretAccessKey: '5ZNFMrjO3VUxpw4F9Y5xXPtVHgriwiWof4sFEsjQ'
|
||||
|
|
|
@ -32,17 +32,17 @@ class ThemeManager
|
|||
stylesElement.onDidRemoveStyleElement @styleElementRemoved.bind(this)
|
||||
stylesElement.onDidUpdateStyleElement @styleElementUpdated.bind(this)
|
||||
|
||||
if atom.inDevMode() and not atom.inSpecMode()
|
||||
console.log('In Dev Mode - Watching /static for LESS changes')
|
||||
watchStylesIn = (folder) =>
|
||||
stylePaths = fs.listTreeSync(folder)
|
||||
PathWatcher = require 'pathwatcher'
|
||||
for stylePath in stylePaths
|
||||
continue unless path.extname(stylePath) is '.less'
|
||||
PathWatcher.watch stylePath, =>
|
||||
@activateThemes()
|
||||
watchStylesIn("#{@resourcePath}/static")
|
||||
watchStylesIn("#{@resourcePath}/internal_packages")
|
||||
watchCoreStyles: ->
|
||||
console.log('Watching /static and /internal_packages for LESS changes')
|
||||
watchStylesIn = (folder) =>
|
||||
stylePaths = fs.listTreeSync(folder)
|
||||
PathWatcher = require 'pathwatcher'
|
||||
for stylePath in stylePaths
|
||||
continue unless path.extname(stylePath) is '.less'
|
||||
PathWatcher.watch stylePath, =>
|
||||
@activateThemes()
|
||||
watchStylesIn("#{@resourcePath}/static")
|
||||
watchStylesIn("#{@resourcePath}/internal_packages")
|
||||
|
||||
styleElementAdded: (styleElement) ->
|
||||
{sheet} = styleElement
|
||||
|
|
|
@ -71,6 +71,8 @@ class WindowEventHandler
|
|||
|
||||
@subscribeToCommand $(window), 'window:toggle-dev-tools', -> atom.toggleDevTools()
|
||||
|
||||
@subscribeToCommand $(window), 'window:open-errorreporter-logs', -> atom.errorReporter.openLogs()
|
||||
|
||||
if process.platform in ['win32', 'linux']
|
||||
@subscribeToCommand $(window), 'window:toggle-menu-bar', ->
|
||||
atom.config.set('core.autoHideMenuBar', !atom.config.get('core.autoHideMenuBar'))
|
||||
|
|
Loading…
Add table
Reference in a new issue