| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| 'use strict'; |
|
|
| module.exports = (grunt, pluginOptions) => { |
| const chalk = require('chalk'); |
| const VinylStream = require('./vinyl-stream'); |
| const Transform = require('stream').Transform; |
| const gulpCompilerOptions = {}; |
| const {getFirstSupportedPlatform} = require('../utils'); |
|
|
| let extraArguments; |
| let platforms; |
| let maxParallelCompilations = false; |
| if (pluginOptions) { |
| if (Array.isArray(extraArguments)) { |
| extraArguments = pluginOptions; |
| } else { |
| if (pluginOptions.platform) { |
| platforms = Array.isArray(pluginOptions.platform) ? pluginOptions.platform : [pluginOptions.platform]; |
| } |
| if (pluginOptions.extraArguments) { |
| extraArguments = pluginOptions.extraArguments; |
| } |
| if (pluginOptions.compile_in_batches && pluginOptions.max_parallel_compilations === undefined) { |
| pluginOptions.max_parallel_compilations = pluginOptions.compile_in_batches; |
| grunt.log.warn('DEPRECATED: compile_in_batches is deprecated. Use max_parallel_compilations.'); |
| } |
| if (typeof pluginOptions.max_parallel_compilations === 'number' && pluginOptions.max_parallel_compilations > 0) { |
| maxParallelCompilations = pluginOptions.max_parallel_compilations; |
| } |
| } |
| } |
|
|
| if (!platforms) { |
| platforms = ['native', 'java']; |
| } |
| const platform = getFirstSupportedPlatform(platforms); |
|
|
| class WriteGruntFiles extends Transform { |
| constructor() { |
| super({objectMode: true}); |
| } |
|
|
| _transform(file, enc, cb) { |
| grunt.file.write(file.path, file.contents); |
| this.push(file); |
| cb(); |
| } |
| } |
|
|
| function compilationPromiseGenerator(files, options, pluginOpts) { |
| return () => compilationPromise(files, options, pluginOpts); |
| } |
|
|
| |
| |
| |
| |
| |
| function compilationPromise(files, options, pluginOpts) { |
| let hadError = false; |
| function logFile(cb) { |
| |
| if (!hadError) { |
| if (options.js_output_file) { |
| grunt.log.ok(chalk.cyan(options.js_output_file) + ' created'); |
| } else { |
| grunt.log.ok('Compilation succeeded'); |
| } |
| } |
| cb(); |
| } |
|
|
| const loggingStream = new Transform({ |
| objectMode: true, |
| transform: function() {}, |
| flush: logFile |
| }); |
|
|
| return new Promise(function(resolve, reject) { |
| let stream; |
| const args = {}; |
| let gulpOpts = Object.assign({}, gulpCompilerOptions, { |
| streamMode: 'IN', |
| logger: grunt.log, |
| pluginName: 'grunt-google-closure-compiler', |
| requireStreamInput: false |
| }); |
| if (extraArguments) { |
| args.extraArguments = extraArguments; |
| } |
| const gulpCompiler = require('../gulp')(args); |
| const compilerOpts = Object.assign({}, gulpOpts, pluginOpts); |
| if (files) { |
| |
| |
| |
| stream = new VinylStream(files, {base: process.cwd()}) |
| .pipe(gulpCompiler(options, compilerOpts)); |
| } else { |
| |
| |
| |
| stream = gulpCompiler(options, compilerOpts); |
| stream.end(); |
| } |
|
|
| stream.on('error', function(err) { |
| hadError = true; |
| reject(err); |
| }); |
| stream.on('end', function(err) { |
| resolve(); |
| }); |
|
|
| stream.pipe(loggingStream); |
| stream.resume(); |
| }); |
| } |
|
|
| function closureCompilerGruntTask() { |
| const taskObject = this; |
| const asyncDone = this.async(); |
| const compileTasks = []; |
|
|
| function getCompilerOptions() { |
| const opts = taskObject.options({ |
| args: undefined |
| }); |
|
|
| const args = opts.args; |
|
|
| delete opts.args; |
|
|
| return { |
| args, |
| compilerOpts: opts |
| } |
| } |
|
|
| |
| taskObject.files.forEach(function (f) { |
| const options = getCompilerOptions(); |
|
|
| const src = f.src.filter(filepath => { |
| if (!grunt.file.exists(filepath)) { |
| grunt.log.warn('Source file ' + chalk.cyan(filepath) + ' not found'); |
| return false; |
| } |
| return true; |
| }); |
|
|
| |
| if (src.length === 0) { |
| grunt.log.warn('Destination ' + chalk.cyan(f.dest) + |
| ' not written because src files were empty'); |
| return; |
| } else { |
| options.compilerOpts.js_output_file = f.dest; |
| } |
|
|
| compileTasks.push(compilationPromiseGenerator(src, options.args || options.compilerOpts, {platform})); |
| }); |
|
|
| |
| |
| if (taskObject.files.length === 0) { |
| const options = getCompilerOptions(); |
| compileTasks.push(compilationPromiseGenerator(null, options.args || options.compilerOpts, {platform})); |
| } |
|
|
| |
| |
|
|
| return (maxParallelCompilations ? processPromisesParallel(compileTasks, maxParallelCompilations) : Promise.all(compileTasks.map(t => t()))) |
| .then(() => asyncDone()) |
| .catch((err) => { |
| grunt.log.warn(err.message); |
| grunt.fail.warn('Compilation error'); |
| asyncDone(); |
| }); |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| function processPromisesParallel(ps, maxParallelCount) { |
| |
| async function goInSequence() { |
| if (!ps.length) { |
| return true; |
| } |
| await ps.shift()(); |
| return goInSequence(); |
| } |
|
|
| let bulk = []; |
| |
| for (let i = 0; i < Math.min(maxParallelCount, ps.length); i++) { |
| bulk.push(goInSequence()); |
| } |
| return Promise.all(bulk); |
| } |
|
|
| grunt.registerMultiTask('closure-compiler', |
| 'Minify files with Google Closure Compiler', |
| closureCompilerGruntTask); |
|
|
| return closureCompilerGruntTask; |
| }; |
|
|