Skip to content

Commit 74243ab

Browse files
committed
merge dev into dev-3.0-async
2 parents 6fc5f5e + 90e06ee commit 74243ab

25 files changed

+6062
-77
lines changed

.github/CONTRIBUTING.md

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,28 @@
1-
# Contributing to Patternlab Node
1+
# Contributing to Pattern Lab Node
22
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.
33

44
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.
55

6+
## Developing Locally
7+
8+
The best way to make changes to the Pattern Lab Node core and test them is through your existing edition.
9+
10+
* Fork this repository on Github.
11+
* Create a new branch in your fork and push your changes in that fork.
12+
* `npm install`
13+
* `npm link`
14+
* `cd /path/to/your/edition`
15+
* `npm link patternlab-node`
16+
617
## Guidelines
7-
1. Please keep your pull requests concise and limited to **ONE** substantive change at a time. This makes reviewing and testing so much easier.
8-
2. _ALWAYS_ submit pull requests against the [dev branch](https://github.com/pattern-lab/patternlab-node/tree/dev). If this does not occur, I will first, try to redirect you gently, second, port over your contribution manually if time allows, and/or third, close your pull request. If you have a major feature to stabilize over time, talk to @bmuenzenmeyer about making a dedicated `feature-branch`
9-
3. If you can, add some unit tests using the existing patterns in the `./test` directory
1018

11-
##Coding style
19+
* _ALWAYS_ submit pull requests against the [dev branch](https://github.com/pattern-lab/patternlab-node/tree/dev). If this does not occur, I will first, try to redirect you gently, second, port over your contribution manually if time allows, and/or third, close your pull request. If you have a major feature to stabilize over time, talk to @bmuenzenmeyer via an issue about making a dedicated `feature-branch`
20+
* Please keep your pull requests concise and limited to **ONE** substantive change at a time. This makes reviewing and testing so much easier.
21+
* Commits should reference the issue you are adressing. For any Pull Request that you send, use the template provided.
22+
* If you can, add some unit tests using the existing patterns in the `./test` directory
23+
* Large enhancements should begin with opening an issue. This will result in a more systematic way for us to review your contribution and determine if a [specifcation discussion](https://github.com/pattern-lab/the-spec/issues) needs to occur.
24+
25+
## Coding style
1226
Two files combine within the project to define and maintain our coding style.
1327

1428
* The `.editorconfig` controls spaces / tabs within supported editors. Check out their [site](http://editorconfig.org/).

.github/stale.yml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Number of days of inactivity before an issue becomes stale
2+
daysUntilStale: 60
3+
# Number of days of inactivity before a stale issue is closed
4+
daysUntilClose: 7
5+
# Issues with these labels will never be considered stale
6+
exemptLabels:
7+
- staged for next release
8+
- pinned
9+
# Label to use when marking an issue as stale
10+
staleLabel: needs response
11+
# Comment to post when marking an issue as stale. Set to `false` to disable
12+
markComment: >
13+
This issue has been automatically marked as stale because it has not had
14+
recent activity. It will be closed if no further activity occurs. Thank you
15+
for your contributions.
16+
# Comment to post when closing a stale issue. Set to `false` to disable
17+
closeComment: false

.vscode/launch.json

Lines changed: 0 additions & 20 deletions
This file was deleted.

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,14 @@ This repository contains the core functionality for Pattern Lab Node. Pattern La
1010

1111
## Support for Pattern Lab Node
1212

13-
Pattern Lab Node wouldn't be what it is today without the support of the community. It will always be free and open source. Continued development is made possible in part from the support of [these wonderful project supporters](https://github.com/pattern-lab/patternlab-node/wiki/Thanks). If you want to learn more about supporting the project, visit the [Pattern Lab Node Patreon page](https://www.patreon.com/patternlab).
13+
Pattern Lab Node wouldn't be what it is today without the support of the community. It will always be free and open source. Continued development is made possible in part from the support of [these wonderful project supporters](https://github.com/pattern-lab/patternlab-node/wiki/Thanks). If you want to learn more about supporting the project, visit the [Pattern Lab Node Patreon page](https://www.patreon.com/patternlab).
1414

15-
**:100: Thanks for support from the following:**
15+
**:100: Thanks for support from the following:**
1616

1717
* **[Brad Frost](http://bradfrost.com/)**
1818
* [Marcos Peebles](https://twitter.com/marcospeebles)
1919
* [Susan Simkins](https://twitter.com/susanmsimkins)
20+
* [Wilfred Nas](https://twitter.com/wnas)
2021

2122
## Installation
2223

core/lib/asset_copy.js

Lines changed: 228 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,228 @@
1+
"use strict";
2+
const _ = require('lodash');
3+
const path = require('path');
4+
const process = require('process');
5+
6+
let copy = require('recursive-copy'); // eslint-disable-line prefer-const
7+
let chokidar = require('chokidar'); // eslint-disable-line prefer-const
8+
9+
const asset_copier = () => {
10+
11+
const transform_paths = (directories) => {
12+
//create array with all source keys minus our blacklist
13+
const dirs = {};
14+
const blackList = ['root', 'patterns', 'data', 'meta', 'annotations', 'patternlabFiles'];
15+
_.each(directories.source, (dir, key) => {
16+
17+
if (blackList.includes(key)) {
18+
return;
19+
}
20+
21+
if (!dirs.key) {
22+
dirs[key] = {};
23+
}
24+
});
25+
26+
// loop through all source keys
27+
_.each(dirs, (dir, key) => {
28+
// add source key path
29+
dirs[key].source = directories.source[key];
30+
31+
// add public key path
32+
dirs[key].public = directories.public[key];
33+
});
34+
return dirs;
35+
};
36+
37+
const copyFile = (p, dest, options) => {
38+
copy(
39+
p,
40+
dest,
41+
options
42+
).on(copy.events.COPY_FILE_COMPLETE, () => {
43+
if (options.debug) {
44+
console.log(`Moved ${p} to ${dest}`);
45+
}
46+
options.emitter.emit('patternlab-asset-change', {
47+
file: p,
48+
dest: dest
49+
});
50+
});
51+
};
52+
53+
const asset_copy = (assetDirectories, patternlab, options) => {
54+
55+
//take our configured paths and sanitize best we can to only the assets
56+
const dirs = transform_paths(assetDirectories);
57+
58+
//find out where we are
59+
const basePath = path.resolve(process.cwd());
60+
61+
const copyOptions =
62+
{
63+
overwrite: true,
64+
emitter: patternlab.events,
65+
debug: patternlab.config.debug
66+
};
67+
68+
//loop through each directory asset object (source / public pairing)
69+
_.each(dirs, (dir, key) => {
70+
71+
//if we want to watch files, do so, otherwise just copy each file
72+
if (options.watch) {
73+
if (patternlab.config.debug) {
74+
console.log(`Pattern Lab is watching ${path.resolve(basePath, dir.source)} for changes`);
75+
}
76+
77+
if (patternlab.watchers[key]) {
78+
patternlab.watchers[key].close();
79+
}
80+
81+
const assetWatcher = chokidar.watch(
82+
path.resolve(basePath, dir.source),
83+
{
84+
ignored: /(^|[\/\\])\../,
85+
ignoreInitial: true,
86+
awaitWriteFinish : {
87+
stabilityThreshold: 200,
88+
pollInterval: 100
89+
}
90+
}
91+
);
92+
93+
//watch for changes and copy
94+
assetWatcher.on('addDir', (p) => {
95+
const destination = path.resolve(basePath, dir.public + '/' + path.basename(p));
96+
copyFile(p, destination, copyOptions);
97+
}).on('add', (p) => {
98+
const destination = path.resolve(basePath, dir.public + '/' + path.basename(p));
99+
copyFile(p, destination, copyOptions);
100+
}).on('change', (p) => {
101+
const destination = path.resolve(basePath, dir.public + '/' + path.basename(p));
102+
copyFile(p, destination, copyOptions);
103+
});
104+
105+
patternlab.watchers[key] = assetWatcher;
106+
107+
} else {
108+
//just copy
109+
const destination = path.resolve(basePath, dir.public);
110+
copyFile(dir.source, destination, copyOptions);
111+
}
112+
});
113+
114+
// copy the styleguide
115+
copyFile(assetDirectories.source.styleguide, assetDirectories.public.root, copyOptions);
116+
117+
// copy the favicon
118+
copyFile(`${assetDirectories.source.root}/favicon.ico`, `${assetDirectories.public.root}/favicon.ico`, copyOptions);
119+
120+
//we need to special case patterns/**/*.md|.json|.pattern-extensions as well as the global structures
121+
if (options.watch) {
122+
123+
// watch global structures, such as _data/* and _meta/
124+
const globalSources = [assetDirectories.source.data, assetDirectories.source.meta];
125+
const globalPaths = globalSources.map(globalSource => path.join(
126+
basePath,
127+
globalSource,
128+
'*'
129+
));
130+
131+
_.each(globalPaths, (globalPath) => {
132+
133+
if (patternlab.config.debug) {
134+
console.log(`Pattern Lab is watching ${globalPath} for changes`);
135+
}
136+
137+
if (patternlab.watchers[globalPath]) {
138+
patternlab.watchers[globalPath].close();
139+
}
140+
141+
const globalWatcher = chokidar.watch(
142+
path.resolve(globalPath),
143+
{
144+
ignored: /(^|[\/\\])\../,
145+
ignoreInitial: true,
146+
awaitWriteFinish : {
147+
stabilityThreshold: 200,
148+
pollInterval: 100
149+
}
150+
}
151+
);
152+
153+
//watch for changes and rebuild
154+
globalWatcher.on('addDir', (p) => {
155+
patternlab.events.emit('patternlab-global-change', {
156+
file: p
157+
});
158+
})
159+
.on('add', (p) => {
160+
patternlab.events.emit('patternlab-global-change', {
161+
file: p
162+
});
163+
}).on('change', (p) => {
164+
patternlab.events.emit('patternlab-global-change', {
165+
file: p
166+
});
167+
});
168+
169+
patternlab.watchers[globalPath] = globalWatcher;
170+
171+
});
172+
173+
// watch patterns
174+
const baseFileExtensions = ['.json', '.yml', '.yaml', '.md'];
175+
const patternWatches = baseFileExtensions.concat(patternlab.engines.getSupportedFileExtensions()).map(
176+
dotExtension => path.join(
177+
basePath,
178+
assetDirectories.source.patterns,
179+
`/**/*${dotExtension}`
180+
)
181+
);
182+
_.each(patternWatches, (patternWatchPath) => {
183+
if (patternlab.config.debug) {
184+
console.log(`Pattern Lab is watching ${patternWatchPath} for changes`);
185+
}
186+
187+
const patternWatcher = chokidar.watch(
188+
path.resolve(patternWatchPath),
189+
{
190+
ignored: /(^|[\/\\])\../,
191+
ignoreInitial: true,
192+
awaitWriteFinish : {
193+
stabilityThreshold: 200,
194+
pollInterval: 100
195+
}
196+
}
197+
);
198+
199+
//watch for changes and rebuild
200+
patternWatcher.on('addDir', (p) => {
201+
patternlab.events.emit('patternlab-pattern-change', {
202+
file: p
203+
});
204+
}).on('add', (p) => {
205+
patternlab.events.emit('patternlab-pattern-change', {
206+
file: p
207+
});
208+
}).on('change', (p) => {
209+
patternlab.events.emit('patternlab-pattern-change', {
210+
file: p
211+
});
212+
});
213+
});
214+
}
215+
};
216+
217+
return {
218+
copyAssets: (assetDirectories, patternlab, options) => {
219+
asset_copy(assetDirectories, patternlab, options);
220+
},
221+
transformConfigPaths: (paths) => {
222+
return transform_paths(paths);
223+
}
224+
};
225+
226+
};
227+
228+
module.exports = asset_copier;

core/lib/data_loader.js

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
"use strict";
2+
3+
const glob = require('glob'),
4+
_ = require('lodash'),
5+
path = require('path'),
6+
yaml = require('js-yaml');
7+
8+
/**
9+
* Loads a single config file, in yaml/json format.
10+
*
11+
* @param dataFilesPath - leave off the file extension.
12+
* @param fsDep
13+
* @returns {*}
14+
*/
15+
function loadFile(dataFilesPath, fsDep) {
16+
const dataFilesFullPath = dataFilesPath + '{.,[!-]*.}{json,yml,yaml}';
17+
18+
if (dataFilesPath) {
19+
const dataFiles = glob.sync(dataFilesFullPath),
20+
dataFile = _.head(dataFiles);
21+
22+
if (dataFile && fsDep.existsSync(path.resolve(dataFile))) {
23+
return yaml.safeLoad(fsDep.readFileSync(path.resolve(dataFile), 'utf8'));
24+
}
25+
}
26+
27+
return null;
28+
}
29+
30+
/**
31+
* Loads a set of config files from a folder, in yaml/json format.
32+
*
33+
* @param dataFilesPath - leave off the file extension
34+
* @param excludeFileNames - leave off the file extension
35+
* @param fsDep
36+
* @returns Object, with merged data files, empty object if no files.
37+
*/
38+
function loadDataFromFolder(dataFilesPath, excludeFileNames, fsDep) {
39+
const dataFilesFullPath = dataFilesPath + '*.{json,yml,yaml}',
40+
excludeFullPath = dataFilesPath + excludeFileNames + '.{json,yml,yaml}';
41+
42+
const globOptions = {};
43+
if (excludeFileNames) {
44+
globOptions.ignore = [excludeFullPath];
45+
}
46+
47+
const dataFiles = glob.sync(dataFilesFullPath, globOptions);
48+
let mergeObject = {};
49+
50+
dataFiles.forEach(function (filePath) {
51+
const jsonData = yaml.safeLoad(fsDep.readFileSync(path.resolve(filePath), 'utf8'));
52+
mergeObject = _.merge(mergeObject, jsonData);
53+
});
54+
55+
return mergeObject;
56+
}
57+
58+
module.exports = function configFileLoader() {
59+
return {
60+
loadDataFromFile: loadFile,
61+
loadDataFromFolder: loadDataFromFolder
62+
};
63+
};

core/lib/object_factory.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ const Pattern = function (relPath, data, patternlab) {
6666

6767
// Let's calculate the verbose name ahead of time! We don't use path.sep here
6868
// on purpose. This isn't a file name!
69-
this.verbosePartial = this.subdir + '/' + this.fileName;
69+
this.verbosePartial = this.subdir.split(path.sep).join('/') + '/' + this.fileName;
7070

7171
this.isPattern = true;
7272
this.isFlatPattern = this.patternGroup === this.patternSubGroup;

0 commit comments

Comments
 (0)