Files
atom/script/lib/package-application.js
Jason Rudolph da8b1a1a42 Merge pull request #19325 from atom/ns/notify-asar-exclude
Exclude @atom/notify binary from the ASAR bundle
2019-05-13 17:38:14 -04:00

168 lines
7.1 KiB
JavaScript

'use strict'
const assert = require('assert')
const childProcess = require('child_process')
const electronPackager = require('electron-packager')
const fs = require('fs-extra')
const hostArch = require('electron-packager/targets').hostArch
const includePathInPackagedApp = require('./include-path-in-packaged-app')
const getLicenseText = require('./get-license-text')
const path = require('path')
const spawnSync = require('./spawn-sync')
const CONFIG = require('../config')
const HOST_ARCH = hostArch()
module.exports = function () {
const appName = getAppName()
console.log(`Running electron-packager on ${CONFIG.intermediateAppPath} with app name "${appName}"`)
return runPackager({
appBundleId: 'com.github.atom',
appCopyright: `Copyright © 2014-${(new Date()).getFullYear()} GitHub, Inc. All rights reserved.`,
appVersion: CONFIG.appMetadata.version,
arch: process.platform === 'darwin' ? 'x64' : HOST_ARCH, // OS X is 64-bit only
asar: {unpack: buildAsarUnpackGlobExpression()},
buildVersion: CONFIG.appMetadata.version,
derefSymlinks: false,
download: {cache: CONFIG.electronDownloadPath},
dir: CONFIG.intermediateAppPath,
electronVersion: CONFIG.appMetadata.electronVersion,
extendInfo: path.join(CONFIG.repositoryRootPath, 'resources', 'mac', 'atom-Info.plist'),
helperBundleId: 'com.github.atom.helper',
icon: path.join(CONFIG.repositoryRootPath, 'resources', 'app-icons', CONFIG.channel, 'atom'),
name: appName,
out: CONFIG.buildOutputPath,
overwrite: true,
platform: process.platform,
// Atom doesn't have devDependencies, but if prune is true, it will delete the non-standard packageDependencies.
prune: false,
win32metadata: {
CompanyName: 'GitHub, Inc.',
FileDescription: 'Atom',
ProductName: 'Atom'
}
}).then((packagedAppPath) => {
let bundledResourcesPath
if (process.platform === 'darwin') {
bundledResourcesPath = path.join(packagedAppPath, 'Contents', 'Resources')
setAtomHelperVersion(packagedAppPath)
} else if (process.platform === 'linux') {
bundledResourcesPath = path.join(packagedAppPath, 'resources')
chmodNodeFiles(packagedAppPath)
} else {
bundledResourcesPath = path.join(packagedAppPath, 'resources')
}
return copyNonASARResources(packagedAppPath, bundledResourcesPath).then(() => {
console.log(`Application bundle created at ${packagedAppPath}`)
return packagedAppPath
})
})
}
function copyNonASARResources (packagedAppPath, bundledResourcesPath) {
console.log(`Copying non-ASAR resources to ${bundledResourcesPath}`)
fs.copySync(
path.join(CONFIG.repositoryRootPath, 'apm', 'node_modules', 'atom-package-manager'),
path.join(bundledResourcesPath, 'app', 'apm'),
{filter: includePathInPackagedApp}
)
if (process.platform !== 'win32') {
// Existing symlinks on user systems point to an outdated path, so just symlink it to the real location of the apm binary.
// TODO: Change command installer to point to appropriate path and remove this fallback after a few releases.
fs.symlinkSync(path.join('..', '..', 'bin', 'apm'), path.join(bundledResourcesPath, 'app', 'apm', 'node_modules', '.bin', 'apm'))
fs.copySync(path.join(CONFIG.repositoryRootPath, 'atom.sh'), path.join(bundledResourcesPath, 'app', 'atom.sh'))
}
if (process.platform === 'darwin') {
fs.copySync(path.join(CONFIG.repositoryRootPath, 'resources', 'mac', 'file.icns'), path.join(bundledResourcesPath, 'file.icns'))
} else if (process.platform === 'linux') {
fs.copySync(path.join(CONFIG.repositoryRootPath, 'resources', 'app-icons', CONFIG.channel, 'png', '1024.png'), path.join(packagedAppPath, 'atom.png'))
} else if (process.platform === 'win32') {
[ 'atom.cmd', 'atom.sh', 'atom.js', 'apm.cmd', 'apm.sh', 'file.ico', 'folder.ico' ]
.forEach(file => fs.copySync(path.join('resources', 'win', file), path.join(bundledResourcesPath, 'cli', file)))
}
console.log(`Writing LICENSE.md to ${bundledResourcesPath}`)
return getLicenseText().then((licenseText) => {
fs.writeFileSync(path.join(bundledResourcesPath, 'LICENSE.md'), licenseText)
})
}
function setAtomHelperVersion (packagedAppPath) {
const frameworksPath = path.join(packagedAppPath, 'Contents', 'Frameworks')
const helperPListPath = path.join(frameworksPath, 'Atom Helper.app', 'Contents', 'Info.plist')
console.log(`Setting Atom Helper Version for ${helperPListPath}`)
spawnSync('/usr/libexec/PlistBuddy', ['-c', `Add CFBundleVersion string ${CONFIG.appMetadata.version}`, helperPListPath])
spawnSync('/usr/libexec/PlistBuddy', ['-c', `Add CFBundleShortVersionString string ${CONFIG.appMetadata.version}`, helperPListPath])
}
function chmodNodeFiles (packagedAppPath) {
console.log(`Changing permissions for node files in ${packagedAppPath}`)
childProcess.execSync(`find "${packagedAppPath}" -type f -name *.node -exec chmod a-x {} \\;`)
}
function buildAsarUnpackGlobExpression () {
const unpack = [
'*.node',
'ctags-config',
'ctags-darwin',
'ctags-linux',
'ctags-win32.exe',
path.join('**', 'node_modules', 'spellchecker', '**'),
path.join('**', 'node_modules', 'dugite', 'git', '**'),
path.join('**', 'node_modules', 'github', 'bin', '**'),
path.join('**', 'node_modules', 'vscode-ripgrep', 'bin', '**'),
path.join('**', 'node_modules', '@atom', 'notify', 'bin', '**'),
path.join('**', 'resources', 'atom.png')
]
return `{${unpack.join(',')}}`
}
function getAppName () {
if (process.platform === 'darwin') {
return CONFIG.appName
} else {
return 'atom'
}
}
async function runPackager (options) {
const packageOutputDirPaths = await electronPackager(options)
assert(packageOutputDirPaths.length === 1, 'Generated more than one electron application!')
return renamePackagedAppDir(packageOutputDirPaths[0])
}
function renamePackagedAppDir (packageOutputDirPath) {
let packagedAppPath
if (process.platform === 'darwin') {
const appBundleName = getAppName() + '.app'
packagedAppPath = path.join(CONFIG.buildOutputPath, appBundleName)
if (fs.existsSync(packagedAppPath)) fs.removeSync(packagedAppPath)
fs.renameSync(path.join(packageOutputDirPath, appBundleName), packagedAppPath)
} else if (process.platform === 'linux') {
const appName = CONFIG.channel !== 'stable' ? `atom-${CONFIG.channel}` : 'atom'
let architecture
if (HOST_ARCH === 'ia32') {
architecture = 'i386'
} else if (HOST_ARCH === 'x64') {
architecture = 'amd64'
} else {
architecture = HOST_ARCH
}
packagedAppPath = path.join(CONFIG.buildOutputPath, `${appName}-${CONFIG.appMetadata.version}-${architecture}`)
if (fs.existsSync(packagedAppPath)) fs.removeSync(packagedAppPath)
fs.renameSync(packageOutputDirPath, packagedAppPath)
} else {
packagedAppPath = path.join(CONFIG.buildOutputPath, CONFIG.appName)
if (process.platform === 'win32' && HOST_ARCH !== 'ia32') {
packagedAppPath += ` ${process.arch}`
}
if (fs.existsSync(packagedAppPath)) fs.removeSync(packagedAppPath)
fs.renameSync(packageOutputDirPath, packagedAppPath)
}
return packagedAppPath
}