Skip to content

Commit

Permalink
configuration amendments
Browse files Browse the repository at this point in the history
  • Loading branch information
guybedford committed Nov 15, 2015
1 parent ff0bd6d commit db92d61
Show file tree
Hide file tree
Showing 10 changed files with 548 additions and 786 deletions.
12 changes: 11 additions & 1 deletion lib/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,22 @@ function dextend(a, b) {
}
exports.dextend = dextend;

var path = require('path');

exports.inDir = inDir;
function inDir(fileName, dir, sep) {
if (dir[dir.length - 1] != path.sep)
dir += path.sep;
return fileName.substr(0, dir.length) === dir && (sep === false || fileName.substr(dir.length - 1, 1) === path.sep);
}

var asp = require('rsvp').denodeify;
var fs = require('graceful-fs');
var path = require('path');

exports.HOME = process.env.LOCALAPPDATA || process.env.HOME || process.env.HOMEPATH;

exports.absURLRegEx = /^[\/]|[^\/]+:\/\//;

exports.toFileURL = function toFileURL(path) {
return 'file://' + (process.platform.match(/^win/) ? '/' : '') + path.replace(/\\/g, '/');
};
Expand Down
75 changes: 61 additions & 14 deletions lib/config/config-file.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,24 @@ function configError(memberArray, msg) {
'\n\t' + (memberArray.length ? '%' + memberArray.join('.') + '% ' : 'File ') + msg + '.');
}

function propertyEquals(propA, propB) {
if (propA instanceof Array || propB instanceof Array) {
if (!(propA instanceof Array && propB instanceof Array))
return false;

if (propA.length != propB.length)
return false;

return !propA.some(function(itemA, index) {
var itemB = propB[index];
return itemA.key != itemB.key || !propertyEquals(itemA.value, itemB.value);
});
}
else {
return propA.value === propB.value;
}
}

// adds the new property to the given properties object
// if the property exists, it is updated to the new value
// if not the property is placed at the first appropriate position alphabetically
Expand All @@ -63,7 +81,8 @@ function setProperty(properties, key, value, ordering) {
var changed = false;
if (properties.some(function(prop) {
if (prop.key == key) {
if (prop.value !== value)
// determine equality
if (!propertyEquals(prop.value, value))
changed = true;
prop.value = value;
return true;
Expand All @@ -79,6 +98,11 @@ function setProperty(properties, key, value, ordering) {
return true;
}

properties.push({
key: key,
value: value
});

// apply ordering algorithm
var orderIndex = orderingIndex(ordering, key);

Expand Down Expand Up @@ -116,10 +140,16 @@ function setProperty(properties, key, value, ordering) {
// returns undefined if not found
// properties is already assumed to be an array
function getProperty(properties, key) {
var propMatch;
properties.some(function(prop) {
var propMatch = {
index: -1,
property: undefined
};
properties.some(function(prop, index) {
if (prop.key == key) {
propMatch = prop;
propMatch = {
property: prop,
index: index
};
return true;
}
});
Expand All @@ -137,9 +167,9 @@ ConfigFile.prototype.getValue = function(memberArray, type) {
if (!parentProps)
return;

var prop = getProperty(parentProps, memberArray[memberArray.length - 1]);
var prop = getProperty(parentProps, memberArray[memberArray.length - 1]).property;

if (!prop)
if (prop === undefined)
return;

if (prop.value instanceof Array)
Expand Down Expand Up @@ -185,7 +215,7 @@ ConfigFile.prototype.getProperties = function(memberArray, createIfUndefined) {
var ordering = this.ordering;
var self = this;
memberArray.some(function(member, index) {
var prop = getProperty(properties, member);
var prop = getProperty(properties, member).property;
if (prop) {
properties = prop.value;
if (!(properties instanceof Array)) {
Expand Down Expand Up @@ -270,7 +300,7 @@ ConfigFile.prototype.has = function(memberArray) {
if (!parentProps)
return false;

return getProperty(parentProps, memberArray[memberArray.length - 1]) !== undefined;
return getProperty(parentProps, memberArray[memberArray.length - 1]).property !== undefined;
};

// removes the given property member name if it exists
Expand Down Expand Up @@ -306,6 +336,7 @@ ConfigFile.prototype.setValue = function(memberArray, value) {
// handles nested objects, memberArray can be 0 length for base-level population
// where target object already exists, it overwrites retaining the same ordering
// default behaviour is to not write empty objects, but to also not clear objects made empty
// also avoids unnecessary changes
ConfigFile.prototype.setProperties = function(memberArray, properties, clearIfEmpty, keepOrder) {
if (!properties.length && clearIfEmpty) {
this.remove(memberArray);
Expand All @@ -329,11 +360,24 @@ ConfigFile.prototype.setProperties = function(memberArray, properties, clearIfEm

for (var i = 0; i < targetProperties.length; i++) {
var prop = targetProperties[i];
if (setKeys.indexOf(prop.key) == -1)
if (setKeys.indexOf(prop.key) == -1) {
targetProperties.splice(i--, 1);
self.changed = true;
}
}
};

// ensures the given property is first in its containing object property
// skips if the property does not exist
ConfigFile.prototype.orderFirst = function(memberArray) {
var properties = this.getProperties(memberArray.slice(0, memberArray.length - 1));

var propIndex = getProperty(properties, memberArray[memberArray.length - 1]).index;

if (propIndex != -1)
properties.unshift(properties.splice(propIndex, 1)[0]);
};

// only clears on empty if not already existing as empty
// sets this.changed, retains ordering and overwrites as with setValue
// keepOrder indicates if new properties should be added in current iteration order
Expand Down Expand Up @@ -385,6 +429,7 @@ ConfigFile.prototype.read = function() {
}

this.setObject([], deserializedObj, false, true);
this.changed = false;
};
ConfigFile.prototype.write = function() {
var timestamp;
Expand All @@ -399,11 +444,13 @@ ConfigFile.prototype.write = function() {
}

if (timestamp !== this.timestamp)
throw new Error('Configuration file ' + this.fileName + ' has been modified by another process.');

fs.writeFileSync(this.fileName, this.serialize(this.getObject([], true)));
throw new Error('Configuration file ' + path.relative(process.cwd(), this.fileName) + ' has been modified by another process.');

this.timestamp = fs.statSync(this.fileName).mtime.getTime();
if (this.changed || timestamp == -1) {
fs.writeFileSync(this.fileName, this.serialize(this.getObject([], true)));
this.changed = false;
this.timestamp = fs.statSync(this.fileName).mtime.getTime();
}
};

function detectStyle(string) {
Expand All @@ -420,7 +467,7 @@ function detectStyle(string) {

// best-effort tab detection
// yes this is overkill, but it avoids possibly annoying edge cases
var tabSpaces = string.match(/^\s+/mg) || [];
var tabSpaces = string.match(/^[ \t]*/mg) || [];
var tabDifferenceFreqs = {};
var lastLength = 0;
tabSpaces.forEach(function(tabSpace) {
Expand Down
Loading

0 comments on commit db92d61

Please sign in to comment.