vscode/build/gulpfile.vscode.linux.js

241 lines
12 KiB
JavaScript
Raw Normal View History

2016-07-20 09:00:43 +00:00
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
const gulp = require('gulp');
const replace = require('gulp-replace');
const rename = require('gulp-rename');
const shell = require('gulp-shell');
const es = require('event-stream');
2016-09-05 10:38:25 +00:00
const vfs = require('vinyl-fs');
2016-07-20 09:00:43 +00:00
const util = require('./lib/util');
const packageJson = require('../package.json');
const product = require('../product.json');
2018-02-01 13:39:12 +00:00
const rpmDependencies = require('../resources/linux/rpm/dependencies.json');
2016-07-20 09:00:43 +00:00
Support building Flatpak bundles This adds support for building Flatpak application bundles, which should be runnable on any Linux distribution with Flatpak support. See the page at http://flatpak.org/getting.html New Gulp tasks are added to prepare a directory with the needed files (vscode-linux-${arch}-prepare-flatpak), assembling the Flatpak bundles (vscode-linux-${arch}-flatpak), and for cleaning the build directories (clean-vscode-linux-${arch}-flatpak). This mimics how the Debian and RPM package creation works. Hence, building an application bundle is done with: $ gulp vscode-linux-x64-flatpak [...] $ ls *.flatpak com.visualstudio.code.oss-x86_64.flatpak Installing and running the application is achieved with: $ flatpak --user install --bundle com.visualstudio.code.oss-x86_64.flatpak $ flatpak run com.visualstudio.code.oss (Removing "--user" would install the application system-wide. Also note that the "org.freedesktop.Platform" runtime needs to be installeed, check the Flatpak website for instructions.) The "flatpak-bundler" development dependency provides an asynchronous API to invoke "flatpak-builder". The "gulp-image-resize" module is used to incorporate scaling of the application icon to multiple sizes, and uses ImageMagick (or GraphicsMagick) under the hood, which is commonly available on most GNU/Linux distributions. Instead of building the Electron dependencies ourselves, this uses the io.atom.electron.BaseApp bundle as base application. Instead of building the Electron dependencies, this reuses the "io.atom.electron.BaseApp" bundle as base application. The contents of the base application are imported at build time, and then Electron and the prepared files added on top. The prebuilt base application will be fetched automatically using the URL specified in the "baseFlatpakref" attribute of the manifest, and it is kindly hosted at Amazon S3 by Endless Computers (https://endlessm.com). The sources for the base application can be found at: https://github.com/endlessm/electron-flatpak-base-app/
2016-11-25 00:21:57 +00:00
const linuxPackageRevision = Math.floor(new Date().getTime() / 1000);
2016-07-20 09:00:43 +00:00
function getDebPackageArch(arch) {
return { x64: 'amd64', ia32: 'i386', arm: 'armhf' }[arch];
2016-07-20 09:00:43 +00:00
}
function prepareDebPackage(arch) {
const binaryDir = '../VSCode-linux-' + arch;
const debArch = getDebPackageArch(arch);
const destination = '.build/linux/deb/' + debArch + '/' + product.applicationName + '-' + debArch;
return function () {
const desktop = gulp.src('resources/linux/code.desktop', { base: '.' })
.pipe(replace('@@NAME_LONG@@', product.nameLong))
.pipe(replace('@@NAME_SHORT@@', product.nameShort))
.pipe(replace('@@NAME@@', product.applicationName))
.pipe(replace('@@ICON@@', product.applicationName))
2016-07-20 09:00:43 +00:00
.pipe(rename('usr/share/applications/' + product.applicationName + '.desktop'));
const appdata = gulp.src('resources/linux/code.appdata.xml', { base: '.' })
.pipe(replace('@@NAME_LONG@@', product.nameLong))
.pipe(replace('@@NAME@@', product.applicationName))
.pipe(replace('@@LICENSE@@', product.licenseName))
.pipe(rename('usr/share/appdata/' + product.applicationName + '.appdata.xml'));
const icon = gulp.src('resources/linux/code.png', { base: '.' })
2016-07-20 09:00:43 +00:00
.pipe(rename('usr/share/pixmaps/' + product.applicationName + '.png'));
const code = gulp.src(binaryDir + '/**/*', { base: binaryDir })
2016-07-20 09:00:43 +00:00
.pipe(rename(function (p) { p.dirname = 'usr/share/' + product.applicationName + '/' + p.dirname; }));
let size = 0;
const control = code.pipe(es.through(
function (f) { size += f.isDirectory() ? 4096 : f.contents.length; },
function () {
const that = this;
gulp.src('resources/linux/debian/control.template', { base: '.' })
.pipe(replace('@@NAME@@', product.applicationName))
.pipe(replace('@@VERSION@@', packageJson.version + '-' + linuxPackageRevision))
.pipe(replace('@@ARCHITECTURE@@', debArch))
.pipe(replace('@@INSTALLEDSIZE@@', Math.ceil(size / 1024)))
.pipe(rename('DEBIAN/control'))
.pipe(es.through(function (f) { that.emit('data', f); }, function () { that.emit('end'); }));
}));
const prerm = gulp.src('resources/linux/debian/prerm.template', { base: '.' })
.pipe(replace('@@NAME@@', product.applicationName))
2016-09-05 10:38:25 +00:00
.pipe(rename('DEBIAN/prerm'));
2016-07-20 09:00:43 +00:00
const postrm = gulp.src('resources/linux/debian/postrm.template', { base: '.' })
.pipe(replace('@@NAME@@', product.applicationName))
2016-09-05 10:38:25 +00:00
.pipe(rename('DEBIAN/postrm'));
2016-07-20 09:00:43 +00:00
const postinst = gulp.src('resources/linux/debian/postinst.template', { base: '.' })
.pipe(replace('@@NAME@@', product.applicationName))
.pipe(replace('@@ARCHITECTURE@@', debArch))
// @ts-ignore JSON checking: quality is optional
2016-07-20 09:00:43 +00:00
.pipe(replace('@@QUALITY@@', product.quality || '@@QUALITY@@'))
// @ts-ignore JSON checking: updateUrl is optional
2016-07-20 09:00:43 +00:00
.pipe(replace('@@UPDATEURL@@', product.updateUrl || '@@UPDATEURL@@'))
2016-09-05 10:38:25 +00:00
.pipe(rename('DEBIAN/postinst'));
2016-07-20 09:00:43 +00:00
const all = es.merge(control, postinst, postrm, prerm, desktop, appdata, icon, code);
2016-07-20 09:00:43 +00:00
2016-09-05 10:38:25 +00:00
return all.pipe(vfs.dest(destination));
2016-07-20 09:00:43 +00:00
};
}
function buildDebPackage(arch) {
const debArch = getDebPackageArch(arch);
return shell.task([
'chmod 755 ' + product.applicationName + '-' + debArch + '/DEBIAN/postinst ' + product.applicationName + '-' + debArch + '/DEBIAN/prerm ' + product.applicationName + '-' + debArch + '/DEBIAN/postrm',
2016-07-20 09:00:43 +00:00
'mkdir -p deb',
'fakeroot dpkg-deb -b ' + product.applicationName + '-' + debArch + ' deb'
], { cwd: '.build/linux/deb/' + debArch });
2016-07-20 09:00:43 +00:00
}
function getRpmBuildPath(rpmArch) {
return '.build/linux/rpm/' + rpmArch + '/rpmbuild';
}
function getRpmPackageArch(arch) {
return { x64: 'x86_64', ia32: 'i386', arm: 'armhf' }[arch];
2016-07-20 09:00:43 +00:00
}
function prepareRpmPackage(arch) {
const binaryDir = '../VSCode-linux-' + arch;
const rpmArch = getRpmPackageArch(arch);
return function () {
const desktop = gulp.src('resources/linux/code.desktop', { base: '.' })
.pipe(replace('@@NAME_LONG@@', product.nameLong))
.pipe(replace('@@NAME_SHORT@@', product.nameShort))
.pipe(replace('@@NAME@@', product.applicationName))
.pipe(replace('@@ICON@@', product.applicationName))
2016-07-20 09:00:43 +00:00
.pipe(rename('BUILD/usr/share/applications/' + product.applicationName + '.desktop'));
const appdata = gulp.src('resources/linux/code.appdata.xml', { base: '.' })
.pipe(replace('@@NAME_LONG@@', product.nameLong))
.pipe(replace('@@NAME@@', product.applicationName))
.pipe(replace('@@LICENSE@@', product.licenseName))
.pipe(rename('usr/share/appdata/' + product.applicationName + '.appdata.xml'));
const icon = gulp.src('resources/linux/code.png', { base: '.' })
2016-07-20 09:00:43 +00:00
.pipe(rename('BUILD/usr/share/pixmaps/' + product.applicationName + '.png'));
const code = gulp.src(binaryDir + '/**/*', { base: binaryDir })
.pipe(rename(function (p) { p.dirname = 'BUILD/usr/share/' + product.applicationName + '/' + p.dirname; }));
const spec = gulp.src('resources/linux/rpm/code.spec.template', { base: '.' })
.pipe(replace('@@NAME@@', product.applicationName))
.pipe(replace('@@NAME_LONG@@', product.nameLong))
.pipe(replace('@@VERSION@@', packageJson.version))
.pipe(replace('@@RELEASE@@', linuxPackageRevision))
.pipe(replace('@@ARCHITECTURE@@', rpmArch))
.pipe(replace('@@LICENSE@@', product.licenseName))
// @ts-ignore JSON checking: quality is optional
2016-07-20 09:00:43 +00:00
.pipe(replace('@@QUALITY@@', product.quality || '@@QUALITY@@'))
// @ts-ignore JSON checking: updateUrl is optional
2016-07-20 09:00:43 +00:00
.pipe(replace('@@UPDATEURL@@', product.updateUrl || '@@UPDATEURL@@'))
2016-12-14 03:58:38 +00:00
.pipe(replace('@@DEPENDENCIES@@', rpmDependencies[rpmArch].join(', ')))
2016-07-20 09:00:43 +00:00
.pipe(rename('SPECS/' + product.applicationName + '.spec'));
const specIcon = gulp.src('resources/linux/rpm/code.xpm', { base: '.' })
.pipe(rename('SOURCES/' + product.applicationName + '.xpm'));
const all = es.merge(code, desktop, appdata, icon, spec, specIcon);
2016-07-20 09:00:43 +00:00
2016-09-05 10:38:25 +00:00
return all.pipe(vfs.dest(getRpmBuildPath(rpmArch)));
};
2016-07-20 09:00:43 +00:00
}
function buildRpmPackage(arch) {
const rpmArch = getRpmPackageArch(arch);
const rpmBuildPath = getRpmBuildPath(rpmArch);
const rpmOut = rpmBuildPath + '/RPMS/' + rpmArch;
2016-07-20 09:00:43 +00:00
const destination = '.build/linux/rpm/' + rpmArch;
2016-09-05 10:38:25 +00:00
2016-07-20 09:00:43 +00:00
return shell.task([
'mkdir -p ' + destination,
'HOME="$(pwd)/' + destination + '" fakeroot rpmbuild -bb ' + rpmBuildPath + '/SPECS/' + product.applicationName + '.spec --target=' + rpmArch,
'cp "' + rpmOut + '/$(ls ' + rpmOut + ')" ' + destination + '/'
2016-07-20 09:00:43 +00:00
]);
}
function getSnapBuildPath(arch) {
return `.build/linux/snap/${arch}/${product.applicationName}-${arch}`;
}
function prepareSnapPackage(arch) {
const binaryDir = '../VSCode-linux-' + arch;
const destination = getSnapBuildPath(arch);
return function () {
const desktop = gulp.src('resources/linux/code.desktop', { base: '.' })
.pipe(replace('@@NAME_LONG@@', product.nameLong))
.pipe(replace('@@NAME_SHORT@@', product.nameShort))
.pipe(replace('@@NAME@@', product.applicationName))
.pipe(replace('@@ICON@@', `/usr/share/pixmaps/${product.applicationName}.png`))
.pipe(rename(`usr/share/applications/${product.applicationName}.desktop`));
const icon = gulp.src('resources/linux/code.png', { base: '.' })
.pipe(rename(`usr/share/pixmaps/${product.applicationName}.png`));
const code = gulp.src(binaryDir + '/**/*', { base: binaryDir })
.pipe(rename(function (p) { p.dirname = 'usr/share/' + product.applicationName + '/' + p.dirname; }));
const snapcraft = gulp.src('resources/linux/snap/snapcraft.yaml', { base: '.' })
.pipe(replace('@@NAME@@', product.applicationName))
.pipe(replace('@@VERSION@@', packageJson.version))
.pipe(rename('snap/snapcraft.yaml'));
const electronLaunch = gulp.src('resources/linux/snap/electron-launch', { base: '.' })
.pipe(rename('electron-launch'));
const all = es.merge(desktop, icon, code, snapcraft, electronLaunch);
return all.pipe(vfs.dest(destination));
};
}
function buildSnapPackage(arch) {
const snapBuildPath = getSnapBuildPath(arch);
2018-01-31 20:55:26 +00:00
const snapFilename = `${product.applicationName}-${packageJson.version}-${linuxPackageRevision}-${arch}.snap`;
return shell.task([
`chmod +x ${snapBuildPath}/electron-launch`,
2018-01-31 20:55:26 +00:00
`cd ${snapBuildPath} && snapcraft snap --output ../${snapFilename}`
]);
}
2016-07-20 09:00:43 +00:00
gulp.task('clean-vscode-linux-ia32-deb', util.rimraf('.build/linux/deb/i386'));
gulp.task('clean-vscode-linux-x64-deb', util.rimraf('.build/linux/deb/amd64'));
gulp.task('clean-vscode-linux-arm-deb', util.rimraf('.build/linux/deb/armhf'));
2016-07-20 09:00:43 +00:00
gulp.task('clean-vscode-linux-ia32-rpm', util.rimraf('.build/linux/rpm/i386'));
gulp.task('clean-vscode-linux-x64-rpm', util.rimraf('.build/linux/rpm/x86_64'));
gulp.task('clean-vscode-linux-arm-rpm', util.rimraf('.build/linux/rpm/armhf'));
2017-09-28 13:44:48 +00:00
gulp.task('clean-vscode-linux-ia32-snap', util.rimraf('.build/linux/snap/x64'));
gulp.task('clean-vscode-linux-x64-snap', util.rimraf('.build/linux/snap/x64'));
gulp.task('clean-vscode-linux-arm-snap', util.rimraf('.build/linux/snap/x64'));
gulp.task('clean-vscode-linux-ia32-flatpak', util.rimraf('.build/linux/flatpak/i386'));
gulp.task('clean-vscode-linux-x64-flatpak', util.rimraf('.build/linux/flatpak/x86_64'));
gulp.task('clean-vscode-linux-arm-flatpak', util.rimraf('.build/linux/flatpak/arm'));
2016-07-20 09:00:43 +00:00
2017-05-12 07:34:45 +00:00
gulp.task('vscode-linux-ia32-prepare-deb', ['clean-vscode-linux-ia32-deb'], prepareDebPackage('ia32'));
gulp.task('vscode-linux-x64-prepare-deb', ['clean-vscode-linux-x64-deb'], prepareDebPackage('x64'));
gulp.task('vscode-linux-arm-prepare-deb', ['clean-vscode-linux-arm-deb'], prepareDebPackage('arm'));
2016-07-20 09:00:43 +00:00
gulp.task('vscode-linux-ia32-build-deb', ['vscode-linux-ia32-prepare-deb'], buildDebPackage('ia32'));
gulp.task('vscode-linux-x64-build-deb', ['vscode-linux-x64-prepare-deb'], buildDebPackage('x64'));
gulp.task('vscode-linux-arm-build-deb', ['vscode-linux-arm-prepare-deb'], buildDebPackage('arm'));
2016-07-20 09:00:43 +00:00
2017-05-12 07:34:45 +00:00
gulp.task('vscode-linux-ia32-prepare-rpm', ['clean-vscode-linux-ia32-rpm'], prepareRpmPackage('ia32'));
gulp.task('vscode-linux-x64-prepare-rpm', ['clean-vscode-linux-x64-rpm'], prepareRpmPackage('x64'));
gulp.task('vscode-linux-arm-prepare-rpm', ['clean-vscode-linux-arm-rpm'], prepareRpmPackage('arm'));
2016-07-20 09:00:43 +00:00
gulp.task('vscode-linux-ia32-build-rpm', ['vscode-linux-ia32-prepare-rpm'], buildRpmPackage('ia32'));
gulp.task('vscode-linux-x64-build-rpm', ['vscode-linux-x64-prepare-rpm'], buildRpmPackage('x64'));
gulp.task('vscode-linux-arm-build-rpm', ['vscode-linux-arm-prepare-rpm'], buildRpmPackage('arm'));
Support building Flatpak bundles This adds support for building Flatpak application bundles, which should be runnable on any Linux distribution with Flatpak support. See the page at http://flatpak.org/getting.html New Gulp tasks are added to prepare a directory with the needed files (vscode-linux-${arch}-prepare-flatpak), assembling the Flatpak bundles (vscode-linux-${arch}-flatpak), and for cleaning the build directories (clean-vscode-linux-${arch}-flatpak). This mimics how the Debian and RPM package creation works. Hence, building an application bundle is done with: $ gulp vscode-linux-x64-flatpak [...] $ ls *.flatpak com.visualstudio.code.oss-x86_64.flatpak Installing and running the application is achieved with: $ flatpak --user install --bundle com.visualstudio.code.oss-x86_64.flatpak $ flatpak run com.visualstudio.code.oss (Removing "--user" would install the application system-wide. Also note that the "org.freedesktop.Platform" runtime needs to be installeed, check the Flatpak website for instructions.) The "flatpak-bundler" development dependency provides an asynchronous API to invoke "flatpak-builder". The "gulp-image-resize" module is used to incorporate scaling of the application icon to multiple sizes, and uses ImageMagick (or GraphicsMagick) under the hood, which is commonly available on most GNU/Linux distributions. Instead of building the Electron dependencies ourselves, this uses the io.atom.electron.BaseApp bundle as base application. Instead of building the Electron dependencies, this reuses the "io.atom.electron.BaseApp" bundle as base application. The contents of the base application are imported at build time, and then Electron and the prepared files added on top. The prebuilt base application will be fetched automatically using the URL specified in the "baseFlatpakref" attribute of the manifest, and it is kindly hosted at Amazon S3 by Endless Computers (https://endlessm.com). The sources for the base application can be found at: https://github.com/endlessm/electron-flatpak-base-app/
2016-11-25 00:21:57 +00:00
2017-09-28 13:44:48 +00:00
gulp.task('vscode-linux-ia32-prepare-snap', ['clean-vscode-linux-ia32-snap'], prepareSnapPackage('ia32'));
gulp.task('vscode-linux-x64-prepare-snap', ['clean-vscode-linux-x64-snap'], prepareSnapPackage('x64'));
2017-09-28 13:44:48 +00:00
gulp.task('vscode-linux-arm-prepare-snap', ['clean-vscode-linux-arm-snap'], prepareSnapPackage('arm'));
gulp.task('vscode-linux-ia32-build-snap', ['vscode-linux-ia32-prepare-snap'], buildSnapPackage('ia32'));
gulp.task('vscode-linux-x64-build-snap', ['vscode-linux-x64-prepare-snap'], buildSnapPackage('x64'));
2017-09-28 13:44:48 +00:00
gulp.task('vscode-linux-arm-build-snap', ['vscode-linux-arm-prepare-snap'], buildSnapPackage('arm'));