create-rpm-package.js
1 'use strict'; 2 3 const assert = require('assert'); 4 const fs = require('fs-extra'); 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 rpm 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 appName = CONFIG.appName; 18 const appDescription = CONFIG.appMetadata.description; 19 // RPM versions can't have dashes or tildes in them. 20 // (Ref.: https://twiki.cern.ch/twiki/bin/view/Main/RPMAndDebVersioning) 21 const appVersion = CONFIG.appMetadata.version.replace(/-/g, '.'); 22 const policyFileName = `atom-${CONFIG.channel}.policy`; 23 24 const rpmPackageDirPath = path.join(CONFIG.homeDirPath, 'rpmbuild'); 25 const rpmPackageBuildDirPath = path.join(rpmPackageDirPath, 'BUILD'); 26 const rpmPackageSourcesDirPath = path.join(rpmPackageDirPath, 'SOURCES'); 27 const rpmPackageSpecsDirPath = path.join(rpmPackageDirPath, 'SPECS'); 28 const rpmPackageRpmsDirPath = path.join(rpmPackageDirPath, 'RPMS'); 29 const rpmPackageApplicationDirPath = path.join( 30 rpmPackageBuildDirPath, 31 appName 32 ); 33 const rpmPackageIconsDirPath = path.join(rpmPackageBuildDirPath, 'icons'); 34 35 if (fs.existsSync(rpmPackageDirPath)) { 36 console.log( 37 `Deleting existing rpm build directory at "${rpmPackageDirPath}"` 38 ); 39 fs.removeSync(rpmPackageDirPath); 40 } 41 42 console.log( 43 `Creating rpm package directory structure at "${rpmPackageDirPath}"` 44 ); 45 fs.mkdirpSync(rpmPackageDirPath); 46 fs.mkdirpSync(rpmPackageBuildDirPath); 47 fs.mkdirpSync(rpmPackageSourcesDirPath); 48 fs.mkdirpSync(rpmPackageSpecsDirPath); 49 50 console.log( 51 `Copying "${packagedAppPath}" to "${rpmPackageApplicationDirPath}"` 52 ); 53 fs.copySync(packagedAppPath, rpmPackageApplicationDirPath); 54 55 console.log(`Copying icons into "${rpmPackageIconsDirPath}"`); 56 fs.copySync( 57 path.join( 58 CONFIG.repositoryRootPath, 59 'resources', 60 'app-icons', 61 CONFIG.channel, 62 'png' 63 ), 64 rpmPackageIconsDirPath 65 ); 66 67 console.log(`Writing rpm package spec file into "${rpmPackageSpecsDirPath}"`); 68 const rpmPackageSpecFilePath = path.join(rpmPackageSpecsDirPath, 'atom.spec'); 69 const rpmPackageSpecsTemplate = fs.readFileSync( 70 path.join( 71 CONFIG.repositoryRootPath, 72 'resources', 73 'linux', 74 'redhat', 75 'atom.spec.in' 76 ) 77 ); 78 const rpmPackageSpecsContents = template(rpmPackageSpecsTemplate)({ 79 appName: appName, 80 appFileName: atomExecutableName, 81 apmFileName: apmExecutableName, 82 description: appDescription, 83 installDir: '/usr', 84 version: appVersion, 85 policyFileName 86 }); 87 fs.writeFileSync(rpmPackageSpecFilePath, rpmPackageSpecsContents); 88 89 console.log(`Writing desktop entry file into "${rpmPackageBuildDirPath}"`); 90 const desktopEntryTemplate = fs.readFileSync( 91 path.join( 92 CONFIG.repositoryRootPath, 93 'resources', 94 'linux', 95 'atom.desktop.in' 96 ) 97 ); 98 const desktopEntryContents = template(desktopEntryTemplate)({ 99 appName: appName, 100 appFileName: atomExecutableName, 101 description: appDescription, 102 installDir: '/usr', 103 iconPath: atomExecutableName 104 }); 105 fs.writeFileSync( 106 path.join(rpmPackageBuildDirPath, `${atomExecutableName}.desktop`), 107 desktopEntryContents 108 ); 109 110 console.log(`Copying atom.sh into "${rpmPackageBuildDirPath}"`); 111 fs.copySync( 112 path.join(CONFIG.repositoryRootPath, 'atom.sh'), 113 path.join(rpmPackageBuildDirPath, 'atom.sh') 114 ); 115 116 console.log(`Copying atom.policy into "${rpmPackageBuildDirPath}"`); 117 fs.copySync( 118 path.join(CONFIG.repositoryRootPath, 'resources', 'linux', 'atom.policy'), 119 path.join(rpmPackageBuildDirPath, policyFileName) 120 ); 121 122 console.log(`Generating .rpm package from "${rpmPackageDirPath}"`); 123 spawnSync('rpmbuild', ['-ba', '--clean', rpmPackageSpecFilePath]); 124 for (let generatedArch of fs.readdirSync(rpmPackageRpmsDirPath)) { 125 const generatedArchDirPath = path.join( 126 rpmPackageRpmsDirPath, 127 generatedArch 128 ); 129 const generatedPackageFileNames = fs.readdirSync(generatedArchDirPath); 130 assert( 131 generatedPackageFileNames.length === 1, 132 'Generated more than one rpm package' 133 ); 134 const generatedPackageFilePath = path.join( 135 generatedArchDirPath, 136 generatedPackageFileNames[0] 137 ); 138 const outputRpmPackageFilePath = path.join( 139 CONFIG.buildOutputPath, 140 `atom.${generatedArch}.rpm` 141 ); 142 console.log( 143 `Copying "${generatedPackageFilePath}" into "${outputRpmPackageFilePath}"` 144 ); 145 fs.copySync(generatedPackageFilePath, outputRpmPackageFilePath); 146 } 147 };