/*
* This file is part of PKM (Persistent Knowledge Monitor).
* Copyright (c) 2020 Capgemini Group, Commissariat à l'énergie atomique et aux énergies alternatives,
* OW2, Sysgo AG, Technikon, Tree Technology, Universitat Politècnica de València.
*
* PKM is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License version 3 as published by
* the Free Software Foundation.
*
* PKM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with PKM. If not, see <https://www.gnu.org/licenses/>.
*/
'use strict';
/** Git config
*/
class GitConfig
{
/** constructor
*
* @param {string} [git_config_output] - text output of 'git config -l'
*/
constructor(git_config_output)
{
if(git_config_output !== undefined)
{
function assign(obj, path, schema, value)
{
function rec_assign(obj, path, schema, value, depth)
{
const key = path[depth];
let schema_value;
if(schema !== undefined)
{
schema_value = schema[key];
if(schema_value === undefined)
{
schema_value = schema['*'];
}
}
if(depth < (path.length - 1))
{
if(obj[key] === undefined) obj[key] = {};
rec_assign(obj[key], path, schema_value, value, depth + 1);
}
else
{
if(schema_value !== undefined)
{
if(typeof schema_value === 'boolean')
{
if(value == 'true')
{
obj[key] = true;
return;
}
else if(value == 'false')
{
obj[key] = false;
return;
}
}
else if(typeof schema_value === 'number')
{
const number = Number(value);
if(number !== NaN)
{
obj[key] = number;
return;
}
}
}
obj[key] = value;
}
}
rec_assign(obj, path, schema, value, 0);
}
const git_config_lines = git_config_output.replace(/\r/, '').split('\n');
git_config_lines.forEach((assignment) =>
{
let i = assignment.indexOf('=');
if(i > -1)
{
const var_name = assignment.slice(0, i);
const var_value = assignment.slice(i + 1);
const path = var_name.split('.');
assign(this, path, GitConfig.schema, var_value);
}
});
}
}
static from(obj)
{
const { deep_copy } = require('./deep_copy');
return Object.assign(new GitConfig(), deep_copy(obj));
}
static schema =
{
advice:
{
'*': true
},
core:
{
repositoryformatversion: 0,
filemode: true,
bare: true,
logallrefupdates: true,
hideDotFiles: true,
ignoreCase: true,
precomposeUnicode: true,
protectHFS: true,
protectNTFS: true,
fsmonitor: 'string',
fsmonitorHookVersion: 1,
trustctime: true,
splitIndex: true,
untrackedCache: true,
checkStat: 'string',
quotePath: 'string',
eol: 'string',
safecrlf: 'string',
autocrlf: 'string',
checkRoundtripEncoding: 'string',
symlinks: true,
gitProxy: 'string',
sshCommand: 'string',
ignoreStat: true,
preferSymlinkRefs: true,
alternateRefsCommand: 'string',
alternateRefsPrefixes: 'string',
worktree: 'string',
sharedRepository : 'string',
warnAmbiguousRefs: true,
compression: -1,
looseCompression: -1,
packedGitWindowSize: 'string',
packedGitLimit: 'string',
deltaBaseCacheLimit: 'string',
bigFileThreshold: 'string',
excludesFile: 'string',
askPass: 'string',
attributesFile: 'string',
hooksPath: 'string',
editor: 'string',
commentChar: 'string',
filesRefLockTimeout: 100,
packedRefsTimeout: 1000,
pager: 'string',
whitespace: 'string',
fsyncObjectFiles: true,
preloadIndex: true,
unsetenvvars: 'string',
restrictinheritedhandles: 'string',
createObject: 'string',
notesRef: 'string',
commitGraph: true,
useReplaceRefs: true,
multiPackIndex: true,
sparseCheckout: true,
sparseCheckoutCone: true,
abbrev: 4
},
add:
{
ignoreErrors: true,
interactive:
{
useBuiltin: true
}
},
alias:
{
'*' : 'string'
},
am:
{
keepcr: true,
threeWay: true
},
apply:
{
ignoreWhitespace: 'string',
whitespace: 'string'
},
blame:
{
blankBoundary: true,
coloring: 'string',
date: 'string',
showEmail: true,
showRoot: true,
ignoreRevsFile: true,
markUnblamables: true,
markIgnoredLines: true
},
branch:
{
autoSetupMerge: true,
autoSetupRebase: true,
sort: 'string',
'*':
{
remote: 'string',
pushRemote: 'string',
merge: 'string',
mergeOptions: 'string',
rebase: true,
description: 'string'
}
},
browser:
{
'*':
{
cmd: 'string',
path: 'string'
}
},
checkout:
{
defaultRemote: 'string',
guess: true,
workers: 1,
thresholdForParallelism: 100,
requireForce: true,
defaultRemoteName: 'string',
rejectShallow: true
},
color:
{
advice: true,
//advice
//{
// hint: 'string'
//},
blame:
{
highlightRecent: 'string',
repeatedLines: 'string',
branch: true,
//branch
//{
// '*': 'string'
//}
},
diff: 'string',
//diff
//{
// '*': 'string'
//},
decorate:
{
'*': 'string'
},
grep: 'string',
//grep
//{
// '*': 'string'
//},
interactive: 'string',
//interactive
//{
// '*': 'string'
//},
pager: true,
push: true,
//push:
//{
// error: 'string'
//},
remote: 'string',
//remote:
//{
// error: 'string'
//},
showBranch: true,
status: true,
//status:
//{
// '*': 'string'
//},
transport: true,
//transport:
//{
// rejected: 'string'
//},
ui: 'string'
},
column:
{
ui: 'string',
branch: 'string',
clean: 'string',
status: 'string',
tag: 'string'
},
commit:
{
cleanup: 'string',
gpgSign: true,
status: true,
template: 'string',
verbose: true,
generationVersion: 1,
maxNewFilters: 1,
readChangedPaths: true
},
credential:
{
helper: 'string',
useHttpPath: true,
username: 'string',
'*':
{
helper: 'string',
useHttpPath: true,
username: 'string'
}
},
credentialCache:
{
ignoreSIGHUP: true,
lockTimeoutMS: 1000,
commands: 'string',
autoRefreshIndex: true,
dirstat: 'string'
},
diff:
{
statGraphWidth: 1,
context: 3,
interHunkContext: 1,
external: 'string',
ignoreSubmodules: 'string',
mnemonicPrefix: 'string',
noprefix: true,
relative: true,
orderFile: 'string',
renameLimit: 1,
renames: true,
suppressBlankEmpty: true,
submodule: 'string',
wordRegex: 'string',
tool: 'string',
guitool: 'string',
indentHeuristic: true,
algorithm: 'string',
wsErrorHighlight: 'string',
colorMoved: 'string',
colorMovedWS: 'string',
'*':
{
command: 'string',
xfuncname: 'string',
binary: true,
textconv: 'string',
wordRegex: 'string',
cachetextconv: true
},
},
difftool:
{
prompt: 'string',
'*':
{
path: 'string',
cmd: 'string'
}
},
extensions:
{
objectFormat: 'string'
},
fastimport:
{
unpackLimit: 1
},
feature:
{
experimental: 'string',
manyFiles: true
},
fetch:
{
recurseSubmodules: true,
fsckObjects: true,
fsck:
{
skipList: 'string'
// '*': 'string'
}
},
gc:
{
aggressiveDepth: 50,
aggressiveWindow: 250,
auto: 6700,
autoPackLimit: 50,
autoDetach: true,
bigPackThreshold: 'string',
writeCommitGraph: true,
logExpiry: 'string',
packRefs: true,
pruneExpire: 'string',
worktreePruneExpire: 'string',
reflogExpire: 'string',
'*':
{
reflogExpire: 'string'
},
reflogExpireUnreachable: 'string',
'*':
{
reflogExpireUnreachable: 'string'
},
rerereResolved: 'string',
rerereUnresolved: 'string'
},
gitcvs:
{
commitMsgAnnotation: 'string',
enabled: true,
logFile: 'string',
usecrlfattr: true,
allBinary: true,
dbName: 'string',
dbDriver: 'string',
dbUser: 'string',
dbPass: 'string',
dbTableNamePrefix: 'string'
},
gitweb:
{
category: 'string',
description: 'string',
owner: 'string',
url: 'string',
avatar: 'string',
blame: true,
grep: true,
highlight: true,
patches: 16,
pickaxe: true,
remote_heads: 'string',
showSizes: true,
snapshot : 'string'
},
grep:
{
lineNumber: true,
column: true,
patternType: 'string',
extendedRegexp: true,
threads: 1,
fallbackToNoIndex: true
},
gpg:
{
program: 'string',
format: 'string',
minTrustLevel: 'string',
'*':
{
program: 'string'
}
},
gui:
{
commitMsgWidth: 75,
diffContext: 5,
displayUntracked: true,
encoding: 'string',
matchTrackingBranch: true,
newBranchTemplate: 'string',
pruneDuringFetch: true,
trustmtime: true,
spellingDictionary: 'string',
fastCopyBlame: true,
copyBlameThreshold: 1,
blamehistoryctx: 1
},
guitool:
{
'*':
{
cmd: 'string',
needsFile: true,
noConsole: true,
noRescan: true,
confirm: true,
argPrompt: true,
revPrompt: true,
revUnmerged: true,
title: 'string',
prompt: 'string'
}
},
help:
{
browser: 'string',
format: 'string',
autoCorrect: 'string',
htmlPath: 'string'
},
http:
{
proxy: 'string',
proxyAuthMethod: 'string',
proxySSLCert: 'string',
proxySSLKey: 'string',
proxySSLCertPasswordProtected: true,
proxySSLCAInfo: 'string',
emptyAuth: true,
delegation: 'string',
extraHeader: 'string',
cookieFile: 'string',
saveCookies: 'string',
version: 'string',
sslVersion: 'string',
sslCipherList: 'string',
sslVerify: true,
sslCert: 'string',
sslKey: 'string',
sslCertPasswordProtected: 'string',
sslCAInfo: 'string',
sslCAPath: 'string',
sslBackend: 'string',
schannelCheckRevoke: 'string',
schannelUseSSLCAInfo: 'string',
pinnedpubkey: 'string',
sslTry: true,
maxRequests: 5,
minSessions: 1,
postBuffer: 1,
lowSpeedLimit: 1,
lowSpeedTime: 1,
noEPSV: true,
userAgent: 'string',
followRedirects: true,
'*':
{
proxy: 'string',
proxyAuthMethod: 'string',
proxySSLCert: 'string',
proxySSLKey: 'string',
proxySSLCertPasswordProtected: true,
proxySSLCAInfo: 'string',
emptyAuth: true,
delegation: 'string',
extraHeader: 'string',
cookieFile: 'string',
saveCookies: 'string',
version: 'string',
sslVersion: 'string',
sslCipherList: 'string',
sslVerify: true,
sslCert: 'string',
sslKey: 'string',
sslCertPasswordProtected: 'string',
sslCAInfo: 'string',
sslCAPath: 'string',
sslBackend: 'string',
schannelCheckRevoke: 'string',
schannelUseSSLCAInfo: 'string',
pinnedpubkey: 'string',
sslTry: true,
maxRequests: 5,
minSessions: 1,
postBuffer: 1,
lowSpeedLimit: 1,
lowSpeedTime: 1,
noEPSV: true,
userAgent: 'string',
followRedirects: true
}
},
i18n:
{
commitEncoding: 'string',
logOutputEncoding: 'string'
},
imap:
{
folder: 'string',
tunnel: 'string',
host: 'string',
user: 'string',
pass: 'string',
port: 1,
sslverify: true,
preformattedHTML: true,
authMethod: 'string'
},
index:
{
recordEndOfIndexEntries: true,
recordOffsetTable: true,
sparse: true,
threads: 1,
version: 1
},
init:
{
templateDir: 'string',
defaultBranch: 'string'
},
instaweb:
{
httpd: 'string',
local: true,
modulePath: 'string',
port: 1
},
interactive:
{
singleKey: true,
diffFilter: 'string'
},
log:
{
abbrevCommit: true,
date: 'string',
decorate: true,
excludeDecoration: 'string',
diffMerges: 'string',
follow: true,
graphColors: 'string',
showRoot: true,
showSignature: true,
mailmap: true
},
lsrefs:
{
unborn: 'string'
},
mailinfo:
{
scissors: true
},
mailmap:
{
file: 'string',
blob: 'string'
},
maintenance:
{
auto: true,
strategy: 'string',
'commit-graph':
{
auto: 100,
},
'loose-objects':
{
auto: 100
},
'incremental-repack':
{
auto: 10
},
'*':
{
enabled: true,
schedule: 'string'
}
},
man:
{
viewer: 'string',
'*':
{
cmd: 'string',
path: 'string'
}
},
merge:
{
conflictStyle: 'string',
defaultToUpstream: true,
ff: true,
verifySignatures: true,
branchdesc: true,
log: true,
suppressDest: true,
renameLimit: 1,
renames: true,
directoryRenames: true,
renormalize: true,
stat: true,
autoStash: true,
tool: 'string',
guitool: 'string',
verbosity: 1,
meld:
{
hasOutput: true,
useAutoMerge: true
},
hideResolved: true,
keepBackup: true,
keepTemporaries: true,
writeToTemp: true,
prompt: 'string',
mergeStrategy: 'string',
'*':
{
name: 'string',
driver: 'string',
recursive: 'string',
path: 'string',
cmd: 'string',
hideResolved: true,
trustExitCode: true
}
},
notes:
{
mergeStrategy: 'string',
displayRef: 'string',
rewrite:
{
'*': true
},
rewriteMode: 'string',
rewriteRef: 'string',
'*':
{
mergeStrategy: 'string'
}
},
pack:
{
window: 10,
depth: 50,
windowMemory: 'string',
compression: 1,
allowPackReuse: true,
island: 'string',
islandCore: 'string',
deltaCacheSize: 1,
deltaCacheLimit: 1,
threads: 1,
indexVersion: 1,
packSizeLimit: 'string',
useBitmaps: true,
useSparse: true,
preferBitmapTips: 'string',
writeBitmaps: true,
writeBitmapHashCache: true,
writeReverseIndex: true
},
pager:
{
'*': 'string'
},
pretty:
{
'*': 'string'
},
protocol:
{
allow: 'string',
version: 1,
'*':
{
allow: 'string',
}
},
pull:
{
ff: true,
rebase: true,
octopus: 'string',
twohead: 'string'
},
push:
{
default: 'string',
followTags: true,
gpgSign: true,
pushOption: 'string',
recurseSubmodules: 'string',
useForceIfIncludes: true,
negotiate: true
},
rebase:
{
backend: 'string',
stat: true,
autoSquash: true,
missingCommitsCheck: 'string',
instructionFormat: 'string',
abbreviateCommands: true,
rescheduleFailedExec: true,
forkPoint: true
},
receive:
{
advertiseAtomic: true,
advertisePushOptions: true,
autogc: true,
certNonceSeed: 'string',
certNonceSlop: 'string',
fsckObjects: true,
fsck:
{
skipList: 'string',
'*': 'string'
},
keepAlive: 5,
unpackLimit: 1,
maxInputSize: 1,
denyDeletes: true,
denyDeleteCurrent: true,
denyCurrentBranch: true,
denyNonFastForwards: true,
hideRefs: 'string',
procReceiveRefs: 'string',
updateServerInfo: true,
shallowUpdate: true
},
remote:
{
pushDefault: 'string',
'*':
{
url: 'string',
pushurl: 'string',
proxy: 'string',
proxyAuthMethod: 'string',
fetch: 'string',
push: 'string',
mirror: true,
skipDefaultUpdate: true,
skipFetchAll: true,
receivepack: 'string',
uploadpack: 'string',
tagOpt: 'string',
vcs: 'string',
prune: true,
pruneTags: true,
promisor: true,
partialclonefilter: 'string'
}
},
remotes:
{
'*': 'string'
},
repack:
{
useDeltaBaseOffset: true,
packKeptObjects: true,
useDeltaIslands: true,
writeBitmaps: true
},
rerere:
{
autoUpdate: true,
enabled: true
},
reset:
{
quiet: true
},
sendemail:
{
identity: 'string',
smtpEncryption: 'string',
smtpssl: 'string',
smtpsslcertpath: 'string',
aliasesFile: 'string',
aliasFileType: 'string',
annotate: true,
bcc: 'string',
cc: 'string',
ccCmd: 'string',
chainReplyTo: true,
confirm: 'string',
envelopeSender: 'string',
from: 'string',
multiEdit: true,
signedoffbycc: true,
smtpPass: 'string',
suppresscc: 'string',
suppressFrom: 'string',
to: 'string',
tocmd: 'string',
smtpDomain: 'string',
smtpServer: 'string',
smtpServerPort: 1,
smtpServerOption: 'string',
smtpUser: 'string',
thread: true,
transferEncoding: 'string',
validate: true,
xmailer: true,
signedoffcc: true,
smtpBatchSize: 1,
smtpReloginDelay: 1,
forbidSendmailVariables: 'string',
'*':
{
'*': 'string'
}
},
sequence:
{
editor: 'string'
},
showBranch:
{
default: 'string'
},
splitIndex:
{
maxPercentChange: 100,
sharedIndexExpire: 'string'
},
ssh:
{
variant: 'string'
},
status:
{
relativePaths: true,
short: true,
branch: true,
aheadBehind: true,
displayCommentPrefix: true,
renameLimit: 1,
renames: 'string',
showStash: true,
showUntrackedFiles: 'string',
submoduleSummary: 1
},
stash:
{
useBuiltin: true,
showIncludeUntracked: true,
showPatch: true,
showStat: true
},
submodule:
{
active: 'string',
recurse: true,
fetchJobs: 1,
alternateLocation: 'string',
alternateErrorStrategy: 'string',
'*':
{
url: 'string',
update: 'string',
branch: 'string',
fetchRecurseSubmodules: true,
ignore: 'string',
active: true
}
},
tag:
{
forceSignAnnotated: true,
sort: 'string',
gpgSign: true,
umask: 'string'
},
tar:
{
umask: 'string'
},
trace2:
{
normalTarget: 'string',
perfTarget: 'string',
eventTarget: 'string',
normalBrief: true,
perfBrief: true,
eventBrief: true,
eventNesting: 1,
configParams: 'string',
envVars: 'string',
destinationDebug: true,
maxFiles: 1
},
transfer:
{
fsckObjects: 'string',
hideRefs: 'string',
unpackLimit: 100,
advertiseSID: true
},
uploadarchive:
{
allowUnreachable: true
},
uploadpack:
{
hideRefs: 'string',
allowTipSHA1InWant: true,
allowReachableSHA1InWant: true,
allowAnySHA1InWant: true,
keepAlive: 5,
packObjectsHook: 'string',
allowFilter: true
},
uploadpackfilter:
{
allow: true,
tree:
{
maxDepth: 1
},
'*':
{
allow: true
}
},
uploadpack:
{
allowRefInWant: true
},
url:
{
'*':
{
insteadOf: 'string',
pushInsteadOf: 'string'
}
},
user:
{
name: 'string',
email: 'string',
useConfigOnly: true,
signingKey: 'string'
},
author:
{
name: 'string',
email: 'string'
},
committer:
{
name: 'string',
email: 'string'
},
versionsort:
{
prereleaseSuffix: 'string',
suffix: 'string'
},
web:
{
browser: 'string'
},
worktree:
{
guessRemote: true
}
};
}
module.exports = GitConfig;