mirror of
https://github.com/pulsar-edit/pulsar.git
synced 2024-09-20 15:37:46 +03:00
cef511c5d2
This is a follow up for #15498
158 lines
6.6 KiB
JavaScript
158 lines
6.6 KiB
JavaScript
'use strict'
|
|
|
|
const fs = require('fs-extra')
|
|
const handleTilde = require('./handle-tilde')
|
|
const path = require('path')
|
|
const template = require('lodash.template')
|
|
const startCase = require('lodash.startcase')
|
|
const execSync = require('child_process').execSync
|
|
|
|
const CONFIG = require('../config')
|
|
|
|
function install (installationDirPath, packagedAppFileName, packagedAppPath) {
|
|
if (fs.existsSync(installationDirPath)) {
|
|
console.log(`Removing previously installed "${packagedAppFileName}" at "${installationDirPath}"`)
|
|
fs.removeSync(installationDirPath)
|
|
}
|
|
|
|
console.log(`Installing "${packagedAppFileName}" at "${installationDirPath}"`)
|
|
fs.copySync(packagedAppPath, installationDirPath)
|
|
}
|
|
|
|
/**
|
|
* Finds the path to the base directory of the icon default icon theme
|
|
* This follows the freedesktop Icon Theme Specification:
|
|
* https://standards.freedesktop.org/icon-theme-spec/icon-theme-spec-latest.html#install_icons
|
|
* and the XDG Base Directory Specification:
|
|
* https://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html#variables
|
|
*/
|
|
function findBaseIconThemeDirPath () {
|
|
const defaultBaseIconThemeDir = '/usr/share/icons/hicolor'
|
|
const dataDirsString = process.env.XDG_DATA_DIRS
|
|
if (dataDirsString) {
|
|
const dataDirs = dataDirsString.split(path.delimiter)
|
|
if (dataDirs.includes('/usr/share/') || dataDirs.includes('/usr/share')) {
|
|
return defaultBaseIconThemeDir
|
|
} else {
|
|
return path.join(dataDirs[0], 'icons', 'hicolor')
|
|
}
|
|
} else {
|
|
return defaultBaseIconThemeDir
|
|
}
|
|
}
|
|
|
|
module.exports = function (packagedAppPath, installDir) {
|
|
const packagedAppFileName = path.basename(packagedAppPath)
|
|
if (process.platform === 'darwin') {
|
|
const installPrefix = installDir !== '' ? handleTilde(installDir) : path.join(path.sep, 'Applications')
|
|
const installationDirPath = path.join(installPrefix, packagedAppFileName)
|
|
install(installationDirPath, packagedAppFileName, packagedAppPath)
|
|
} else if (process.platform === 'win32') {
|
|
const installPrefix = installDir !== '' ? installDir : process.env.LOCALAPPDATA
|
|
const installationDirPath = path.join(installPrefix, packagedAppFileName, 'app-dev')
|
|
try {
|
|
install(installationDirPath, packagedAppFileName, packagedAppPath)
|
|
} catch (e) {
|
|
console.log(`Administrator elevation required to install into "${installationDirPath}"`)
|
|
const fsAdmin = require('fs-admin')
|
|
return new Promise((resolve, reject) => {
|
|
fsAdmin.recursiveCopy(packagedAppPath, installationDirPath, (error) => {
|
|
error ? reject(error) : resolve()
|
|
})
|
|
})
|
|
}
|
|
} else {
|
|
const atomExecutableName = CONFIG.channel === 'stable' ? 'atom' : 'atom-' + CONFIG.channel
|
|
const apmExecutableName = CONFIG.channel === 'stable' ? 'apm' : 'apm-' + CONFIG.channel
|
|
const appName = CONFIG.channel === 'stable' ? 'Atom' : startCase('Atom ' + CONFIG.channel)
|
|
const appDescription = CONFIG.appMetadata.description
|
|
const prefixDirPath = installDir !== '' ? handleTilde(installDir) : path.join('/usr', 'local')
|
|
const shareDirPath = path.join(prefixDirPath, 'share')
|
|
const installationDirPath = path.join(shareDirPath, atomExecutableName)
|
|
const applicationsDirPath = path.join(shareDirPath, 'applications')
|
|
|
|
const binDirPath = path.join(prefixDirPath, 'bin')
|
|
|
|
fs.mkdirpSync(applicationsDirPath)
|
|
fs.mkdirpSync(binDirPath)
|
|
|
|
install(installationDirPath, packagedAppFileName, packagedAppPath)
|
|
|
|
{ // Install icons
|
|
const baseIconThemeDirPath = findBaseIconThemeDirPath()
|
|
const fullIconName = atomExecutableName + '.png'
|
|
|
|
let existingIconsFound = false
|
|
fs.readdirSync(baseIconThemeDirPath).forEach(size => {
|
|
const iconPath = path.join(baseIconThemeDirPath, size, 'apps', fullIconName)
|
|
if (fs.existsSync(iconPath)) {
|
|
if (!existingIconsFound) {
|
|
console.log(`Removing existing icons from "${baseIconThemeDirPath}"`)
|
|
}
|
|
existingIconsFound = true
|
|
fs.removeSync(iconPath)
|
|
}
|
|
})
|
|
|
|
console.log(`Installing icons at "${baseIconThemeDirPath}"`)
|
|
const appIconsPath = path.join(CONFIG.repositoryRootPath, 'resources', 'app-icons', CONFIG.channel, 'png')
|
|
fs.readdirSync(appIconsPath).forEach(imageName => {
|
|
if (/\.png$/.test(imageName)) {
|
|
const size = path.basename(imageName, '.png')
|
|
const iconPath = path.join(appIconsPath, imageName)
|
|
fs.copySync(iconPath, path.join(baseIconThemeDirPath, `${size}x${size}`, 'apps', fullIconName))
|
|
}
|
|
})
|
|
|
|
console.log(`Updating icon cache for "${baseIconThemeDirPath}"`)
|
|
try {
|
|
execSync(`gtk-update-icon-cache ${baseIconThemeDirPath} --force`)
|
|
} catch (e) {}
|
|
}
|
|
|
|
{ // Install xdg desktop file
|
|
const desktopEntryPath = path.join(applicationsDirPath, `${atomExecutableName}.desktop`)
|
|
if (fs.existsSync(desktopEntryPath)) {
|
|
console.log(`Removing existing desktop entry file at "${desktopEntryPath}"`)
|
|
fs.removeSync(desktopEntryPath)
|
|
}
|
|
console.log(`Writing desktop entry file at "${desktopEntryPath}"`)
|
|
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: atomExecutableName
|
|
})
|
|
fs.writeFileSync(desktopEntryPath, desktopEntryContents)
|
|
}
|
|
|
|
{ // Add atom executable to the PATH
|
|
const atomBinDestinationPath = path.join(binDirPath, atomExecutableName)
|
|
if (fs.existsSync(atomBinDestinationPath)) {
|
|
console.log(`Removing existing executable at "${atomBinDestinationPath}"`)
|
|
fs.removeSync(atomBinDestinationPath)
|
|
}
|
|
console.log(`Copying atom.sh to "${atomBinDestinationPath}"`)
|
|
fs.copySync(path.join(CONFIG.repositoryRootPath, 'atom.sh'), atomBinDestinationPath)
|
|
}
|
|
|
|
{ // Link apm executable to the PATH
|
|
const apmBinDestinationPath = path.join(binDirPath, apmExecutableName)
|
|
try {
|
|
fs.lstatSync(apmBinDestinationPath)
|
|
console.log(`Removing existing executable at "${apmBinDestinationPath}"`)
|
|
fs.removeSync(apmBinDestinationPath)
|
|
} catch (e) { }
|
|
console.log(`Symlinking apm to "${apmBinDestinationPath}"`)
|
|
fs.symlinkSync(path.join('..', 'share', atomExecutableName, 'resources', 'app', 'apm', 'node_modules', '.bin', 'apm'), apmBinDestinationPath)
|
|
}
|
|
|
|
console.log(`Changing permissions to 755 for "${installationDirPath}"`)
|
|
fs.chmodSync(installationDirPath, '755')
|
|
}
|
|
|
|
return Promise.resolve()
|
|
}
|