Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
165 changes: 143 additions & 22 deletions gulpfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ 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');
Expand All @@ -13,6 +15,7 @@ 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');
Expand All @@ -33,6 +36,8 @@ var nwBuilderOptions = {
winIco: './src/images/bf_icon.ico'
};

var nwArmVersion = '0.27.6';

//-----------------
//Pre tasks operations
//-----------------
Expand Down Expand Up @@ -74,12 +79,13 @@ gulp.task('default', debugBuild);

// Get platform from commandline args
// #
// # gulp <task> [<platform>]+ Run only for platform(s) (with <platform> one of --linux64, --linux32, --osx64, --win32, --win64, or --chromeos)
// #
// # 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', 'osx64', 'win32','win64', 'chromeos'];
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) {
Expand All @@ -88,7 +94,7 @@ function getInputPlatforms() {
console.log('Unknown platform: ' + arg);
process.exit();
}
}
}

if (platforms.length === 0) {
var defaultPlatform = getDefaultPlatform();
Expand Down Expand Up @@ -126,10 +132,10 @@ function getDefaultPlatform() {
defaultPlatform = 'win32';

break;

default:
defaultPlatform = '';

break;
}
return defaultPlatform;
Expand All @@ -156,6 +162,7 @@ function getRunDebugAppCommand(arch) {

case 'linux64':
case 'linux32':
case 'armv7':
return path.join(DEBUG_DIR, pkg.name, arch, pkg.name);

break;
Expand All @@ -177,24 +184,24 @@ function getReleaseFilename(platform, ext) {
return 'betaflight-configurator_' + pkg.version + '_' + platform + '.' + ext;
}

function clean_dist() {
return del([DIST_DIR + '**'], { force: true });
function clean_dist() {
return del([DIST_DIR + '**'], { force: true });
};

function clean_apps() {
return del([APPS_DIR + '**'], { force: true });
function clean_apps() {
return del([APPS_DIR + '**'], { force: true });
};

function clean_debug() {
return del([DEBUG_DIR + '**'], { force: true });
function clean_debug() {
return del([DEBUG_DIR + '**'], { force: true });
};

function clean_release() {
return del([RELEASE_DIR + '**'], { force: true });
function clean_release() {
return del([RELEASE_DIR + '**'], { force: true });
};

function clean_cache() {
return del(['./cache/**'], { force: true });
function clean_cache() {
return del(['./cache/**'], { force: true });
};

// Real work for dist task. Done in another task to call it via
Expand Down Expand Up @@ -238,8 +245,8 @@ function apps(done) {
var platforms = getPlatforms();
removeItem(platforms, 'chromeos');

buildNWApps(platforms, 'normal', APPS_DIR, done);
};
buildNWAppsWrapper(platforms, 'normal', APPS_DIR, done);
}

function listPostBuildTasks(folder, done) {

Expand All @@ -255,6 +262,10 @@ function listPostBuildTasks(folder, done) {
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() });
Expand All @@ -264,14 +275,19 @@ function listPostBuildTasks(folder, done) {

function post_build(arch, folder, done) {

if ((arch =='linux32') || (arch == 'linux64')) {
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();
}

Expand All @@ -280,11 +296,112 @@ function debug(done) {
var platforms = getPlatforms();
removeItem(platforms, 'chromeos');

buildNWApps(platforms, 'sdk', DEBUG_DIR, done);
buildNWAppsWrapper(platforms, 'sdk', DEBUG_DIR, done);
}

function buildNWApps(platforms, flavor, 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,
Expand All @@ -311,7 +428,7 @@ function start_debug(done) {

var platforms = getPlatforms();

var exec = require('child_process').exec;
var exec = require('child_process').exec;
if (platforms.length === 1) {
var run = getRunDebugAppCommand(platforms[0]);
console.log('Starting debug app (' + run + ')...');
Expand Down Expand Up @@ -534,6 +651,10 @@ function listReleaseTasks(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') });
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Space before brace missing.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you're referring to release_armv7_zip(){, I'm consistent with the rest of the script.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually you are not:

mikeller@pc:~/git/betaflight-configurator$ grep -e "function.*) {" gulpfile.js | wc -l
34
mikeller@pc:~/git/betaflight-configurator$ grep -e "function.*){" gulpfile.js | wc -l
12

And yes, the script is already inconsistent in this respect.

In general, I don't like the use of single line function definitions - they make maintenance of the code harder by increasing the probability of merge conflicts.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this segment of code they could as well be anonymous functions, but naming them helps a bit while debugging I guess.

I'd suggest that this block (arch-specific build functions) should be allowed to have one liners & no space after the function's declaration, in order to strive for an overall shorter line length.

If you want to keep the spaced style I'll fix the rest of the occurrences in the file, but this might somehow clutter the scope of this PR.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can leave them for now and clean this up in another pull request.

I do not quite get what advantage you see in 'overall shorter line length', to me the goal should be to be consistent for all function definitions.

}

if (platforms.indexOf('osx64') !== -1) {
releaseTasks.push(release_osx64);
}
Expand Down
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@
"devDependencies": {
"command-exists": "^1.2.2",
"del": "^3.0.0",
"follow-redirects": "^1.4.1",
"fs-extra": "^6.0.1",
"gulp": "~4.0.0",
"gulp-concat": "~2.6.1",
"gulp-debian": "~0.1.8",
Expand All @@ -55,6 +57,7 @@
"os": "^0.1.1",
"platform-dependent-modules": "0.0.14",
"rpm-builder": "^0.7.0",
"targz": "^1.0.1",
"temp": "^0.8.3"
},
"config": {
Expand Down