Skip to content
This repository was archived by the owner on Jun 27, 2019. It is now read-only.

Commit afd5408

Browse files
authored
Develop (#48)
Adding install command and new live-server
1 parent ce9207c commit afd5408

14 files changed

+470
-1052
lines changed

bin/cli-actions/init.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,20 +35,20 @@ const init = options => wrapAsync(function*() {
3535
yield scaffold(projectDir, sourceDir, publicDir, exportDir); // 2
3636

3737
if (edition) {
38-
spinner.text = `Installing edition: ${edition}`;
38+
spinner.text = `⊙ patternlab → Installing edition: ${edition}`;
3939
const newConf = yield installEdition(edition, patternlabConfig); // 3.1
4040
patternlabConfig = Object.assign(patternlabConfig, newConf); // 3.2
41-
spinner.succeed(`Installed edition: ${edition}`);
41+
spinner.succeed(`⊙ patternlab → Installed edition: ${edition}`);
4242
}
4343
if (starterkit) {
44-
spinner.text = `Installing starterkit ${starterkit}`;
44+
spinner.text = `⊙ patternlab → Installing starterkit ${starterkit}`;
4545
spinner.start();
4646
yield installStarterkit(starterkit, patternlabConfig);
47-
spinner.succeed(`Installed starterkit: ${starterkit}`);
47+
spinner.succeed(`⊙ patternlab → Installed starterkit: ${starterkit}`);
4848
} // 4
4949
yield writeJsonAsync(path.resolve(projectDir, 'patternlab-config.json'), patternlabConfig); // 5
5050

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

bin/cli-actions/install.js

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
'use strict';
2+
const ora = require('ora');
3+
const installPlugin = require('../install-plugin');
4+
const installStarterkit = require('../install-starterkit');
5+
const resolveConfig = require('../resolve-config');
6+
const wrapAsync = require('../utils').wrapAsync;
7+
const writeJsonAsync = require('../utils').writeJsonAsync;
8+
9+
/**
10+
* install
11+
* @desc Handles async install and activation of starterkits/plugins
12+
* @param {object} options
13+
*/
14+
const install = options => wrapAsync(function*() {
15+
const config = yield resolveConfig(options.parent.config);
16+
17+
const spinner = ora(`⊙ patternlab → Installing additional resources …`).start();
18+
19+
if (options.starterkits && Array.isArray(options.starterkits)) {
20+
const starterkits = yield Promise.all(options.starterkits.map(starterkit =>
21+
wrapAsync(function*() {
22+
spinner.text = `⊙ patternlab → Installing starterkit: ${starterkit}`;
23+
return yield installStarterkit({
24+
name: starterkit,
25+
value: starterkit
26+
}, config)
27+
})
28+
));
29+
spinner.succeed(`⊙ patternlab → Installed following starterkits: ${starterkits.join(', ')}`);
30+
}
31+
if (options.plugins && Array.isArray(options.plugins)) {
32+
const plugins = yield Promise.all(options.plugins.map(plugin =>
33+
wrapAsync(function*() {
34+
return yield installPlugin({
35+
name: plugin,
36+
value: plugin
37+
}, config)
38+
})
39+
));
40+
spinner.succeed(`⊙ patternlab → Installed following plugins: ${plugins.join(', ')}`);
41+
}
42+
yield writeJsonAsync(options.parent.config, config);
43+
spinner.succeed(`⊙ patternlab → Updated config`);
44+
});
45+
46+
module.exports = install;

bin/install-plugin.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
'use strict';
2+
const checkAndInstallPackage = require('./utils').checkAndInstallPackage;
3+
const wrapAsync = require('./utils').wrapAsync;
4+
5+
const installPlugin = (plugin, config) => wrapAsync(function*() {
6+
const name = plugin.name || plugin;
7+
const url = `pattern-lab/${name}`;
8+
yield checkAndInstallPackage(name, url);
9+
// Put the installed plugin in the patternlab-config.json
10+
config[name] = false;
11+
return name;
12+
});
13+
14+
module.exports = installPlugin;
15+

bin/install-starterkit.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ const installStarterkit = (starterkit, config) => wrapAsync(function*() {
1010
const url = `pattern-lab/${name}`;
1111
yield checkAndInstallPackage(name, url);
1212
yield copyAsync(path.resolve('./node_modules', name, 'dist'), path.resolve(sourceDir));
13+
return name;
1314
});
1415

1516
module.exports = installStarterkit;

bin/patternlab.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ const build = require('./cli-actions/build');
55
const help = require('./cli-actions/help');
66
const version = require('./cli-actions/version');
77
const init = require('./cli-actions/init');
8+
const install = require('./cli-actions/install');
89
const exportPatterns = require('./cli-actions/export');
910
const serve = require('./cli-actions/serve');
1011
const error = require('./utils').error;
@@ -23,6 +24,9 @@ const silenceLogs = () => {
2324
log.removeAllListeners('patternlab.error');
2425
};
2526

27+
// Split strings into an array
28+
const list = val => val.split(',');
29+
2630
/**
2731
* Hook up cli version, usage and options
2832
*/
@@ -66,6 +70,18 @@ cli
6670
.option('-k, --starterkit <name>', 'Specify a starterkit to install')
6771
.action(init);
6872

73+
/**
74+
* install
75+
* @desc Installs Pattern Lab related modules like starterkits or plugins
76+
*/
77+
cli
78+
.command('install')
79+
.alias('add')
80+
.description('Installs Pattern Lab related modules like starterkits or plugins')
81+
.option('--starterkits <names>', 'Specify one or more starterkit to install', list)
82+
.option('--plugins <names>', 'Specify one or more plugins to install', list)
83+
.action(install);
84+
6985
/**
7086
* serve
7187
* @desc Starts a server to inspect files in browser

bin/serve.js

Lines changed: 22 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
'use strict';
2-
const bs = require('browser-sync').create('PatternLab');
3-
const buildPatterns = require('./build');
2+
const chokidar = require('chokidar');
3+
const liveServer = require('live-server');
44
const patternlab = require('patternlab-node');
5-
const htmlInjector = require('bs-html-injector');
65
const path = require('path');
76
const _ = require('lodash');
7+
8+
const buildPatterns = require('./build');
89
const isValidConfig = require('./validate-config');
910
const copyWithPattern = require('./utils').copyWithPattern;
1011
const wrapAsync = require('./utils').wrapAsync;
@@ -18,14 +19,14 @@ const error = require('./utils').error;
1819
*/
1920
function serve(config, watch) {
2021
if (!isValidConfig) throw new TypeError('serve: Expects config not to be empty and of type object.');
21-
22+
2223
if (!_.has(config, 'paths.public.root') || _.isEmpty(config.paths.public.root)) {
2324
throw new TypeError('serve: config.paths.public.root is empty or does not exist. Please check your PatternLab config.');
2425
}
2526
if (!_.has(config, 'paths.source.root') || _.isEmpty(config.paths.source.root)) {
2627
throw new TypeError('serve: config.paths.source.root is empty or does not exist. Please check your PatternLab config.');
2728
}
28-
29+
2930
try {
3031
const pl = patternlab();
3132
const src = config.paths.source;
@@ -34,71 +35,48 @@ function serve(config, watch) {
3435
const sourceStyleguide = path.join(path.resolve(src.styleguide), '/**/*.*');
3536
const patterns = pl.getSupportedTemplateExtensions().map(dotExtension => path.join(path.resolve(src.patterns), `/**/*${dotExtension}`));
3637

37-
// The browser-sync config
38-
const bsConfig = {
39-
server: publicDir,
40-
snippetOptions: {
41-
blacklist: ['/index.html', '/', '/?*'] // Ignore all HTML files within the templates folder
42-
},
43-
notify: {
44-
styles: [
45-
'display: none',
46-
'padding: 15px',
47-
'font-family: sans-serif',
48-
'position: fixed',
49-
'font-size: 1em',
50-
'z-index: 9999',
51-
'bottom: 0px',
52-
'right: 0px',
53-
'border-top-left-radius: 5px',
54-
'background-color: #1B2032',
55-
'opacity: 0.4',
56-
'margin: 0',
57-
'color: white',
58-
'text-align: center'
59-
]
60-
}
38+
// The liveserver config
39+
const liveServerConf = {
40+
root: publicDir,
41+
open: true,
42+
ignore: path.join(publicDir),
43+
file: 'index.html'
6144
};
62-
45+
6346
/**
6447
* @func copyAndReloadCSS
6548
*/
6649
const copyAndReloadCSS = () => wrapAsync(function *() {
6750
yield copyWithPattern(path.resolve(src.css), '**/*.css', path.resolve(config.paths.public.css));
68-
bs.reload('*.css');
51+
liveServer.refreshCSS();
6952
});
70-
53+
7154
/**
7255
* @func copyAndReloadStyleguide
7356
*/
7457
const copyAndReloadStyleguide = () => wrapAsync(function *() {
7558
yield copyWithPattern(path.resolve(src.styleguide), '**/!(*.css)', path.resolve(config.paths.public.styleguide));
7659
yield copyWithPattern(path.resolve(src.styleguide), '**/*.css', path.resolve(config.paths.public.styleguide));
77-
bs.reload('*.css');
60+
liveServer.refreshCSS();
7861
});
79-
62+
8063
/**
8164
* @func reload
8265
* @desc Calls browser-sync's reload method to tell browsers to refresh their page
8366
*/
8467
const buildAndReload = function () {
8568
buildPatterns(config);
86-
bs.reload();
69+
liveServer.reload();
8770
};
8871

89-
// Register plugins
90-
bs.use(htmlInjector, {
91-
files: [publicDir + '/index.html', publicDir + '../styleguide/styleguide.html']
92-
});
93-
9472
if (watch) {
9573
/**
9674
* 1. Watch source css, then copy css and callreloadCSS
9775
* 2. Watch source styleguide, then copy styleguide and css and call reloadCSS
9876
* 3. Watch pattern-specific and engine-specific extensions, run build and reload
9977
*/
100-
bs.watch(sourceCSS).on('change', copyAndReloadCSS); // 1
101-
bs.watch(sourceStyleguide).on('change', copyAndReloadStyleguide); // 2
78+
chokidar.watch(sourceCSS).on('change', copyAndReloadCSS); // 1
79+
chokidar.watch(sourceStyleguide).on('change', copyAndReloadStyleguide); // 2
10280
const patternWatches = [
10381
path.join(path.resolve(src.patterns), '**/*.json'),
10482
path.join(path.resolve(src.patterns), '**/*.md'),
@@ -109,11 +87,10 @@ function serve(config, watch) {
10987
path.join(path.resolve(src.annotations), '*')
11088
].concat(patterns); // 3
11189

112-
bs.watch(patternWatches).on('change', buildAndReload);
90+
chokidar.watch(patternWatches).on('change', buildAndReload);
11391
}
114-
11592
// Init browser-sync
116-
bs.init(bsConfig);
93+
liveServer.start(liveServerConf);
11794
} catch (err) {
11895
error(err);
11996
}

package.json

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "patternlab-node-cli",
33
"description": "Command-line interface (CLI) for the patternlab-node core.",
4-
"version": "0.0.1-alpha.8",
4+
"version": "0.0.1-alpha.10",
55
"bin": {
66
"patternlab": "bin/patternlab.js"
77
},
@@ -11,26 +11,24 @@
1111
"private": true,
1212
"dependencies": {
1313
"archiver": "2.0.3",
14-
"browser-sync": "2.18.13",
15-
"bs-html-injector": "3.0.3",
1614
"chalk": "2.1.0",
15+
"chokidar": "1.7.0",
1716
"commander": "2.11.0",
1817
"execa": "0.8.0",
1918
"fs-promise": "2.0.3",
2019
"glob": "7.1.2",
2120
"has-yarn": "1.0.0",
2221
"inquirer": "3.3.0",
22+
"live-server": "pattern-lab/live-server",
2323
"lodash": "4.17.4",
2424
"ora": "1.3.0",
2525
"path-exists": "3.0.0",
2626
"patternlab-node": "2.12.0",
2727
"sanitize-filename": "1.6.1"
2828
},
2929
"devDependencies": {
30-
"edition-node": "0.0.4",
3130
"eslint": "4.8.0",
3231
"proxyquire": "1.8.0",
33-
"starterkit-mustache-base": "3.0.1",
3432
"tap": "10.7.2"
3533
},
3634
"files": [

readme.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ Usage: patternlab <cmd> [options]
2222
build|compile [options] Build the PatternLab. Optionally (re-)build only the patterns
2323
export Export a PatternLab patterns into a compressed format
2424
init [options] Initialize a PatternLab project from scratch or import an edition and/or starterkit
25+
install|add [options] Installs Pattern Lab related modules like starterkits or plugins
2526
serve|browse [options] Starts a server to inspect files in browser
2627
2728
Options:
@@ -79,6 +80,19 @@ Export a PatternLab patterns into a compressed format
7980
-h, --help output usage information
8081
```
8182

83+
### Install Pattern Lab starterkits or plugins
84+
```
85+
Usage: install|add [options]
86+
87+
Installs Pattern Lab related modules like starterkits or plugins
88+
89+
Options:
90+
-h, --help output usage information
91+
--starterkits <names> Specify one or more starterkits to install
92+
--plugins <names> Specify one or more plugins to install
93+
94+
```
95+
8296
## Examples
8397
```
8498
$ patternlab init # Initialize a PatternLab project.

test/install-plugin.test.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
const tap = require('tap');
2+
const installPlugin = require('../bin/install-plugin');
3+
const wrapAsync = require('../bin/utils').wrapAsync;
4+
const getUniqueProjectPath = require('./utils/getUniqueProjectPath');
5+
const moduleExist = require.resolve;
6+
7+
const projectRoot = getUniqueProjectPath();
8+
9+
const minimalConfig = {
10+
paths: {
11+
source: {
12+
root: projectRoot
13+
}
14+
}
15+
};
16+
17+
tap.test('Install plugin-node-tab ->', t => wrapAsync(function*() {
18+
yield installPlugin('plugin-node-tab', minimalConfig);
19+
const pkg = yield moduleExist('plugin-node-tab');
20+
t.ok(pkg, 'module should exist after install');
21+
t.equal(minimalConfig['plugin-node-tab'], false, 'and persist it on the patternlab-config.json');
22+
t.end();
23+
}));

0 commit comments

Comments
 (0)