500 lines
14 KiB
JavaScript
500 lines
14 KiB
JavaScript
const path = require('path'),
|
|
gchmod = require('gulp-chmod'),
|
|
CWD = process.cwd()
|
|
gconcat = require('gulp-concat'),
|
|
grename = require('gulp-rename'),
|
|
_ = require('underscore'),
|
|
gutil = require('gulp-util'),
|
|
grename = require('gulp-rename'),
|
|
del = require('del'),
|
|
exec = require('child_process').exec,
|
|
execFile = require('child_process').execFile,
|
|
fs = require('fs'),
|
|
mkdirp = require('mkdirp'),
|
|
replace = require('gulp-replace'),
|
|
isWIN = /^win/.test(process.platform);
|
|
|
|
var gulp = require('gulp'),
|
|
config = require('./config/build.json');
|
|
|
|
function getVariableName(varName) {
|
|
if (/^\%.+\%$/.test(varName)) {
|
|
return varName.match(/^\%(.+)\%$/)[1];
|
|
}
|
|
return null;
|
|
}
|
|
|
|
function getValue(key, vars) {
|
|
var value = this[key],
|
|
finalValue = '',
|
|
variable,
|
|
i;
|
|
|
|
if (typeof value !== 'string') {
|
|
return value;
|
|
}
|
|
|
|
if (/^\$\[(.*)\]\$$/.test(value)) {
|
|
value = JSON.parse(value.match(/^\$(\[.*\])\$$/)[1]);
|
|
|
|
for (i = 0; i < value.length; i += 1) {
|
|
if (variable = getVariableName(value[i])) {
|
|
finalValue += vars[variable];
|
|
} else {
|
|
finalValue += value[i];
|
|
}
|
|
}
|
|
} else if (variable = getVariableName(value)) {
|
|
finalValue = vars[variable];
|
|
} else {
|
|
finalValue = value;
|
|
}
|
|
|
|
return finalValue;
|
|
}
|
|
|
|
function executeSequence(sequence, callback) {
|
|
var current;
|
|
if (sequence.length) {
|
|
current = sequence.shift();
|
|
current(function (err, returnValue) {
|
|
if (err) {
|
|
callback(err);
|
|
return;
|
|
}
|
|
executeSequence(sequence, callback);
|
|
});
|
|
} else {
|
|
callback();
|
|
}
|
|
}
|
|
|
|
function validatePath(dir) {
|
|
// for the sake of security absolute paths are not allowed
|
|
if (path.isAbsolute(dir)) {
|
|
throw new Error('Absolute paths are not allowed (used path: ' + dir + ').');
|
|
}
|
|
|
|
// for the sake of security paths directioning outside the current directory are not allowed
|
|
if (/\.\./.test(path.relative(CWD, dir))) {
|
|
throw new Error('Paths poiting outside ProcessMaker project are not allowed (used path: ' + dir + ').');
|
|
}
|
|
}
|
|
|
|
function cleanDirectory(dir, callback) {
|
|
validatePath(dir);
|
|
del.sync([
|
|
dir
|
|
], {force: true});
|
|
|
|
return mkdirp(dir, function (err) {
|
|
if (typeof callback === 'function') {
|
|
callback(err);
|
|
}
|
|
});
|
|
}
|
|
|
|
function executeRake(cb, vars) {
|
|
var task = this.rake_task.trim(),
|
|
dir = this.rake_dir.trim(),
|
|
that = this;
|
|
|
|
validatePath(dir);
|
|
|
|
gutil.log(gutil.colors.yellow('Executing Rake ' + (task ? '(task: ' + task + ') ' : '') + 'in ' + this.rake_dir));
|
|
exec('rake ' + task, {
|
|
cwd: path.join(__dirname , dir)
|
|
}, function (err, stdout, stderr) {
|
|
if (err) {
|
|
cb(err);
|
|
} else {
|
|
if (typeof that.variable === 'string') {
|
|
vars[that.variable] = stdout.trim();
|
|
}
|
|
cb();
|
|
}
|
|
});
|
|
}
|
|
|
|
function executeCopy(cb) {
|
|
var src_dir = this['src_dir'] || '',
|
|
dest_dir = this['dest_dir'] || '',
|
|
file_mode = this['file_mode'],
|
|
stream,
|
|
file,
|
|
file_dest_dir,
|
|
file_dest_name,
|
|
files_length = this['files'].length,
|
|
origin,
|
|
destination,
|
|
i,
|
|
copied = 0,
|
|
finishCopy = function () {
|
|
copied ++;
|
|
if (copied === files_length) {
|
|
cb();
|
|
}
|
|
},
|
|
showError = function (e) {
|
|
gutil.log(gutil.colors.red(e));
|
|
};
|
|
|
|
gutil.log(gutil.colors.yellow('Executing copy of files from ' + src_dir + ' to ' + dest_dir));
|
|
|
|
for (i = 0; i < this['files'].length; i += 1) {
|
|
file = this.files[i];
|
|
file_dest_dir = file['dest_dir'] || '';
|
|
file_dest_name = file['dest_name'] || '';
|
|
|
|
origin = path.join(src_dir, file['src']);
|
|
destination = path.join(dest_dir, file_dest_dir);
|
|
|
|
validatePath(destination);
|
|
|
|
gutil.log('copying: ' + origin + ' to ' + path.join(destination, file_dest_name));
|
|
|
|
if (file_dest_name) {
|
|
stream = gulp.src([origin])
|
|
.pipe(grename(file_dest_name))
|
|
.pipe(gulp.dest(destination))
|
|
.on('error', showError)
|
|
.on('end', finishCopy);
|
|
} else {
|
|
stream = gulp.src([origin])
|
|
.pipe(gulp.dest(destination))
|
|
.on('error', showError)
|
|
.on('end', finishCopy);
|
|
}
|
|
|
|
if (file_mode) {
|
|
stream.pipe(gchmod(file_mode));
|
|
}
|
|
}
|
|
}
|
|
|
|
function executeDir(cb) {
|
|
gutil.log(gutil.colors.yellow('Executing directory operation (' + this.operation + ') over ' + this.dir));
|
|
validatePath(this.dir);
|
|
switch (this.operation) {
|
|
case 'clean':
|
|
cleanDirectory(this.dir, cb);
|
|
}
|
|
}
|
|
|
|
function executeRead(cb, vars) {
|
|
var that = this,
|
|
src = getValue.call(this, 'src', vars);
|
|
gutil.log(gutil.colors.yellow('Executing read operation from ' + src));
|
|
|
|
validatePath(src);
|
|
|
|
fs.readFile(src, function (err, data) {
|
|
if (err) {
|
|
return cb(err);
|
|
}
|
|
|
|
data = data.toString();
|
|
|
|
if (typeof that.variable === 'string') {
|
|
vars[that.variable] = data;
|
|
}
|
|
cb();
|
|
});
|
|
}
|
|
|
|
function executeParse(cb, vars) {
|
|
var data, path, i;
|
|
|
|
gutil.log(gutil.colors.yellow('Executing parsing (' + this.parseTo + ')'));
|
|
|
|
switch (this.parseTo) {
|
|
case 'json':
|
|
path = this.path || "";
|
|
path = path.split("/");
|
|
data = JSON.parse(getValue.call(this, 'data', vars));
|
|
|
|
for (i = 0; i < path.length; i += 1) {
|
|
if (path[i]) {
|
|
data = data[path[i]];
|
|
}
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if (typeof this.variable === 'string') {
|
|
vars[this.variable] = data;
|
|
}
|
|
cb();
|
|
}
|
|
|
|
function executeReplaceFileContents(cb, vars) {
|
|
var originalFile = getValue.call(this, 'orig_file', vars), // It can be string or array
|
|
replacements = getValue.call(this, 'replacements', vars),
|
|
dest_dir = getValue.call(this, 'dest_dir', vars),
|
|
dest_file = getValue.call(this, 'dest_file', vars),
|
|
completePath = path.join(dest_dir, dest_file),
|
|
that = this,
|
|
replacement,
|
|
stream,
|
|
i;
|
|
|
|
gutil.log(gutil.colors.yellow('Executing content replacement of file ' + originalFile + ' files to ' + completePath));
|
|
|
|
if (!_.isArray(replacements)) {
|
|
return cb("The replacements must be an array.");
|
|
}
|
|
|
|
validatePath(completePath);
|
|
|
|
stream = gulp.src(originalFile);
|
|
|
|
for (i = 0; i < replacements.length; i += 1) {
|
|
replacement = replacements[i];
|
|
stream = stream.pipe(replace(
|
|
getValue.call(replacement, 'search', vars),
|
|
getValue.call(replacement, 'replaceBy', vars)
|
|
));
|
|
}
|
|
|
|
stream.pipe(grename(dest_file))
|
|
.pipe(gulp.dest(dest_dir))
|
|
.on('end', function () {
|
|
if (typeof this.variable === 'string') {
|
|
vars[this.variable] = data;
|
|
}
|
|
cb();
|
|
});
|
|
}
|
|
|
|
function executeReplaceString(cb, vars) {
|
|
var target = getValue.call(this, 'target', vars),
|
|
replacement,
|
|
result = [],
|
|
isString = false,
|
|
i,
|
|
j;
|
|
|
|
gutil.log(gutil.colors.yellow('Executing replacing'));
|
|
|
|
if (typeof target === 'string') {
|
|
target = [target];
|
|
isString = true;
|
|
}
|
|
|
|
for (j = 0; j < target.length; j += 1) {
|
|
result[j] = target[j];
|
|
for (i = 0; i < this.replacements.length; i += 1) {
|
|
replacement = this.replacements[i];
|
|
result[j] = result[j].replace(getValue.call(replacement, "search", vars), getValue.call(replacement, "replaceBy", vars));
|
|
}
|
|
}
|
|
|
|
result = isString ? result[0] : result;
|
|
|
|
if (typeof this.variable === 'string') {
|
|
vars[this.variable] = result;
|
|
}
|
|
cb();
|
|
}
|
|
|
|
function executeConcatenate(cb, vars) {
|
|
var files = getValue.call(this, 'files', vars),
|
|
name = getValue.call(this, 'dest_name', vars),
|
|
completePath,
|
|
result = "",
|
|
that = this;
|
|
|
|
if (this.dest_dir && this.dest_name) {
|
|
completePath = path.join(this.dest_dir, name);
|
|
gutil.log(gutil.colors.yellow('Executing concatenation of ' + files.length + ' files to ' + completePath));
|
|
validatePath(completePath);
|
|
gulp.src(files)
|
|
.on('error', function (err) {
|
|
cb(err);
|
|
})
|
|
.on('data', function (chunk) {
|
|
result += chunk.contents;
|
|
})
|
|
.on('end', function () {
|
|
if (typeof that.variable === 'string') {
|
|
vars[that.variable] = result;
|
|
}
|
|
cb();
|
|
})
|
|
.pipe(gconcat(name))
|
|
.pipe(gulp.dest(this['dest_dir']));
|
|
} else {
|
|
gutil.log(gutil.colors.yellow('Executing concatenation of ' + files.length + ' files'));
|
|
|
|
gulp.src(files)
|
|
.pipe(gconcat('__TMP__'))
|
|
.on('error', function (err) {
|
|
cb(err);
|
|
})
|
|
.on('data', function (chunk) {
|
|
result += chunk.contents;
|
|
})
|
|
.on('end', function () {
|
|
if (typeof that.variable === 'string') {
|
|
vars[that.variable] = result;
|
|
}
|
|
cb();
|
|
});
|
|
}
|
|
}
|
|
|
|
function executeWrite(cb, vars) {
|
|
var thePath = path.join(
|
|
getValue.call(this, "dest_dir", vars),
|
|
getValue.call(this, "dest_name", vars)
|
|
);
|
|
|
|
gutil.log(gutil.colors.yellow('Executing writing of file ' + thePath));
|
|
|
|
validatePath(thePath);
|
|
|
|
fs.writeFile(thePath, getValue.call(this, "contents", vars), function (err) {
|
|
cb(err);
|
|
});
|
|
}
|
|
|
|
function executeExec(cb, vars) {
|
|
var that = this,
|
|
working_dir = path.join(this['working_dir']), // This modifies the path to POSIX/Windows
|
|
args = this['arguments'] || [],
|
|
opts = {};
|
|
|
|
if (isWIN) {
|
|
opts['shell'] = 'git-bash.exe';
|
|
}
|
|
|
|
gutil.log(gutil.colors.yellow('Executing shell command: ') + gutil.colors.bold.yellow(this['command'] + ' ' + args.join(' ')) + ' in ' + gutil.colors.bold.yellow(working_dir));
|
|
validatePath(working_dir);
|
|
|
|
execFile(this['command'], args, {
|
|
cwd: working_dir
|
|
}, function (err, stdout, stderr) {
|
|
if (err) {
|
|
return cb(err);
|
|
}
|
|
if (typeof that.variable === 'string') {
|
|
vars[that.variable] = stdout.trim();
|
|
}
|
|
cb();
|
|
});
|
|
}
|
|
|
|
function executeVariable(cb, vars) {
|
|
var varName = getValue.call(this, 'name', vars);
|
|
gutil.log(gutil.colors.yellow('Executing assignation into variable ' + varName));
|
|
vars[varName] = getValue.call(this, 'value', vars);
|
|
cb();
|
|
}
|
|
|
|
function processTask(callback, stepIndex, variables) {
|
|
var step, fn, i, that = this;
|
|
|
|
stepIndex = stepIndex || 0;
|
|
variables = variables || {};
|
|
|
|
if (stepIndex === 0) {
|
|
gutil.log(gutil.colors.green(this.description));
|
|
}
|
|
|
|
try {
|
|
if (stepIndex < this.steps.length) {
|
|
step = this.steps[stepIndex];
|
|
|
|
if (step) {
|
|
switch (step.type) {
|
|
case 'rake':
|
|
fn = executeRake;
|
|
break;
|
|
case 'copy':
|
|
fn = executeCopy;
|
|
break;
|
|
case 'dir':
|
|
fn = executeDir;
|
|
break;
|
|
case 'read':
|
|
fn = executeRead;
|
|
break;
|
|
case 'parse':
|
|
fn = executeParse;
|
|
break;
|
|
case 'replaceFileContents':
|
|
fn = executeReplaceFileContents;
|
|
break;
|
|
case 'replace_string':
|
|
fn = executeReplaceString;
|
|
break;
|
|
case 'concatenate':
|
|
fn = executeConcatenate;
|
|
break;
|
|
case 'write':
|
|
fn = executeWrite;
|
|
break;
|
|
case 'exec':
|
|
fn = executeExec;
|
|
break;
|
|
case 'variable':
|
|
fn = executeVariable;
|
|
}
|
|
|
|
if (fn) {
|
|
fn.call(step, function (err) {
|
|
if (err) {
|
|
callback(err);
|
|
return;
|
|
}
|
|
processTask.call(that, callback, stepIndex + 1, variables);
|
|
}, variables);
|
|
} else {
|
|
processTask.call(this, callback, stepIndex + 1, variables);
|
|
}
|
|
}
|
|
} else {
|
|
gutil.log(gutil.colors.green('DONE!'));
|
|
callback();
|
|
}
|
|
} catch (e) {
|
|
gutil.log(gutil.colors.red('Error at processing ' + this.id + ', step #' + (stepIndex + 1) + ' (' + step.type + '): ' + e.message));
|
|
process.exit();
|
|
}
|
|
}
|
|
|
|
gulp.task('clean', function () {
|
|
gutil.log(gutil.colors.green('Cleaning directories...'));
|
|
|
|
cleanDirectory('workflow/public_html/lib');
|
|
});
|
|
|
|
/**
|
|
* This scheduled task is to be able to create the guest user constants
|
|
*/
|
|
gulp.task('__env', function (cb) {
|
|
var data = require('./config/enviromentvariables.json'),
|
|
pathEnviroment = 'vendor/colosa/MichelangeloFE/src/enviroment/',
|
|
content = 'var __env = __env || {};';
|
|
|
|
gutil.log(gutil.colors.green('Creating System Constants...'));
|
|
|
|
fs.writeFile(
|
|
pathEnviroment + 'constants.js',
|
|
content + '__env.USER_GUEST = ' + JSON.stringify(data.constants.userguest) + ';',
|
|
cb
|
|
);
|
|
});
|
|
|
|
gulp.task('default', ['clean', '__env'], function (cb) {
|
|
var i, tasks = [];
|
|
|
|
gutil.log(gutil.colors.green('Initializing ProcessMaker building...'));
|
|
|
|
for (i = 0; i < config.length; i += 1) {
|
|
tasks.push(_.bind(processTask, config[i]));
|
|
}
|
|
executeSequence(tasks, cb);
|
|
}); |