tooltwist
Version:
Tooltwist Command Line Interface
332 lines (276 loc) • 10.4 kB
JavaScript
/**
* Create example templates.
*/
var fs = require('fs'),
path = require('path'),
Log = require('./log'),
Config = require('./config'),
Mustache = require("mustache"),
mkdirp = require('mkdirp');
//var _templateOverrideDirectory = null;
/**
* Define the template override directory. If a template can be found
* in this directory, use it in preference to the default template
* provided by the tooltwist node page.
exports.setTemplateOverrideDirectory = function(dir) {
if (dir) {
_templateOverrideDirectory = null;
return;
}
// Check the directory exists
try {
if ( !fs.lstatSync(dir).isDirectory()) {
Log.error();
Log.error('Error: Template directory not found: ' + templatesDir);
Log.error();
return callback(false);
}
}
catch (e) {
Log.error('\nError: Could not access template directory: ' + templatesDir + '\n')
return callback(false);
}
Log.info();
Log.info('Where available will use templates in ' + templatesDir)
_templateOverrideDirectory = dir;
}
*/
/**
* Look for a template in the override directory, or default template directory.
*/
exports.findTemplate = function(defaultTemplateDir, relativePath) {
Log.debug();
Log.debug('templates.findTemplate(' + defaultTemplateDir + ', ' + relativePath + ')');
// See if we have a override template.
var path = Config.TEMPLATE_OVERRIDE_DIR + '/' + relativePath;
if (fs.existsSync(path)) {
Log.debug(' - use custom template: ' + path);
return path;
}
// var templateDirectories = [
// Config.RESOURCES_DIR + '/templates',
// Config.RESOURCES_DIR + '/plugins/docker/templates',
// ];
// Look in node directory for the tooltwist package.
var path = defaultTemplateDir + '/' + relativePath;
Log.debug(' - use default template: ' + path);
return path;
}
/**
* Create a file, using a Mustache template.
*/
exports.copyTemplate = function(defaultTemplateDir, source, target, view) {
/*
// Get the default template location
var from = Config.RESOURCES_DIR + '/templates/' + source;
// See if there is a template to override the default
if (templateDirectory) {
var path = templateDirectory + '/' + source;
if (fs.existsSync(path)) {
Log.info(' - using custom template: ' + path)
from = path;
}
}
*/
// Load the template
var from = exports.findTemplate(defaultTemplateDir, source);
var template = fs.readFileSync(from, "utf8");
// If we don't have an absolute path, place it beneath .toolwist
if (target.substring(0, 1) !== '/') {
target = Config.HIDDEN_DIR + '/' + target;
}
Log.debug(from + ' --> ' + target)
var creatingExamples = false;
exports.copy(from, target, creatingExamples, view);
}
/**
* Create example templates.
*/
exports.createExampleTemplates = function(config) {
Log.debug('templates.createExampleTemplates()')
// Create example config files for designer (PHASE1)
var overridesDir = Config.PROJECT_ROOT + '/' + Config.TEMPLATES_DIRNAME;
Log.always('\n\tPlacing example template overrides in ' + overridesDir + '\n');
copyExampleTemplate('/../templates/', '.', 'template.build.gradle');
copyExampleTemplate('/../templates/', '.', 'template.filemap.xml');
copyExampleTemplate('/../templates/', '.', 'template.logback.xml');
copyExampleTemplate('/../templates/', '.', 'template.tooltwist.xml');
copyExampleTemplate('/../templates/', '.', 'template.wbd.conf');
copyExampleTemplate('/../templates/', '.', 'template.web.xml');
// Example config file for generation phase (PHASE2)
if (config.mode != 'designer') {
copyExampleTemplate('/../templates/generate/', 'generate', 'filters.xml');
}
// Example config files for production
if (config.mode === 'war') {
exports.copyTemplateDirectory(__dirname + '/../plugins/war/templates', 'production', 'war-production-', true, overridesDir, config);
} else if (config.mode === 'docker') {
exports.copyTemplateDirectory(__dirname + '/../plugins/docker/templates', 'production', 'docker-production-', true, overridesDir, config);
}
// Provide instructions
createReadmeFile();
Log.always();
process.exit(0);
}
/**
* Recursively copy files from a templates directory, overriding
* and adding files from directory tooltwist.templates.
*/
exports.copyTemplateDirectory = function(templateDir, subdirectory, removePrefix, creatingExamples, destinationDirectory, config) {
Log.debug('copyTemplateDirectory(' + templateDir + ', ' + subdirectory + ', creatingExamples=' + creatingExamples + ', ' + destinationDirectory + ')')
// Load files in the template directory
var files = [ ]; // name -> path
loadFilesRecursively(templateDir, subdirectory, files);
// Load files in the override directory
if ( !creatingExamples) {
var overridesDirectory = Config.PROJECT_ROOT + '/' + Config.TEMPLATES_DIRNAME;
var top = overridesDirectory + '/' + subdirectory;
console.log('Checking for extra templates at ' + top);
if (fs.existsSync(top) && fs.statSync(top).isDirectory) {
loadFilesRecursively(overridesDirectory, subdirectory, files);
}
}
// Now copy the files
for (var relativePath in files) {
var absolutePath = files[relativePath];
var destination = destinationDirectory + '/' + relativePath;
//console.log('** ' + relativePath + ':\n' + ' -> ' + absolutePath + ' => ' + destination)
// If this is an example template, perhaps ignore it.
var suffix = '.example';
var sourceIsExample = (relativePath.indexOf(suffix, relativePath.length - suffix.length) !== -1);
// Ignore examples when generating files.
if (sourceIsExample && !creatingExamples) {
continue;
}
// If we're creating override templates, add '.example' suffix if it's not already there.
if (creatingExamples && !sourceIsExample) {
destination += '.example';
}
// if (relativePath.indexOf(suffix, relativePath.length - suffix.length) !== -1) {
//
// // Source filename ends with '.example'
// if (creatingExamples) {
//
// // Use the same name when creating overrides
// var destination = destinationDirectory + '/' + relativePath;
// } else {
//
// // Ignore examples when generating files
// //console.log(' (ignore example)')
// continue;
// }
// } else {
//
// }
// // See if the name matches our prefix
// if (creatingExamples) {
// //console.log(' (make example)')
// destination += '.example';
// }
// console.log(' ==> destination=' + destination)
var dir = path.dirname(destination);
var name = path.basename(destination);
// If the template name starts with the prefix, remove the prefix.
if (name.indexOf(removePrefix) === 0) {
// Strip off the prefix
//console.log(' (strip off prefix)')
var name = name.substring(removePrefix.length);
destination = dir + '/' + name;
}
// Check the directory exists and create the file.
mkdirp.sync(dir);
//console.log(' creating ' + destination)
exports.copy(absolutePath, destination, creatingExamples, config);
}
}
// Recursively find files in a template directory
function loadFilesRecursively(basedir, subdir, files) {
// console.log('loadFilesRecursively(' + basedir + ', ' + subdir + ')');
var list = fs.readdirSync(basedir + '/' + subdir);
for (var i = 0; i < list.length; i++) {
var name = list[i];
var absolutePath = basedir + '/' + subdir + '/' + name;
if (fs.statSync(absolutePath).isDirectory()) {
var childDir = subdir + '/' + name;
loadFilesRecursively(basedir, childDir, files);
} else {
var relativePath = subdir + '/' + name;
files[relativePath] = absolutePath;
}
}
}
/**
* Copy a template into the overrides directory, as an example file.
*/
function copyExampleTemplate(from, dir, name) {
var template = __dirname + from + name;
if (dir === '.') {
var relativeDir = Config.TEMPLATES_DIRNAME;
var relativePath = relativeDir + '/' + name + '.example';
} else {
var template = __dirname + "/../templates/" + dir + '/' + name;
var relativeDir = Config.TEMPLATES_DIRNAME + '/' + dir;
var relativePath = relativeDir + '/' + name + '.example';
}
// Check the directory exists
mkdirp.sync(Config.PROJECT_ROOT + '/' + relativeDir);
// Load the template
Log.debug('template --------------> ' + template)
var content = fs.readFileSync(template, "utf8");
var to = Config.PROJECT_ROOT + '/' + relativePath;
Log.debug('to --------------> ' + to)
fs.writeFileSync(to, content, { encoding: 'utf8' });
// Nice message
//Log.always('\t - ' + relativePath);
}
/**
* Create a README file, and write instructions to Stdout.
*/
function createReadmeFile() {
var str = instructions();
Log.always(str);
var readmeFile = Config.PROJECT_ROOT + '/' + Config.TEMPLATES_DIRNAME + '/README';
fs.writeFileSync(readmeFile, str, { encoding: 'utf8' });
}
/**
* Description for how to use override templates.
*/
function instructions() {
return '\
\n\n\
OVER-RIDING TEMPLATES:\n\
\n\
Most of the configuration files used by the \'tooltwist\' command are\n\
generated from templates. Default templates are used, but in some\n\
cases you may wish to alter a config file. You do that by overriding\n\
the default template for the config file.\n\
\n\
If you are familiar with ToolTwist the template names will be familiar.\n\
To override a template, remove the \'.example\' from the end of any of\n\
the files in the overrides directory (' + Config.TEMPLATES_DIRNAME + ') and alter\n\
the file as you wish. The examples can be recreated at any time with\n\
the command \'tooltwist example-templates\'.\n\
\n\
Files in the \'production\' directory are used when generating the\n\
final application, for example when creating docker or war images.\n\
\n\
The \'generate\' directory contains templates used during the generation step.\n\
\n\
Additional files for designer mode can be placed in the \'designer\' directory.\n'
}
/**
* Create a new file from a Mustache template.
*/
exports.copy = function(from, to, creatingExamples, data) {
Log.debug('template.copy ' + from + ", " + to)
var template = fs.readFileSync(from, "utf8");
if (creatingExamples) {
// We are cloning to an example template - copy as-is
fs.writeFileSync(to, template, { encoding: 'utf8' });
} else {
// Substitute values into the template
var data = data ? data : { };
var output = Mustache.render(template, data);
fs.writeFileSync(to, output, { encoding: 'utf8' });
}
}