Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
21 changes: 19 additions & 2 deletions core/lib/changes_hunter.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,23 @@ ChangesHunter.prototype = {
let renderedTemplatePath =
patternlab.config.paths.public.patterns + pattern.getPatternLink(patternlab, 'rendered');

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

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

try {
// Prevent error message if file does not exist
fs.accessSync(renderedTemplatePath, fs.F_OK);

// renderedTemplatePath required to display a single element
// Markup only is required for "View All" pages. It will get loaded later on.
// If any of these is missing, mark pattern for recompile
[renderedTemplatePath, markupOnlyPath].forEach(renderedFile =>
// Prevent error message if file does not exist
fs.accessSync(renderedFile, fs.F_OK)
);
let outputLastModified = fs.statSync(renderedTemplatePath).mtime.getTime();

if (pattern.lastModified && outputLastModified > pattern.lastModified) {
Expand Down Expand Up @@ -76,6 +86,13 @@ ChangesHunter.prototype = {
// Ignore, not a regular file
}
}
},

needsRebuild: function(lastModified, p) {
if (p.compileState !== CompileState.CLEAN || ! p.lastModified) {
return true;
}
return p.lastModified >= lastModified;
}
};

Expand Down
42 changes: 35 additions & 7 deletions core/lib/pattern_assembler.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"use strict";

var path = require('path'),
_ = require('lodash'),
fs = require('fs-extra'),
Pattern = require('./object_factory').Pattern,
CompileState = require('./object_factory').CompileState,
Expand Down Expand Up @@ -406,13 +407,40 @@ var pattern_assembler = function () {
decomposePattern(currentPattern, patternlab);
}

function findModifiedPatterns(lastModified, patternlab) {
return patternlab.patterns.filter(p => {
if (p.compileState !== CompileState.CLEAN || ! p.lastModified) {
return true;

/**
* Finds patterns that were modified and need to be rebuilt. For clean patterns load the already
* rendered markup.
*
* @param lastModified
* @param patternlab
*/
function markModifiedPatterns(lastModified, patternlab) {
/**
* If the given array exists, apply a function to each of its elements
* @param {Array} array
* @param {Function} func
*/
const forEachExisting = (array, func) => {
if (array) {
array.forEach(func);
}
return p.lastModified >= lastModified;
};
const modifiedOrNot = _.groupBy(
patternlab.patterns,
p => changes_hunter.needsRebuild(lastModified, p) ? 'modified' : 'notModified');

// For all unmodified patterns load their rendered template output
forEachExisting(modifiedOrNot.notModified, cleanPattern => {
const xp = path.join(patternlab.config.paths.public.patterns, cleanPattern.getPatternLink(patternlab, 'markupOnly'));

// Pattern with non-existing markupOnly files were already marked for rebuild and thus are not "CLEAN"
cleanPattern.patternPartialCode = fs.readFileSync(xp, 'utf8');
});

// For all patterns that were modified, schedule them for rebuild
forEachExisting(modifiedOrNot.modified, p => p.compileState = CompileState.NEEDS_REBUILD);
return modifiedOrNot;
}

function expandPartials(foundPatternPartials, list_item_hunter, patternlab, currentPattern) {
Expand Down Expand Up @@ -528,8 +556,8 @@ var pattern_assembler = function () {
}

return {
find_modified_patterns: function (lastModified, patternlab) {
return findModifiedPatterns(lastModified, patternlab);
mark_modified_patterns: function (lastModified, patternlab) {
return markModifiedPatterns(lastModified, patternlab);
},
find_pattern_partials: function (pattern) {
return pattern.findPartials();
Expand Down
7 changes: 1 addition & 6 deletions core/lib/patternlab.js
Original file line number Diff line number Diff line change
Expand Up @@ -564,12 +564,7 @@ var patternlab_engine = function (config) {

// TODO Find created or deleted files
let now = new Date().getTime();
let modified = pattern_assembler.find_modified_patterns(now, patternlab);

// First mark all modified files
for (let p of modified) {
p.compileState = CompileState.NEEDS_REBUILD;
}
pattern_assembler.mark_modified_patterns(now, patternlab);
patternsToBuild = patternlab.graph.compileOrder();
} else {
// build all patterns, mark all to be rebuilt
Expand Down
51 changes: 32 additions & 19 deletions test/pattern_assembler_tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ function emptyPatternLab() {
}
}

const patterns_dir = './test/files/_patterns';
const public_dir = './test/public';

tap.test('process_pattern_recursive recursively includes partials', function(test) {

//tests inclusion of partial that will be discovered by diveSync later in iteration than parent
Expand All @@ -23,8 +26,6 @@ tap.test('process_pattern_recursive recursively includes partials', function(tes
var pa = require('../core/lib/pattern_assembler');
var plMain = require('../core/lib/patternlab');
var pattern_assembler = new pa();
var patterns_dir = './test/files/_patterns';
var public_dir = './test/public';
var patternlab = emptyPatternLab();
patternlab.config = fs.readJSONSync('./patternlab-config.json');
patternlab.config.paths.source.patterns = patterns_dir;
Expand Down Expand Up @@ -662,14 +663,24 @@ tap.test('addPattern - adds pattern template to patternlab partial object if ext
test.end();
});

tap.test('findModifiedPatterns - finds patterns modified since a given date', function(test){
tap.test('markModifiedPatterns - finds patterns modified since a given date', function(test){
const fs = require('fs-extra');
// test/myModule.test.js
var rewire = require("rewire");

var pattern_assembler_mock = rewire("../core/lib/pattern_assembler");
var fsMock = {
readFileSync: function (path, encoding, cb) {
return "";
}
};
pattern_assembler_mock.__set__("fs", fsMock);
//arrange
var pattern_assembler = new pa();
var pattern_assembler = new pattern_assembler_mock();
var patternlab = emptyPatternLab();
patternlab.partials = {};
patternlab.data = {link: {}};
patternlab.config = { debug: false };
patternlab.config.outputFileSuffixes = {rendered : ''};
patternlab.config = fs.readJSONSync('./patternlab-config.json');
patternlab.config.paths.public.patterns = public_dir + "/patterns";
patternlab.config.outputFileSuffixes = {rendered: '', markupOnly: '.markup-only'};

var pattern = new Pattern('00-test/01-bar.mustache');
pattern.extendedTemplate = undefined;
Expand All @@ -681,17 +692,19 @@ tap.test('findModifiedPatterns - finds patterns modified since a given date', fu
patternlab.patterns = [pattern];

var lastCompilationRun = new Date("2016-01-01").getTime();
var p = pattern_assembler.find_modified_patterns(lastCompilationRun, patternlab);
var modifiedOrNot = pattern_assembler.mark_modified_patterns(lastCompilationRun, patternlab);

test.same(p.length, 1, "The pattern was modified after the last compilation");
test.same(modifiedOrNot.modified.length, 1, "The pattern was modified after the last compilation");

// Reset the compile state as it was previously set by pattern_assembler.mark_modified_patterns
pattern.compileState = CompileState.CLEAN;
lastCompilationRun = new Date("2016-12-31").getTime();
p = pattern_assembler.find_modified_patterns(lastCompilationRun, patternlab);
test.same(p.length, 0, "Pattern was already compiled and hasn't been modified since last compile");
modifiedOrNot = pattern_assembler.mark_modified_patterns(lastCompilationRun, patternlab);
test.same(modifiedOrNot.notModified.length, 1, "Pattern was already compiled and hasn't been modified since last compile");
test.end();
})
});

tap.test('findModifiedPatterns - finds patterns when modification date is missing', function(test){
tap.test('markModifiedPatterns - finds patterns when modification date is missing', function(test){
//arrange
var pattern_assembler = new pa();
var patternlab = emptyPatternLab();
Expand All @@ -706,13 +719,13 @@ tap.test('findModifiedPatterns - finds patterns when modification date is missin
pattern.lastModified = undefined;
patternlab.patterns = [pattern];

let p = pattern_assembler.find_modified_patterns(1000, patternlab);
test.same(p.length, 1);
let p = pattern_assembler.mark_modified_patterns(1000, patternlab);
test.same(p.modified.length, 1);
test.end();
});

// This is the case when we want to force recompilation
tap.test('findModifiedPatterns - finds patterns via compile state', function(test){
tap.test('markModifiedPatterns - finds patterns via compile state', function(test){
//arrange
var pattern_assembler = new pa();
var patternlab = emptyPatternLab();
Expand All @@ -728,8 +741,8 @@ tap.test('findModifiedPatterns - finds patterns via compile state', function(tes
pattern.compileState = CompileState.NEEDS_REBUILD;
patternlab.patterns = [pattern];

let p = pattern_assembler.find_modified_patterns(1000, patternlab);
test.same(p.length, 1);
let p = pattern_assembler.mark_modified_patterns(1000, patternlab);
test.same(p.modified.length, 1);
test.end();
});

Expand Down