From 258f50119423382020a6dcbc406621ae6d5ac61f Mon Sep 17 00:00:00 2001 From: Raphael Okon Date: Thu, 1 Sep 2016 21:02:50 +0200 Subject: [PATCH 01/15] listStartkits now fetches a list of repos and returns a Promise with {name,url} per repo --- core/lib/starterkit_manager.js | 40 +++++++++++++++++++++++++++++----- package.json | 1 + 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/core/lib/starterkit_manager.js b/core/lib/starterkit_manager.js index 5be59c776..1f6eef800 100644 --- a/core/lib/starterkit_manager.js +++ b/core/lib/starterkit_manager.js @@ -1,10 +1,11 @@ "use strict"; var starterkit_manager = function (config) { - var path = require('path'), - fs = require('fs-extra'), - util = require('./utilities'), - paths = config.paths; + var path = require('path'), + fetch = require('node-fetch'), + fs = require('fs-extra'), + util = require('./utilities'), + paths = config.paths; function loadStarterKit(starterkitName, clean) { try { @@ -41,8 +42,35 @@ var starterkit_manager = function (config) { } } + /** + * @func listStarterkits + * @desc Fetches starterkit repos from GH API that contain 'starterkit' in their name for the user 'pattern-lab' + * @returns {Promise} Returns an Array<{name,url}> for the starterkit repos + */ function listStarterkits() { - console.log('https://github.com/search?utf8=%E2%9C%93&q=starterkit+in%3Aname%2C+user%3Apattern-lab&type=Repositories&ref=searchresults'); + return fetch('https://api.github.com/search/repositories?q=starterkit+in:name+user:pattern-lab&sort=stars&order=desc', { + method: 'GET', + headers: { + 'Accept': 'application/json' + } + }).then(function (res) { + var contentType = res.headers.get('content-type'); + if (contentType && contentType.indexOf('application/json') === -1) { + throw new TypeError("StarterkitManager->listStarterkits: Not valid JSON"); + } + return res.json() + }).then(function (json) { + if (!json.items || !Array.isArray(json.items)) { + return false; + } + return json.items + .map(function (repo) { + return {name: repo.name, url: repo.html_url} + }); + }).catch(function (err) { + console.error(err); + return false; + }); } function packStarterkit() { @@ -63,7 +91,7 @@ var starterkit_manager = function (config) { loadStarterKit(starterkitName, clean); }, list_starterkits: function () { - listStarterkits(); + return listStarterkits(); }, pack_starterkit: function () { packStarterkit(); diff --git a/package.json b/package.json index f6f795888..3d0957921 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ "json5": "^0.5.0", "lodash": "~4.13.1", "markdown-it": "^6.0.1", + "node-fetch": "^1.6.0", "patternengine-node-mustache": "^1.0.0" }, "devDependencies": { From f6becee53786f5bd829c96eda1a1d69ade60a05a Mon Sep 17 00:00:00 2001 From: gael-boyenval Date: Wed, 24 Aug 2016 18:48:31 +0200 Subject: [PATCH 02/15] feat: clean html at rendering --- core/lib/object_factory.js | 3 ++- package.json | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/core/lib/object_factory.js b/core/lib/object_factory.js index 71c07e4e6..6455e73dd 100644 --- a/core/lib/object_factory.js +++ b/core/lib/object_factory.js @@ -3,6 +3,7 @@ var patternEngines = require('./pattern_engines'); var path = require('path'); var extend = require('util')._extend; +var cleanHtml = require('js-beautify').html; // Pattern properties @@ -73,7 +74,7 @@ Pattern.prototype = { // render function render: function (data, partials) { if (this.engine) { - return this.engine.renderPattern(this, data || this.jsonFileData, partials); + return cleanHtml(this.engine.renderPattern(this, data || this.jsonFileData, partials)); } return null; }, diff --git a/package.json b/package.json index 6027e9d53..c37bfd5eb 100644 --- a/package.json +++ b/package.json @@ -7,6 +7,7 @@ "diveSync": "^0.3.0", "fs-extra": "^0.30.0", "glob": "^7.0.0", + "js-beautify": "^1.6.3", "js-yaml": "^3.6.1", "json5": "^0.5.0", "lodash": "~4.13.1", From 8467b203c048f491b7820480820f4c55342ecaa1 Mon Sep 17 00:00:00 2001 From: gael-boyenval Date: Fri, 2 Sep 2016 12:44:01 +0200 Subject: [PATCH 03/15] fix: move html cleaner to a more apropriate place --- core/lib/object_factory.js | 3 +-- core/lib/patternlab.js | 8 ++++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/core/lib/object_factory.js b/core/lib/object_factory.js index 6455e73dd..71c07e4e6 100644 --- a/core/lib/object_factory.js +++ b/core/lib/object_factory.js @@ -3,7 +3,6 @@ var patternEngines = require('./pattern_engines'); var path = require('path'); var extend = require('util')._extend; -var cleanHtml = require('js-beautify').html; // Pattern properties @@ -74,7 +73,7 @@ Pattern.prototype = { // render function render: function (data, partials) { if (this.engine) { - return cleanHtml(this.engine.renderPattern(this, data || this.jsonFileData, partials)); + return this.engine.renderPattern(this, data || this.jsonFileData, partials); } return null; }, diff --git a/core/lib/patternlab.js b/core/lib/patternlab.js index cafd77b71..ca3fc1c09 100644 --- a/core/lib/patternlab.js +++ b/core/lib/patternlab.js @@ -14,7 +14,8 @@ var diveSync = require('diveSync'), glob = require('glob'), _ = require('lodash'), path = require('path'), - plutils = require('./utilities'); + plutils = require('./utilities'), + cleanHtml = require('js-beautify').html; function buildPatternData(dataFilesPath, fs) { var dataFiles = glob.sync(dataFilesPath + '*.json', {"ignore" : [dataFilesPath + 'listitems.json']}); @@ -386,13 +387,16 @@ var patternlab_engine = function (config) { //write the compiled template to the public patterns directory var patternPage = headHTML + pattern.patternPartialCode + footerHTML; + var cleanedPatternPage = cleanHtml(patternPage); + var cleanedPatternPartialCode = cleanHtml(pattern.patternPartialCode); + fs.outputFileSync(paths.public.patterns + pattern.getPatternLink(patternlab, 'rendered'), patternPage); //write the mustache file too fs.outputFileSync(paths.public.patterns + pattern.getPatternLink(patternlab, 'rawTemplate'), pattern.template); //write the encoded version too - fs.outputFileSync(paths.public.patterns + pattern.getPatternLink(patternlab, 'markupOnly'), pattern.patternPartialCode); + fs.outputFileSync(paths.public.patterns + pattern.getPatternLink(patternlab, 'markupOnly'), cleanedPatternPartialCode); return true; }); From a6f4d9c46d130b62ca3614d8c6630263eae9adad Mon Sep 17 00:00:00 2001 From: gael-boyenval Date: Fri, 2 Sep 2016 13:55:50 +0200 Subject: [PATCH 04/15] feat: optionate cleanHtmlOutput --- core/lib/patternlab.js | 6 +++--- patternlab-config.json | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/core/lib/patternlab.js b/core/lib/patternlab.js index ca3fc1c09..168029fe4 100644 --- a/core/lib/patternlab.js +++ b/core/lib/patternlab.js @@ -387,10 +387,10 @@ var patternlab_engine = function (config) { //write the compiled template to the public patterns directory var patternPage = headHTML + pattern.patternPartialCode + footerHTML; - var cleanedPatternPage = cleanHtml(patternPage); - var cleanedPatternPartialCode = cleanHtml(pattern.patternPartialCode); + var cleanedPatternPage = config.cleanOutputHtml ? cleanHtml(patternPage) : patternPage; + var cleanedPatternPartialCode = config.cleanOutputHtml ? cleanHtml(pattern.patternPartialCode) : pattern.patternPartialCode; - fs.outputFileSync(paths.public.patterns + pattern.getPatternLink(patternlab, 'rendered'), patternPage); + fs.outputFileSync(paths.public.patterns + pattern.getPatternLink(patternlab, 'rendered'), cleanedPatternPage); //write the mustache file too fs.outputFileSync(paths.public.patterns + pattern.getPatternLink(patternlab, 'rawTemplate'), pattern.template); diff --git a/patternlab-config.json b/patternlab-config.json index 5292c76bd..ffc197121 100644 --- a/patternlab-config.json +++ b/patternlab-config.json @@ -59,5 +59,6 @@ "rendered": ".rendered", "rawTemplate": "", "markupOnly": ".markup-only" - } + }, + "cleanOutputHtml": true } From 79cfcfc8b62d4c4c4fdfa9cd05bbd9e2bb7d67cd Mon Sep 17 00:00:00 2001 From: Brian Muenzenmeyer Date: Fri, 2 Sep 2016 12:37:54 -0500 Subject: [PATCH 05/15] attempt to fix defaultPattern render --- core/lib/ui_builder.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/core/lib/ui_builder.js b/core/lib/ui_builder.js index 3d41acea5..6b290272b 100644 --- a/core/lib/ui_builder.js +++ b/core/lib/ui_builder.js @@ -92,6 +92,7 @@ var ui_builder = function () { if (patternlab.config.debug) { console.log('Omitting ' + pattern.patternPartial + ' from styleguide patterns because it is defined as a defaultPattern.'); } + patternlab.defaultPattern = pattern; return true; } @@ -611,6 +612,12 @@ var ui_builder = function () { //build the viewall pages var allPatterns = buildViewAllPages(headerHTML, patternlab, styleguidePatterns); + //add the defaultPattern if we found one + if (patternlab.defaultPattern) { + allPatterns.push(patternlab.defaultPattern); + addToPatternPaths(patternlab, patternlab.defaultPattern); + } + //build the main styleguide page var styleguideHtml = pattern_assembler.renderPattern(patternlab.viewAll, { From e0333701100442da2b4e39c1e027db21fd09955e Mon Sep 17 00:00:00 2001 From: BRIAN MUENZENMEYER Date: Wed, 7 Sep 2016 23:34:58 -0500 Subject: [PATCH 06/15] install plugin postinstall setting config flag as part of 432 --- core/lib/plugin_manager.js | 77 +++++++++++++++++++++++++++++++++++++ core/scripts/postinstall.js | 20 +++++++++- 2 files changed, 96 insertions(+), 1 deletion(-) create mode 100644 core/lib/plugin_manager.js diff --git a/core/lib/plugin_manager.js b/core/lib/plugin_manager.js new file mode 100644 index 000000000..05f0defe3 --- /dev/null +++ b/core/lib/plugin_manager.js @@ -0,0 +1,77 @@ +"use strict"; + +var plugin_manager = function (config, configPath) { + var path = require('path'), + fs = require('fs-extra'), + util = require('./utilities'), + paths = config.paths; + + function loadPlugin(pluginName) { + var pluginInstance = require(path.join(process.cwd(), 'node_modules', pluginName)); + return pluginInstance; + } + + function installPlugin(pluginName) { + try { + var pluginPath = path.resolve( + path.join(process.cwd(), 'node_modules', pluginName) + ); + console.log('Attempting to load plugin from', pluginPath); + try { + var pluginDirStats = fs.statSync(pluginPath); + } catch (ex) { + util.logRed(pluginName + ' not found, please use npm to install it first.'); + util.logRed(pluginName + ' not loaded.'); + return; + } + var pluginPathDirExists = pluginDirStats.isDirectory(); + if (pluginPathDirExists) { + + //write config entry back + var diskConfig = fs.readJSONSync(path.resolve(configPath), 'utf8'); + diskConfig[pluginName] = true; + fs.outputFileSync(path.resolve(configPath), JSON.stringify(diskConfig, null, 2)); + } + } catch (ex) { + console.log(ex); + } + } + + function detectPlugins() { + var node_modules_path = path.join(process.cwd(), 'node_modules'); + var npm_modules = fs.readdirSync(node_modules_path).filter(function (dir) { + var module_path = path.join(process.cwd(), 'node_modules', dir); + return fs.statSync(module_path).isDirectory() && dir.indexOf('plugin-node-') === 0; + }); + return npm_modules; + } + + function disablePlugin(pluginName) { + console.log('not implemented yet'); + } + + function enablePlugin(pluginName) { + console.log('not implemented yet'); + } + + return { + install_plugin: function(pluginName) { + installPlugin(pluginName); + }, + load_plugin: function (pluginName) { + loadPlugin(pluginName); + }, + detect_plugins: function () { + return detectPlugins(); + }, + disable_plugin: function (pluginName) { + disablePlugin(pluginName); + }, + enable_plugin: function (pluginName) { + enablePlugin(pluginName); + } + }; + +}; + +module.exports = plugin_manager; diff --git a/core/scripts/postinstall.js b/core/scripts/postinstall.js index ea546658e..a93e51c01 100644 --- a/core/scripts/postinstall.js +++ b/core/scripts/postinstall.js @@ -4,6 +4,7 @@ try{ console.log('Beginning Pattern Lab postinstall...'); var sm = require('../lib/starterkit_manager.js'); + var pm = require('../lib/plugin_manager.js'); var u = require('../lib/utilities.js'); var path = require('path'); var fs = require('fs-extra'); @@ -17,11 +18,28 @@ try{ var foundStarterkits = starterkit_manager.detect_starterkits(); //todo - enhance to support multiple kits with prompt for each or all - if(foundStarterkits && foundStarterkits.length > 0) { + if (foundStarterkits && foundStarterkits.length > 0) { starterkit_manager.load_starterkit(foundStarterkits[0], true); } else { console.log('No starterkits found to automatically load.') } + + //determine if any plugins are already installed + var plugin_manager = new pm(config, configPath); + var foundPlugins = plugin_manager.detect_plugins(); + + if (foundPlugins && foundPlugins.length > 0) { + + for (var i = 0; i < foundPlugins.length; i++) { + console.log('Found plugin', foundPlugins[i]); + plugin_manager.install_plugin(foundPlugins[i]); + } + } + + + + + u.logGreen('Pattern Lab postinstall complete.'); } catch (ex) { From 4c3c2905f8aaa186f84bfdfb4d79d04dce7de7d3 Mon Sep 17 00:00:00 2001 From: BRIAN MUENZENMEYER Date: Thu, 8 Sep 2016 00:29:38 -0500 Subject: [PATCH 07/15] WIP loading plugin as part of #432 --- core/lib/patternlab.js | 27 +++++++++++++++++++++------ core/lib/plugin_manager.js | 2 +- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/core/lib/patternlab.js b/core/lib/patternlab.js index 99accaa15..2a3a82f0b 100644 --- a/core/lib/patternlab.js +++ b/core/lib/patternlab.js @@ -1,10 +1,10 @@ -/* - * patternlab-node - v2.4.4 - 2016 - * +/* + * patternlab-node - v2.4.4 - 2016 + * * Brian Muenzenmeyer, Geoff Pursell, and the web community. - * Licensed under the MIT license. - * - * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. + * Licensed under the MIT license. + * + * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. * */ @@ -84,12 +84,14 @@ var patternlab_engine = function (config) { lh = require('./lineage_hunter'), ui = require('./ui_builder'), sm = require('./starterkit_manager'), + pm = require('./plugin_manager'), patternlab = {}; patternlab.package = fs.readJSONSync(path.resolve(__dirname, '../../package.json')); patternlab.config = config || fs.readJSONSync(path.resolve(__dirname, '../../patternlab-config.json')); checkConfiguration(patternlab); + initializePlugins(patternlab); var paths = patternlab.config.paths; @@ -170,6 +172,19 @@ var patternlab_engine = function (config) { } } + function initializePlugins(patternlab) { + var plugin_manager = new pm(patternlab.config, path.resolve(__dirname, '../../patternlab-config.json')); + var foundPlugins = plugin_manager.detect_plugins(); + + if (foundPlugins && foundPlugins.length > 0) { + + for (var i = 0; i < foundPlugins.length; i++) { + var plugin = plugin_manager.load_plugin(foundPlugins[i]); + plugin(patternlab); + } + } + } + function setCacheBust() { if (patternlab.config.cacheBust) { if (patternlab.config.debug) { diff --git a/core/lib/plugin_manager.js b/core/lib/plugin_manager.js index 05f0defe3..3e26b98ba 100644 --- a/core/lib/plugin_manager.js +++ b/core/lib/plugin_manager.js @@ -59,7 +59,7 @@ var plugin_manager = function (config, configPath) { installPlugin(pluginName); }, load_plugin: function (pluginName) { - loadPlugin(pluginName); + return loadPlugin(pluginName); }, detect_plugins: function () { return detectPlugins(); From d087d99fc22c9b726a8ccd1a6efe7db20fbc71db Mon Sep 17 00:00:00 2001 From: BRIAN MUENZENMEYER Date: Fri, 9 Sep 2016 00:09:21 -0500 Subject: [PATCH 08/15] tightened up eslint semicolons eslinting --- .eslintrc | 2 +- core/lib/annotation_exporter.js | 6 +++--- core/lib/pattern_assembler.js | 2 +- core/lib/patternlab.js | 28 ++++++++++++++-------------- core/lib/plugin_manager.js | 11 ++++------- core/lib/ui_builder.js | 4 ++-- 6 files changed, 25 insertions(+), 28 deletions(-) diff --git a/.eslintrc b/.eslintrc index 6e83375f1..1a6fc01c8 100644 --- a/.eslintrc +++ b/.eslintrc @@ -67,7 +67,7 @@ "no-with": 2, "quotes": [0, "single"], "radix": 2, - "semi": [0, "never"], + "semi": [1, "always"], "strict": 0, "space-before-blocks": 1, "space-before-function-paren": [1, { diff --git a/core/lib/annotation_exporter.js b/core/lib/annotation_exporter.js index 8d4ebc3bb..d12054145 100644 --- a/core/lib/annotation_exporter.js +++ b/core/lib/annotation_exporter.js @@ -59,11 +59,11 @@ var annotations_exporter = function (pl) { //take the annotation snippets and split them on our custom delimiter var annotationsYAML = annotationsMD.split('~*~'); for (var i = 0; i < annotationsYAML.length; i++) { - var annotation = buildAnnotationMD(annotationsYAML[i], markdown_parser) + var annotation = buildAnnotationMD(annotationsYAML[i], markdown_parser); annotations.push(annotation); } return false; - } + }; } /* @@ -72,7 +72,7 @@ var annotations_exporter = function (pl) { function parseAnnotationsMD() { var markdown_parser = new mp(); var annotations = []; - var mdFiles = glob.sync(paths.source.annotations + '/*.md') + var mdFiles = glob.sync(paths.source.annotations + '/*.md'); mdFiles.forEach(parseMDFile(annotations, markdown_parser)); return annotations; diff --git a/core/lib/pattern_assembler.js b/core/lib/pattern_assembler.js index 1c305688d..50f20b00c 100644 --- a/core/lib/pattern_assembler.js +++ b/core/lib/pattern_assembler.js @@ -520,7 +520,7 @@ var pattern_assembler = function () { parseDataLinks(patternlab); }, parse_data_links_specific: function (patternlab, data, label) { - return parseDataLinksHelper(patternlab, data, label) + return parseDataLinksHelper(patternlab, data, label); }, parse_pattern_markdown: function (pattern, patternlab) { parsePatternMarkdown(pattern, patternlab); diff --git a/core/lib/patternlab.js b/core/lib/patternlab.js index 2a3a82f0b..1b77624a5 100644 --- a/core/lib/patternlab.js +++ b/core/lib/patternlab.js @@ -14,6 +14,7 @@ var diveSync = require('diveSync'), glob = require('glob'), _ = require('lodash'), path = require('path'), + pm = require('./plugin_manager'), plutils = require('./utilities'); function buildPatternData(dataFilesPath, fs) { @@ -74,6 +75,19 @@ function checkConfiguration(patternlab) { patternlab.config.outputFileSuffixes = _.extend(outputFileSuffixes, patternlab.config.outputFileSuffixes); } +function initializePlugins(patternlab) { + var plugin_manager = new pm(patternlab.config, path.resolve(__dirname, '../../patternlab-config.json')); + var foundPlugins = plugin_manager.detect_plugins(); + + if (foundPlugins && foundPlugins.length > 0) { + + for (var i = 0; i < foundPlugins.length; i++) { + var plugin = plugin_manager.load_plugin(foundPlugins[i]); + plugin(patternlab); + } + } +} + var patternlab_engine = function (config) { 'use strict'; @@ -84,7 +98,6 @@ var patternlab_engine = function (config) { lh = require('./lineage_hunter'), ui = require('./ui_builder'), sm = require('./starterkit_manager'), - pm = require('./plugin_manager'), patternlab = {}; patternlab.package = fs.readJSONSync(path.resolve(__dirname, '../../package.json')); @@ -172,19 +185,6 @@ var patternlab_engine = function (config) { } } - function initializePlugins(patternlab) { - var plugin_manager = new pm(patternlab.config, path.resolve(__dirname, '../../patternlab-config.json')); - var foundPlugins = plugin_manager.detect_plugins(); - - if (foundPlugins && foundPlugins.length > 0) { - - for (var i = 0; i < foundPlugins.length; i++) { - var plugin = plugin_manager.load_plugin(foundPlugins[i]); - plugin(patternlab); - } - } - } - function setCacheBust() { if (patternlab.config.cacheBust) { if (patternlab.config.debug) { diff --git a/core/lib/plugin_manager.js b/core/lib/plugin_manager.js index 3e26b98ba..4102c111f 100644 --- a/core/lib/plugin_manager.js +++ b/core/lib/plugin_manager.js @@ -3,12 +3,10 @@ var plugin_manager = function (config, configPath) { var path = require('path'), fs = require('fs-extra'), - util = require('./utilities'), - paths = config.paths; + util = require('./utilities'); function loadPlugin(pluginName) { - var pluginInstance = require(path.join(process.cwd(), 'node_modules', pluginName)); - return pluginInstance; + return require(path.join(process.cwd(), 'node_modules', pluginName)); } function installPlugin(pluginName) { @@ -39,11 +37,10 @@ var plugin_manager = function (config, configPath) { function detectPlugins() { var node_modules_path = path.join(process.cwd(), 'node_modules'); - var npm_modules = fs.readdirSync(node_modules_path).filter(function (dir) { + return fs.readdirSync(node_modules_path).filter(function (dir) { var module_path = path.join(process.cwd(), 'node_modules', dir); return fs.statSync(module_path).isDirectory() && dir.indexOf('plugin-node-') === 0; }); - return npm_modules; } function disablePlugin(pluginName) { @@ -55,7 +52,7 @@ var plugin_manager = function (config, configPath) { } return { - install_plugin: function(pluginName) { + install_plugin: function (pluginName) { installPlugin(pluginName); }, load_plugin: function (pluginName) { diff --git a/core/lib/ui_builder.js b/core/lib/ui_builder.js index 4fecf68d8..6992ecb08 100644 --- a/core/lib/ui_builder.js +++ b/core/lib/ui_builder.js @@ -235,7 +235,7 @@ var ui_builder = function () { patternState: pattern.patternState, patternSrcPath: encodeURI(pattern.subdir + '/' + pattern.fileName), patternPath: patternPath - } + }; } /** @@ -618,7 +618,7 @@ var ui_builder = function () { return { buildFrontend: function (patternlab) { - buildFrontend(patternlab) + buildFrontend(patternlab); }, isPatternExcluded: function (pattern, patternlab) { return isPatternExcluded(pattern, patternlab); From 93a4bc62ffab3da17562b90eda75ebdb769f93f7 Mon Sep 17 00:00:00 2001 From: BRIAN MUENZENMEYER Date: Sun, 11 Sep 2016 00:39:23 -0500 Subject: [PATCH 09/15] event emitter and initial events for end to end test of plugin-node-tab as part of #432 --- core/lib/object_factory.js | 7 ++++++- core/lib/patternlab.js | 22 ++++++++++++++++++++++ core/lib/plugin_manager.js | 7 ++++++- core/lib/ui_builder.js | 4 ++-- core/scripts/postinstall.js | 4 ---- 5 files changed, 36 insertions(+), 8 deletions(-) diff --git a/core/lib/object_factory.js b/core/lib/object_factory.js index 71c07e4e6..a03e2b400 100644 --- a/core/lib/object_factory.js +++ b/core/lib/object_factory.js @@ -87,7 +87,7 @@ Pattern.prototype = { // calculated path from the root of the public directory to the generated html // file for this pattern. // Should look something like '00-atoms-00-global-00-colors/00-atoms-00-global-00-colors.html' - getPatternLink: function (patternlab, suffixType) { + getPatternLink: function (patternlab, suffixType, customfileExtension) { // if no suffixType is provided, we default to rendered var suffixConfig = patternlab.config.outputFileSuffixes; var suffix = suffixType ? suffixConfig[suffixType] : suffixConfig.rendered; @@ -95,6 +95,11 @@ Pattern.prototype = { if (suffixType === 'rawTemplate') { return this.name + path.sep + this.name + suffix + this.fileExtension; } + + if (suffixType === 'custom') { + return this.name + path.sep + this.name + customfileExtension; + } + return this.name + path.sep + this.name + suffix + '.html'; }, diff --git a/core/lib/patternlab.js b/core/lib/patternlab.js index 1b77624a5..f076ceb75 100644 --- a/core/lib/patternlab.js +++ b/core/lib/patternlab.js @@ -14,9 +14,12 @@ var diveSync = require('diveSync'), glob = require('glob'), _ = require('lodash'), path = require('path'), + inherits = require('util').inherits, pm = require('./plugin_manager'), plutils = require('./utilities'); +var EventEmitter = require('events').EventEmitter; + function buildPatternData(dataFilesPath, fs) { var dataFilesPath = dataFilesPath; var dataFiles = glob.sync(dataFilesPath + '*.json', {"ignore" : [dataFilesPath + 'listitems.json']}); @@ -88,6 +91,11 @@ function initializePlugins(patternlab) { } } +function PatternLabEventEmitter() { + EventEmitter.call(this); +} +inherits(PatternLabEventEmitter, EventEmitter); + var patternlab_engine = function (config) { 'use strict'; @@ -102,8 +110,11 @@ var patternlab_engine = function (config) { patternlab.package = fs.readJSONSync(path.resolve(__dirname, '../../package.json')); patternlab.config = config || fs.readJSONSync(path.resolve(__dirname, '../../patternlab-config.json')); + patternlab.events = new PatternLabEventEmitter(); checkConfiguration(patternlab); + + //todo: determine if this is the best place to wire up plugins initializePlugins(patternlab); var paths = patternlab.config.paths; @@ -207,6 +218,9 @@ var patternlab_engine = function (config) { } function buildPatterns(deletePatternDir) { + + patternlab.events.emit('patternlab-build-pattern-start', patternlab); + try { patternlab.data = buildPatternData(paths.source.data, fs); } catch (ex) { @@ -244,9 +258,13 @@ var patternlab_engine = function (config) { pattern_assembler.combine_listItems(patternlab); + patternlab.events.emit('patternlab-build-global-data-end', patternlab); + // diveSync once to perform iterative populating of patternlab object processAllPatternsIterative(pattern_assembler, patterns_dir, patternlab); + patternlab.events.emit('patternlab-pattern-iteration-end', patternlab); + //diveSync again to recursively include partials, filling out the //extendedTemplate property of the patternlab.patterns elements processAllPatternsRecursive(pattern_assembler, patterns_dir, patternlab); @@ -369,6 +387,8 @@ var patternlab_engine = function (config) { patternLabFoot : footerPartial }); + patternlab.events.emit('patternlab-pattern-write-begin', patternlab, pattern); + //write the compiled template to the public patterns directory var patternPage = headHTML + pattern.patternPartialCode + footerHTML; fs.outputFileSync(paths.public.patterns + pattern.getPatternLink(patternlab, 'rendered'), patternPage); @@ -379,6 +399,8 @@ var patternlab_engine = function (config) { //write the encoded version too fs.outputFileSync(paths.public.patterns + pattern.getPatternLink(patternlab, 'markupOnly'), pattern.patternPartialCode); + patternlab.events.emit('patternlab-pattern-write-end', patternlab, pattern); + return true; }); diff --git a/core/lib/plugin_manager.js b/core/lib/plugin_manager.js index 4102c111f..59205f503 100644 --- a/core/lib/plugin_manager.js +++ b/core/lib/plugin_manager.js @@ -27,8 +27,13 @@ var plugin_manager = function (config, configPath) { //write config entry back var diskConfig = fs.readJSONSync(path.resolve(configPath), 'utf8'); - diskConfig[pluginName] = true; + diskConfig[pluginName] = false; fs.outputFileSync(path.resolve(configPath), JSON.stringify(diskConfig, null, 2)); + + util.logGreen('Plugin ' + pluginName + ' installed.'); + + //todo, tell them how to uninstall or disable + } } catch (ex) { console.log(ex); diff --git a/core/lib/ui_builder.js b/core/lib/ui_builder.js index 6992ecb08..a60e4c136 100644 --- a/core/lib/ui_builder.js +++ b/core/lib/ui_builder.js @@ -532,8 +532,8 @@ var ui_builder = function () { //viewAllPaths output += 'var viewAllPaths = ' + JSON.stringify(patternlab.viewAllPaths) + ';' + eol; - //plugins someday - output += 'var plugins = [];' + eol; + //plugins + output += 'var plugins = ' + JSON.stringify(patternlab.plugins) + ';' + eol; //smaller config elements output += 'var defaultShowPatternInfo = ' + (patternlab.config.defaultShowPatternInfo ? patternlab.config.defaultShowPatternInfo : 'false') + ';' + eol; diff --git a/core/scripts/postinstall.js b/core/scripts/postinstall.js index a93e51c01..11e7fddd6 100644 --- a/core/scripts/postinstall.js +++ b/core/scripts/postinstall.js @@ -36,10 +36,6 @@ try{ } } - - - - u.logGreen('Pattern Lab postinstall complete.'); } catch (ex) { From bfef92f8b00ce993d0d884b8e6b8904e6aaed767 Mon Sep 17 00:00:00 2001 From: Brian Muenzenmeyer Date: Wed, 21 Sep 2016 12:30:21 -0500 Subject: [PATCH 10/15] Make the absence of source/_data/listitems.json a warning instead of an error closes #475 --- core/lib/patternlab.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/lib/patternlab.js b/core/lib/patternlab.js index cafd77b71..961d89103 100644 --- a/core/lib/patternlab.js +++ b/core/lib/patternlab.js @@ -245,7 +245,7 @@ var patternlab_engine = function (config) { try { patternlab.listitems = fs.readJSONSync(path.resolve(paths.source.data, 'listitems.json')); } catch (ex) { - plutils.logRed('missing or malformed' + paths.source.data + 'listitems.json Pattern Lab may not work without this file.'); + plutils.logOrange('WARNING: missing or malformed ' + paths.source.data + 'listitems.json file. Pattern Lab may not work without this file.'); patternlab.listitems = {}; } try { From 5df0eb445745b4d134eb3ec3d2a022e95c548767 Mon Sep 17 00:00:00 2001 From: Brian Muenzenmeyer Date: Thu, 22 Sep 2016 11:52:36 -0500 Subject: [PATCH 11/15] copy found partials when processing pseudo-patterns fixes #474 --- core/lib/pseudopattern_hunter.js | 2 + .../00-test/474-pseudomodifier.mustache | 2 + .../00-test/474-pseudomodifier~test.json | 3 + test/pseudopattern_hunter_tests.js | 76 ++++++++++++++----- 4 files changed, 63 insertions(+), 20 deletions(-) create mode 100644 test/files/_patterns/00-test/474-pseudomodifier.mustache create mode 100644 test/files/_patterns/00-test/474-pseudomodifier~test.json diff --git a/core/lib/pseudopattern_hunter.js b/core/lib/pseudopattern_hunter.js index 2b799f2f3..d695b4f0e 100644 --- a/core/lib/pseudopattern_hunter.js +++ b/core/lib/pseudopattern_hunter.js @@ -51,6 +51,8 @@ var pseudopattern_hunter = function () { extendedTemplate: currentPattern.extendedTemplate, isPseudoPattern: true, basePattern: currentPattern, + stylePartials: currentPattern.stylePartials, + parameteredPartials: currentPattern.parameteredPartials, // use the same template engine as the non-variant engine: currentPattern.engine diff --git a/test/files/_patterns/00-test/474-pseudomodifier.mustache b/test/files/_patterns/00-test/474-pseudomodifier.mustache new file mode 100644 index 000000000..3ddc86ae6 --- /dev/null +++ b/test/files/_patterns/00-test/474-pseudomodifier.mustache @@ -0,0 +1,2 @@ +{{test}} +{{> test-styled-atom:modifier--foo }} diff --git a/test/files/_patterns/00-test/474-pseudomodifier~test.json b/test/files/_patterns/00-test/474-pseudomodifier~test.json new file mode 100644 index 000000000..6138ad655 --- /dev/null +++ b/test/files/_patterns/00-test/474-pseudomodifier~test.json @@ -0,0 +1,3 @@ +{ + "test" : "pseudo" +} diff --git a/test/pseudopattern_hunter_tests.js b/test/pseudopattern_hunter_tests.js index dd2d4c4c2..dd9b922ce 100644 --- a/test/pseudopattern_hunter_tests.js +++ b/test/pseudopattern_hunter_tests.js @@ -5,29 +5,35 @@ var pha = require('../core/lib/pseudopattern_hunter'); var pa = require('../core/lib/pattern_assembler'); var Pattern = require('../core/lib/object_factory').Pattern; +var fs = require('fs-extra'); +var pattern_assembler = new pa(); +var pseudopattern_hunter = new pha(); +var patterns_dir = './test/files/_patterns/'; + +function stubPatternlab() { + var pl = {}; + pl.config = { + paths: { + source: { + patterns: patterns_dir + } + } + }; + pl.data = {}; + pl.data.link = {}; + pl.config.debug = false; + pl.patterns = []; + pl.partials = {}; + pl.config.patternStates = {}; + pl.config.outputFileSuffixes = { rendered: ''} + + return pl; +} + exports['pseudopattern_hunter'] = { 'pseudpattern found and added as a pattern' : function (test) { //arrange - var fs = require('fs-extra'); - var pattern_assembler = new pa(); - var pseudopattern_hunter = new pha(); - var patterns_dir = './test/files/_patterns/'; - - var pl = {}; - pl.config = { - paths: { - source: { - patterns: patterns_dir - } - } - }; - pl.data = {}; - pl.data.link = {}; - pl.config.debug = false; - pl.patterns = []; - pl.partials = {}; - pl.config.patternStates = {}; - pl.config.outputFileSuffixes = { rendered: ''} + var pl = stubPatternlab(); var atomPattern = new Pattern('00-test/03-styled-atom.mustache'); atomPattern.template = fs.readFileSync(patterns_dir + '00-test/03-styled-atom.mustache', 'utf8'); @@ -47,6 +53,36 @@ exports['pseudopattern_hunter'] = { test.equals(JSON.stringify(pl.patterns[1].jsonFileData), JSON.stringify({"message": "alternateMessage"})); test.equals(pl.patterns[1].patternLink, '00-test-03-styled-atom-alt' + path.sep + '00-test-03-styled-atom-alt.html'); + test.done(); + }, + + 'pseudpattern variant includes stylePartials and parameteredPartials' : function (test) { + //arrange + var pl = stubPatternlab(); + + var atomPattern = new Pattern('00-test/03-styled-atom.mustache'); + atomPattern.template = fs.readFileSync(patterns_dir + '00-test/03-styled-atom.mustache', 'utf8'); + atomPattern.extendedTemplate = atomPattern.template; + atomPattern.stylePartials = atomPattern.findPartialsWithStyleModifiers(atomPattern); + atomPattern.parameteredPartials = atomPattern.findPartialsWithPatternParameters(atomPattern); + + var pseudoPattern = new Pattern('00-test/474-pseudomodifier.mustache'); + pseudoPattern.template = fs.readFileSync(patterns_dir + '00-test/474-pseudomodifier.mustache', 'utf8'); + pseudoPattern.extendedTemplate = atomPattern.template; + pseudoPattern.stylePartials = pseudoPattern.findPartialsWithStyleModifiers(pseudoPattern); + pseudoPattern.parameteredPartials = pseudoPattern.findPartialsWithPatternParameters(pseudoPattern); + + pattern_assembler.addPattern(atomPattern, pl); + pattern_assembler.addPattern(pseudoPattern, pl); + + //act + pseudopattern_hunter.find_pseudopatterns(pseudoPattern, pl); + + //assert + test.equals(pl.patterns[2].patternPartial, 'test-pseudomodifier-test'); + test.equals(pl.patterns[2].stylePartials, pseudoPattern.stylePartials); + test.equals(pl.patterns[2].parameteredPartials, pseudoPattern.parameteredPartials); + test.done(); } }; From 4a7cf8d29ab4f4484af2970d81b92976ae238ca3 Mon Sep 17 00:00:00 2001 From: Brian Muenzenmeyer Date: Fri, 23 Sep 2016 07:38:48 -0500 Subject: [PATCH 12/15] beautify template code too. dial down the indent to reduce horizontal scroll closes #448 --- core/lib/patternlab.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/core/lib/patternlab.js b/core/lib/patternlab.js index a0d7a391a..c6ecbebbd 100644 --- a/core/lib/patternlab.js +++ b/core/lib/patternlab.js @@ -385,15 +385,18 @@ var patternlab_engine = function (config) { var footerHTML = pattern_assembler.renderPattern(patternlab.userFoot, allFooterData); - //write the compiled template to the public patterns directory var patternPage = headHTML + pattern.patternPartialCode + footerHTML; - var cleanedPatternPage = config.cleanOutputHtml ? cleanHtml(patternPage) : patternPage; - var cleanedPatternPartialCode = config.cleanOutputHtml ? cleanHtml(pattern.patternPartialCode) : pattern.patternPartialCode; + //beautify the output if configured to do so + var cleanedPatternPage = config.cleanOutputHtml ? cleanHtml(patternPage, {indent_size: 2}) : patternPage; + var cleanedPatternPartialCode = config.cleanOutputHtml ? cleanHtml(pattern.patternPartialCode, {indent_size: 2}) : pattern.patternPartialCode; + var cleanedPatternTemplateCode = config.cleanOutputHtml ? cleanHtml(pattern.template, {indent_size: 2}) : pattern.template; + + //write the compiled template to the public patterns directory fs.outputFileSync(paths.public.patterns + pattern.getPatternLink(patternlab, 'rendered'), cleanedPatternPage); //write the mustache file too - fs.outputFileSync(paths.public.patterns + pattern.getPatternLink(patternlab, 'rawTemplate'), pattern.template); + fs.outputFileSync(paths.public.patterns + pattern.getPatternLink(patternlab, 'rawTemplate'), cleanedPatternTemplateCode); //write the encoded version too fs.outputFileSync(paths.public.patterns + pattern.getPatternLink(patternlab, 'markupOnly'), cleanedPatternPartialCode); From 2d3af2620003ad3c65c96f5f8a629f8d35035147 Mon Sep 17 00:00:00 2001 From: Brian Muenzenmeyer Date: Fri, 23 Sep 2016 13:58:59 -0500 Subject: [PATCH 13/15] add a javadoc comment to a new funciton --- core/lib/patternlab.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/core/lib/patternlab.js b/core/lib/patternlab.js index f076ceb75..f0de9be91 100644 --- a/core/lib/patternlab.js +++ b/core/lib/patternlab.js @@ -78,6 +78,10 @@ function checkConfiguration(patternlab) { patternlab.config.outputFileSuffixes = _.extend(outputFileSuffixes, patternlab.config.outputFileSuffixes); } +/** + * Finds and calls the main method of any found plugins. + * @param patternlab - global data store + */ function initializePlugins(patternlab) { var plugin_manager = new pm(patternlab.config, path.resolve(__dirname, '../../patternlab-config.json')); var foundPlugins = plugin_manager.detect_plugins(); From 0da7f3afabbf061628b42974049ca4c206e9c532 Mon Sep 17 00:00:00 2001 From: Brian Muenzenmeyer Date: Tue, 27 Sep 2016 07:52:02 -0500 Subject: [PATCH 14/15] resolve files correctly under dependency scenarios closes #478 --- core/scripts/postinstall.js | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/core/scripts/postinstall.js b/core/scripts/postinstall.js index ea546658e..3d19894c6 100644 --- a/core/scripts/postinstall.js +++ b/core/scripts/postinstall.js @@ -1,12 +1,13 @@ "use strict"; -try{ - +try { console.log('Beginning Pattern Lab postinstall...'); - var sm = require('../lib/starterkit_manager.js'); - var u = require('../lib/utilities.js'); var path = require('path'); var fs = require('fs-extra'); + var smPath = path.resolve(__dirname, '..', 'lib/starterkit_manager.js'); + var uPath = path.resolve(__dirname, '..', 'lib/utilities.js'); + var sm = require(smPath); + var u = require(uPath); //get the config var configPath = path.resolve(process.cwd(), 'patternlab-config.json'); @@ -17,7 +18,7 @@ try{ var foundStarterkits = starterkit_manager.detect_starterkits(); //todo - enhance to support multiple kits with prompt for each or all - if(foundStarterkits && foundStarterkits.length > 0) { + if (foundStarterkits && foundStarterkits.length > 0) { starterkit_manager.load_starterkit(foundStarterkits[0], true); } else { console.log('No starterkits found to automatically load.') @@ -25,9 +26,7 @@ try{ u.logGreen('Pattern Lab postinstall complete.'); } catch (ex) { - u.logOrange(ex); + console.log(ex); u.logOrange('An error occurred during Pattern Lab Node postinstall.'); u.logOrange('Pattern Lab postinstall completed with errors.'); } - - From 33889f28b4f29edca584095d6995f13b0be04d13 Mon Sep 17 00:00:00 2001 From: Brian Muenzenmeyer Date: Tue, 27 Sep 2016 08:12:07 -0500 Subject: [PATCH 15/15] linting and version bump for 2.6.0-alpha --- core/lib/patternlab.js | 2 +- core/lib/starterkit_manager.js | 10 +++++----- package.json | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/core/lib/patternlab.js b/core/lib/patternlab.js index c6ecbebbd..49a19162d 100644 --- a/core/lib/patternlab.js +++ b/core/lib/patternlab.js @@ -1,5 +1,5 @@ /* - * patternlab-node - v2.5.1 - 2016 + * patternlab-node - v2.6.0-alpha - 2016 * * Brian Muenzenmeyer, Geoff Pursell, and the web community. * Licensed under the MIT license. diff --git a/core/lib/starterkit_manager.js b/core/lib/starterkit_manager.js index 1f6eef800..6b16c82fe 100644 --- a/core/lib/starterkit_manager.js +++ b/core/lib/starterkit_manager.js @@ -1,11 +1,11 @@ "use strict"; var starterkit_manager = function (config) { - var path = require('path'), - fetch = require('node-fetch'), - fs = require('fs-extra'), - util = require('./utilities'), - paths = config.paths; + var path = require('path'), + fetch = require('node-fetch'), + fs = require('fs-extra'), + util = require('./utilities'), + paths = config.paths; function loadStarterKit(starterkitName, clean) { try { diff --git a/package.json b/package.json index 7346d9609..ab66fa4a4 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "patternlab-node", "description": "Pattern Lab is a collection of tools to help you create atomic design systems. This is the node command line interface (CLI).", - "version": "2.5.1", + "version": "2.6.0-alpha", "main": "./core/lib/patternlab.js", "dependencies": { "diveSync": "^0.3.0",