Skip to content

Commit

Permalink
Merge branch 'release/0.4.10'
Browse files Browse the repository at this point in the history
  • Loading branch information
kmcgrath committed Jan 23, 2016
2 parents ad81181 + 400e6f2 commit 61b1221
Show file tree
Hide file tree
Showing 8 changed files with 146 additions and 131 deletions.
66 changes: 27 additions & 39 deletions README.md
Expand Up @@ -84,48 +84,22 @@ bucket.
* [particles-cloudsploit-scans](https://github.com/SungardAS/particles-cloudsploit-scans)
* [particles-enhanced-snapshots](https://github.com/SungardAS/particles-enhanced-snapshots)

## Use

### Create a project

> npm init

### Recommended .gitignore

condensation_errors
config/local.js
dist
node_modules

#### Install [gulp](http://gulpjs.com/)

> npm install -g gulp
Check out the growing list of particles on
[npm](https://www.npmjs.com/browse/keyword/condensation-particles)!

#### Install condensation

> npm install condensation --save
## Use

#### Add condensation to gulpfile.js
Get started with the Yeoman
[generator](https://github.com/SungardAS/generator-condensation).

var gulp = require('gulp');
> npm install -g yo

> npm install -g generator-condensation

> yo condensation:particles

var config = {
s3: [
{
aws: {
region: 'us-east-1',
bucket: 'MY-FAVORITE-BUCKET',
},
validate: true,
create: true
}
],
dist: 'dist'
};
This will set up a project for building and sharing particles.

// Add gulp tasks to build, compile and validate
// CloudFormation templates
require('condensation').buildTasks(gulp,config);

### Project Structure

Expand Down Expand Up @@ -330,10 +304,10 @@ plus any extensions.

#### metadata

Contents of files will be loaded as metadatas that can be used in
Contents of files will be loaded as metadata that can be used in
in a traditional template or a `layout` (**recommended**)

Directory: `metadatas`
Directory: `metadata`
Helper: `metadata`

{{{metadata 'my-metadata' logicalId="MyMetadata"}}}
Expand Down Expand Up @@ -527,6 +501,20 @@ default data definitions.
Errors due to badly formed JSON or failed CF validations will stop the
process and the offending files will be dumped to `condensation_errors`

## Experimental

### condensation.js

If a project contains `condensation.js` the file will be loaded as a
module and will attement to run the `initialize` function providing a
callback as the only parameter.

This can be used by particle project to bootstrap any necessary assets
before any template compiling begins.

Example:
[particles-cloudsploit-scans](https://github.com/SungardAS/particles-cloudsploit-scans)

## Acknowledgements

Big thank-you to [Brent Stees](https://github.com/bstees) for creating
Expand Down
4 changes: 2 additions & 2 deletions lib/condensation/index.js
Expand Up @@ -129,7 +129,7 @@ Condensation.prototype.condense = function() {
return gulp.src(['**/package.json'])
.pipe(through.obj(function(file,enc,cb) {
var packageJson = JSON.parse(file.contents);
if (_.contains(packageJson.keywords,'condensation-particles')) {
if (_.includes(packageJson.keywords,'condensation-particles')) {
this.push(file);
}
cb();
Expand Down Expand Up @@ -176,7 +176,7 @@ Condensation.prototype.condense = function() {
gulp.task(self.genTaskName('build'),buildTasks);
gulp.task(self.genTaskName('deploy'), deployTasks);
gulp.task(self.genTaskName('default'),[self.genTaskName('build')]);
_.each(_.pairs(labelTasks),function(kv) {
_.each(_.toPairs(labelTasks),function(kv) {
gulp.task(self.genTaskName('build',kv[0]),kv[1].buildTasks);
gulp.task(self.genTaskName('deploy',kv[0]),kv[1].deployTasks);
});
Expand Down
2 changes: 1 addition & 1 deletion lib/condensation/loaders/all-helpers.js
Expand Up @@ -22,7 +22,7 @@ module.exports = function(options) {


var engine = options.handlebars;
_.each(_.pairs(helpers), function(kv) {
_.each(_.toPairs(helpers), function(kv) {
if (!engine.helpers[kv[0]]) {
engine.registerHelper(kv[0],kv[1]);
}
Expand Down
2 changes: 1 addition & 1 deletion lib/condensation/loaders/particle-loader.js
Expand Up @@ -130,7 +130,7 @@ ParticleLoader.prototype.processablePaths = function() {
var templatePaths = _.values(this.registry.template);
var assetPaths = _.values(this.registry.asset);

return _.pluck(_.flatten([templatePaths,assetPaths]),'path');
return _.map(_.flatten([templatePaths,assetPaths]),'path');
};

module.exports = ParticleLoader;
Expand Down
12 changes: 10 additions & 2 deletions lib/condensation/tasks/build.js
Expand Up @@ -52,7 +52,7 @@ module.exports = function(s3opts,distPath,awsS3) {
streamCb();
}
else {
var paths = _.invoke(
var paths = _.invokeMap(
self.particleLoader.processablePaths(),
function() {
return this+"?(.hbs)";
Expand All @@ -65,7 +65,15 @@ module.exports = function(s3opts,distPath,awsS3) {
});
};

runStreams(["particles/cftemplates/**"],{cwd:self.options.root,base:self.options.root});
runStreams(
[
"particles/cftemplates/**/*.json",
"particles/cftemplates/**/*.template",
"particles/cftemplates/**/*.hbs"
],
{cwd:self.options.root,base:self.options.root}
);

});


Expand Down
2 changes: 1 addition & 1 deletion lib/condensation/template-helpers/layout.js
Expand Up @@ -25,7 +25,7 @@ var helper = function(cModule,pPath,hArgs,hOpts,cOpts) {
template.Description = hOpts.hash.TemplateDescription + "";
}

_.each(_.pairs(sectionMap), function(kv) {
_.each(_.toPairs(sectionMap), function(kv) {
if (kv[1].items.length) {
try {
template[kv[0]] = JSON.parse('{'+kv[1].items.join(',')+'}');
Expand Down
122 changes: 68 additions & 54 deletions lib/condensation/template-helpers/sections/_buildHelper.js
@@ -1,7 +1,7 @@
var _ = require('lodash'),
fs = require('fs'),
File = require('vinyl'),
matter = require('gray-matter');
fs = require('fs'),
File = require('vinyl'),
matter = require('gray-matter');


module.exports = function(particleName,options) {
Expand All @@ -11,78 +11,48 @@ module.exports = function(particleName,options) {

var helper = function(cModule,pPath,hArgs,hOpts,cOpts) {

// If this particle is extended by another and both have content blocks, merge them
// This variable holds the extended output to be merged.
var deepMerge = {};

var engine = cOpts.handlebars;
var data = cOpts.handlebars.createFrame(hOpts.data || {});

var wrapLogicalId = _.isUndefined(data.wrapLogicalId) ? opts.wrapLogicalId : data.wrapLogicalId;
var extended = data.extended || false;
var callerFile = data._file;

// Once a section partical has been started any subsequent calls should not wrap a logical id.
// Once a section has been started any subsequent calls should not wrap a logical id.
// Allows a particle to 'extend' another particle
data.extended = true;
data.wrapLogicalId = false;

var fn,
m = {},
file = data._file;
var mergeParticleTemplate = '{}';
var templateContent = '{}';

if (hOpts.fn) {
templateContent = processTemplate.call(this,hOpts.fn,hOpts,cOpts,{data:{}},data,extended,particleName);
}

if (pPath) {
var particle = cOpts.particleLoader.loadParticle(particleName,cModule,pPath,{parentFile: hOpts.data._file});
file = new File({path: particle.path});
var file = new File({path: particle.path});
m = matter(fs.readFileSync(particle.fsPath,{encoding:'utf8'}));
fn = engine.compile(m.content,{noEscape:true});
}
else {
fn = hOpts.fn;
m.data = {};
}

data._file = file;
var pData = _.cloneDeep(data);
pData._file = file;

var templateContent = '';
if (extended) {
// If extending another particle of the same type merge options in reverse
templateContent = new engine.SafeString(fn(_.merge(hOpts.hash,_.merge(m.data,this)),{data:data}));
}
else {
templateContent = new engine.SafeString(fn(_.merge(_.merge(m.data,this),hOpts.hash),{data:data}));
var fn = engine.compile(m.content,{noEscape:true,data:pData});
mergeParticleTemplate = processTemplate.call(this,fn,hOpts,cOpts,m,pData,true,particleName);
}

var logicalId = [hOpts.hash.logicalIdPrefix,hOpts.hash.logicalId,hOpts.hash.logicalIdSuffix].join('');
templateContent = JSON.stringify(_.merge(JSON.parse(mergeParticleTemplate),JSON.parse(templateContent)));

var finalContent = templateContent;

if (wrapLogicalId === true) {

/* For backwards compatiblity with older partials check to see if the
* content is a valid JSON object. If it is, don't wrap the content in braces
*
*/
try {
var testContent = JSON.parse(templateContent);
if (_.isObject(testContent)) {
finalContent = '"'+logicalId+'":'+templateContent;
}
else {
throw new Error("Must be an Object");
}
}
catch(e) {
/* If the try block does not work, no need to catch the error.
* Wrap the string in braces and move on to the next try
*/
finalContent = '"'+logicalId+'":{'+templateContent+'}';
}

/* Ensure the manufactured string is JSON compliant.
* If not, trow an error for this inclusion.
*/
try {
JSON.parse('{'+finalContent+'}');
}
catch(e) {
throw new Error(e+"\nSection parse error: " + particleName + " in file " + hOpts.data._file.path + "\n" + finalContent);
}
// TODO Throw if no logicalId
var logicalId = [hOpts.hash.logicalIdPrefix,hOpts.hash.logicalId,hOpts.hash.logicalIdSuffix].join('');
finalContent = '"'+logicalId+'":'+finalContent;
}

/* Check to see if this is being added to a layout.
Expand All @@ -100,3 +70,47 @@ module.exports = function(particleName,options) {

return helper;
};

var processTemplate = function(fn,hOpts,cOpts,m,data,extended,particleName) {

var engine = cOpts.handlebars;
var templateContent = '';

if (extended) {
// If extending another particle of the same type merge options in reverse
templateContent = new engine.SafeString(fn(_.merge(hOpts.hash,_.merge(m.data,this)),{data:data}));
}
else {
templateContent = new engine.SafeString(fn(_.merge(_.merge(m.data,this),hOpts.hash),{data:data}));
}


/* For backwards compatiblity with older partials check to see if the
* content is a valid JSON object. If it is, don't wrap the content in braces
*
*/
try {
var testContent = JSON.parse(templateContent);
if (!_.isObject(testContent)) {
throw new Error("Must be an Object");
}
}
catch(e) {
/* If the try block does not work, no need to catch the error.
* Wrap the string in braces and move on to the next try
*/
templateContent = '{'+templateContent+'}';
}


/* Ensure the manufactured string is JSON compliant.
* If not, trow an error for this inclusion.
*/
try {
JSON.parse(templateContent);
}
catch(e) {
throw new Error(e+"\nSection parse error: " + particleName + " in file " + hOpts.data._file.path + "\n" + templateContent);
}
return templateContent;
}

0 comments on commit 61b1221

Please sign in to comment.