adds support for `include`

master
jonschlinkert 7 years ago
parent ae8a931c62
commit 4a32467144

@ -9,6 +9,7 @@
var fs = require('fs');
var path = require('path');
var expand = require('expand-tilde');
var exists = require('fs-exists-sync');
var extend = require('extend-shallow');
var configPath = require('git-config-path');
@ -33,23 +34,36 @@ var ini = require('ini');
function parse(options, cb) {
if (typeof options === 'function') {
cb = options;
options = {};
options = null;
}
if (typeof cb !== 'function') {
throw new TypeError('parse-git-config async expects a callback function.');
throw new TypeError('expected callback to be a function');
}
options = options || {};
var filepath = parse.resolve(options);
var filepath = parse.resolveConfigPath(options);
if (filepath === null) {
cb();
return;
}
fs.stat(filepath, function(err, stat) {
if (err) return cb(err);
if (err) {
cb(err);
return;
}
fs.readFile(filepath, 'utf8', function(err, str) {
if (err) return cb(err);
var parsed = ini.parse(str);
cb(null, parsed);
if (err) {
cb(err);
return;
}
if (options && options.include === true) {
str = injectInclude(str, path.resolve(path.dirname(filepath)));
}
cb(null, ini.parse(str));
});
});
}
@ -69,12 +83,17 @@ function parse(options, cb) {
*/
parse.sync = function parseSync(options) {
options = options || {};
var filepath = parse.resolve(options);
var filepath = parse.resolveConfigPath(options);
if (filepath && exists(filepath)) {
var str = fs.readFileSync(filepath, 'utf8');
return ini.parse(str);
var input = fs.readFileSync(filepath, 'utf8');
if (options && options.include === true) {
var cwd = path.resolve(path.dirname(filepath));
var str = injectInclude(input, cwd);
return ini.parse(str);
}
return ini.parse(input);
}
return {};
};
@ -83,15 +102,23 @@ parse.sync = function parseSync(options) {
* Resolve the git config path
*/
parse.resolve = function resolve(options) {
parse.resolveConfigPath = function(options) {
if (typeof options === 'string') {
options = { type: options };
}
var opts = extend({cwd: process.cwd()}, options);
var fp = opts.path || configPath(opts.type);
var fp = opts.path ? expand(opts.path) : configPath(opts.type);
return fp ? path.resolve(opts.cwd, fp) : null;
};
/**
* Deprecated: use `.resolveConfigPath` instead
*/
parse.resolve = function(options) {
return parse.resolveConfigPath(options);
};
/**
* Returns an object with only the properties that had ini-style keys
* converted to objects (example below).
@ -118,6 +145,38 @@ parse.keys = function parseKeys(config) {
return res;
};
function injectInclude(input, cwd) {
var pathRegex = /^\s*path\s*=\s*/;
var lines = input.split('\n');
var len = lines.length;
var filepath = '';
var res = [];
for (var i = 0; i < len; i++) {
var line = lines[i];
var n = i;
if (line.indexOf('[include]') === 0) {
while (n < len && !pathRegex.test(filepath)) {
filepath = lines[++n];
}
if (!filepath) {
return input;
}
filepath = filepath.replace(pathRegex, '');
var fp = path.resolve(cwd, expand(filepath));
res.push(fs.readFileSync(fp));
} else {
res.push(line);
}
}
return res.join('\n');
}
/**
* Expose `parse`
*/

@ -25,15 +25,16 @@
"test": "mocha"
},
"dependencies": {
"extend-shallow": "^2.0.1",
"expand-tilde": "^2.0.2",
"extend-shallow": "^3.0.2",
"fs-exists-sync": "^0.1.0",
"git-config-path": "^1.0.1",
"ini": "^1.3.4"
"ini": "^1.3.5"
},
"devDependencies": {
"gulp-format-md": "^0.1.11",
"homedir-polyfill": "^1.0.1",
"mocha": "^3.2.0"
"gulp-format-md": "^1.0.0",
"mocha": "^3.5.3",
"homedir-polyfill": "^1.0.1"
},
"keywords": [
"config",

@ -0,0 +1,122 @@
module.exports = {
user: {
email: 'email',
name: 'name',
signingkey: 'https://help.github.com/articles/generating-a-new-gpg-key/'
},
github: {
user: 'name',
token: 'https://github.com/settings/tokens'
},
commit: {
gpgsign: true
},
tag: {
gpgsign: true,
path: '_gitconfig.local',
sort: 'version:refname'
},
core: {
legacyheaders: false,
quotepath: false,
trustctime: false,
precomposeunicode: false,
pager: 'cat',
logAllRefUpdates: true,
excludesfile: '~/.gitignore'
},
repack: {
usedeltabaseoffset: true
},
merge: {
log: true,
conflictstyle: 'diff3'
},
apply: {
whitespace: 'fix'
},
help: {
autocorrect: '1'
},
rerere: {
enabled: true
},
color: {
diff: 'auto',
status: 'auto',
branch: 'auto',
interactive: 'auto',
ui: 'always'
},
'color "diff"': {
meta: 'yellow bold',
frag: 'magenta',
plain: 'white bold',
old: 'red bold',
new: 'green bold',
commit: 'yellow bold',
func: 'green dim',
whitespace: 'red reverse'
},
'color "status"': {
added: 'yellow',
changed: 'green',
untracked: 'cyan'
},
'color "branch"': {
current: 'yellow reverse',
local: 'yellow',
remote: 'green'
},
diff: {
renames: 'copies',
algorithm: 'patience',
compactionHeuristic: true,
wsErrorHighlight: 'all'
},
'diff "bin"': {
textconv: 'hexdump -v -C'
},
credential: {
helper: 'store'
},
status: {
relativePaths: true,
showUntrackedFiles: 'no'
},
pull: {
rebase: true
},
push: {
default: 'current',
followTags: true
},
alias: {
a: 'commit --amend',
c: 'commit -am',
d: '!git diff --exit-code && git diff --cached',
dif: 'diff',
git: '!exec git',
p: 'push -u',
r: 'reset --soft HEAD~1',
s: 'status',
sc: 'clone --depth=1',
l: 'log --graph --pretty=format:\'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset\' --abbrev-commit -n 15'
},
'remote "origin"': {
fetch: '+refs/tags/*:refs/tags/*'
},
branch: {
autosetupmerge: 'always',
autosetuprebase: 'always'
},
http: {
sslverify: false
},
submodule: {
fetchJobs: '0'
},
fetch: {
prune: true
}
};

@ -0,0 +1,86 @@
[include]
path = _gitconfig.local
[core]
legacyheaders = false
quotepath = false
trustctime = false
precomposeunicode = false
pager = cat
logAllRefUpdates = true
excludesfile = ~/.gitignore
[repack]
usedeltabaseoffset = true
[merge]
log = true
conflictstyle = diff3
[apply]
whitespace = fix
[help]
autocorrect = 1
[rerere]
enabled = true
[color]
diff = auto
status = auto
branch = auto
interactive = auto
ui = always
[color "diff"]
meta = yellow bold
frag = magenta
plain = white bold
old = red bold
new = green bold
commit = yellow bold
func = green dim
whitespace = red reverse
[color "status"]
added = yellow
changed = green
untracked = cyan
[color "branch"]
current = yellow reverse
local = yellow
remote = green
[diff]
renames = copies
algorithm = patience
compactionHeuristic = true
wsErrorHighlight = all
[diff "bin"]
textconv = hexdump -v -C
[credential]
helper = store
[status]
relativePaths = true
showUntrackedFiles = no
[pull]
rebase = true
[push]
default = current
followTags = true
[alias]
a = commit --amend
c = commit -am
d = !git diff --exit-code && git diff --cached
dif = diff
git = !exec git
p = push -u
r = reset --soft HEAD~1
s = status
sc = clone --depth=1
l = log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit -n 15
[remote "origin"]
fetch = +refs/pr/*/head:refs/remotes/origin/pr/*
fetch = +refs/tags/*:refs/tags/*
[branch]
autosetupmerge = always
autosetuprebase = always
[http]
sslverify = false
[submodule]
fetchJobs = 0
[fetch]
prune = true
[tag]
sort = version:refname

@ -0,0 +1,11 @@
[user]
email = email
name = name
signingkey = https://help.github.com/articles/generating-a-new-gpg-key/
[github]
user = name
token = https://github.com/settings/tokens
[commit]
gpgsign = true
[tag]
gpgsign = true

@ -1,7 +1,7 @@
/*!
* parse-git-config <https://github.com/jonschlinkert/parse-git-config>
*
* Copyright (c) 2015 Jon Schlinkert.
* Copyright (c) 2015-2018 Jon Schlinkert.
* Licensed under the MIT license.
*/
@ -9,11 +9,16 @@
require('mocha');
var isTravis = process.env.TRAVIS || process.env.CLI;
var fs = require('fs');
var os = require('os');
var assert = require('assert');
var path = require('path');
var homedir = require('homedir-polyfill');
var parse = require('./');
var parse = require('..');
function read(filepath) {
return fs.readFileSync(path.join(__dirname, filepath), 'utf8');
}
describe('sync:', function() {
it('should return an object', function() {
@ -22,14 +27,10 @@ describe('sync:', function() {
});
describe('async:', function() {
it('should throw a callback is not passed:', function(cb) {
try {
it('should throw a callback is not passed:', function() {
assert.throws(function() {
parse();
cb(new Error('expected an error'));
} catch (err) {
assert.equal(err.message, 'parse-git-config async expects a callback function.');
cb();
}
}, /expected/);
});
it('should parse .git/config', function(cb) {
@ -40,8 +41,18 @@ describe('async:', function() {
});
});
it('should include other config sources', function() {
var fp = path.join(__dirname, 'fixtures/_gitconfig');
parse({ path: fp, include: true }, function(err, config) {
assert(!err);
assert.deepEqual(config, require('./expected/_gitconfig.js'));
cb();
});
});
it('should throw an error when .git/config does not exist:', function(cb) {
parse({path: 'foo'}, function(err, config) {
parse({ path: 'foo' }, function(err, config) {
assert(err instanceof Error);
assert(/ENOENT.*parse-git-config/.test(err.message));
cb();
@ -56,11 +67,17 @@ describe('resolve:', function() {
it('should allow override path', function() {
var fp = path.resolve(homedir(), '.gitconfig');
assert.equal(parse.resolve({path: fp}), fp);
assert.equal(parse.resolve({ path: fp }), fp);
});
it('should include other config sources', function() {
var fp = path.join(__dirname, 'fixtures/_gitconfig');
var actual = parse.sync({ path: fp, include: true });
assert.deepEqual(actual, require('./expected/_gitconfig.js'));
});
it('should resolve relative path to cwd', function() {
assert.equal(parse.resolve({path: '.config'}), path.resolve(process.cwd(), '.config'));
assert.equal(parse.resolve({ path: '.config' }), path.resolve(process.cwd(), '.config'));
});
it('should resolve relative path to the global git config when `global` is passed', function() {
@ -69,7 +86,7 @@ describe('resolve:', function() {
});
it('should allow override of cwd', function() {
var actual = parse.resolve({path: '.config', cwd: '/opt/config'});
var actual = parse.resolve({ path: '.config', cwd: '/opt/config' });
assert.equal(actual, path.resolve('/opt/config/.config'));
});
});
Loading…
Cancel
Save