Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
077fc9e
Add test cases for @block-partial issue in Handlebars engine
teehemkay Oct 31, 2016
039528a
Expose the pattern engines as a property of the patternlab object
patternfly-build Nov 8, 2016
ef92a93
Merge pull request #548 from teehemkay/dev
bmuenzenmeyer Nov 14, 2016
f699022
Fixed the path to the plugins object. Issue 91 on the edition-node-gu…
giuseppepaul Nov 14, 2016
ccaa25d
Updated to catch issue with undefined plugins array
giuseppepaul Nov 15, 2016
f5bab2a
Merge pull request #558 from giuseppepaul/dev-issue-91-edition-node-gulp
bmuenzenmeyer Nov 16, 2016
c168ccc
Merge pull request #555 from bleathem/expose-pattern-engines
bmuenzenmeyer Nov 16, 2016
b4a07cb
grab chalk and use it to make the build and engine loading process pr…
geoffp Nov 24, 2016
a18c3bb
Merge pull request #565 from pattern-lab/pretty-engine-loading
bmuenzenmeyer Nov 25, 2016
481a715
rename files to align with unit tests that may someday read them
bmuenzenmeyer Nov 25, 2016
027a26d
lint
bmuenzenmeyer Nov 25, 2016
c5905ec
trump filename sort order with pattern.md frontmatter property "order"
bmuenzenmeyer Nov 25, 2016
2ee1090
Merge pull request #567 from pattern-lab/features/376-patternorder
bmuenzenmeyer Nov 26, 2016
c8e752c
start #566 by copying @raphaelokon's great work over at https://githu…
bmuenzenmeyer Nov 26, 2016
f3abd13
orange is not a valid chalk color
bmuenzenmeyer Nov 26, 2016
1e54af0
register our events
bmuenzenmeyer Nov 26, 2016
53f877f
Merge pull request #568 from pattern-lab/features/logs
bmuenzenmeyer Nov 26, 2016
e19a6db
Issue #540 Incremental Builds
Oct 28, 2016
a38dde2
#540 fix pattern graph
Nov 30, 2016
64e6ba0
#540 Only allow linking nodes which have been added before explicitly
Nov 30, 2016
606f96c
#540 always add the pattern to the graph
Nov 30, 2016
9442cf8
#540 Patch Pattern.createEmpty to create a relPath when possible, so …
Nov 30, 2016
46eade6
#540 Remove FIXME
Nov 30, 2016
a920aea
#540 Log which patterns have been built
Nov 30, 2016
1e57ccd
#540 Move lastModified checks to new changes_hunter, fix bug with alw…
Nov 30, 2016
9a3f027
#540 JSLint and documentation, enable ES6 in .eslintrc
Dec 1, 2016
f716134
#540 Fix engine tests
Dec 2, 2016
b704443
#540 add testDependencyGraph.json to fix graph tests, remove tests/pu…
Dec 2, 2016
47d7e6c
#540 Correct .gitignore
Dec 2, 2016
b10108b
Hot fox to update link to up for grabs issues
scottgruber Dec 8, 2016
abddf62
Merge pull request #574 from scottgruber/dev
bmuenzenmeyer Dec 8, 2016
6471790
#540 Add a version to the serialized graph
Dec 12, 2016
c919e3d
#540 Add flag for GraphViz export
Dec 12, 2016
967e768
eslint
bmuenzenmeyer Dec 12, 2016
b0bde03
Merge pull request #569 from pattern-lab/features/incremental-build
bmuenzenmeyer Dec 12, 2016
73c10d2
Merge branch 'master' into dev
bmuenzenmeyer Dec 19, 2016
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
{
"env": {
"node": true,
"builtin": true
"builtin": true,
"es6": true
},
"parserOptions": {
"ecmaVersion": 6,
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,5 @@ Thumbs.db
source/css/style.css.map
.idea/
public
!test/patterns/public/.gitkeep
!test/patterns/testDependencyGraph.json
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ The [command line interface](https://github.com/pattern-lab/patternlab-node/wiki

If you'd like to contribute to Pattern Lab Node, please do so! There is always a lot of ground to cover and something for your wheelhouse.

No pull request is too small. Check out any [up for grabs issues](https://github.com/pattern-lab/patternlab-node/labels/up%20for%20grabs) as a good way to get your feet wet, or add some more unit tests.
No pull request is too small. Check out any [up for grabs issues](https://github.com/pattern-lab/patternlab-node/labels/help%20wanted%20%2F%20up%20for%20grabs) as a good way to get your feet wet, or add some more unit tests.

## Guidelines
1. Please keep your pull requests concise and limited to **ONE** substantive change at a time. This makes reviewing and testing so much easier.
Expand Down
81 changes: 81 additions & 0 deletions core/lib/changes_hunter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
"use strict";
const fs = require("fs-extra"),
CompileState = require('./object_factory').CompileState;

/**
* For detecting changed patterns.
* @constructor
*/
let ChangesHunter = function () {
};

ChangesHunter.prototype = {

/**
* Checks the build state of a pattern by comparing the modification date of the rendered output
* file with the {@link Pattern.lastModified}. If the pattern was modified after the last
* time it has been rendered, it is flagged for rebuilding via {@link CompileState.NEEDS_REBUILD}.
*
* @param {Pattern} pattern
* @param patternlab
*
* @see {@link CompileState}
*/
checkBuildState: function (pattern, patternlab) {

//write the compiled template to the public patterns directory
let renderedTemplatePath =
patternlab.config.paths.public.patterns + pattern.getPatternLink(patternlab, 'rendered');

if (!pattern.compileState) {
pattern.compileState = CompileState.NEEDS_REBUILD;
}

try {
// Prevent error message if file does not exist
fs.accessSync(renderedTemplatePath, fs.F_OK);
let outputLastModified = fs.statSync(renderedTemplatePath).mtime.getTime();

if (pattern.lastModified && outputLastModified > pattern.lastModified) {
pattern.compileState = CompileState.CLEAN;
}
} catch (e) {
// Output does not exist yet, needs recompile
}

let node = patternlab.graph.node(pattern);

// Make the pattern known to the PatternGraph and remember its compileState
if (!node) {
patternlab.graph.add(pattern);
} else {
// Works via object reference, so we directly manipulate the node data here
node.compileState = pattern.compileState;
}


},

/**
* Updates {Pattern#lastModified} to the files modification date if the file was modified
* after {Pattern#lastModified}.
*
* @param {Pattern} currentPattern
* @param {string} file
*/
checkLastModified: function (currentPattern, file) {
if (file) {
try {
let stat = fs.statSync(file);

// Needs recompile whenever one of the patterns files (template, json, pseudopatterns) changed
currentPattern.lastModified =
Math.max(stat.mtime.getTime(), currentPattern.lastModified || 0);
} catch (e) {
// Ignore, not a regular file
}
}
}
};

module.exports = ChangesHunter;
70 changes: 44 additions & 26 deletions core/lib/lineage_hunter.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
"use strict";

var extend = require("util")._extend;

var lineage_hunter = function () {

var pa = require('./pattern_assembler');

function findlineage(pattern, patternlab) {
// As we are adding edges from pattern to ancestor patterns, ensure it is known to the graph
patternlab.graph.add(pattern);

var pattern_assembler = new pa();

Expand All @@ -28,6 +32,11 @@ var lineage_hunter = function () {
l.lineageState = ancestorPattern.patternState;
}

patternlab.graph.add(ancestorPattern);

// Confusing: pattern includes "ancestorPattern", not the other way round
patternlab.graph.link(pattern, ancestorPattern);

pattern.lineage.push(l);

//also, add the lineageR entry if it doesn't exist
Expand All @@ -44,62 +53,71 @@ var lineage_hunter = function () {
}

ancestorPattern.lineageR.push(lr);
extend(patternlab.graph.node(ancestorPattern), lr);
}
}
});
}
}

function setPatternState(direction, pattern, targetPattern) {
// if the request came from the past, apply target pattern state to current pattern lineage
/**
* Apply the target pattern state either to any predecessors or successors of the given
* pattern in the pattern graph.
* @param direction Either 'fromPast' or 'fromFuture'
* @param pattern {Pattern}
* @param targetPattern {Pattern}
* @param graph {PatternGraph}
*/
function setPatternState(direction, pattern, targetPattern, graph) {
var index = null;
if (direction === 'fromPast') {
for (var i = 0; i < pattern.lineageIndex.length; i++) {
if (pattern.lineageIndex[i] === targetPattern.patternPartial) {
pattern.lineage[i].lineageState = targetPattern.patternState;
}
}
index = graph.lineage(pattern);
} else {
//the request came from the future, apply target pattern state to current pattern reverse lineage
for (var i = 0; i < pattern.lineageRIndex.length; i++) {
if (pattern.lineageRIndex[i] === targetPattern.patternPartial) {
pattern.lineageR[i].lineageState = targetPattern.patternState;
}
index = graph.lineageR(pattern);
}

// if the request came from the past, apply target pattern state to current pattern lineage
for (var i = 0; i < index.length; i++) {
if (index[i].patternPartial === targetPattern.patternPartial) {
index[i].lineageState = targetPattern.patternState;
}
}
}


function cascadePatternStates(patternlab) {

var pattern_assembler = new pa();

for (var i = 0; i < patternlab.patterns.length; i++) {
var pattern = patternlab.patterns[i];

//for each pattern with a defined state
if (pattern.patternState) {
var lineage = patternlab.graph.lineage(pattern);

if (pattern.lineageIndex && pattern.lineageIndex.length > 0) {
if (lineage && lineage.length > 0) {

//find all lineage - patterns being consumed by this one
for (var h = 0; h < pattern.lineageIndex.length; h++) {
var lineagePattern = pattern_assembler.getPartial(pattern.lineageIndex[h], patternlab);
setPatternState('fromFuture', lineagePattern, pattern);
for (var h = 0; h < lineage.length; h++) {
// Not needed, the graph already knows the concrete pattern
// var lineagePattern = pattern_assembler.getPartial(lineageIndex[h], patternlab);
setPatternState('fromFuture', lineage[h], pattern, patternlab.graph);
}
}

if (pattern.lineageRIndex && pattern.lineageRIndex.length > 0) {
var lineageR = patternlab.graph.lineageR(pattern);
if (lineageR && lineageR.length > 0) {

//find all reverse lineage - that is, patterns consuming this one
for (var j = 0; j < pattern.lineageRIndex.length; j++) {
for (var j = 0; j < lineageR.length; j++) {

var lineageRPattern = pattern_assembler.getPartial(pattern.lineageRIndex[j], patternlab);
var lineageRPattern = lineageR[j];

//only set patternState if pattern.patternState "is less than" the lineageRPattern.patternstate
//or if lineageRPattern.patternstate (the consuming pattern) does not have a state
//this makes patternlab apply the lowest common ancestor denominator
if (lineageRPattern.patternState === '' || (patternlab.config.patternStateCascade.indexOf(pattern.patternState)
< patternlab.config.patternStateCascade.indexOf(lineageRPattern.patternState))) {
let patternStateCascade = patternlab.config.patternStateCascade;
let patternStateIndex = patternStateCascade.indexOf(pattern.patternState);
let patternReverseStateIndex = patternStateCascade.indexOf(lineageRPattern.patternState);
if (lineageRPattern.patternState === '' || (patternStateIndex < patternReverseStateIndex)) {

if (patternlab.config.debug) {
console.log('Found a lower common denominator pattern state: ' + pattern.patternState + ' on ' + pattern.patternPartial + '. Setting reverse lineage pattern ' + lineageRPattern.patternPartial + ' from ' + (lineageRPattern.patternState === '' ? '<<blank>>' : lineageRPattern.patternState));
Expand All @@ -108,9 +126,9 @@ var lineage_hunter = function () {
lineageRPattern.patternState = pattern.patternState;

//take this opportunity to overwrite the lineageRPattern's lineage state too
setPatternState('fromPast', lineageRPattern, pattern);
setPatternState('fromPast', lineageRPattern, pattern, patternlab.graph);
} else {
setPatternState('fromPast', pattern, lineageRPattern);
setPatternState('fromPast', pattern, lineageRPattern, patternlab.graph);
}
}
}
Expand Down
36 changes: 34 additions & 2 deletions core/lib/object_factory.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,23 @@ var Pattern = function (relPath, data, patternlab) {
this.lineageR = [];
this.lineageRIndex = [];
this.isPseudoPattern = false;
this.order = Number.MAX_SAFE_INTEGER;
this.engine = patternEngines.getEngineForPattern(this);

/**
* Determines if this pattern needs to be recompiled.
*
* @ee {@link CompileState}*/
this.compileState = null;

/**
* Timestamp in milliseconds when the pattern template or auxilary file (e.g. json) were modified.
* If multiple files are affected, this is the timestamp of the most recent change.
*
* @see {@link pattern}
*/
this.lastModified = null;

};

// Pattern methods
Expand Down Expand Up @@ -140,7 +156,16 @@ Pattern.prototype = {
// factory: creates an empty Pattern for miscellaneous internal use, such as
// by list_item_hunter
Pattern.createEmpty = function (customProps, patternlab) {
var pattern = new Pattern('', null, patternlab);
let relPath = '';
if (customProps) {
if (customProps.relPath) {
relPath = customProps.relPath;
} else if (customProps.subdir && customProps.filename) {
relPath = customProps.subdir + path.sep + customProps.filename;
}
}

var pattern = new Pattern(relPath, null, patternlab);
return extend(pattern, customProps);
};

Expand All @@ -152,6 +177,13 @@ Pattern.create = function (relPath, data, customProps, patternlab) {
return extend(newPattern, customProps);
};

var CompileState = {
NEEDS_REBUILD: "needs rebuild",
BUILDING: "building",
CLEAN: "clean"
};

module.exports = {
Pattern: Pattern
Pattern: Pattern,
CompileState: CompileState
};
Loading