Merge branch 'master' into mb-use-native-text-buffer

This commit is contained in:
Max Brunsfeld
2017-06-01 11:09:09 -07:00
38 changed files with 273 additions and 226 deletions

View File

@@ -7,7 +7,7 @@ Ubuntu LTS 12.04 64-bit is the recommended platform.
* OS with 64-bit or 32-bit architecture
* C++11 toolchain
* Git
* Node.js 6.x (we recommend installing it via [nvm](https://github.com/creationix/nvm))
* Node.js 6.x or later (we recommend installing it via [nvm](https://github.com/creationix/nvm))
* npm 3.10.x or later (run `npm install -g npm`)
* Ensure node-gyp uses python2 (run `npm config set python /usr/bin/python2 -g`, use `sudo` if you didn't install node via nvm)
* Development headers for [libsecret](https://wiki.gnome.org/Projects/Libsecret).

View File

@@ -3,7 +3,7 @@
## Requirements
* macOS 10.8 or later
* Node.js 6.x (we recommend installing it via [nvm](https://github.com/creationix/nvm))
* Node.js 6.x or later (we recommend installing it via [nvm](https://github.com/creationix/nvm))
* npm 3.10.x or later (run `npm install -g npm`)
* Command Line Tools for [Xcode](https://developer.apple.com/xcode/downloads/) (run `xcode-select --install` to install)

View File

@@ -2,7 +2,7 @@
## Requirements
* Node.js 6.x (the architecture of node available to the build system will determine whether you build 32-bit or 64-bit Atom)
* Node.js 6.x or later (the architecture of node available to the build system will determine whether you build 32-bit or 64-bit Atom)
* Python v2.7.x
* The python.exe must be available at `%SystemDrive%\Python27\python.exe`. If it is installed elsewhere create a symbolic link to the directory containing the python.exe using: `mklink /d %SystemDrive%\Python27 D:\elsewhere\Python27`
* 7zip (7z.exe available from the command line) - for creating distribution zip files

View File

@@ -78,8 +78,8 @@
"atom-light-ui": "0.46.0",
"base16-tomorrow-dark-theme": "1.5.0",
"base16-tomorrow-light-theme": "1.5.0",
"one-dark-ui": "1.10.4",
"one-light-ui": "1.10.4",
"one-dark-ui": "1.10.5",
"one-light-ui": "1.10.5",
"one-dark-syntax": "1.7.1",
"one-light-syntax": "1.7.1",
"solarized-dark-syntax": "1.1.2",

View File

@@ -14,7 +14,7 @@ const yargs = require('yargs')
const argv = yargs
.usage('Usage: $0 [options]')
.help('help')
.describe('code-sign', 'Code-sign executables (macOS and Windows only)')
.describe('code-sign', 'Code-sign executables (macOS and Windows only)')
.describe('create-windows-installer', 'Create installer (Windows only)')
.describe('create-debian-package', 'Create .deb package (Linux only)')
.describe('create-rpm-package', 'Create .rpm package (Linux only)')
@@ -77,8 +77,7 @@ dumpSymbols()
} else if (process.platform === 'win32') {
if (argv.createWindowsInstaller) {
return createWindowsInstaller(packagedAppPath, argv.codeSign).then(() => packagedAppPath)
}
else {
} else {
console.log('Skipping creating installer. Specify the --create-windows-installer option to create a Squirrel-based Windows installer.'.gray)
if (argv.codeSign) {
codeSignOnWindows(packagedAppPath)

View File

@@ -22,11 +22,21 @@ const apmMetadata = require(path.join(apmRootPath, 'package.json'))
const channel = getChannel()
module.exports = {
appMetadata, apmMetadata, channel,
repositoryRootPath, apmRootPath, scriptRootPath,
buildOutputPath, docsOutputPath, intermediateAppPath, symbolsPath,
electronDownloadPath, atomHomeDirPath, homeDirPath,
getApmBinPath, getNpmBinPath,
appMetadata,
apmMetadata,
channel,
repositoryRootPath,
apmRootPath,
scriptRootPath,
buildOutputPath,
docsOutputPath,
intermediateAppPath,
symbolsPath,
electronDownloadPath,
atomHomeDirPath,
homeDirPath,
getApmBinPath,
getNpmBinPath,
snapshotAuxiliaryData: {}
}

View File

@@ -1,21 +1,21 @@
const fs = require('fs-extra')
const path = require('path')
module.exports = function(packagePath) {
module.exports = function (packagePath) {
const nodeModulesPath = path.join(packagePath, 'node_modules')
const nodeModulesBackupPath = path.join(packagePath, 'node_modules.bak')
if (fs.existsSync(nodeModulesBackupPath)) {
throw new Error("Cannot back up " + nodeModulesPath + "; " + nodeModulesBackupPath + " already exists")
throw new Error('Cannot back up ' + nodeModulesPath + '; ' + nodeModulesBackupPath + ' already exists')
}
// some packages may have no node_modules after deduping, but we still want
// to "back-up" and later restore that fact
if (!fs.existsSync(nodeModulesPath)) {
const msg = "Skipping backing up " + nodeModulesPath + " as it does not exist"
const msg = 'Skipping backing up ' + nodeModulesPath + ' as it does not exist'
console.log(msg.gray)
const restore = function stubRestoreNodeModules() {
const restore = function stubRestoreNodeModules () {
if (fs.existsSync(nodeModulesPath)) {
fs.removeSync(nodeModulesPath)
}
@@ -26,11 +26,11 @@ module.exports = function(packagePath) {
fs.copySync(nodeModulesPath, nodeModulesBackupPath)
const restore = function restoreNodeModules() {
const restore = function restoreNodeModules () {
if (!fs.existsSync(nodeModulesBackupPath)) {
throw new Error("Cannot restore " + nodeModulesPath + "; " + nodeModulesBackupPath + " does not exist")
throw new Error('Cannot restore ' + nodeModulesPath + '; ' + nodeModulesBackupPath + ' does not exist')
}
if (fs.existsSync(nodeModulesPath)) {
fs.removeSync(nodeModulesPath)
}

View File

@@ -9,14 +9,14 @@ module.exports = function () {
const fs = require('fs-extra')
const apmDependenciesPath = path.join(CONFIG.apmRootPath, 'node_modules')
console.log(`Cleaning ${apmDependenciesPath}`);
console.log(`Cleaning ${apmDependenciesPath}`)
fs.removeSync(apmDependenciesPath)
const atomDependenciesPath = path.join(CONFIG.repositoryRootPath, 'node_modules')
console.log(`Cleaning ${atomDependenciesPath}`);
console.log(`Cleaning ${atomDependenciesPath}`)
fs.removeSync(atomDependenciesPath)
const scriptDependenciesPath = path.join(CONFIG.scriptRootPath, 'node_modules')
console.log(`Cleaning ${scriptDependenciesPath}`);
console.log(`Cleaning ${scriptDependenciesPath}`)
fs.removeSync(scriptDependenciesPath)
}

View File

@@ -1,5 +1,4 @@
const fs = require('fs-extra')
const path = require('path')
const CONFIG = require('../config')
module.exports = function () {

View File

@@ -10,7 +10,7 @@ module.exports = function (packagedAppPath) {
return
}
let certPath = process.env.ATOM_MAC_CODE_SIGNING_CERT_PATH;
let certPath = process.env.ATOM_MAC_CODE_SIGNING_CERT_PATH
if (!certPath) {
certPath = path.join(os.tmpdir(), 'mac.p12')
downloadFileFromGithub(process.env.ATOM_MAC_CODE_SIGNING_CERT_DOWNLOAD_URL, certPath)
@@ -33,7 +33,6 @@ module.exports = function (packagedAppPath) {
'-T', '/usr/bin/codesign'
])
console.log('Running incantation to suppress dialog when signing on macOS Sierra')
try {
spawnSync('security', [
@@ -42,7 +41,7 @@ module.exports = function (packagedAppPath) {
process.env.ATOM_MAC_CODE_SIGNING_KEYCHAIN
])
} catch (e) {
console.log('Incantation failed... maybe this isn\'t Sierra?');
console.log('Incantation failed... maybe this isn\'t Sierra?')
}
console.log(`Code-signing application at ${packagedAppPath}`)

View File

@@ -28,7 +28,7 @@ module.exports = function (packagedAppPath) {
}
}
function signFile(filePath) {
function signFile (filePath) {
const signCommand = path.resolve(__dirname, '..', 'node_modules', 'electron-winstaller', 'vendor', 'signtool.exe')
const args = [ // Changing any of these should also be done in create-windows-installer.js
'sign',

View File

@@ -18,17 +18,17 @@ module.exports = function (packagedAppPath) {
function getArchiveName () {
switch (process.platform) {
case 'darwin': return 'atom-mac.zip'
case 'win32': return `atom-windows.zip`
default: return `atom-${getLinuxArchiveArch()}.tar.gz`
case 'darwin': return 'atom-mac.zip'
case 'win32': return 'atom-windows.zip'
default: return `atom-${getLinuxArchiveArch()}.tar.gz`
}
}
function getLinuxArchiveArch () {
switch (process.arch) {
case 'ia32': return 'i386'
case 'x64' : return 'amd64'
default: return process.arch
case 'ia32': return 'i386'
case 'x64' : return 'amd64'
default: return process.arch
}
}

View File

@@ -10,7 +10,7 @@ const glob = require('glob')
const includePathInPackagedApp = require('./include-path-in-packaged-app')
module.exports = function () {
console.log(`Copying assets to ${CONFIG.intermediateAppPath}`);
console.log(`Copying assets to ${CONFIG.intermediateAppPath}`)
let srcPaths = [
path.join(CONFIG.repositoryRootPath, 'benchmarks', 'benchmark-runner.js'),
path.join(CONFIG.repositoryRootPath, 'dot-atom'),

View File

@@ -77,16 +77,22 @@ module.exports = function (packagedAppPath) {
const packageSizeInKilobytes = spawnSync('du', ['-sk', packagedAppPath]).stdout.toString().split(/\s+/)[0]
const controlFileTemplate = fs.readFileSync(path.join(CONFIG.repositoryRootPath, 'resources', 'linux', 'debian', 'control.in'))
const controlFileContents = template(controlFileTemplate)({
appFileName: atomExecutableName, version: appVersion, arch: arch,
installedSize: packageSizeInKilobytes, description: appDescription
appFileName: atomExecutableName,
version: appVersion,
arch: arch,
installedSize: packageSizeInKilobytes,
description: appDescription
})
fs.writeFileSync(path.join(debianPackageConfigPath, 'control'), controlFileContents)
console.log(`Writing desktop entry file into "${debianPackageApplicationsDirPath}"`)
const desktopEntryTemplate = fs.readFileSync(path.join(CONFIG.repositoryRootPath, 'resources', 'linux', 'atom.desktop.in'))
const desktopEntryContents = template(desktopEntryTemplate)({
appName: appName, appFileName: atomExecutableName, description: appDescription,
installDir: '/usr', iconPath: atomExecutableName
appName: appName,
appFileName: atomExecutableName,
description: appDescription,
installDir: '/usr',
iconPath: atomExecutableName
})
fs.writeFileSync(path.join(debianPackageApplicationsDirPath, `${atomExecutableName}.desktop`), desktopEntryContents)

View File

@@ -2,7 +2,6 @@
const assert = require('assert')
const fs = require('fs-extra')
const os = require('os')
const path = require('path')
const spawnSync = require('./spawn-sync')
const template = require('lodash.template')
@@ -51,16 +50,23 @@ module.exports = function (packagedAppPath) {
const rpmPackageSpecFilePath = path.join(rpmPackageSpecsDirPath, 'atom.spec')
const rpmPackageSpecsTemplate = fs.readFileSync(path.join(CONFIG.repositoryRootPath, 'resources', 'linux', 'redhat', 'atom.spec.in'))
const rpmPackageSpecsContents = template(rpmPackageSpecsTemplate)({
appName: appName, appFileName: atomExecutableName, apmFileName: apmExecutableName,
description: appDescription, installDir: '/usr', version: appVersion
appName: appName,
appFileName: atomExecutableName,
apmFileName: apmExecutableName,
description: appDescription,
installDir: '/usr',
version: appVersion
})
fs.writeFileSync(rpmPackageSpecFilePath, rpmPackageSpecsContents)
console.log(`Writing desktop entry file into "${rpmPackageBuildDirPath}"`)
const desktopEntryTemplate = fs.readFileSync(path.join(CONFIG.repositoryRootPath, 'resources', 'linux', 'atom.desktop.in'))
const desktopEntryContents = template(desktopEntryTemplate)({
appName: appName, appFileName: atomExecutableName, description: appDescription,
installDir: '/usr', iconPath: atomExecutableName
appName: appName,
appFileName: atomExecutableName,
description: appDescription,
installDir: '/usr',
iconPath: atomExecutableName
})
fs.writeFileSync(path.join(rpmPackageBuildDirPath, `${atomExecutableName}.desktop`), desktopEntryContents)

View File

@@ -7,13 +7,13 @@ module.exports = function () {
process.env['PATH'] =
process.env['PATH']
.split(';')
.filter(function(p) {
.filter(function (p) {
if (fs.existsSync(path.join(p, 'msbuild.exe'))) {
console.log('Excluding "' + p + '" from PATH to avoid msbuild.exe mismatch that causes errors during module installation')
return false;
return false
} else {
return true;
return true
}
})
.join(';');
.join(';')
}

View File

@@ -158,7 +158,7 @@ function checkDeprecatedPackagesMetadata () {
for (let packageName of Object.keys(deprecatedPackagesMetadata)) {
const packageMetadata = deprecatedPackagesMetadata[packageName]
if (packageMetadata.version && !semver.validRange(packageMetadata.version)) {
throw new Error(`Invalid range: ${version} (${name}).`)
throw new Error(`Invalid range: ${packageMetadata.version} (${packageName}).`)
}
}
}

View File

@@ -28,46 +28,46 @@ module.exports = function (packagedAppPath) {
coreModules.has(modulePath) ||
(relativePath.startsWith(path.join('..', 'src')) && relativePath.endsWith('-element.js')) ||
relativePath.startsWith(path.join('..', 'node_modules', 'dugite')) ||
relativePath == path.join('..', 'exports', 'atom.js') ||
relativePath == path.join('..', 'src', 'electron-shims.js') ||
relativePath == path.join('..', 'src', 'safe-clipboard.js') ||
relativePath == path.join('..', 'node_modules', 'atom-keymap', 'lib', 'command-event.js') ||
relativePath == path.join('..', 'node_modules', 'babel-core', 'index.js') ||
relativePath == path.join('..', 'node_modules', 'cached-run-in-this-context', 'lib', 'main.js') ||
relativePath == path.join('..', 'node_modules', 'coffee-script', 'lib', 'coffee-script', 'register.js') ||
relativePath == path.join('..', 'node_modules', 'cson-parser', 'node_modules', 'coffee-script', 'lib', 'coffee-script', 'register.js') ||
relativePath == path.join('..', 'node_modules', 'decompress-zip', 'lib', 'decompress-zip.js') ||
relativePath == path.join('..', 'node_modules', 'debug', 'node.js') ||
relativePath == path.join('..', 'node_modules', 'fs-extra', 'lib', 'index.js') ||
relativePath == path.join('..', 'node_modules', 'git-utils', 'lib', 'git.js') ||
relativePath == path.join('..', 'node_modules', 'glob', 'glob.js') ||
relativePath == path.join('..', 'node_modules', 'graceful-fs', 'graceful-fs.js') ||
relativePath == path.join('..', 'node_modules', 'htmlparser2', 'lib', 'index.js') ||
relativePath == path.join('..', 'node_modules', 'markdown-preview', 'node_modules', 'htmlparser2', 'lib', 'index.js') ||
relativePath == path.join('..', 'node_modules', 'roaster', 'node_modules', 'htmlparser2', 'lib', 'index.js') ||
relativePath == path.join('..', 'node_modules', 'task-lists', 'node_modules', 'htmlparser2', 'lib', 'index.js') ||
relativePath == path.join('..', 'node_modules', 'iconv-lite', 'lib', 'index.js') ||
relativePath == path.join('..', 'node_modules', 'less', 'index.js') ||
relativePath == path.join('..', 'node_modules', 'less', 'lib', 'less', 'fs.js') ||
relativePath == path.join('..', 'node_modules', 'less', 'lib', 'less-node', 'index.js') ||
relativePath == path.join('..', 'node_modules', 'less', 'node_modules', 'graceful-fs', 'graceful-fs.js') ||
relativePath == path.join('..', 'node_modules', 'minimatch', 'minimatch.js') ||
relativePath == path.join('..', 'node_modules', 'node-fetch', 'lib', 'fetch-error.js') ||
relativePath == path.join('..', 'node_modules', 'nsfw', 'node_modules', 'fs-extra', 'lib', 'index.js') ||
relativePath == path.join('..', 'node_modules', 'superstring', 'index.js') ||
relativePath == path.join('..', 'node_modules', 'oniguruma', 'src', 'oniguruma.js') ||
relativePath == path.join('..', 'node_modules', 'request', 'index.js') ||
relativePath == path.join('..', 'node_modules', 'resolve', 'index.js') ||
relativePath == path.join('..', 'node_modules', 'resolve', 'lib', 'core.js') ||
relativePath == path.join('..', 'node_modules', 'scandal', 'node_modules', 'minimatch', 'minimatch.js') ||
relativePath == path.join('..', 'node_modules', 'settings-view', 'node_modules', 'glob', 'glob.js') ||
relativePath == path.join('..', 'node_modules', 'settings-view', 'node_modules', 'minimatch', 'minimatch.js') ||
relativePath == path.join('..', 'node_modules', 'spellchecker', 'lib', 'spellchecker.js') ||
relativePath == path.join('..', 'node_modules', 'spelling-manager', 'node_modules', 'natural', 'lib', 'natural', 'index.js') ||
relativePath == path.join('..', 'node_modules', 'tar', 'tar.js') ||
relativePath == path.join('..', 'node_modules', 'temp', 'lib', 'temp.js') ||
relativePath == path.join('..', 'node_modules', 'tmp', 'lib', 'tmp.js') ||
relativePath == path.join('..', 'node_modules', 'tree-view', 'node_modules', 'minimatch', 'minimatch.js')
relativePath === path.join('..', 'exports', 'atom.js') ||
relativePath === path.join('..', 'src', 'electron-shims.js') ||
relativePath === path.join('..', 'src', 'safe-clipboard.js') ||
relativePath === path.join('..', 'node_modules', 'atom-keymap', 'lib', 'command-event.js') ||
relativePath === path.join('..', 'node_modules', 'babel-core', 'index.js') ||
relativePath === path.join('..', 'node_modules', 'cached-run-in-this-context', 'lib', 'main.js') ||
relativePath === path.join('..', 'node_modules', 'coffee-script', 'lib', 'coffee-script', 'register.js') ||
relativePath === path.join('..', 'node_modules', 'cson-parser', 'node_modules', 'coffee-script', 'lib', 'coffee-script', 'register.js') ||
relativePath === path.join('..', 'node_modules', 'decompress-zip', 'lib', 'decompress-zip.js') ||
relativePath === path.join('..', 'node_modules', 'debug', 'node.js') ||
relativePath === path.join('..', 'node_modules', 'fs-extra', 'lib', 'index.js') ||
relativePath === path.join('..', 'node_modules', 'git-utils', 'lib', 'git.js') ||
relativePath === path.join('..', 'node_modules', 'glob', 'glob.js') ||
relativePath === path.join('..', 'node_modules', 'graceful-fs', 'graceful-fs.js') ||
relativePath === path.join('..', 'node_modules', 'htmlparser2', 'lib', 'index.js') ||
relativePath === path.join('..', 'node_modules', 'markdown-preview', 'node_modules', 'htmlparser2', 'lib', 'index.js') ||
relativePath === path.join('..', 'node_modules', 'roaster', 'node_modules', 'htmlparser2', 'lib', 'index.js') ||
relativePath === path.join('..', 'node_modules', 'task-lists', 'node_modules', 'htmlparser2', 'lib', 'index.js') ||
relativePath === path.join('..', 'node_modules', 'iconv-lite', 'lib', 'index.js') ||
relativePath === path.join('..', 'node_modules', 'less', 'index.js') ||
relativePath === path.join('..', 'node_modules', 'less', 'lib', 'less', 'fs.js') ||
relativePath === path.join('..', 'node_modules', 'less', 'lib', 'less-node', 'index.js') ||
relativePath === path.join('..', 'node_modules', 'less', 'node_modules', 'graceful-fs', 'graceful-fs.js') ||
relativePath === path.join('..', 'node_modules', 'minimatch', 'minimatch.js') ||
relativePath === path.join('..', 'node_modules', 'node-fetch', 'lib', 'fetch-error.js') ||
relativePath === path.join('..', 'node_modules', 'nsfw', 'node_modules', 'fs-extra', 'lib', 'index.js') ||
relativePath === path.join('..', 'node_modules', 'superstring', 'index.js') ||
relativePath === path.join('..', 'node_modules', 'oniguruma', 'src', 'oniguruma.js') ||
relativePath === path.join('..', 'node_modules', 'request', 'index.js') ||
relativePath === path.join('..', 'node_modules', 'resolve', 'index.js') ||
relativePath === path.join('..', 'node_modules', 'resolve', 'lib', 'core.js') ||
relativePath === path.join('..', 'node_modules', 'scandal', 'node_modules', 'minimatch', 'minimatch.js') ||
relativePath === path.join('..', 'node_modules', 'settings-view', 'node_modules', 'glob', 'glob.js') ||
relativePath === path.join('..', 'node_modules', 'settings-view', 'node_modules', 'minimatch', 'minimatch.js') ||
relativePath === path.join('..', 'node_modules', 'spellchecker', 'lib', 'spellchecker.js') ||
relativePath === path.join('..', 'node_modules', 'spelling-manager', 'node_modules', 'natural', 'lib', 'natural', 'index.js') ||
relativePath === path.join('..', 'node_modules', 'tar', 'tar.js') ||
relativePath === path.join('..', 'node_modules', 'temp', 'lib', 'temp.js') ||
relativePath === path.join('..', 'node_modules', 'tmp', 'lib', 'tmp.js') ||
relativePath === path.join('..', 'node_modules', 'tree-view', 'node_modules', 'minimatch', 'minimatch.js')
)
}
}).then((snapshotScript) => {

View File

@@ -20,7 +20,7 @@ module.exports = function () {
'with the following licenses:\n\n'
for (let packageName of Object.keys(packagesLicenses).sort()) {
const packageLicense = packagesLicenses[packageName]
text += "-------------------------------------------------------------------------\n\n"
text += '-------------------------------------------------------------------------\n\n'
text += `Package: ${packageName}\n`
text += `License: ${packageLicense.license}\n`
if (packageLicense.source) {

View File

@@ -13,7 +13,7 @@ module.exports = function (aPath) {
const user = (sepIndex < 0) ? aPath.substring(1) : aPath.substring(1, sepIndex)
const rest = (sepIndex < 0) ? '' : aPath.substring(sepIndex)
const home = (user === '') ? os.homedir() : (() => {
const passwd = passwdUser.sync(user);
const passwd = passwdUser.sync(user)
if (passwd === undefined) {
throw new Error(`Failed to expand the tilde in ${aPath} - user "${user}" does not exist`)
}

View File

@@ -67,7 +67,7 @@ const EXCLUDE_REGEXPS_SOURCES = [
// Ignore test and example folders
'node_modules' + escapeRegExp(path.sep) + '.*' + escapeRegExp(path.sep) + '_*te?sts?_*' + escapeRegExp(path.sep),
'node_modules' + escapeRegExp(path.sep) + '.*' + escapeRegExp(path.sep) + 'examples?' + escapeRegExp(path.sep),
'node_modules' + escapeRegExp(path.sep) + '.*' + escapeRegExp(path.sep) + 'examples?' + escapeRegExp(path.sep)
]
// Ignore spec directories in all bundled packages
@@ -89,5 +89,5 @@ const INCLUDED_PATHS_REGEXP = new RegExp(
)
function escapeRegExp (string) {
return string.replace(/[.?*+^$[\]\\(){}|-]/g, "\\$&")
return string.replace(/[.?*+^$[\]\\(){}|-]/g, '\\$&')
}

View File

@@ -1,7 +1,6 @@
'use strict'
const childProcess = require('child_process')
const path = require('path')
const CONFIG = require('../config')

View File

@@ -69,8 +69,11 @@ module.exports = function (packagedAppPath, installDir) {
const iconPath = path.join(CONFIG.repositoryRootPath, 'resources', 'app-icons', CONFIG.channel, 'png', '1024.png')
const desktopEntryTemplate = fs.readFileSync(path.join(CONFIG.repositoryRootPath, 'resources', 'linux', 'atom.desktop.in'))
const desktopEntryContents = template(desktopEntryTemplate)({
appName, appFileName: atomExecutableName, description: appDescription,
installDir: prefixDirPath, iconPath
appName,
appFileName: atomExecutableName,
description: appDescription,
installDir: prefixDirPath,
iconPath
})
fs.writeFileSync(desktopEntryPath, desktopEntryContents)

View File

@@ -1,7 +1,6 @@
'use strict'
const childProcess = require('child_process')
const path = require('path')
const CONFIG = require('../config')

View File

@@ -9,6 +9,7 @@ const CONFIG = require('../config')
module.exports = function () {
const globPathsToLint = [
path.join(CONFIG.repositoryRootPath, 'exports', '**', '*.js'),
path.join(CONFIG.repositoryRootPath, 'script', '**', '*.js'),
path.join(CONFIG.repositoryRootPath, 'src', '**', '*.js'),
path.join(CONFIG.repositoryRootPath, 'static', '*.js')
]

View File

@@ -55,7 +55,7 @@ module.exports = function () {
path.join(CONFIG.intermediateAppPath, 'node_modules', syntaxTheme, 'styles'),
path.join(CONFIG.intermediateAppPath, 'node_modules', uiTheme, 'styles'),
path.join(CONFIG.intermediateAppPath, 'static', 'variables'),
path.join(CONFIG.intermediateAppPath, 'static'),
path.join(CONFIG.intermediateAppPath, 'static')
]
})
@@ -72,30 +72,21 @@ module.exports = function () {
}
}
function cacheCompiledCSS(lessFilePath, importFallbackVariables) {
let lessSource = fs.readFileSync(lessFilePath, 'utf8')
if (importFallbackVariables) {
lessSource = FALLBACK_VARIABLE_IMPORTS + lessSource
}
lessCache.cssForFile(lessFilePath, lessSource)
saveIntoSnapshotAuxiliaryData(lessFilePath, lessSource)
}
// Cache all styles in static; don't append variable imports
for (let lessFilePath of glob.sync(path.join(CONFIG.intermediateAppPath, 'static', '**', '*.less'))) {
cacheCompiledCSS(lessFilePath, false)
cacheCompiledCSS(lessCache, lessFilePath, false)
}
// Cache styles for all bundled non-theme packages
for (let nonThemePackage of nonThemePackages) {
for (let lessFilePath of glob.sync(path.join(CONFIG.intermediateAppPath, 'node_modules', nonThemePackage, '**', '*.less'))) {
cacheCompiledCSS(lessFilePath, true)
cacheCompiledCSS(lessCache, lessFilePath, true)
}
}
// Cache styles for this UI theme
const uiThemeMainPath = path.join(CONFIG.intermediateAppPath, 'node_modules', uiTheme, 'index.less')
cacheCompiledCSS(uiThemeMainPath, true)
cacheCompiledCSS(lessCache, uiThemeMainPath, true)
for (let lessFilePath of glob.sync(path.join(CONFIG.intermediateAppPath, 'node_modules', uiTheme, '**', '*.less'))) {
if (lessFilePath !== uiThemeMainPath) {
saveIntoSnapshotAuxiliaryData(lessFilePath, fs.readFileSync(lessFilePath, 'utf8'))
@@ -104,7 +95,7 @@ module.exports = function () {
// Cache styles for this syntax theme
const syntaxThemeMainPath = path.join(CONFIG.intermediateAppPath, 'node_modules', syntaxTheme, 'index.less')
cacheCompiledCSS(syntaxThemeMainPath, true)
cacheCompiledCSS(lessCache, syntaxThemeMainPath, true)
for (let lessFilePath of glob.sync(path.join(CONFIG.intermediateAppPath, 'node_modules', syntaxTheme, '**', '*.less'))) {
if (lessFilePath !== syntaxThemeMainPath) {
saveIntoSnapshotAuxiliaryData(lessFilePath, fs.readFileSync(lessFilePath, 'utf8'))
@@ -116,4 +107,13 @@ module.exports = function () {
for (let lessFilePath of glob.sync(path.join(CONFIG.intermediateAppPath, 'node_modules', 'atom-ui', '**', '*.less'))) {
saveIntoSnapshotAuxiliaryData(lessFilePath, fs.readFileSync(lessFilePath, 'utf8'))
}
function cacheCompiledCSS (lessCache, lessFilePath, importFallbackVariables) {
let lessSource = fs.readFileSync(lessFilePath, 'utf8')
if (importFallbackVariables) {
lessSource = FALLBACK_VARIABLE_IMPORTS + lessSource
}
lessCache.cssForFile(lessFilePath, lessSource)
saveIntoSnapshotAuxiliaryData(lessFilePath, lessSource)
}
}

View File

@@ -1,7 +1,6 @@
'use strict'
const childProcess = require('child_process')
const path = require('path')
const CONFIG = require('../config')
@@ -11,7 +10,7 @@ module.exports = function (packagePath) {
installEnv.ATOM_RESOURCE_PATH = CONFIG.repositoryRootPath
// Set our target (Electron) version so that node-pre-gyp can download the
// proper binaries.
installEnv.npm_config_target = CONFIG.appMetadata.electronVersion;
installEnv.npm_config_target = CONFIG.appMetadata.electronVersion
childProcess.execFileSync(
CONFIG.getApmBinPath(),
['--loglevel=error', 'install'],

View File

@@ -6,15 +6,6 @@ const glob = require('glob')
const path = require('path')
const CONFIG = require('../config')
const BABEL_OPTIONS = require('../../static/babelrc.json')
const BABEL_PREFIXES = [
"'use babel'",
'"use babel"',
'/** @babel */',
'/* @flow */'
]
const PREFIX_LENGTH = Math.max.apply(null, BABEL_PREFIXES.map(prefix => prefix.length))
const BUFFER = Buffer(PREFIX_LENGTH)
module.exports = function () {
console.log(`Transpiling Babel paths in ${CONFIG.intermediateAppPath}`)

View File

@@ -11,7 +11,6 @@ const runApmInstall = require('./run-apm-install')
require('colors')
module.exports = function () {
console.log(`Transpiling packages with custom transpiler configurations in ${CONFIG.intermediateAppPath}`)
for (let packageName of Object.keys(CONFIG.appMetadata.packageDependencies)) {

View File

@@ -1,6 +1,6 @@
'use strict'
const peg = require("pegjs")
const peg = require('pegjs')
const fs = require('fs')
const glob = require('glob')
const path = require('path')

View File

@@ -17,10 +17,11 @@ module.exports = function () {
function verifyNode () {
const fullVersion = process.versions.node
const majorVersion = fullVersion.split('.')[0]
if (majorVersion >= 4 && majorVersion < 7) {
if (majorVersion >= 6) {
console.log(`Node:\tv${fullVersion}`)
} else if (majorVersion >= 7) {
throw new Error(`Atom does not build properly on node v7+. node v${fullVersion} is installed.`)
} else if (majorVersion >= 4) {
console.log(`Node:\tv${fullVersion}`)
console.warn('\tWarning: Building on Node below version 6 is deprecated. Please use Node 6.x+ to build Atom.')
} else {
throw new Error(`node v4+ is required to build Atom. node v${fullVersion} is installed.`)
}
@@ -51,7 +52,7 @@ function verifyPython () {
}
}
const stdout = childProcess.execFileSync(pythonExecutable, ['-c', 'import platform\nprint(platform.python_version())'], {env: process.env})
let stdout = childProcess.execFileSync(pythonExecutable, ['-c', 'import platform\nprint(platform.python_version())'], {env: process.env})
if (stdout.indexOf('+') !== -1) stdout = stdout.replace(/\+/g, '')
if (stdout.indexOf('rc') !== -1) stdout = stdout.replace(/rc(.*)$/ig, '')
const fullVersion = stdout.toString().trim()

File diff suppressed because one or more lines are too long

View File

@@ -107,8 +107,8 @@ for (let packageName in CONFIG.appMetadata.packageDependencies) {
}
const cp = childProcess.spawn(executablePath, testArguments)
let stderrOutput = ''
cp.stderr.on('data', data => stderrOutput += data)
cp.stdout.on('data', data => stderrOutput += data)
cp.stderr.on('data', data => { stderrOutput += data })
cp.stdout.on('data', data => { stderrOutput += data })
cp.on('error', error => {
finalize()
callback(error)

View File

@@ -59,7 +59,7 @@ describe "MenuManager", ->
atom.keymaps.add 'test', 'atom-workspace': 'ctrl-b': 'b'
menu.update()
waits 1
waits 50
runs -> expect(menu.sendToBrowserProcess.argsForCall[0][1]['b']).toEqual ['ctrl-b']

View File

@@ -27,6 +27,11 @@ document.registerElement('text-editor-component-test-element', {
describe('TextEditorComponent', () => {
beforeEach(() => {
jasmine.useRealClock()
// Force scrollbars to be visible regardless of local system configuration
const scrollbarStyle = document.createElement('style')
scrollbarStyle.textContent = '::-webkit-scrollbar { -webkit-appearance: none }'
jasmine.attachToDOM(scrollbarStyle)
})
describe('rendering', () => {
@@ -591,11 +596,32 @@ describe('TextEditorComponent', () => {
)
})
it('supports the isLineNumberGutterVisible parameter', () => {
it('does not render the line number gutter at all if the isLineNumberGutterVisible parameter is false', () => {
const {component, element, editor} = buildComponent({lineNumberGutterVisible: false})
expect(element.querySelector('.line-number')).toBe(null)
})
it('does not render the line numbers but still renders the line number gutter if showLineNumbers is false', async () => {
function checkScrollContainerLeft (component) {
const {scrollContainer, gutterContainer} = component.refs
expect(scrollContainer.getBoundingClientRect().left).toBe(Math.round(gutterContainer.element.getBoundingClientRect().right))
}
const {component, element, editor} = buildComponent({showLineNumbers: false})
expect(Array.from(element.querySelectorAll('.line-number')).every((e) => e.textContent === '')).toBe(true)
checkScrollContainerLeft(component)
await editor.update({showLineNumbers: true})
expect(Array.from(element.querySelectorAll('.line-number')).map((e) => e.textContent)).toEqual([
'00', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13'
])
checkScrollContainerLeft(component)
await editor.update({showLineNumbers: false})
expect(Array.from(element.querySelectorAll('.line-number')).every((e) => e.textContent === '')).toBe(true)
checkScrollContainerLeft(component)
})
it('supports the placeholderText parameter', () => {
const placeholderText = 'Placeholder Test'
const {element} = buildComponent({placeholderText, text: ''})
@@ -3396,7 +3422,7 @@ function buildEditor (params = {}) {
const buffer = new TextBuffer({text})
const editorParams = {buffer}
if (params.height != null) params.autoHeight = false
for (const paramName of ['mini', 'autoHeight', 'autoWidth', 'lineNumberGutterVisible', 'placeholderText', 'softWrapped']) {
for (const paramName of ['mini', 'autoHeight', 'autoWidth', 'lineNumberGutterVisible', 'showLineNumbers', 'placeholderText', 'softWrapped']) {
if (params[paramName] != null) editorParams[paramName] = params[paramName]
}
return new TextEditor(editorParams)

View File

@@ -447,6 +447,7 @@ class Pane
# Public: Make the given item *active*, causing it to be displayed by
# the pane's view.
#
# * `item` The item to activate
# * `options` (optional) {Object}
# * `pending` (optional) {Boolean} indicating that the item should be added
# in a pending state if it does not yet exist in the pane. Existing pending

View File

@@ -116,6 +116,7 @@ class TextEditorComponent {
this.lineNodesByScreenLineId = new Map()
this.textNodesByScreenLineId = new Map()
this.overlayComponents = new Set()
this.overlayDimensionsByElement = new WeakMap()
this.shouldRenderDummyScrollbars = true
this.remeasureScrollbars = false
this.pendingAutoscroll = null
@@ -134,6 +135,7 @@ class TextEditorComponent {
this.idsByTileStartRow = new Map()
this.nextTileId = 0
this.renderedTileStartRows = []
this.showLineNumbers = this.props.model.doesShowLineNumbers()
this.lineNumbersToRender = {
maxDigits: 2,
bufferRows: [],
@@ -481,6 +483,7 @@ class TextEditorComponent {
guttersToRender: this.guttersToRender,
decorationsToRender: this.decorationsToRender,
isLineNumberGutterVisible: this.props.model.isLineNumberGutterVisible(),
showLineNumbers: this.showLineNumbers,
lineNumbersToRender: this.lineNumbersToRender,
didMeasureVisibleBlockDecoration: this.didMeasureVisibleBlockDecoration
})
@@ -754,6 +757,7 @@ class TextEditorComponent {
{
key: overlayProps.element,
overlayComponents: this.overlayComponents,
measuredDimensions: this.overlayDimensionsByElement.get(overlayProps.element),
didResize: () => { this.updateSync() }
},
overlayProps
@@ -816,6 +820,10 @@ class TextEditorComponent {
queryLineNumbersToRender () {
const {model} = this.props
if (!model.isLineNumberGutterVisible()) return
if (this.showLineNumbers !== model.doesShowLineNumbers()) {
this.remeasureGutterDimensions = true
this.showLineNumbers = model.doesShowLineNumbers()
}
this.queryMaxLineNumberDigits()
@@ -1300,15 +1308,16 @@ class TextEditorComponent {
const {row, column} = screenPosition
let wrapperTop = contentClientRect.top + this.pixelPositionAfterBlocksForRow(row) + this.getLineHeight()
let wrapperLeft = contentClientRect.left + this.pixelLeftForRowAndColumn(row, column)
const clientRect = element.getBoundingClientRect()
this.overlayDimensionsByElement.set(element, clientRect)
if (avoidOverflow !== false) {
const computedStyle = window.getComputedStyle(element)
const elementHeight = element.offsetHeight
const elementTop = wrapperTop + parseInt(computedStyle.marginTop)
const elementBottom = elementTop + elementHeight
const flippedElementTop = wrapperTop - this.getLineHeight() - elementHeight - parseInt(computedStyle.marginBottom)
const elementBottom = elementTop + clientRect.height
const flippedElementTop = wrapperTop - this.getLineHeight() - clientRect.height - parseInt(computedStyle.marginBottom)
const elementLeft = wrapperLeft + parseInt(computedStyle.marginLeft)
const elementRight = elementLeft + element.offsetWidth
const elementRight = elementLeft + clientRect.width
if (elementBottom > windowInnerHeight && flippedElementTop >= 0) {
wrapperTop -= (elementTop - flippedElementTop)
@@ -1320,8 +1329,8 @@ class TextEditorComponent {
}
}
decoration.pixelTop = wrapperTop
decoration.pixelLeft = wrapperLeft
decoration.pixelTop = Math.round(wrapperTop)
decoration.pixelLeft = Math.round(wrapperLeft)
}
}
@@ -1410,24 +1419,8 @@ class TextEditorComponent {
this.scheduleUpdate()
}
// Transfer focus to the hidden input, but first ensure the input is in the
// visible part of the scrolled content to avoid the browser trying to
// auto-scroll to the form-field.
const {hiddenInput} = this.refs.cursorsAndInput.refs
hiddenInput.style.top = this.getScrollTop() + 'px'
hiddenInput.style.left = this.getScrollLeft() + 'px'
hiddenInput.focus()
// Restore the previous position of the field now that it is already focused
// and won't cause unwanted scrolling.
if (this.hiddenInputPosition) {
hiddenInput.style.top = this.hiddenInputPosition.pixelTop + 'px'
hiddenInput.style.left = this.hiddenInputPosition.pixelLeft + 'px'
} else {
hiddenInput.style.top = 0
hiddenInput.style.left = 0
}
}
// Called by TextEditorElement so that this function is always the first
@@ -1450,6 +1443,12 @@ class TextEditorComponent {
}
didFocusHiddenInput () {
// Focusing the hidden input when it is off-screen causes the browser to
// scroll it into view. Since we use synthetic scrolling this behavior
// causes all the lines to disappear so we counteract it by always setting
// the scroll position to 0.
this.refs.scrollContainer.scrollTop = 0
this.refs.scrollContainer.scrollLeft = 0
if (!this.focused) {
this.focused = true
this.startCursorBlinking()
@@ -2899,7 +2898,7 @@ class GutterContainerComponent {
renderLineNumberGutter (gutter) {
const {
rootComponent, isLineNumberGutterVisible, hasInitialMeasurements, lineNumbersToRender,
rootComponent, isLineNumberGutterVisible, showLineNumbers, hasInitialMeasurements, lineNumbersToRender,
renderedStartRow, renderedEndRow, rowsPerTile, decorationsToRender, didMeasureVisibleBlockDecoration,
scrollHeight, lineNumberGutterWidth, lineHeight
} = this.props
@@ -2925,13 +2924,15 @@ class GutterContainerComponent {
didMeasureVisibleBlockDecoration: didMeasureVisibleBlockDecoration,
height: scrollHeight,
width: lineNumberGutterWidth,
lineHeight: lineHeight
lineHeight: lineHeight,
showLineNumbers
})
} else {
return $(LineNumberGutterComponent, {
ref: 'lineNumberGutter',
element: gutter.getElement(),
maxDigits: lineNumbersToRender.maxDigits
maxDigits: lineNumbersToRender.maxDigits,
showLineNumbers
})
}
}
@@ -2955,7 +2956,7 @@ class LineNumberGutterComponent {
render () {
const {
rootComponent, height, width, lineHeight, startRow, endRow, rowsPerTile,
rootComponent, showLineNumbers, height, width, lineHeight, startRow, endRow, rowsPerTile,
maxDigits, keys, bufferRows, softWrappedFlags, foldableFlags, decorations
} = this.props
@@ -2980,8 +2981,11 @@ class LineNumberGutterComponent {
const decorationsForRow = decorations[row - startRow]
if (decorationsForRow) className = className + ' ' + decorationsForRow
let number = softWrapped ? '•' : bufferRow + 1
number = NBSP_CHARACTER.repeat(maxDigits - number.length) + number
let number = null
if (showLineNumbers) {
number = softWrapped ? '•' : bufferRow + 1
number = NBSP_CHARACTER.repeat(maxDigits - number.length) + number
}
const lineNumberProps = {
key,
@@ -3024,7 +3028,7 @@ class LineNumberGutterComponent {
return $.div(
{
className: 'gutter line-bufferRows',
className: 'gutter line-numbers',
attributes: {'gutter-name': 'line-number'},
style: {position: 'relative', height: height + 'px'},
on: {
@@ -3032,7 +3036,7 @@ class LineNumberGutterComponent {
}
},
$.div({key: 'placeholder', className: 'line-number dummy', style: {visibility: 'hidden'}},
'0'.repeat(maxDigits),
showLineNumbers ? '0'.repeat(maxDigits) : null,
$.div({className: 'icon-right'})
),
children
@@ -3042,6 +3046,7 @@ class LineNumberGutterComponent {
shouldUpdate (newProps) {
const oldProps = this.props
if (oldProps.showLineNumbers !== newProps.showLineNumbers) return true
if (oldProps.height !== newProps.height) return true
if (oldProps.width !== newProps.width) return true
if (oldProps.lineHeight !== newProps.lineHeight) return true
@@ -3855,10 +3860,13 @@ class OverlayComponent {
// Synchronous DOM updates in response to resize events might trigger a
// "loop limit exceeded" error. We disconnect the observer before
// potentially mutating the DOM, and then reconnect it on the next tick.
this.resizeObserver = new ResizeObserver(() => {
this.resizeObserver.disconnect()
this.props.didResize()
process.nextTick(() => { this.resizeObserver.observe(this.element) })
this.resizeObserver = new ResizeObserver((entries) => {
const {contentRect} = entries[0]
if (contentRect.width !== this.props.measuredDimensions.width || contentRect.height !== this.props.measuredDimensions.height) {
this.resizeObserver.disconnect()
this.props.didResize()
process.nextTick(() => { this.resizeObserver.observe(this.element) })
}
})
this.didAttach()
this.props.overlayComponents.add(this)

View File

@@ -98,7 +98,6 @@ class TextEditor extends Model
registered: false
atomicSoftTabs: true
invisibles: null
showLineNumbers: true
scrollSensitivity: 40
Object.defineProperty @prototype, "element",
@@ -156,7 +155,7 @@ class TextEditor extends Model
{
@softTabs, @initialScrollTopRow, @initialScrollLeftColumn, initialLine, initialColumn, tabLength,
@softWrapped, @decorationManager, @selectionsMarkerLayer, @buffer, suppressCursorCreation,
@mini, @placeholderText, lineNumberGutterVisible, @largeFileMode,
@mini, @placeholderText, lineNumberGutterVisible, @showLineNumbers, @largeFileMode,
@assert, grammar, @showInvisibles, @autoHeight, @autoWidth, @scrollPastEnd, @editorWidthInChars,
@tokenizedBuffer, @displayLayer, @invisibles, @showIndentGuide,
@softWrapped, @softWrapAtPreferredLineLength, @preferredLineLength,
@@ -184,6 +183,7 @@ class TextEditor extends Model
@softWrapped ?= false
@softWrapAtPreferredLineLength ?= false
@preferredLineLength ?= 80
@showLineNumbers ?= true
@buffer ?= new TextBuffer({
shouldDestroyOnFileDelete: -> atom.config.get('core.closeDeletedFileTabs')
@@ -358,6 +358,7 @@ class TextEditor extends Model
when 'showLineNumbers'
if value isnt @showLineNumbers
@showLineNumbers = value
@component?.scheduleUpdate()
when 'showInvisibles'
if value isnt @showInvisibles