Skip to content
This repository was archived by the owner on Jun 27, 2019. It is now read-only.
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
10 changes: 5 additions & 5 deletions bin/cli-actions/init.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,20 +35,20 @@ const init = options => wrapAsync(function*() {
yield scaffold(projectDir, sourceDir, publicDir, exportDir); // 2

if (edition) {
spinner.text = `Installing edition: ${edition}`;
spinner.text = `⊙ patternlab → Installing edition: ${edition}`;
const newConf = yield installEdition(edition, patternlabConfig); // 3.1
patternlabConfig = Object.assign(patternlabConfig, newConf); // 3.2
spinner.succeed(`Installed edition: ${edition}`);
spinner.succeed(`⊙ patternlab → Installed edition: ${edition}`);
}
if (starterkit) {
spinner.text = `Installing starterkit ${starterkit}`;
spinner.text = `⊙ patternlab → Installing starterkit ${starterkit}`;
spinner.start();
yield installStarterkit(starterkit, patternlabConfig);
spinner.succeed(`Installed starterkit: ${starterkit}`);
spinner.succeed(`⊙ patternlab → Installed starterkit: ${starterkit}`);
} // 4
yield writeJsonAsync(path.resolve(projectDir, 'patternlab-config.json'), patternlabConfig); // 5

spinner.succeed(`Yay ☺. PatternLab Node was successfully initialised in ${projectDir}`);
spinner.succeed(`⊙ patternlab → Yay ☺. PatternLab Node was successfully initialised in ${projectDir}`);
return true;
});

Expand Down
46 changes: 46 additions & 0 deletions bin/cli-actions/install.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
'use strict';
const ora = require('ora');
const installPlugin = require('../install-plugin');
const installStarterkit = require('../install-starterkit');
const resolveConfig = require('../resolve-config');
const wrapAsync = require('../utils').wrapAsync;
const writeJsonAsync = require('../utils').writeJsonAsync;

/**
* install
* @desc Handles async install and activation of starterkits/plugins
* @param {object} options
*/
const install = options => wrapAsync(function*() {
const config = yield resolveConfig(options.parent.config);

const spinner = ora(`⊙ patternlab → Installing additional resources …`).start();

if (options.starterkits && Array.isArray(options.starterkits)) {
const starterkits = yield Promise.all(options.starterkits.map(starterkit =>
wrapAsync(function*() {
spinner.text = `⊙ patternlab → Installing starterkit: ${starterkit}`;
return yield installStarterkit({
name: starterkit,
value: starterkit
}, config)
})
));
spinner.succeed(`⊙ patternlab → Installed following starterkits: ${starterkits.join(', ')}`);
}
if (options.plugins && Array.isArray(options.plugins)) {
const plugins = yield Promise.all(options.plugins.map(plugin =>
wrapAsync(function*() {
return yield installPlugin({
name: plugin,
value: plugin
}, config)
})
));
spinner.succeed(`⊙ patternlab → Installed following plugins: ${plugins.join(', ')}`);
}
yield writeJsonAsync(options.parent.config, config);
spinner.succeed(`⊙ patternlab → Updated config`);
});

module.exports = install;
15 changes: 15 additions & 0 deletions bin/install-plugin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
'use strict';
const checkAndInstallPackage = require('./utils').checkAndInstallPackage;
const wrapAsync = require('./utils').wrapAsync;

const installPlugin = (plugin, config) => wrapAsync(function*() {
const name = plugin.name || plugin;
const url = `pattern-lab/${name}`;
yield checkAndInstallPackage(name, url);
// Put the installed plugin in the patternlab-config.json
config[name] = false;
return name;
});

module.exports = installPlugin;

1 change: 1 addition & 0 deletions bin/install-starterkit.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const installStarterkit = (starterkit, config) => wrapAsync(function*() {
const url = `pattern-lab/${name}`;
yield checkAndInstallPackage(name, url);
yield copyAsync(path.resolve('./node_modules', name, 'dist'), path.resolve(sourceDir));
return name;
});

module.exports = installStarterkit;
16 changes: 16 additions & 0 deletions bin/patternlab.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const build = require('./cli-actions/build');
const help = require('./cli-actions/help');
const version = require('./cli-actions/version');
const init = require('./cli-actions/init');
const install = require('./cli-actions/install');
const exportPatterns = require('./cli-actions/export');
const serve = require('./cli-actions/serve');
const error = require('./utils').error;
Expand All @@ -23,6 +24,9 @@ const silenceLogs = () => {
log.removeAllListeners('patternlab.error');
};

// Split strings into an array
const list = val => val.split(',');

/**
* Hook up cli version, usage and options
*/
Expand Down Expand Up @@ -66,6 +70,18 @@ cli
.option('-k, --starterkit <name>', 'Specify a starterkit to install')
.action(init);

/**
* install
* @desc Installs Pattern Lab related modules like starterkits or plugins
*/
cli
.command('install')
.alias('add')
.description('Installs Pattern Lab related modules like starterkits or plugins')
.option('--starterkits <names>', 'Specify one or more starterkit to install', list)
.option('--plugins <names>', 'Specify one or more plugins to install', list)
.action(install);

/**
* serve
* @desc Starts a server to inspect files in browser
Expand Down
67 changes: 22 additions & 45 deletions bin/serve.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
'use strict';
const bs = require('browser-sync').create('PatternLab');
const buildPatterns = require('./build');
const chokidar = require('chokidar');
const liveServer = require('live-server');
const patternlab = require('patternlab-node');
const htmlInjector = require('bs-html-injector');
const path = require('path');
const _ = require('lodash');

const buildPatterns = require('./build');
const isValidConfig = require('./validate-config');
const copyWithPattern = require('./utils').copyWithPattern;
const wrapAsync = require('./utils').wrapAsync;
Expand All @@ -18,14 +19,14 @@ const error = require('./utils').error;
*/
function serve(config, watch) {
if (!isValidConfig) throw new TypeError('serve: Expects config not to be empty and of type object.');

if (!_.has(config, 'paths.public.root') || _.isEmpty(config.paths.public.root)) {
throw new TypeError('serve: config.paths.public.root is empty or does not exist. Please check your PatternLab config.');
}
if (!_.has(config, 'paths.source.root') || _.isEmpty(config.paths.source.root)) {
throw new TypeError('serve: config.paths.source.root is empty or does not exist. Please check your PatternLab config.');
}

try {
const pl = patternlab();
const src = config.paths.source;
Expand All @@ -34,71 +35,48 @@ function serve(config, watch) {
const sourceStyleguide = path.join(path.resolve(src.styleguide), '/**/*.*');
const patterns = pl.getSupportedTemplateExtensions().map(dotExtension => path.join(path.resolve(src.patterns), `/**/*${dotExtension}`));

// The browser-sync config
const bsConfig = {
server: publicDir,
snippetOptions: {
blacklist: ['/index.html', '/', '/?*'] // Ignore all HTML files within the templates folder
},
notify: {
styles: [
'display: none',
'padding: 15px',
'font-family: sans-serif',
'position: fixed',
'font-size: 1em',
'z-index: 9999',
'bottom: 0px',
'right: 0px',
'border-top-left-radius: 5px',
'background-color: #1B2032',
'opacity: 0.4',
'margin: 0',
'color: white',
'text-align: center'
]
}
// The liveserver config
const liveServerConf = {
root: publicDir,
open: true,
ignore: path.join(publicDir),
file: 'index.html'
};

/**
* @func copyAndReloadCSS
*/
const copyAndReloadCSS = () => wrapAsync(function *() {
yield copyWithPattern(path.resolve(src.css), '**/*.css', path.resolve(config.paths.public.css));
bs.reload('*.css');
liveServer.refreshCSS();
});

/**
* @func copyAndReloadStyleguide
*/
const copyAndReloadStyleguide = () => wrapAsync(function *() {
yield copyWithPattern(path.resolve(src.styleguide), '**/!(*.css)', path.resolve(config.paths.public.styleguide));
yield copyWithPattern(path.resolve(src.styleguide), '**/*.css', path.resolve(config.paths.public.styleguide));
bs.reload('*.css');
liveServer.refreshCSS();
});

/**
* @func reload
* @desc Calls browser-sync's reload method to tell browsers to refresh their page
*/
const buildAndReload = function () {
buildPatterns(config);
bs.reload();
liveServer.reload();
};

// Register plugins
bs.use(htmlInjector, {
files: [publicDir + '/index.html', publicDir + '../styleguide/styleguide.html']
});

if (watch) {
/**
* 1. Watch source css, then copy css and callreloadCSS
* 2. Watch source styleguide, then copy styleguide and css and call reloadCSS
* 3. Watch pattern-specific and engine-specific extensions, run build and reload
*/
bs.watch(sourceCSS).on('change', copyAndReloadCSS); // 1
bs.watch(sourceStyleguide).on('change', copyAndReloadStyleguide); // 2
chokidar.watch(sourceCSS).on('change', copyAndReloadCSS); // 1
chokidar.watch(sourceStyleguide).on('change', copyAndReloadStyleguide); // 2
const patternWatches = [
path.join(path.resolve(src.patterns), '**/*.json'),
path.join(path.resolve(src.patterns), '**/*.md'),
Expand All @@ -109,11 +87,10 @@ function serve(config, watch) {
path.join(path.resolve(src.annotations), '*')
].concat(patterns); // 3

bs.watch(patternWatches).on('change', buildAndReload);
chokidar.watch(patternWatches).on('change', buildAndReload);
}

// Init browser-sync
bs.init(bsConfig);
liveServer.start(liveServerConf);
} catch (err) {
error(err);
}
Expand Down
8 changes: 3 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "patternlab-node-cli",
"description": "Command-line interface (CLI) for the patternlab-node core.",
"version": "0.0.1-alpha.8",
"version": "0.0.1-alpha.10",
"bin": {
"patternlab": "bin/patternlab.js"
},
Expand All @@ -11,26 +11,24 @@
"private": true,
"dependencies": {
"archiver": "2.0.3",
"browser-sync": "2.18.13",
"bs-html-injector": "3.0.3",
"chalk": "2.1.0",
"chokidar": "1.7.0",
"commander": "2.11.0",
"execa": "0.8.0",
"fs-promise": "2.0.3",
"glob": "7.1.2",
"has-yarn": "1.0.0",
"inquirer": "3.3.0",
"live-server": "pattern-lab/live-server",
"lodash": "4.17.4",
"ora": "1.3.0",
"path-exists": "3.0.0",
"patternlab-node": "2.12.0",
"sanitize-filename": "1.6.1"
},
"devDependencies": {
"edition-node": "0.0.4",
"eslint": "4.8.0",
"proxyquire": "1.8.0",
"starterkit-mustache-base": "3.0.1",
"tap": "10.7.2"
},
"files": [
Expand Down
14 changes: 14 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ Usage: patternlab <cmd> [options]
build|compile [options] Build the PatternLab. Optionally (re-)build only the patterns
export Export a PatternLab patterns into a compressed format
init [options] Initialize a PatternLab project from scratch or import an edition and/or starterkit
install|add [options] Installs Pattern Lab related modules like starterkits or plugins
serve|browse [options] Starts a server to inspect files in browser

Options:
Expand Down Expand Up @@ -79,6 +80,19 @@ Export a PatternLab patterns into a compressed format
-h, --help output usage information
```

### Install Pattern Lab starterkits or plugins
```
Usage: install|add [options]

Installs Pattern Lab related modules like starterkits or plugins

Options:
-h, --help output usage information
--starterkits <names> Specify one or more starterkits to install
--plugins <names> Specify one or more plugins to install

```

## Examples
```
$ patternlab init # Initialize a PatternLab project.
Expand Down
23 changes: 23 additions & 0 deletions test/install-plugin.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
const tap = require('tap');
const installPlugin = require('../bin/install-plugin');
const wrapAsync = require('../bin/utils').wrapAsync;
const getUniqueProjectPath = require('./utils/getUniqueProjectPath');
const moduleExist = require.resolve;

const projectRoot = getUniqueProjectPath();

const minimalConfig = {
paths: {
source: {
root: projectRoot
}
}
};

tap.test('Install plugin-node-tab ->', t => wrapAsync(function*() {
yield installPlugin('plugin-node-tab', minimalConfig);
const pkg = yield moduleExist('plugin-node-tab');
t.ok(pkg, 'module should exist after install');
t.equal(minimalConfig['plugin-node-tab'], false, 'and persist it on the patternlab-config.json');
t.end();
}));
Loading