[IMPROVE] Build tasks (#806)

* Fix lint warning

* Use arrow functions in gulp tasks

* Rearrange task files

* Rewrite tasks for tests

* Improve watch task

* Move release process to gulpfile

* Update .travis.yml and appveyor.yml

* Fix release task

* Fix codacy error
This commit is contained in:
Tasso Evangelista 2018-08-09 22:21:59 -03:00 committed by GitHub
parent 63340f8ffd
commit 31131570bb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 172 additions and 135 deletions

View file

@ -28,9 +28,7 @@ install:
script:
- if [[ "$TRAVIS_PULL_REQUEST" != "false" ]]; then export CSC_IDENTITY_AUTO_DISCOVERY=false; fi
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then yarn release --x64 --mac; fi
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then yarn release --x64 --linux; fi
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then yarn release --ia32 --linux deb rpm; fi
- yarn release
branches:
only:

View file

@ -36,7 +36,7 @@ test_script:
# - yarn e2e
build_script:
- yarn release -- --ia32 --x64 --win nsis appx
- yarn release
artifacts:
- path: 'dist\*.exe'

View file

@ -1,5 +1,6 @@
'use strict';
require('./tasks/build_app');
require('./tasks/build_tests');
require('./tasks/build-app');
require('./tasks/build-tests');
require('./tasks/release');
require('./tasks/start');

View file

@ -76,15 +76,14 @@
"scripts": {
"postinstall": "electron-builder install-app-deps",
"start": "gulp start",
"build": "gulp build",
"build": "gulp build-app",
"changelog": "conventional-changelog --config .github/changelog.js -i HISTORY.md -s",
"prerelease": "gulp build --env=production",
"release": "build",
"release": "gulp release --env=production",
"lint": "eslint .",
"pretest": "gulp build-unit --env=test",
"pretest": "gulp build-unit-tests --env=test",
"test": "electron-mocha app/specs.js.autogenerated --renderer --require source-map-support/register",
"coverage": "npm test -- -R scripts/istanbul-reporter",
"pree2e": "gulp build-e2e --env=test",
"pree2e": "gulp build-e2e-tests --env=test",
"e2e": "mocha app/e2e.js.autogenerated --require source-map-support/register"
},
"dependencies": {
@ -108,6 +107,8 @@
"gulp-batch": "^1.0.5",
"gulp-less": "^4.0.1",
"gulp-plumber": "^1.2.0",
"gulp-rename": "^1.4.0",
"gulp-sequence": "^1.0.0",
"gulp-util": "^3.0.8",
"gulp-watch": "^5.0.1",
"istanbul": "^0.4.5",

View file

@ -47,7 +47,7 @@ export const start = function () {
invalidUrl.style.display = 'none';
hostField.classList.remove('wrong');
let host = hostField.value.trim();
const host = hostField.value.trim();
hostField.value = host;
if (host.length === 0) {

64
tasks/build-app.js Normal file
View file

@ -0,0 +1,64 @@
'use strict';
const gulp = require('gulp');
const batch = require('gulp-batch');
const less = require('gulp-less');
const plumber = require('gulp-plumber');
const rename = require('gulp-rename');
const watch = require('gulp-watch');
const bundle = require('./bundle');
const utils = require('./utils');
const { beepSound, srcDir, configDir, appDir } = require('./utils');
gulp.task('public', () => {
return gulp.src(srcDir.path('public/**/*'))
.pipe(plumber())
.pipe(gulp.dest(appDir.path('public')));
});
gulp.task('i18n', () => {
return gulp.src(srcDir.path('i18n/lang/**/*'))
.pipe(plumber())
.pipe(gulp.dest(appDir.path('i18n/lang')));
});
gulp.task('bundle', () => {
return Promise.all([
bundle(srcDir.path('background.js'), appDir.path('background.js')),
bundle(srcDir.path('app.js'), appDir.path('app.js')),
bundle(srcDir.path('i18n/index.js'), appDir.path('i18n/index.js'))
]);
});
gulp.task('less', () => {
return gulp.src(srcDir.path('stylesheets/main.less'))
.pipe(plumber())
.pipe(less())
.pipe(gulp.dest(appDir.path('stylesheets')));
});
gulp.task('environment', () => {
return gulp.src(configDir.path(`env_${ utils.getEnvName() }.json`))
.pipe(plumber())
.pipe(rename('env.json'))
.pipe(gulp.dest(appDir.path('.')));
});
gulp.task('build-app', [ 'public', 'i18n', 'bundle', 'less', 'environment' ]);
gulp.task('watch', () => {
const runOnChanges = taskName => batch((event, done) => {
gulp.start(taskName, err => {
if (err) {
beepSound();
}
done(err);
});
});
watch(srcDir.path('public/**/*'), runOnChanges('public'));
watch(srcDir.path('i18n/lang/**/*'), runOnChanges('i18n'));
watch(srcDir.path('**/*.js'), runOnChanges('bundle'));
watch(srcDir.path('**/*.less'), runOnChanges('less'));
watch(configDir.path('**/*'), runOnChanges('environment'));
});

34
tasks/build-tests.js Normal file
View file

@ -0,0 +1,34 @@
'use strict';
const gulp = require('gulp');
const jetpack = require('fs-jetpack');
const bundle = require('./bundle');
const istanbul = require('rollup-plugin-istanbul');
const createEntryFile = (srcDir, matching, outputDir, entryFileName, rollupOptions) => {
return srcDir.findAsync('.', { matching })
.then(specPaths => specPaths.map(path => `import './${ path.replace(/\\/g, '/') }';`))
.then(imports => (
"// This file is generated automatically.\n" +
"// All modifications will be lost.\n" +
imports.join('\n')
))
.then(entryFileContent => srcDir.writeAsync(entryFileName, entryFileContent))
.then(() => bundle(srcDir.path(entryFileName), outputDir.path(entryFileName), rollupOptions))
.then(() => srcDir.remove(entryFileName));
};
gulp.task('build-unit-tests', [ 'environment' ], () => {
return createEntryFile(jetpack.cwd('src'), '*.spec.js', jetpack.cwd('app'), 'specs.js.autogenerated', {
rollupPlugins: [
istanbul({
exclude: ['**/*.spec.js', '**/specs.js.autogenerated'],
sourcemap: true
})
]
});
});
gulp.task('build-e2e-tests', [ 'build-app' ], () => {
return createEntryFile(jetpack.cwd('e2e'), '*.e2e.js', jetpack.cwd('app'), 'e2e.js.autogenerated');
});

View file

@ -1,56 +0,0 @@
'use strict';
const gulp = require('gulp');
const less = require('gulp-less');
const watch = require('gulp-watch');
const batch = require('gulp-batch');
const plumber = require('gulp-plumber');
const jetpack = require('fs-jetpack');
const bundle = require('./bundle');
const utils = require('./utils');
const projectDir = jetpack;
const srcDir = jetpack.cwd('./src');
const destDir = jetpack.cwd('./app');
gulp.task('bundle', function () {
return Promise.all([
bundle(srcDir.path('background.js'), destDir.path('background.js')),
bundle(srcDir.path('app.js'), destDir.path('app.js')),
bundle(srcDir.path('i18n/index.js'), destDir.path('i18n/index.js')),
gulp.src(srcDir.path('public')+'/**/*').pipe(gulp.dest(destDir.path('public'))),
gulp.src(srcDir.path('i18n/lang')+'/**/*').pipe(gulp.dest(destDir.path('i18n/lang')))
]);
});
gulp.task('less', function () {
return gulp.src(srcDir.path('stylesheets/main.less'))
.pipe(plumber())
.pipe(less())
.pipe(gulp.dest(destDir.path('stylesheets')));
});
gulp.task('environment', function () {
const configFile = 'config/env_' + utils.getEnvName() + '.json';
projectDir.copy(configFile, destDir.path('env.json'), { overwrite: true });
});
gulp.task('watch', function () {
const beepOnError = function (done) {
return function (err) {
if (err) {
utils.beepSound();
}
done(err);
};
};
watch('src/**/*.js', batch(function (events, done) {
gulp.start('bundle', beepOnError(done));
}));
watch('src/**/*.less', batch(function (events, done) {
gulp.start('less', beepOnError(done));
}));
});
gulp.task('build', ['bundle', 'less', 'environment']);

View file

@ -1,51 +0,0 @@
'use strict';
const gulp = require('gulp');
const jetpack = require('fs-jetpack');
const bundle = require('./bundle');
const istanbul = require('rollup-plugin-istanbul');
// Spec files are scattered through the whole project. Here we're searching
// for them and generate one entry file which will run all the tests.
const generateEntryFile = function (dir, destFileName, filePattern) {
const fileBanner = "// This file is generated automatically.\n"
+ "// All modifications will be lost.\n";
return dir.findAsync('.', { matching: filePattern })
.then(function (specPaths) {
const fileContent = specPaths.map(function (path) {
return 'import "./' + path.replace(/\\/g, '/') + '";';
}).join('\n');
return dir.writeAsync(destFileName, fileBanner + fileContent);
})
.then(function () {
return dir.path(destFileName);
});
};
gulp.task('build-unit', ['environment'], function () {
const srcDir = jetpack.cwd('src');
const destDir = jetpack.cwd('app');
return generateEntryFile(srcDir, 'specs.js.autogenerated', '*.spec.js')
.then(function (entryFilePath) {
return bundle(entryFilePath, destDir.path('specs.js.autogenerated'), {
rollupPlugins: [
istanbul({
exclude: ['**/*.spec.js', '**/specs.js.autogenerated'],
sourcemap: true
})
]
});
});
});
gulp.task('build-e2e', ['build'], function () {
const srcDir = jetpack.cwd('e2e');
const destDir = jetpack.cwd('app');
return generateEntryFile(srcDir, 'e2e.js.autogenerated', '*.e2e.js')
.then(function (entryFilePath) {
return bundle(entryFilePath, destDir.path('e2e.js.autogenerated'));
});
});

34
tasks/release.js Normal file
View file

@ -0,0 +1,34 @@
'use strict';
const gulp = require('gulp');
const sequence = require('gulp-sequence');
const childProcess = require('child_process');
const os = require('os');
const { getEnvName } = require('./utils');
const argv = process.argv.slice(3).filter(arg => !arg.startsWith('--env'));
const publishArgs = getEnvName() !== 'production' ? [ '--publish', 'never' ] : [];
const buildRelease = (...args) => cb => {
childProcess.spawn('node_modules/.bin/build', [ ...argv, ...publishArgs, ...args ], { stdio: 'inherit' })
.on('close', () => cb());
};
gulp.task('release:osx', [ 'build-app' ], buildRelease('--x64', '--mac'));
gulp.task('release:win', [ 'build-app' ], buildRelease('--ia32', '--x64', '--win', 'nsis', 'appx'));
gulp.task('release:linux-x64', buildRelease('--x64', '--linux'));
gulp.task('release:linux-ia32', buildRelease('--ia32', '--linux', 'deb', 'rpm'));
gulp.task('release:linux', [ 'build-app' ], sequence('release:linux-x64', 'release:linux-ia32'));
gulp.task('release', cb => {
switch (os.platform()) {
case 'darwin':
return gulp.start('release:osx', cb);
case 'win32':
return gulp.start('release:win', cb);
case 'linux':
return gulp.start('release:linux', cb);
}
});

View file

@ -1,15 +1,10 @@
'use strict';
const gulp = require('gulp');
const childProcess = require('child_process');
const electron = require('electron');
const gulp = require('gulp');
gulp.task('start', ['build', 'watch'], function () {
childProcess.spawn(electron, ['.'], {
stdio: 'inherit'
})
.on('close', function () {
// User closed the app. Kill the host process.
process.exit();
});
gulp.task('start', [ 'build-app', 'watch' ], () => {
childProcess.spawn(electron, [ '.' ], { stdio: 'inherit' })
.on('close', () => process.exit());
});

View file

@ -1,11 +1,14 @@
'use strict';
const argv = require('minimist')(process.argv);
const jetpack = require('fs-jetpack');
const minimist = require('minimist');
exports.getEnvName = function () {
return argv.env || 'development';
};
const argv = minimist(process.argv);
exports.beepSound = function () {
process.stdout.write('\u0007');
};
exports.getEnvName = () => argv.env || 'development';
exports.beepSound = () => process.stdout.write('\u0007');
exports.appDir = jetpack.cwd('app');
exports.configDir = jetpack.cwd('config');
exports.srcDir = jetpack.cwd('src');

View file

@ -2321,6 +2321,16 @@ gulp-plumber@^1.2.0:
plugin-error "^0.1.2"
through2 "^2.0.3"
gulp-rename@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/gulp-rename/-/gulp-rename-1.4.0.tgz#de1c718e7c4095ae861f7296ef4f3248648240bd"
gulp-sequence@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/gulp-sequence/-/gulp-sequence-1.0.0.tgz#862f93e6503e67c350a42948fa666953cf88ba67"
dependencies:
thunks "^4.9.0"
gulp-util@^3.0.0, gulp-util@^3.0.8:
version "3.0.8"
resolved "https://registry.yarnpkg.com/gulp-util/-/gulp-util-3.0.8.tgz#0054e1e744502e27c04c187c3ecc505dd54bbb4f"
@ -4968,6 +4978,10 @@ through@2, "through@>=2.2.7 <3", through@^2.3.6:
version "2.3.8"
resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
thunks@^4.9.0:
version "4.9.2"
resolved "https://registry.yarnpkg.com/thunks/-/thunks-4.9.2.tgz#aac2d353812512160a4611e3008d7a96e3756f8e"
tildify@^1.0.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/tildify/-/tildify-1.2.0.tgz#dcec03f55dca9b7aa3e5b04f21817eb56e63588a"