create-debian-package.js
1 'use strict'; 2 3 const fs = require('fs-extra'); 4 const os = require('os'); 5 const path = require('path'); 6 const spawnSync = require('./spawn-sync'); 7 const template = require('lodash.template'); 8 9 const CONFIG = require('../config'); 10 11 module.exports = function(packagedAppPath) { 12 console.log(`Creating Debian package for "${packagedAppPath}"`); 13 const atomExecutableName = 14 CONFIG.channel === 'stable' ? 'atom' : `atom-${CONFIG.channel}`; 15 const apmExecutableName = 16 CONFIG.channel === 'stable' ? 'apm' : `apm-${CONFIG.channel}`; 17 const appDescription = CONFIG.appMetadata.description; 18 const appVersion = CONFIG.appMetadata.version; 19 let arch; 20 if (process.arch === 'ia32') { 21 arch = 'i386'; 22 } else if (process.arch === 'x64') { 23 arch = 'amd64'; 24 } else if (process.arch === 'ppc') { 25 arch = 'powerpc'; 26 } else { 27 arch = process.arch; 28 } 29 30 const outputDebianPackageFilePath = path.join( 31 CONFIG.buildOutputPath, 32 `atom-${arch}.deb` 33 ); 34 const debianPackageDirPath = path.join( 35 os.tmpdir(), 36 path.basename(packagedAppPath) 37 ); 38 const debianPackageConfigPath = path.join(debianPackageDirPath, 'DEBIAN'); 39 const debianPackageInstallDirPath = path.join(debianPackageDirPath, 'usr'); 40 const debianPackageBinDirPath = path.join(debianPackageInstallDirPath, 'bin'); 41 const debianPackageShareDirPath = path.join( 42 debianPackageInstallDirPath, 43 'share' 44 ); 45 const debianPackageAtomDirPath = path.join( 46 debianPackageShareDirPath, 47 atomExecutableName 48 ); 49 const debianPackageApplicationsDirPath = path.join( 50 debianPackageShareDirPath, 51 'applications' 52 ); 53 const debianPackageIconsDirPath = path.join( 54 debianPackageShareDirPath, 55 'pixmaps' 56 ); 57 const debianPackageLintianOverridesDirPath = path.join( 58 debianPackageShareDirPath, 59 'lintian', 60 'overrides' 61 ); 62 const debianPackageDocsDirPath = path.join( 63 debianPackageShareDirPath, 64 'doc', 65 atomExecutableName 66 ); 67 68 if (fs.existsSync(debianPackageDirPath)) { 69 console.log( 70 `Deleting existing build dir for Debian package at "${debianPackageDirPath}"` 71 ); 72 fs.removeSync(debianPackageDirPath); 73 } 74 if (fs.existsSync(`${debianPackageDirPath}.deb`)) { 75 console.log( 76 `Deleting existing Debian package at "${debianPackageDirPath}.deb"` 77 ); 78 fs.removeSync(`${debianPackageDirPath}.deb`); 79 } 80 if (fs.existsSync(debianPackageDirPath)) { 81 console.log( 82 `Deleting existing Debian package at "${outputDebianPackageFilePath}"` 83 ); 84 fs.removeSync(debianPackageDirPath); 85 } 86 87 console.log( 88 `Creating Debian package directory structure at "${debianPackageDirPath}"` 89 ); 90 fs.mkdirpSync(debianPackageDirPath); 91 fs.mkdirpSync(debianPackageConfigPath); 92 fs.mkdirpSync(debianPackageInstallDirPath); 93 fs.mkdirpSync(debianPackageShareDirPath); 94 fs.mkdirpSync(debianPackageApplicationsDirPath); 95 fs.mkdirpSync(debianPackageIconsDirPath); 96 fs.mkdirpSync(debianPackageLintianOverridesDirPath); 97 fs.mkdirpSync(debianPackageDocsDirPath); 98 fs.mkdirpSync(debianPackageBinDirPath); 99 100 console.log(`Copying "${packagedAppPath}" to "${debianPackageAtomDirPath}"`); 101 fs.copySync(packagedAppPath, debianPackageAtomDirPath); 102 fs.chmodSync(debianPackageAtomDirPath, '755'); 103 104 console.log(`Copying binaries into "${debianPackageBinDirPath}"`); 105 fs.copySync( 106 path.join(CONFIG.repositoryRootPath, 'atom.sh'), 107 path.join(debianPackageBinDirPath, atomExecutableName) 108 ); 109 fs.symlinkSync( 110 path.join( 111 '..', 112 'share', 113 atomExecutableName, 114 'resources', 115 'app', 116 'apm', 117 'node_modules', 118 '.bin', 119 'apm' 120 ), 121 path.join(debianPackageBinDirPath, apmExecutableName) 122 ); 123 124 console.log(`Writing control file into "${debianPackageConfigPath}"`); 125 const packageSizeInKilobytes = spawnSync('du', ['-sk', packagedAppPath]) 126 .stdout.toString() 127 .split(/\s+/)[0]; 128 const controlFileTemplate = fs.readFileSync( 129 path.join( 130 CONFIG.repositoryRootPath, 131 'resources', 132 'linux', 133 'debian', 134 'control.in' 135 ) 136 ); 137 const controlFileContents = template(controlFileTemplate)({ 138 appFileName: atomExecutableName, 139 version: appVersion, 140 arch: arch, 141 installedSize: packageSizeInKilobytes, 142 description: appDescription 143 }); 144 fs.writeFileSync( 145 path.join(debianPackageConfigPath, 'control'), 146 controlFileContents 147 ); 148 149 console.log( 150 `Writing desktop entry file into "${debianPackageApplicationsDirPath}"` 151 ); 152 const desktopEntryTemplate = fs.readFileSync( 153 path.join( 154 CONFIG.repositoryRootPath, 155 'resources', 156 'linux', 157 'atom.desktop.in' 158 ) 159 ); 160 const desktopEntryContents = template(desktopEntryTemplate)({ 161 appName: CONFIG.appName, 162 appFileName: atomExecutableName, 163 description: appDescription, 164 installDir: '/usr', 165 iconPath: atomExecutableName 166 }); 167 fs.writeFileSync( 168 path.join( 169 debianPackageApplicationsDirPath, 170 `${atomExecutableName}.desktop` 171 ), 172 desktopEntryContents 173 ); 174 175 console.log(`Copying icon into "${debianPackageIconsDirPath}"`); 176 fs.copySync( 177 path.join( 178 packagedAppPath, 179 'resources', 180 'app.asar.unpacked', 181 'resources', 182 'atom.png' 183 ), 184 path.join(debianPackageIconsDirPath, `${atomExecutableName}.png`) 185 ); 186 187 console.log(`Copying license into "${debianPackageDocsDirPath}"`); 188 fs.copySync( 189 path.join(packagedAppPath, 'resources', 'LICENSE.md'), 190 path.join(debianPackageDocsDirPath, 'copyright') 191 ); 192 193 console.log( 194 `Copying lintian overrides into "${debianPackageLintianOverridesDirPath}"` 195 ); 196 fs.copySync( 197 path.join( 198 CONFIG.repositoryRootPath, 199 'resources', 200 'linux', 201 'debian', 202 'lintian-overrides' 203 ), 204 path.join(debianPackageLintianOverridesDirPath, atomExecutableName) 205 ); 206 207 console.log( 208 `Copying polkit configuration into "${debianPackageShareDirPath}"` 209 ); 210 fs.copySync( 211 path.join(CONFIG.repositoryRootPath, 'resources', 'linux', 'atom.policy'), 212 path.join( 213 debianPackageShareDirPath, 214 'polkit-1', 215 'actions', 216 `atom-${CONFIG.channel}.policy` 217 ) 218 ); 219 220 console.log(`Generating .deb file from ${debianPackageDirPath}`); 221 spawnSync('fakeroot', ['dpkg-deb', '-b', debianPackageDirPath], { 222 stdio: 'inherit' 223 }); 224 225 console.log( 226 `Copying generated package into "${outputDebianPackageFilePath}"` 227 ); 228 fs.copySync(`${debianPackageDirPath}.deb`, outputDebianPackageFilePath); 229 };