Commit
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,17 +6,29 @@ const reporterOutputLogger = require('./reporters/reporterOutputLogger'); | |
|
||
|
||
function coerceToArray(value) { | ||
if (Array.isArray(value)) { | ||
return value; | ||
} if (typeof value === 'string') { | ||
return [value]; | ||
} if ((value == null)) { | ||
return []; | ||
} | ||
if (Array.isArray(value)) return value; | ||
if (typeof value === 'string') return [value]; | ||
if (value == null) return []; | ||
return value; | ||
} | ||
|
||
|
||
function coerceToBoolean(value) { | ||
if (value === 'true') return true; | ||
if (value === 'false') return false; | ||
if (value) return true; | ||
return false; | ||
} | ||
|
||
|
||
function cloneConfig(config) { | ||
const emitter = config.emitter; | ||
const clonedConfig = clone(config); | ||
if (emitter) clonedConfig.emitter = emitter; | ||
return clonedConfig; | ||
} | ||
|
||
|
||
function applyLoggingOptions(options) { | ||
if (options.color === false) { | ||
logger.transports.console.colorize = false; | ||
|
@@ -36,16 +48,102 @@ function applyLoggingOptions(options) { | |
} else if (['warn', 'error'].includes(loglevel)) { | ||
logger.transports.console.level = loglevel; | ||
} else { | ||
throw new Error(`Unsupported logging level: '${loglevel}'`); | ||
logger.transports.console.level = 'warn'; | ||
throw new Error(`The logging level '${loglevel}' is unsupported, ` | ||
+ 'supported are: silent, error, warning, debug'); | ||
} | ||
} else { | ||
logger.transports.console.level = 'warn'; | ||
} | ||
} | ||
|
||
|
||
function applyConfiguration(config) { | ||
const configuration = { | ||
function coerceRemovedOptions(config = {}) { | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
kylef
Member
|
||
const coercedConfig = cloneConfig(config); | ||
|
||
const errors = []; | ||
const warnings = []; | ||
|
||
if (config.options) { | ||
if (config.options.c != null) { | ||
warnings.push('DEPRECATED: Dredd does not support ' | ||
+ '-c anymore, use --color/--no-color instead'); | ||
coercedConfig.options.color = coerceToBoolean(config.options.c); | ||
delete coercedConfig.options.c; | ||
} | ||
if (typeof config.options.color === 'string') { | ||
warnings.push('DEPRECATED: Dredd does not support ' | ||
+ `--color=${config.options.color} anymore, use --color/--no-color instead`); | ||
coercedConfig.options.color = coerceToBoolean(config.options.color); | ||
} | ||
if (config.options.level) { | ||
warnings.push('DEPRECATED: Dredd does not support ' | ||
+ '--level anymore, use --loglevel instead'); | ||
} | ||
if (config.options.level || config.options.l) { | ||
const level = config.options.level || config.options.l; | ||
if (!['silent', 'error', 'warning', 'debug'].includes(level)) { | ||
warnings.push('DEPRECATED: Dredd does not support ' | ||
+ `'${level}' log level anymore, use 'silent', 'error', ` | ||
+ "'warning', or 'debug' instead"); | ||
} | ||
let loglevel; | ||
if (['silly', 'debug', 'verbose'].includes(level)) { | ||
loglevel = 'debug'; | ||
} else if (level === 'error') { | ||
loglevel = 'error'; | ||
} else if (level === 'silent') { | ||
loglevel = 'silent'; | ||
} else { | ||
loglevel = 'warn'; | ||
} | ||
coercedConfig.options.loglevel = loglevel; | ||
coercedConfig.options.l = loglevel; | ||
delete coercedConfig.options.level; | ||
} | ||
if (config.options.timestamp || config.options.t) { | ||
warnings.push('DEPRECATED: Dredd does not support ' | ||
+ '--timestamp anymore, use --loglevel=debug instead'); | ||
coercedConfig.options.loglevel = 'debug'; | ||
coercedConfig.options.l = 'debug'; | ||
delete coercedConfig.options.timestamp; | ||
delete coercedConfig.options.t; | ||
} | ||
if (config.options.silent || config.options.q) { | ||
warnings.push('DEPRECATED: Dredd does not support ' | ||
+ '-q/--silent anymore, use --loglevel=silent instead'); | ||
coercedConfig.options.loglevel = 'silent'; | ||
coercedConfig.options.l = 'silent'; | ||
delete coercedConfig.options.silent; | ||
delete coercedConfig.options.q; | ||
} | ||
if (config.options.sandbox || config.options.b) { | ||
errors.push('REMOVED: Dredd does not support ' | ||
+ 'sandboxed JS hooks anymore, use standard JS hooks instead'); | ||
delete coercedConfig.options.sandbox; | ||
delete coercedConfig.options.b; | ||
} | ||
} | ||
if (config.hooksData) { | ||
errors.push('REMOVED: Dredd does not support ' | ||
+ 'sandboxed JS hooks anymore, use standard JS hooks instead'); | ||
delete coercedConfig.hooksData; | ||
} | ||
if (config.blueprintPath) { | ||
warnings.push('DEPRECATED: Dredd does not support ' | ||
+ "the 'blueprintPath' option anymore, use 'path' instead"); | ||
coercedConfig.options = config.options || {}; | ||
coercedConfig.options.path = coerceToArray(coercedConfig.options.path); | ||
coercedConfig.options.path.push(config.blueprintPath); | ||
delete coercedConfig.blueprintPath; | ||
} | ||
|
||
return { config: coercedConfig, errors, warnings }; | ||
} | ||
|
||
|
||
function applyConfiguration(inConfig) { | ||
const outConfig = { | ||
server: null, | ||
emitter: new EventEmitter(), | ||
custom: { // Used for custom settings of various APIs or reporters | ||
|
@@ -56,7 +154,6 @@ function applyConfiguration(config) { | |
'dry-run': false, | ||
reporter: null, | ||
output: null, | ||
debug: false, | ||
header: null, | ||
user: null, | ||
'inline-errors': false, | ||
|
@@ -80,56 +177,59 @@ function applyConfiguration(config) { | |
}, | ||
}; | ||
|
||
// Normalize options and config | ||
for (const key of Object.keys(config || {})) { | ||
// Copy anything except "custom" hash | ||
const value = config[key]; | ||
if (key !== 'custom') { | ||
configuration[key] = value; | ||
} else { | ||
if (!configuration.custom) { configuration.custom = {}; } | ||
const object = config.custom || {}; | ||
for (const customKey of Object.keys(object || {})) { | ||
const customVal = object[customKey]; | ||
configuration.custom[customKey] = clone(customVal, false); | ||
} | ||
} | ||
} | ||
// Gracefully deal with the removed options | ||
const coerceResult = coerceRemovedOptions(inConfig); | ||
const coercedInConfig = coerceResult.config; | ||
|
||
// Apply the values from the coerced config over the default ones | ||
const custom = coercedInConfig.custom || {}; | ||
Object.keys(custom) | ||
.forEach((key) => { outConfig.custom[key] = clone(custom[key], false); }); | ||
|
||
const options = coercedInConfig.options || {}; | ||
Object.keys(options) | ||
.forEach((key) => { outConfig.options[key] = options[key]; }); | ||
|
||
Object.keys(coercedInConfig) | ||
.filter(key => !['custom', 'options'].includes(key)) | ||
.forEach((key) => { outConfig[key] = coercedInConfig[key]; }); | ||
|
||
// Coerce single/multiple options into an array | ||
configuration.options.reporter = coerceToArray(configuration.options.reporter); | ||
configuration.options.output = coerceToArray(configuration.options.output); | ||
configuration.options.header = coerceToArray(configuration.options.header); | ||
configuration.options.method = coerceToArray(configuration.options.method); | ||
configuration.options.only = coerceToArray(configuration.options.only); | ||
configuration.options.path = coerceToArray(configuration.options.path); | ||
|
||
configuration.options.method = configuration.options.method.map(method => method.toUpperCase()); | ||
|
||
if (configuration.options.user) { | ||
const authHeader = `Authorization:Basic ${Buffer.from(configuration.options.user).toString('base64')}`; | ||
configuration.options.header.push(authHeader); | ||
outConfig.options.reporter = coerceToArray(outConfig.options.reporter); | ||
outConfig.options.output = coerceToArray(outConfig.options.output); | ||
outConfig.options.header = coerceToArray(outConfig.options.header); | ||
outConfig.options.method = coerceToArray(outConfig.options.method); | ||
outConfig.options.only = coerceToArray(outConfig.options.only); | ||
outConfig.options.path = coerceToArray(outConfig.options.path); | ||
|
||
outConfig.options.method = outConfig.options.method | ||
.map(method => method.toUpperCase()); | ||
|
||
if (outConfig.options.user) { | ||
const token = Buffer.from(outConfig.options.user).toString('base64'); | ||
outConfig.options.header.push(`Authorization: Basic ${token}`); | ||
delete outConfig.options.user; | ||
} | ||
|
||
applyLoggingOptions(configuration.options); | ||
applyLoggingOptions(outConfig.options); | ||
|
||
if (config) { | ||
if (config.hooksData | ||
|| (config.options && (config.options.b || config.options.sandbox))) { | ||
throw new Error('DEPRECATED: Dredd does not support ' | ||
+ 'sandboxed JS hooks anymore. Use standard JS hooks instead.'); | ||
} | ||
if (config.blueprintPath) { | ||
throw new Error('DEPRECATED: Dredd does not support ' | ||
+ "the 'blueprintPath' option anymore. Use 'path' instead."); | ||
} | ||
// Log accumulated errors and warnings | ||
coerceResult.errors.forEach(message => logger.error(message)); | ||
coerceResult.warnings.forEach(message => logger.warn(message)); | ||
|
||
// Abort Dredd if there has been any errors | ||
if (coerceResult.errors.length) { | ||
throw new Error('Could not configure Dredd'); | ||
} | ||
|
||
return configuration; | ||
return outConfig; | ||
} | ||
|
||
|
||
module.exports = { | ||
applyConfiguration, | ||
applyLoggingOptions, | ||
|
||
// only for the purpose of unit tests | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
honzajavorek
Author
Contributor
|
||
_coerceRemovedOptions: coerceRemovedOptions, | ||
}; |
This method does not respect the order of the preferences, IMO the configuration should be updated "in place" in the object. The function should preserve the user defined order of preferences, take the following example:
would become interpreted as:
As
-c
(enable colour) is specified before disabling the colour, it should be equivilent to: