Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ Options:
-r, --rules [ruleFile] provide multiple rules files
-s, --skip [ruleName] provide multiple rules to skip
-j, --json-schema treat $ref like JSON Schema and convert to OpenAPI Schema Objects
-v, --verbose increase verbosity
-v, --verbose set verbosity (use multiple times to increase level)
-h, --help output usage information
```

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

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

Expand All @@ -138,7 +138,8 @@ jsonSchema: true
# Keep the noise down
quiet: true
# Output a lot of information about what is happening (wont work if you have quiet on)
verbose: true
# Default stdout = 1
verbose: 2
# Rules specific to the lint command
lint:
# rules files to load
Expand Down
14 changes: 11 additions & 3 deletions lib/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ nconf.formats.yaml = require('nconf-yaml');
class Config {

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

this.load(configFile, {
quiet: args.quiet,
Expand Down Expand Up @@ -40,20 +40,28 @@ class Config {
format: nconf.formats.yaml,
file,
});

if (!nconf.get('quiet') && nconf.get('verbose') > 2) {
console.error('LOADING CONFIG', file);
}
}

get(key, defaultValue) {
// Search through all known stores for the value
const value = nconf.get(key);
return (value === undefined) ? defaultValue : value;
const result = (value === undefined) ? defaultValue : value;
if (!nconf.get('quiet') && nconf.get('verbose') > 2) {
console.error(`CONFIG VALUE ${key} = ${result} (default = ${defaultValue})`)
}
return result
}

// Don't want an object full of null
cleanObject(object) {
const cleaned = {};
Object.keys(object).forEach(key => {
const value = object[key];
if (value === undefined || value === null) {
if (value === undefined || value === null || (Array.isArray(value) && value.length === 0)) {
return;
} else if (typeof value === "object" && !Array.isArray(value)) {
cleaned[key] = this.cleanObject(value);
Expand Down
8 changes: 4 additions & 4 deletions lib/loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -152,9 +152,9 @@ async function asyncMap(array, callback) {

const loadRulesets = async (loadFiles, options = {}) => {
const { verbose } = options;
const rulesetList = (loadFiles.length > 0 ? loadFiles : ['default']);
const allDependancies = await asyncMap(rulesetList, ruleset => recursivelyLoadRulesets(ruleset, [], { verbose }));
const flatDependencies = [].concat(...allDependancies);
const rulesetList = (loadFiles && loadFiles.length > 0 ? loadFiles : ['default']);
const allDependencies = await asyncMap(rulesetList, ruleset => recursivelyLoadRulesets(ruleset, [], { verbose }));
const flatDependencies = [].concat(...allDependencies);
// Unique copy of the array
return [...(new Set(flatDependencies))];
}
Expand All @@ -168,7 +168,7 @@ const resolveContent = (openapi, options) => {
externalRefs: {},
rewriteRefs: true,
openapi: openapi,
verbose: options.verbose === 2,
verbose: options.verbose > 1,
});
}

Expand Down
4 changes: 2 additions & 2 deletions lint.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ More information: ${rule.url}#${rule.name}
const command = async (specFile, cmd) => {
config.init(cmd);
const jsonSchema = config.get('jsonSchema');
const verbose = config.get('quiet') ? 0 : config.get('verbose', 1);
const verbose = config.get('quiet') ? 0 : config.get('verbose', 1);
const rulesets = config.get('lint:rules');
const skip = config.get('lint:skip');

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

const spec = await loader.readOrError(
specFile,
buildLoaderOptions(jsonSchema, verbose),
buildLoaderOptions(jsonSchema, verbose)
);

return new Promise((resolve, reject) => {
Expand Down
10 changes: 6 additions & 4 deletions resolve.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,18 @@ const fs = require('fs');
const yaml = require('js-yaml');
const config = require('./lib/config.js');
const loader = require('./lib/loader.js');
const resolver = require('oas-resolver');
const fromJsonSchema = require('json-schema-to-openapi-schema');

const command = async (file, cmd) => {
config.init(cmd);
const jsonSchema = config.get('jsonSchema');
const output = config.get('resolve:output');
const verbose = config.get('quiet') ? 0 : (config.get('verbose') ? 2 : 1);
const verbose = config.get('quiet') ? 0 : config.get('verbose', 1);

const spec = await loader.readOrError(file, buildLoaderOptions(jsonSchema, verbose));
const spec = await loader.readOrError(
file,
buildLoaderOptions(jsonSchema, verbose)
);
const content = yaml.safeDump(spec, { lineWidth: -1 });

return new Promise((resolve, reject) => {
Expand Down Expand Up @@ -53,4 +55,4 @@ const buildLoaderOptions = (jsonSchema, verbose) => {
return options;
}

module.exports = { command }
module.exports = { command };
2 changes: 1 addition & 1 deletion serve.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ const launchServer = (app, port, specFile, { verbose }) => {
const command = async (specFile, cmd) => {
config.init(cmd);
const jsonSchema = config.get('jsonSchema');
const verbose = config.get('quiet') ? 0 : (config.get('verbose') ? 2 : 1);
const verbose = config.get('quiet') ? 0 : config.get('verbose', 1);
const port = config.get('serve:port', DEFAULT_PORT);

const app = express();
Expand Down
34 changes: 26 additions & 8 deletions speccy.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,16 @@ program
.option('-r, --rules [ruleFile]', 'provide multiple rules files', collect, [])
.option('-s, --skip [ruleName]', 'provide multiple rules to skip', collect, [])
.option('-j, --json-schema', 'treat $ref like JSON Schema and convert to OpenAPI Schema Objects (default: false)')
.option('-v, --verbose', 'increase verbosity', increaseVerbosity, 0)
.option('-v, --verbose', 'increase verbosity', increaseVerbosity, 1)
.action((specFile, cmd) => {
lint.command(specFile, cmd)
.then(() => { process.exit(0) })
.catch(() => { process.exit(1) });
.catch((err) => {
if (err) {
console.error(err.message);
}
process.exit(1);
});
});

program
Expand All @@ -45,11 +50,16 @@ program
.option('-o, --output <file>', 'file to output to')
.option('-q, --quiet', 'reduce verbosity')
.option('-j, --json-schema', 'treat $ref like JSON Schema and convert to OpenAPI Schema Objects (default: false)')
.option('-v, --verbose', 'increase verbosity', increaseVerbosity, 0)
.action((file, cmd) => {
resolve.command(file, cmd)
.option('-v, --verbose', 'increase verbosity', increaseVerbosity,1)
.action((specFile, cmd) => {
resolve.command(specFile, cmd)
.then(() => { process.exit(0) })
.catch(() => { process.exit(1) });
.catch((err) => {
if (err) {
console.error(err.message);
}
process.exit(1);
});
});

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

program.parse(process.argv);

Expand Down
4 changes: 2 additions & 2 deletions test/fixtures/config/valid.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"jsonSchema": true,
"quiet": true,
"verbose": true,
"verbose": 2,
"lint": {
"rules": [
"strict",
Expand All @@ -18,4 +18,4 @@
"serve": {
"port": 8001
}
}
}
2 changes: 1 addition & 1 deletion test/fixtures/config/valid.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ jsonSchema: true
# Keep the noise down
quiet: true
# Output a lot of information about what is happening (wont work if you have quiet on)
verbose: true
verbose: 2
# Rules specific to the lint command
lint:
# rules files to load
Expand Down
35 changes: 30 additions & 5 deletions test/lib/config.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@ describe('Config', () => {
describe('init()', () => {
test('does not throw for invalid file', () => {
const configFile = 'test/fixtures/config/doesnotexist.yaml';
const f = () => { config.init({ config: configFile }); }
expect(f).not.toThrow;
const f = () => { config.init({ parent: { config: configFile } }); };
expect(f).not.toThrow();
});

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

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

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

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

expect(config.get('jsonSchema')).toBe(true);
expect(config.get('serve:port')).toBe(8001);
Expand All @@ -48,7 +48,7 @@ describe('Config', () => {
describe('and no config options are supplied', () => {
test('it will have undefined values', () => {
config.load(configFile, {});
expect(config.get('foo:bar')).toBeUndefined;
expect(config.get('foo:bar')).toBeUndefined();
});
});

Expand All @@ -60,4 +60,29 @@ describe('Config', () => {
});
});
});

describe('arguments priority', () => {
describe('arguments have higher priority than config file', () => {
const configFile = 'test/fixtures/config/valid.yaml';

test('can override config values with arguments', () => {
config.init({
jsonSchema: false,
verbose: 3,
rules: ['foo'],
port: 5555,
parent: {
config: configFile
}
});

expect(config.get('serve:port')).toBe(5555);
expect(config.get('jsonSchema')).toBe(false);
expect(config.get('verbose')).toBe(3);
expect(config.get('lint:rules')).toEqual(['foo']);
expect(config.get('lint:skip')).toEqual(['info-contact']);
});

});
});
});