Skip to content

Commit bd1e10a

Browse files
dlouzandjtarazona
authored andcommitted
fix: correctly load external config file
- external configuration files are properly handled - transform verbose parameter in config file to a 'loglevel' integer that can be increased. uniformity in handling of verbose param - add test cases
1 parent 653ed1b commit bd1e10a

File tree

10 files changed

+88
-34
lines changed

10 files changed

+88
-34
lines changed

README.md

+5-4
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ Options:
6565
-r, --rules [ruleFile] provide multiple rules files
6666
-s, --skip [ruleName] provide multiple rules to skip
6767
-j, --json-schema treat $ref like JSON Schema and convert to OpenAPI Schema Objects
68-
-v, --verbose increase verbosity
68+
-v, --verbose set verbosity (use multiple times to increase level)
6969
-h, --help output usage information
7070
```
7171

@@ -98,7 +98,7 @@ Options:
9898
-o, --output <file> file to output to
9999
-q, --quiet reduce verbosity
100100
-j, --json-schema treat $ref like JSON Schema and convert to OpenAPI Schema Objects
101-
-v, --verbose increase verbosity
101+
-v, --verbose set verbosity (use multiple times to increase level)
102102
-h, --help output usage information
103103
```
104104

@@ -122,7 +122,7 @@ Options:
122122
-p, --port [value] port on which the server will listen (default: 5000)
123123
-q, --quiet reduce verbosity
124124
-j, --json-schema treat $ref like JSON Schema and convert to OpenAPI Schema Objects
125-
-v, --verbose increase verbosity
125+
-v, --verbose set verbosity (use multiple times to increase level)
126126
-h, --help output usage information
127127
```
128128

@@ -138,7 +138,8 @@ jsonSchema: true
138138
# Keep the noise down
139139
quiet: true
140140
# Output a lot of information about what is happening (wont work if you have quiet on)
141-
verbose: true
141+
# Default stdout = 1
142+
verbose: 2
142143
# Rules specific to the lint command
143144
lint:
144145
# rules files to load

lib/config.js

+11-3
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ nconf.formats.yaml = require('nconf-yaml');
77
class Config {
88

99
init(args) {
10-
const configFile = args.config || './speccy.yaml';
10+
const configFile = (args.parent && args.parent.config) ? args.parent.config : './speccy.yaml';
1111

1212
this.load(configFile, {
1313
quiet: args.quiet,
@@ -40,20 +40,28 @@ class Config {
4040
format: nconf.formats.yaml,
4141
file,
4242
});
43+
44+
if (!nconf.get('quiet') && nconf.get('verbose') > 2) {
45+
console.error('LOADING CONFIG', file);
46+
}
4347
}
4448

4549
get(key, defaultValue) {
4650
// Search through all known stores for the value
4751
const value = nconf.get(key);
48-
return (value === undefined) ? defaultValue : value;
52+
const result = (value === undefined) ? defaultValue : value;
53+
if (!nconf.get('quiet') && nconf.get('verbose') > 2) {
54+
console.error(`CONFIG VALUE ${key} = ${result} (default = ${defaultValue})`)
55+
}
56+
return result
4957
}
5058

5159
// Don't want an object full of null
5260
cleanObject(object) {
5361
const cleaned = {};
5462
Object.keys(object).forEach(key => {
5563
const value = object[key];
56-
if (value === undefined || value === null) {
64+
if (value === undefined || value === null || (Array.isArray(value) && value.length === 0)) {
5765
return;
5866
} else if (typeof value === "object" && !Array.isArray(value)) {
5967
cleaned[key] = this.cleanObject(value);

lib/loader.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -152,9 +152,9 @@ async function asyncMap(array, callback) {
152152

153153
const loadRulesets = async (loadFiles, options = {}) => {
154154
const { verbose } = options;
155-
const rulesetList = (loadFiles.length > 0 ? loadFiles : ['default']);
156-
const allDependancies = await asyncMap(rulesetList, ruleset => recursivelyLoadRulesets(ruleset, [], { verbose }));
157-
const flatDependencies = [].concat(...allDependancies);
155+
const rulesetList = (loadFiles && loadFiles.length > 0 ? loadFiles : ['default']);
156+
const allDependencies = await asyncMap(rulesetList, ruleset => recursivelyLoadRulesets(ruleset, [], { verbose }));
157+
const flatDependencies = [].concat(...allDependencies);
158158
// Unique copy of the array
159159
return [...(new Set(flatDependencies))];
160160
}
@@ -168,7 +168,7 @@ const resolveContent = (openapi, options) => {
168168
externalRefs: {},
169169
rewriteRefs: true,
170170
openapi: openapi,
171-
verbose: options.verbose === 2,
171+
verbose: options.verbose > 1,
172172
});
173173
}
174174

lint.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ More information: ${rule.url}#${rule.name}
6868
const command = async (specFile, cmd) => {
6969
config.init(cmd);
7070
const jsonSchema = config.get('jsonSchema');
71-
const verbose = config.get('quiet') ? 0 : config.get('verbose', 1);
71+
const verbose = config.get('quiet') ? 0 : config.get('verbose', 1);
7272
const rulesets = config.get('lint:rules');
7373
const skip = config.get('lint:skip');
7474

@@ -80,7 +80,7 @@ const command = async (specFile, cmd) => {
8080

8181
const spec = await loader.readOrError(
8282
specFile,
83-
buildLoaderOptions(jsonSchema, verbose),
83+
buildLoaderOptions(jsonSchema, verbose)
8484
);
8585

8686
return new Promise((resolve, reject) => {

resolve.js

+6-4
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,18 @@ const fs = require('fs');
66
const yaml = require('js-yaml');
77
const config = require('./lib/config.js');
88
const loader = require('./lib/loader.js');
9-
const resolver = require('oas-resolver');
109
const fromJsonSchema = require('json-schema-to-openapi-schema');
1110

1211
const command = async (file, cmd) => {
1312
config.init(cmd);
1413
const jsonSchema = config.get('jsonSchema');
1514
const output = config.get('resolve:output');
16-
const verbose = config.get('quiet') ? 0 : (config.get('verbose') ? 2 : 1);
15+
const verbose = config.get('quiet') ? 0 : config.get('verbose', 1);
1716

18-
const spec = await loader.readOrError(file, buildLoaderOptions(jsonSchema, verbose));
17+
const spec = await loader.readOrError(
18+
file,
19+
buildLoaderOptions(jsonSchema, verbose)
20+
);
1921
const content = yaml.safeDump(spec, { lineWidth: -1 });
2022

2123
return new Promise((resolve, reject) => {
@@ -53,4 +55,4 @@ const buildLoaderOptions = (jsonSchema, verbose) => {
5355
return options;
5456
}
5557

56-
module.exports = { command }
58+
module.exports = { command };

serve.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ const launchServer = (app, port, specFile, { verbose }) => {
3737
const command = async (specFile, cmd) => {
3838
config.init(cmd);
3939
const jsonSchema = config.get('jsonSchema');
40-
const verbose = config.get('quiet') ? 0 : (config.get('verbose') ? 2 : 1);
40+
const verbose = config.get('quiet') ? 0 : config.get('verbose', 1);
4141
const port = config.get('serve:port', DEFAULT_PORT);
4242

4343
const app = express();

speccy.js

+26-8
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,16 @@ program
3232
.option('-r, --rules [ruleFile]', 'provide multiple rules files', collect, [])
3333
.option('-s, --skip [ruleName]', 'provide multiple rules to skip', collect, [])
3434
.option('-j, --json-schema', 'treat $ref like JSON Schema and convert to OpenAPI Schema Objects (default: false)')
35-
.option('-v, --verbose', 'increase verbosity', increaseVerbosity, 0)
35+
.option('-v, --verbose', 'increase verbosity', increaseVerbosity, 1)
3636
.action((specFile, cmd) => {
3737
lint.command(specFile, cmd)
3838
.then(() => { process.exit(0) })
39-
.catch(() => { process.exit(1) });
39+
.catch((err) => {
40+
if (err) {
41+
console.error(err.message);
42+
}
43+
process.exit(1);
44+
});
4045
});
4146

4247
program
@@ -45,11 +50,16 @@ program
4550
.option('-o, --output <file>', 'file to output to')
4651
.option('-q, --quiet', 'reduce verbosity')
4752
.option('-j, --json-schema', 'treat $ref like JSON Schema and convert to OpenAPI Schema Objects (default: false)')
48-
.option('-v, --verbose', 'increase verbosity', increaseVerbosity, 0)
49-
.action((file, cmd) => {
50-
resolve.command(file, cmd)
53+
.option('-v, --verbose', 'increase verbosity', increaseVerbosity,1)
54+
.action((specFile, cmd) => {
55+
resolve.command(specFile, cmd)
5156
.then(() => { process.exit(0) })
52-
.catch(() => { process.exit(1) });
57+
.catch((err) => {
58+
if (err) {
59+
console.error(err.message);
60+
}
61+
process.exit(1);
62+
});
5363
});
5464

5565
program
@@ -58,9 +68,17 @@ program
5868
.option('-p, --port [value]', 'port on which the server will listen (default: 5000)')
5969
.option('-q, --quiet', 'reduce verbosity')
6070
.option('-j, --json-schema', 'treat $ref like JSON Schema and convert to OpenAPI Schema Objects (default: false)')
61-
.option('-v, --verbose', 'increase verbosity', increaseVerbosity, 0)
71+
.option('-v, --verbose', 'increase verbosity', increaseVerbosity,1)
6272
// TODO .option('-w, --watch', 'reloading browser on spec file changes')
63-
.action(serve.command);
73+
.action((specFile, cmd) => {
74+
serve.command(specFile, cmd)
75+
.catch((err) => {
76+
if (err) {
77+
console.error(err.message);
78+
}
79+
process.exit(1);
80+
});
81+
});
6482

6583
program.parse(process.argv);
6684

test/fixtures/config/valid.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"jsonSchema": true,
33
"quiet": true,
4-
"verbose": true,
4+
"verbose": 2,
55
"lint": {
66
"rules": [
77
"strict",
@@ -18,4 +18,4 @@
1818
"serve": {
1919
"port": 8001
2020
}
21-
}
21+
}

test/fixtures/config/valid.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ jsonSchema: true
33
# Keep the noise down
44
quiet: true
55
# Output a lot of information about what is happening (wont work if you have quiet on)
6-
verbose: true
6+
verbose: 2
77
# Rules specific to the lint command
88
lint:
99
# rules files to load

test/lib/config.test.js

+30-5
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,15 @@ describe('Config', () => {
66
describe('init()', () => {
77
test('does not throw for invalid file', () => {
88
const configFile = 'test/fixtures/config/doesnotexist.yaml';
9-
const f = () => { config.init({ config: configFile }); }
10-
expect(f).not.toThrow;
9+
const f = () => { config.init({ parent: { config: configFile } }); };
10+
expect(f).not.toThrow();
1111
});
1212

1313
describe('with a valid json file', () => {
1414
const configFile = 'test/fixtures/config/valid.json';
1515

1616
test('can find expected values', () => {
17-
config.init({ config: configFile });
17+
config.init({ parent: { config: configFile } });
1818

1919
expect(config.get('jsonSchema')).toBe(true);
2020
expect(config.get('serve:port')).toBe(8001);
@@ -25,7 +25,7 @@ describe('Config', () => {
2525
const configFile = 'test/fixtures/config/valid.yaml';
2626

2727
test('can find expected values', () => {
28-
config.init({ config: configFile });
28+
config.init({ parent: { config: configFile } });
2929

3030
expect(config.get('jsonSchema')).toBe(true);
3131
expect(config.get('serve:port')).toBe(8001);
@@ -48,7 +48,7 @@ describe('Config', () => {
4848
describe('and no config options are supplied', () => {
4949
test('it will have undefined values', () => {
5050
config.load(configFile, {});
51-
expect(config.get('foo:bar')).toBeUndefined;
51+
expect(config.get('foo:bar')).toBeUndefined();
5252
});
5353
});
5454

@@ -60,4 +60,29 @@ describe('Config', () => {
6060
});
6161
});
6262
});
63+
64+
describe('arguments priority', () => {
65+
describe('arguments have higher priority than config file', () => {
66+
const configFile = 'test/fixtures/config/valid.yaml';
67+
68+
test('can override config values with arguments', () => {
69+
config.init({
70+
jsonSchema: false,
71+
verbose: 3,
72+
rules: ['foo'],
73+
port: 5555,
74+
parent: {
75+
config: configFile
76+
}
77+
});
78+
79+
expect(config.get('serve:port')).toBe(5555);
80+
expect(config.get('jsonSchema')).toBe(false);
81+
expect(config.get('verbose')).toBe(3);
82+
expect(config.get('lint:rules')).toEqual(['foo']);
83+
expect(config.get('lint:skip')).toEqual(['info-contact']);
84+
});
85+
86+
});
87+
});
6388
});

0 commit comments

Comments
 (0)