1 Star 0 Fork 0

WinterSunny / cleanflight-configurator

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
gulpfile.js 21.76 KB
一键复制 编辑 原始数据 按行查看 历史
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722
'use strict';
const pkg = require('./package.json');
const child_process = require('child_process');
const fs = require('fs');
const fse = require('fs-extra');
const https = require('follow-redirects').https;
const path = require('path');
const zip = require('gulp-zip');
const del = require('del');
const NwBuilder = require('nw-builder');
const makensis = require('makensis');
const deb = require('gulp-debian');
const buildRpm = require('rpm-builder');
const commandExistsSync = require('command-exists').sync;
const targz = require('targz');
const gulp = require('gulp');
const concat = require('gulp-concat');
const install = require("gulp-install");
const rename = require('gulp-rename');
const os = require('os');
const removeTrailingPathSeparator = require('remove-trailing-path-separator');
const git = require('gulp-git');
const DIST_DIR = './dist/';
const APPS_DIR = './apps/';
const DEBUG_DIR = './debug/';
const RELEASE_DIR = './release/';
var nwBuilderOptions = {
version: '0.32.2',
files: './dist/**/*',
macIcns: './src/images/cf_icon.icns',
macPlist: { 'CFBundleDisplayName': 'Cleanflight Configurator'},
winIco: './src/images/cf_icon.ico',
zip: false
};
var nwArmVersion = '0.27.6';
//-----------------
//Pre tasks operations
//-----------------
const SELECTED_PLATFORMS = getInputPlatforms();
//-----------------
//Tasks
//-----------------
gulp.task('clean', gulp.parallel(clean_dist, clean_apps, clean_debug, clean_release));
gulp.task('clean-dist', clean_dist);
gulp.task('clean-apps', clean_apps);
gulp.task('clean-debug', clean_debug);
gulp.task('clean-release', clean_release);
gulp.task('clean-cache', clean_cache);
gulp.task('get-changeset-id', getChangesetId);
var distBuild = gulp.series(dist_src, dist_locale, dist_libraries, dist_resources, getChangesetId);
var distRebuild = gulp.series(clean_dist, distBuild);
gulp.task('dist', distRebuild);
var appsBuild = gulp.series(gulp.parallel(clean_apps, distRebuild), apps, gulp.parallel(listPostBuildTasks(APPS_DIR)));
gulp.task('apps', appsBuild);
var debugBuild = gulp.series(distBuild, debug, gulp.parallel(listPostBuildTasks(DEBUG_DIR)), start_debug)
gulp.task('debug', debugBuild);
var releaseBuild = gulp.series(gulp.parallel(clean_release, appsBuild), gulp.parallel(listReleaseTasks()));
gulp.task('release', releaseBuild);
gulp.task('default', debugBuild);
// -----------------
// Helper functions
// -----------------
// Get platform from commandline args
// #
// # gulp <task> [<platform>]+ Run only for platform(s) (with <platform> one of --linux64, --linux32, --armv7, --osx64, --win32, --win64, or --chromeos)
// #
function getInputPlatforms() {
var supportedPlatforms = ['linux64', 'linux32', 'armv7', 'osx64', 'win32','win64', 'chromeos'];
var platforms = [];
var regEx = /--(\w+)/;
console.log(process.argv);
for (var i = 3; i < process.argv.length; i++) {
var arg = process.argv[i].match(regEx)[1];
if (supportedPlatforms.indexOf(arg) > -1) {
platforms.push(arg);
} else {
console.log('Unknown platform: ' + arg);
process.exit();
}
}
if (platforms.length === 0) {
var defaultPlatform = getDefaultPlatform();
if (supportedPlatforms.indexOf(defaultPlatform) > -1) {
platforms.push(defaultPlatform);
} else {
console.error(`Your current platform (${os.platform()}) is not a supported build platform. Please specify platform to build for on the command line.`);
process.exit();
}
}
if (platforms.length > 0) {
console.log('Building for platform(s): ' + platforms + '.');
} else {
console.error('No suitables platforms found.');
process.exit();
}
return platforms;
}
// Gets the default platform to be used
function getDefaultPlatform() {
var defaultPlatform;
switch (os.platform()) {
case 'darwin':
defaultPlatform = 'osx64';
break;
case 'linux':
defaultPlatform = 'linux64';
break;
case 'win32':
defaultPlatform = 'win32';
break;
default:
defaultPlatform = '';
break;
}
return defaultPlatform;
}
function getPlatforms() {
return SELECTED_PLATFORMS.slice();
}
function removeItem(platforms, item) {
var index = platforms.indexOf(item);
if (index >= 0) {
platforms.splice(index, 1);
}
}
function getRunDebugAppCommand(arch) {
switch (arch) {
case 'osx64':
return 'open ' + path.join(DEBUG_DIR, pkg.name, arch, pkg.name + '.app');
break;
case 'linux64':
case 'linux32':
case 'armv7':
return path.join(DEBUG_DIR, pkg.name, arch, pkg.name);
break;
case 'win32':
case 'win64':
return path.join(DEBUG_DIR, pkg.name, arch, pkg.name + '.exe');
break;
default:
return '';
break;
}
}
function getReleaseFilename(platform, ext) {
return 'cleanflight-configurator_' + pkg.version + '_' + platform + '.' + ext;
}
function clean_dist() {
return del([DIST_DIR + '**'], { force: true });
};
function clean_apps() {
return del([APPS_DIR + '**'], { force: true });
};
function clean_debug() {
return del([DEBUG_DIR + '**'], { force: true });
};
function clean_release() {
return del([RELEASE_DIR + '**'], { force: true });
};
function clean_cache() {
return del(['./cache/**'], { force: true });
};
// Real work for dist task. Done in another task to call it via
// run-sequence.
function dist_src() {
var distSources = [
'./src/**/*',
'!./src/css/dropdown-lists/LICENSE',
'!./src/css/font-awesome/css/font-awesome.css',
'!./src/css/opensans_webfontkit/*.{txt,html}',
'!./src/support/**'
];
return gulp.src(distSources, { base: 'src' })
.pipe(gulp.src('manifest.json', { passthrougth: true }))
.pipe(gulp.src('package.json', { passthrougth: true }))
.pipe(gulp.src('changelog.html', { passthrougth: true }))
.pipe(gulp.dest(DIST_DIR))
.pipe(install({
npm: '--production --ignore-scripts'
}));
};
function dist_locale() {
return gulp.src('./locales/**/*', { base: 'locales'})
.pipe(gulp.dest(DIST_DIR + '_locales'));
}
function dist_libraries() {
return gulp.src('./libraries/**/*', { base: '.'})
.pipe(gulp.dest(DIST_DIR + 'js'));
}
function dist_resources() {
return gulp.src('./resources/**/*', { base: '.'})
.pipe(gulp.dest(DIST_DIR));
}
// Create runable app directories in ./apps
function apps(done) {
var platforms = getPlatforms();
removeItem(platforms, 'chromeos');
buildNWAppsWrapper(platforms, 'normal', APPS_DIR, done);
}
function listPostBuildTasks(folder, done) {
var platforms = getPlatforms();
var postBuildTasks = [];
if (platforms.indexOf('linux32') != -1) {
postBuildTasks.push(function post_build_linux32(done) {
return post_build('linux32', folder, done);
});
}
if (platforms.indexOf('linux64') != -1) {
postBuildTasks.push(function post_build_linux64(done) {
return post_build('linux64', folder, done);
});
}
if (platforms.indexOf('armv7') != -1) {
postBuildTasks.push(function post_build_armv7(done) {
return post_build('armv7', folder, done);
});
}
// We need to return at least one task, if not gulp will throw an error
if (postBuildTasks.length == 0) {
postBuildTasks.push(function post_build_none(done) {
done();
});
}
return postBuildTasks;
}
function post_build(arch, folder, done) {
if ((arch === 'linux32') || (arch === 'linux64')) {
// Copy Ubuntu launcher scripts to destination dir
var launcherDir = path.join(folder, pkg.name, arch);
console.log('Copy Ubuntu launcher scripts to ' + launcherDir);
return gulp.src('assets/linux/**')
.pipe(gulp.dest(launcherDir));
}
if (arch === 'armv7') {
console.log('Moving ARMv7 build from "linux32" to "armv7" directory...');
fse.moveSync(path.join(folder, pkg.name, 'linux32'), path.join(folder, pkg.name, 'armv7'));
}
return done();
}
// Create debug app directories in ./debug
function debug(done) {
var platforms = getPlatforms();
removeItem(platforms, 'chromeos');
buildNWAppsWrapper(platforms, 'sdk', DEBUG_DIR, done);
}
function injectARMCache(flavor, callback) {
var flavorPostfix = `-${flavor}`;
var flavorDownloadPostfix = flavor !== 'normal' ? `-${flavor}` : '';
clean_cache().then(function() {
if (!fs.existsSync('./cache')) {
fs.mkdirSync('./cache');
}
fs.closeSync(fs.openSync('./cache/_ARMv7_IS_CACHED', 'w'));
var versionFolder = `./cache/${nwBuilderOptions.version}${flavorPostfix}`;
if (!fs.existsSync(versionFolder)) {
fs.mkdirSync(versionFolder);
}
if (!fs.existsSync(versionFolder + '/linux32')) {
fs.mkdirSync(`${versionFolder}/linux32`);
}
var downloadedArchivePath = `${versionFolder}/nwjs${flavorPostfix}-v${nwArmVersion}-linux-arm.tar.gz`;
var downloadUrl = `https://github.com/LeonardLaszlo/nw.js-armv7-binaries/releases/download/v${nwArmVersion}/nwjs${flavorDownloadPostfix}-v${nwArmVersion}-linux-arm.tar.gz`;
if (fs.existsSync(downloadedArchivePath)) {
console.log('Prebuilt ARMv7 binaries found in /tmp');
downloadDone(flavorDownloadPostfix, downloadedArchivePath, versionFolder);
} else {
console.log(`Downloading prebuilt ARMv7 binaries from "${downloadUrl}"...`);
process.stdout.write('> Starting download...\r');
var armBuildBinary = fs.createWriteStream(downloadedArchivePath);
var request = https.get(downloadUrl, function(res) {
var totalBytes = res.headers['content-length'];
var downloadedBytes = 0;
res.pipe(armBuildBinary);
res.on('data', function (chunk) {
downloadedBytes += chunk.length;
process.stdout.write(`> ${parseInt((downloadedBytes * 100) / totalBytes)}% done \r`);
});
armBuildBinary.on('finish', function() {
process.stdout.write('> 100% done \n');
armBuildBinary.close(function() {
downloadDone(flavorDownloadPostfix, downloadedArchivePath, versionFolder);
});
});
});
}
});
function downloadDone(flavorDownloadPostfix, downloadedArchivePath, versionFolder) {
console.log('Injecting prebuilt ARMv7 binaries into Linux32 cache...');
targz.decompress({
src: downloadedArchivePath,
dest: versionFolder,
}, function(err) {
if (err) {
console.log(err);
clean_debug();
process.exit(1);
} else {
fs.rename(
`${versionFolder}/nwjs${flavorDownloadPostfix}-v${nwArmVersion}-linux-arm`,
`${versionFolder}/linux32`,
(err) => {
if (err) {
console.log(err);
clean_debug();
process.exit(1);
}
callback();
}
);
}
});
}
}
function buildNWAppsWrapper(platforms, flavor, dir, done) {
function buildNWAppsCallback() {
buildNWApps(platforms, flavor, dir, done);
}
if (platforms.indexOf('armv7') !== -1) {
if (platforms.indexOf('linux32') !== -1) {
console.log('Cannot build ARMv7 and Linux32 versions at the same time!');
clean_debug();
process.exit(1);
}
removeItem(platforms, 'armv7');
platforms.push('linux32');
if (!fs.existsSync('./cache/_ARMv7_IS_CACHED', 'w')) {
console.log('Purging cache because it needs to be overwritten...');
clean_cache().then(() => {
injectARMCache(flavor, buildNWAppsCallback);
})
} else {
buildNWAppsCallback();
}
} else {
if (platforms.indexOf('linux32') !== -1 && fs.existsSync('./cache/_ARMv7_IS_CACHED')) {
console.log('Purging cache because it was previously overwritten...');
clean_cache().then(buildNWAppsCallback);
} else {
buildNWAppsCallback();
}
}
}
function buildNWApps(platforms, flavor, dir, done) {
if (platforms.length > 0) {
var builder = new NwBuilder(Object.assign({
buildDir: dir,
platforms: platforms,
flavor: flavor
}, nwBuilderOptions));
builder.on('log', console.log);
builder.build(function (err) {
if (err) {
console.log('Error building NW apps: ' + err);
clean_debug();
process.exit(1);
}
done();
});
} else {
console.log('No platform suitable for NW Build')
done();
}
}
function getChangesetId(done) {
git.exec({args : 'log -1 --format="%h"'}, function (err, stdout) {
var version;
if (err) {
version = 'unsupported';
} else {
version = stdout.trim();
}
var versionData = { gitChangesetId: version }
var destFile = path.join(DIST_DIR, 'version.json');
fs.writeFile(destFile, JSON.stringify(versionData) , function () {
done();
});
});
}
function start_debug(done) {
var platforms = getPlatforms();
var exec = require('child_process').exec;
if (platforms.length === 1) {
var run = getRunDebugAppCommand(platforms[0]);
console.log('Starting debug app (' + run + ')...');
exec(run);
} else {
console.log('More than one platform specified, not starting debug app');
}
done();
}
// Create installer package for windows platforms
function release_win(arch, done) {
// Check if makensis exists
if (!commandExistsSync('makensis')) {
console.warn('makensis command not found, not generating win package for ' + arch);
return done();
}
// The makensis does not generate the folder correctly, manually
createDirIfNotExists(RELEASE_DIR);
// Parameters passed to the installer script
const options = {
verbose: 2,
define: {
'VERSION': pkg.version,
'PLATFORM': arch,
'DEST_FOLDER': RELEASE_DIR
}
}
var output = makensis.compileSync('./assets/windows/installer.nsi', options);
if (output.status !== 0) {
console.error('Installer for platform ' + arch + ' finished with error ' + output.status + ': ' + output.stderr);
}
done();
}
// Create distribution package (zip) for windows and linux platforms
function release_zip(arch) {
var src = path.join(APPS_DIR, pkg.name, arch, '**');
var output = getReleaseFilename(arch, 'zip');
var base = path.join(APPS_DIR, pkg.name, arch);
return compressFiles(src, base, output, 'Cleanflight Configurator');
}
// Create distribution package for chromeos platform
function release_chromeos() {
var src = path.join(DIST_DIR, '**');
var output = getReleaseFilename('chromeos', 'zip');
var base = DIST_DIR;
return compressFiles(src, base, output, '.');
}
// Compress files from srcPath, using basePath, to outputFile in the RELEASE_DIR
function compressFiles(srcPath, basePath, outputFile, zipFolder) {
return gulp.src(srcPath, { base: basePath })
.pipe(rename(function(actualPath) {
actualPath.dirname = path.join(zipFolder, actualPath.dirname);
}))
.pipe(zip(outputFile))
.pipe(gulp.dest(RELEASE_DIR));
}
function release_deb(arch, done) {
// Check if dpkg-deb exists
if (!commandExistsSync('dpkg-deb')) {
console.warn('dpkg-deb command not found, not generating deb package for ' + arch);
return done();
}
return gulp.src([path.join(APPS_DIR, pkg.name, arch, '*')])
.pipe(deb({
package: pkg.name,
version: pkg.version,
section: 'base',
priority: 'optional',
architecture: getLinuxPackageArch('deb', arch),
maintainer: pkg.author,
description: pkg.description,
postinst: ['xdg-desktop-menu install /opt/cleanflight/cleanflight-configurator/cleanflight-configurator.desktop'],
prerm: ['xdg-desktop-menu uninstall cleanflight-configurator.desktop'],
depends: 'libgconf-2-4',
changelog: [],
_target: 'opt/cleanflight/cleanflight-configurator',
_out: removeTrailingPathSeparator(RELEASE_DIR),
_copyright: 'assets/linux/copyright',
_clean: true
}));
}
function release_rpm(arch, done) {
// Check if dpkg-deb exists
if (!commandExistsSync('rpmbuild')) {
console.warn('rpmbuild command not found, not generating rpm package for ' + arch);
return done();
}
// The buildRpm does not generate the folder correctly, manually
createDirIfNotExists(RELEASE_DIR);
var options = {
name: pkg.name,
version: pkg.version,
buildArch: getLinuxPackageArch('rpm', arch),
vendor: pkg.author,
summary: pkg.description,
license: 'GNU General Public License v3.0',
requires: 'libgconf-2-4',
prefix: '/opt',
files:
[ { cwd: path.join(APPS_DIR, pkg.name, arch),
src: '*',
dest: '/opt/cleanflight/cleanflight-configurator' } ],
postInstallScript: ['xdg-desktop-menu install /opt/cleanflight/cleanflight-configurator/cleanflight-configurator.desktop'],
preUninstallScript: ['xdg-desktop-menu uninstall cleanflight-configurator.desktop'],
tempDir: path.join(RELEASE_DIR,'tmp-rpm-build-' + arch),
keepTemp: false,
verbose: false,
rpmDest: RELEASE_DIR
};
buildRpm(options, function(err, rpm) {
if (err) {
console.error("Error generating rpm package: " + err);
}
done();
});
}
function getLinuxPackageArch(type, arch) {
var packArch;
switch (arch) {
case 'linux32':
packArch = 'i386';
break;
case 'linux64':
if (type == 'rpm') {
packArch = 'x86_64';
} else {
packArch = 'amd64';
}
break;
default:
console.error("Package error, arch: " + arch);
process.exit(1);
break;
}
return packArch;
}
// Create distribution package for macOS platform
function release_osx64() {
var appdmg = require('gulp-appdmg');
// The appdmg does not generate the folder correctly, manually
createDirIfNotExists(RELEASE_DIR);
// The src pipe is not used
return gulp.src(['.'])
.pipe(appdmg({
target: path.join(RELEASE_DIR, getReleaseFilename('macOS', 'dmg')),
basepath: path.join(APPS_DIR, pkg.name, 'osx64'),
specification: {
title: 'Cleanflight Configurator',
contents: [
{ 'x': 448, 'y': 342, 'type': 'link', 'path': '/Applications' },
{ 'x': 192, 'y': 344, 'type': 'file', 'path': pkg.name + '.app', 'name': 'Cleanflight Configurator.app' }
],
background: path.join(__dirname, 'assets/osx/cf_dmg-background.png'),
format: 'UDZO',
window: {
size: {
width: 638,
height: 479
}
}
},
})
);
}
// Create the dir directory, with write permissions
function createDirIfNotExists(dir) {
fs.mkdir(dir, '0775', function(err) {
if (err) {
if (err.code !== 'EEXIST') {
throw err;
}
}
});
}
// Create a list of the gulp tasks to execute for release
function listReleaseTasks(done) {
var platforms = getPlatforms();
var releaseTasks = [];
if (platforms.indexOf('chromeos') !== -1) {
releaseTasks.push(release_chromeos);
}
if (platforms.indexOf('linux64') !== -1) {
releaseTasks.push(function release_linux64_zip() {
return release_zip('linux64');
});
releaseTasks.push(function release_linux64_deb(done) {
return release_deb('linux64', done);
});
releaseTasks.push(function release_linux64_rpm(done) {
return release_rpm('linux64', done);
});
}
if (platforms.indexOf('linux32') !== -1) {
releaseTasks.push(function release_linux32_zip() {
return release_zip('linux32');
});
releaseTasks.push(function release_linux32_deb(done) {
return release_deb('linux32', done);
});
releaseTasks.push(function release_linux32_rpm(done) {
return release_rpm('linux32', done);
});
}
if (platforms.indexOf('armv7') !== -1) {
releaseTasks.push(function release_armv7_zip() {
return release_zip('armv7');
});
}
if (platforms.indexOf('osx64') !== -1) {
releaseTasks.push(release_osx64);
}
if (platforms.indexOf('win32') !== -1) {
releaseTasks.push(function release_win32(done) {
return release_win('win32', done);
});
}
if (platforms.indexOf('win64') !== -1) {
releaseTasks.push(function release_win64(done) {
return release_win('win64', done);
});
}
return releaseTasks;
}
1
https://gitee.com/wintersunny/cleanflight-configurator.git
git@gitee.com:wintersunny/cleanflight-configurator.git
wintersunny
cleanflight-configurator
cleanflight-configurator
master

搜索帮助