Skip to content

#349: Use js-yaml to parse json, yaml, and yml config files #634

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
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
63 changes: 63 additions & 0 deletions core/lib/data_loader.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
"use strict";

const glob = require('glob'),
_ = require('lodash'),
path = require('path'),
yaml = require('js-yaml');

/**
* Loads a single config file, in yaml/json format.
*
* @param dataFilesPath - leave off the file extension.
* @param fsDep
* @returns {*}
*/
function loadFile(dataFilesPath, fsDep) {
const dataFilesFullPath = dataFilesPath + '*.{json,yml,yaml}';

if (dataFilesPath) {
const dataFiles = glob.sync(dataFilesFullPath),
dataFile = _.head(dataFiles);

if (dataFile && fsDep.existsSync(path.resolve(dataFile))) {
return yaml.safeLoad(fsDep.readFileSync(path.resolve(dataFile), 'utf8'));
}
}

return null;
}

/**
* Loads a set of config files from a folder, in yaml/json format.
*
* @param dataFilesPath - leave off the file extension
* @param excludeFileNames - leave off the file extension
* @param fsDep
* @returns Object, with merged data files, empty object if no files.
*/
function loadDataFromFolder(dataFilesPath, excludeFileNames, fsDep) {
const dataFilesFullPath = dataFilesPath + '*.{json,yml,yaml}',
excludeFullPath = dataFilesPath + excludeFileNames + '.{json,yml,yaml}';

let globOptions = {};
if (excludeFileNames) {
globOptions.ignore = [excludeFullPath];
}

const dataFiles = glob.sync(dataFilesFullPath, globOptions);
let mergeObject = {};

dataFiles.forEach(function (filePath) {
let jsonData = yaml.safeLoad(fsDep.readFileSync(path.resolve(filePath), 'utf8'));
mergeObject = _.merge(mergeObject, jsonData);
});

return mergeObject;
}

module.exports = function configFileLoader() {
return {
loadDataFromFile: loadFile,
loadDataFromFolder: loadDataFromFolder
};
};
31 changes: 13 additions & 18 deletions core/lib/pattern_assembler.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ var path = require('path'),
pph = require('./pseudopattern_hunter'),
mp = require('./markdown_parser'),
plutils = require('./utilities'),
dataLoader = require('./data_loader')(),
patternEngines = require('./pattern_engines'),
lh = require('./lineage_hunter'),
lih = require('./list_item_hunter'),
Expand Down Expand Up @@ -318,16 +319,13 @@ var pattern_assembler = function () {

//look for a json file for this template
try {
var jsonFilename = path.resolve(patternsPath, currentPattern.subdir, currentPattern.fileName + ".json");
try {
var jsonFilenameStats = fs.statSync(jsonFilename);
} catch (err) {
//not a file
}
if (jsonFilenameStats && jsonFilenameStats.isFile()) {
currentPattern.jsonFileData = fs.readJSONSync(jsonFilename);
var jsonFilename = path.resolve(patternsPath, currentPattern.subdir, currentPattern.fileName);
let configData = dataLoader.loadDataFromFile(jsonFilename, fs);

if (configData) {
currentPattern.jsonFileData = configData;
if (patternlab.config.debug) {
console.log('processPatternIterative: found pattern-specific data.json for ' + currentPattern.patternPartial);
console.log('processPatternIterative: found pattern-specific config data for ' + currentPattern.patternPartial);
}
}
}
Expand All @@ -338,17 +336,14 @@ var pattern_assembler = function () {

//look for a listitems.json file for this template
try {
var listJsonFileName = path.resolve(patternsPath, currentPattern.subdir, currentPattern.fileName + ".listitems.json");
try {
var listJsonFileStats = fs.statSync(listJsonFileName);
} catch (err) {
//not a file
}
if (listJsonFileStats && listJsonFileStats.isFile()) {
currentPattern.listitems = fs.readJSONSync(listJsonFileName);
var listJsonFileName = path.resolve(patternsPath, currentPattern.subdir, currentPattern.fileName + ".listitems");
let listItemsConfig = dataLoader.loadDataFromFile(listJsonFileName, fs);

if (listItemsConfig) {
currentPattern.listitems = listItemsConfig;
buildListItems(currentPattern);
if (patternlab.config.debug) {
console.log('found pattern-specific listitems.json for ' + currentPattern.patternPartial);
console.log('found pattern-specific listitems config for ' + currentPattern.patternPartial);
}
}
}
Expand Down
20 changes: 10 additions & 10 deletions core/lib/patternlab.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
"use strict";

var diveSync = require('diveSync'),
glob = require('glob'),
_ = require('lodash'),
path = require('path'),
chalk = require('chalk'),
Expand All @@ -20,6 +19,7 @@ var diveSync = require('diveSync'),
pm = require('./plugin_manager'),
fs = require('fs-extra'),
packageInfo = require('../../package.json'),
dataLoader = require('./data_loader')(),
plutils = require('./utilities'),
PatternGraph = require('./pattern_graph').PatternGraph;

Expand All @@ -38,14 +38,14 @@ console.log(
var patternEngines = require('./pattern_engines');
var EventEmitter = require('events').EventEmitter;

/**
* Given a path, load info from the folder to compile into a single config object.
* @param dataFilesPath
* @param fsDep
* @returns {{}}
*/
function buildPatternData(dataFilesPath, fsDep) {
var dataFiles = glob.sync(dataFilesPath + '*.json', {"ignore" : [dataFilesPath + 'listitems.json']});
var mergeObject = {};
dataFiles.forEach(function (filePath) {
var jsonData = fsDep.readJSONSync(path.resolve(filePath), 'utf8');
mergeObject = _.merge(mergeObject, jsonData);
});
return mergeObject;
return dataLoader.loadDataFromFolder(dataFilesPath, 'listitems', fsDep);
}

// GTP: these two diveSync pattern processors factored out so they can be reused
Expand Down Expand Up @@ -492,9 +492,9 @@ var patternlab_engine = function (config) {
patternlab.data = {};
}
try {
patternlab.listitems = fs.readJSONSync(path.resolve(paths.source.data, 'listitems.json'));
patternlab.listitems = dataLoader.loadDataFromFile(path.resolve(paths.source.data, 'listitems.{json,yml,yaml}'));
} catch (ex) {
plutils.warning('WARNING: missing or malformed ' + paths.source.data + 'listitems.json file. Pattern Lab may not work without this file.');
plutils.warning('WARNING: missing or malformed ' + paths.source.data + 'listitems file. Pattern Lab may not work without this file.');
patternlab.listitems = {};
}
try {
Expand Down
13 changes: 13 additions & 0 deletions test/data_loader_tests.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
'use strict';

const tap = require('tap');

tap.test('loadDataFromFile - Load ', function(test){
const fs = require('fs-extra'),
dataLoader = require('../core/lib/data_loader')(),
data_dir = './test/files/_data/';

let data = dataLoader.loadDataFromFile(data_dir + 'foo', fs);
test.equals(data.foo, 'bar');
test.end();
});
2 changes: 1 addition & 1 deletion test/files/_data/data.json
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
{ "data" : "test" }
{ "data" : "test", "from_json" : "from_json" }

1 change: 1 addition & 0 deletions test/files/_data/data.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from_yaml: "from_yaml"
1 change: 1 addition & 0 deletions test/files/_data/data.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from_yml: "from_yml"
22 changes: 17 additions & 5 deletions test/patternlab_tests.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,27 @@
'use strict';

var tap = require('tap');
const tap = require('tap');

tap.test('buildPatternData - should merge all JSON files in the data folder except listitems', function(test){
var fs = require('fs-extra');
var plMain = require('../core/lib/patternlab');
var data_dir = './test/files/_data/';
const fs = require('fs-extra'),
plMain = require('../core/lib/patternlab'),
data_dir = './test/files/_data/';

var dataResult = plMain.build_pattern_data(data_dir, fs);
let dataResult = plMain.build_pattern_data(data_dir, fs);
test.equals(dataResult.data, "test");
test.equals(dataResult.foo, "bar");
test.equals(dataResult.test_list_item, undefined);
test.end();
});

tap.test('buildPatternData - can load json, yaml, and yml files', function(test) {
const fs = require('fs-extra'),
plMain = require('../core/lib/patternlab'),
data_dir = './test/files/_data/';

let dataResult = plMain.build_pattern_data(data_dir, fs);
test.equals(dataResult.from_yml, "from_yml");
test.equals(dataResult.from_yaml, "from_yaml");
test.equals(dataResult.from_json, "from_json");
test.end();
});