From 426f5a5c0785f90d5bcf9de35aea3ec3e36f309a Mon Sep 17 00:00:00 2001 From: PoppinL Date: Wed, 31 Jan 2018 17:31:15 +0800 Subject: [PATCH 1/4] Support globs and fix some issues --- lib/cli.js | 176 ++++++++++++++++++-------------------------- package-lock.json | 183 ++++++++++++++++++++++++++++++++++++++++++++++ package.json | 4 +- 3 files changed, 257 insertions(+), 106 deletions(-) create mode 100644 package-lock.json diff --git a/lib/cli.js b/lib/cli.js index 981c15f..6471cfb 100755 --- a/lib/cli.js +++ b/lib/cli.js @@ -2,87 +2,80 @@ var fs = require("fs"); var path = require("path"); -var parser = require("./jsonlint").parser; +var program = require("commander"); var JSV = require("JSV").JSV; +var parser = require("./jsonlint").parser; var formatter = require("./formatter.js").formatter; - -var options = require("nomnom") - .script("jsonlint") - .options({ - file: { - position: 0, - help: "file to parse; otherwise uses stdin" - }, - version: { - flag : true, - string: '-v, --version', - help: 'print version and exit', - callback: function() { - return require("../package").version; +var pkg = require('../package.json'); + +var hasError = false; + +program + .version(pkg.version, '-v, --version') + .description(pkg.description) + .name(pkg.name) + .arguments('[file...]') + .action(main) + .option('-s, --sort-keys', 'sort object keys') + .option('-i, --in-place', 'overwrite the file') + .option('-t, --indent ', 'character(s) to use for indentation', ' ') + .option('-c, --compact', 'compact error display') + .option('-V, --validate', 'a JSON schema to use for validation') + .option('-e, --environment ', 'which specification of JSON Schema the validation file uses', 'json-schema-draft-03') + .option('-q, --quiet', 'do not print the parsed json to STDOUT') + .option('-p, --pretty-print', 'force pretty printing even if invalid') + .allowUnknownOption() + .parse(process.argv); + +function main(files) { + var options = program.opts(); + + if (files) { + files.forEach(function (file) { + var filePath = path.normalize(file); + var code = parse(fs.readFileSync(filePath, 'utf8'), file, options); + + if (options.inPlace) { + fs.writeSync(fs.openSync(json, 'w+'), code, 0, "utf8"); + } else { + if (!options.quiet) { console.log(code) }; } - }, - sort : { - flag : true, - string: '-s, --sort-keys', - help: 'sort object keys' - }, - inplace : { - flag : true, - string: '-i, --in-place', - help: 'overwrite the file' - }, - indent : { - string: '-t CHAR, --indent CHAR', - "default": " ", - help: 'character(s) to use for indentation' - }, - compact : { - flag : true, - string: '-c, --compact', - help : 'compact error display' - }, - validate : { - string: '-V, --validate', - help : 'a JSON schema to use for validation' - }, - env : { - string: '-e, --environment', - "default": "json-schema-draft-03", - help: 'which specification of JSON Schema the validation file uses' - }, - quiet: { - flag: true, - key: "value", - string: '-q, --quiet', - "default": false, - help: 'do not print the parsed json to STDOUT' - }, - forcePrettyPrint: { - flag: true, - string: '-p, --pretty-print', - help: 'force pretty printing even if invalid' - } - }).parse(); + }); + } else { + var stdin = process.openStdin(); + var code = ''; -if (options.compact) { - var fileName = options.file? options.file + ': ' : ''; - parser.parseError = parser.lexer.parseError = function(str, hash) { - console.error(fileName + 'line '+ hash.loc.first_line +', col '+ hash.loc.last_column +', found: \''+ hash.token +'\' - expected: '+ hash.expected.join(', ') +'.'); - throw new Error(str); - }; + stdin.setEncoding('utf8'); + stdin.on('data', function (chunk) { + code += chunk.toString('utf8'); + }); + stdin.on('end', function () { + if (!options.quiet) { console.log(parse(code, null, options)) }; + }); + } + + hasError && process.exit(1); } -function parse (source) { +function parse(source, file, options) { var parsed, - formatted; + formatted; + + if (options.compact) { + var fileName = file ? file + ': ' : ''; + parser.parseError = parser.lexer.parseError = function (str, hash) { + console.error(fileName + 'line ' + hash.loc.first_line + ', col ' + hash.loc.last_column + ', found: \'' + hash.token + '\' - expected: ' + hash.expected.join(', ') + '.'); + throw new Error(str); + }; + } try { - parsed = options.sort ? + parsed = options.sortKeys ? sortObject(parser.parse(source)) : parser.parse(source); if (options.validate) { - var env = JSV.createEnvironment(options.env); + var env = JSV.createEnvironment(options.environment); var schema = JSON.parse(fs.readFileSync(path.normalize(options.validate), "utf8")); var report = env.validate(parsed, schema); if (report.errors.length) { @@ -92,7 +85,7 @@ function parse (source) { return JSON.stringify(parsed, null, options.indent); } catch (e) { - if (options.forcePrettyPrint) { + if (options.prettyPrint) { /* From https://github.com/umbrae/jsonlintdotcom: * If we failed to validate, run our manual formatter and then re-validate so that we * can get a better line number. On a successful validate, we don't want to run our @@ -104,51 +97,28 @@ function parse (source) { // Re-parse so exception output gets better line numbers parsed = parser.parse(formatted); } catch (e) { - if (! options.compact) { + if (!options.compact) { console.error(e); } // force the pretty print before exiting console.log(formatted); } } else { - if (! options.compact) { + if (!options.compact) { console.error(e); } } - process.exit(1); + hasError = true; } } -function schemaError (str, err) { +function schemaError(str, err) { return str + - "\n\n"+err.message + - "\nuri: " + err.uri + - "\nschemaUri: " + err.schemaUri + - "\nattribute: " + err.attribute + - "\ndetails: " + JSON.stringify(err.details); -} - -function main (args) { - var source = ''; - if (options.file) { - var json = path.normalize(options.file); - source = parse(fs.readFileSync(json, "utf8")); - if (options.inplace) { - fs.writeSync(fs.openSync(json,'w+'), source, 0, "utf8"); - } else { - if (! options.quiet) { console.log(source)}; - } - } else { - var stdin = process.openStdin(); - stdin.setEncoding('utf8'); - - stdin.on('data', function (chunk) { - source += chunk.toString('utf8'); - }); - stdin.on('end', function () { - if (! options.quiet) {console.log(parse(source))}; - }); - } + "\n\n" + err.message + + "\nuri: " + err.uri + + "\nschemaUri: " + err.schemaUri + + "\nattribute: " + err.attribute + + "\ndetails: " + JSON.stringify(err.details); } // from http://stackoverflow.com/questions/1359761/sorting-a-json-object-in-javascript @@ -160,7 +130,7 @@ function sortObject(o) { } var sorted = {}, - key, a = []; + key, a = []; for (key in o) { if (o.hasOwnProperty(key)) { @@ -175,5 +145,3 @@ function sortObject(o) { } return sorted; } - -main(process.argv.slice(1)); diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..2659d41 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,183 @@ +{ + "name": "jsonlint", + "version": "1.6.2", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "JSONSelect": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/JSONSelect/-/JSONSelect-0.4.0.tgz", + "integrity": "sha1-oI7cxn6z/L6Z7WMIVTRKDPKCu40=", + "dev": true + }, + "JSV": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/JSV/-/JSV-4.0.2.tgz", + "integrity": "sha1-0Hf2glVx+CEy+d/67Vh7QCn+/1c=" + }, + "amdefine": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", + "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", + "dev": true, + "optional": true + }, + "ansi-font": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/ansi-font/-/ansi-font-0.0.2.tgz", + "integrity": "sha1-iQMBvVhBRi/TnAt3Ca/R9SUUMzE=", + "dev": true + }, + "cjson": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/cjson/-/cjson-0.3.0.tgz", + "integrity": "sha1-5kObkHA9MS/24iJAl76pLOPQKhQ=", + "dev": true, + "requires": { + "jsonlint": "1.6.0" + } + }, + "colors": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/colors/-/colors-0.5.1.tgz", + "integrity": "sha1-fQAj6usVTo7p/Oddy5I9DtFmd3Q=", + "dev": true + }, + "commander": { + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.13.0.tgz", + "integrity": "sha512-MVuS359B+YzaWqjCL/c+22gfryv+mCBPHAv3zyVI2GN8EY6IRP8VwtasXn8jyyhvvq84R4ImN1OKRtcbIasjYA==" + }, + "ebnf-parser": { + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/ebnf-parser/-/ebnf-parser-0.1.10.tgz", + "integrity": "sha1-zR9rpHfFY4xAyX7ZtXLbW6tdgzE=", + "dev": true + }, + "escodegen": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.3.3.tgz", + "integrity": "sha1-8CQBb1qI4Eb9EgBQVek5gC5sXyM=", + "dev": true, + "requires": { + "esprima": "1.1.1", + "estraverse": "1.5.1", + "esutils": "1.0.0", + "source-map": "0.1.43" + } + }, + "esprima": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-1.1.1.tgz", + "integrity": "sha1-W28VR/TRAuZw4UDFCb5ncdautUk=", + "dev": true + }, + "estraverse": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.5.1.tgz", + "integrity": "sha1-hno+jlip+EYYr7bC3bzZFrfLr3E=", + "dev": true + }, + "esutils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-1.0.0.tgz", + "integrity": "sha1-gVHTWOIMisx/t0XnRywAJf5JZXA=", + "dev": true + }, + "jison": { + "version": "0.4.18", + "resolved": "https://registry.npmjs.org/jison/-/jison-0.4.18.tgz", + "integrity": "sha512-FKkCiJvozgC7VTHhMJ00a0/IApSxhlGsFIshLW6trWJ8ONX2TQJBBz6DlcO1Gffy4w9LT+uL+PA+CVnUSJMF7w==", + "dev": true, + "requires": { + "JSONSelect": "0.4.0", + "cjson": "0.3.0", + "ebnf-parser": "0.1.10", + "escodegen": "1.3.3", + "esprima": "1.1.1", + "jison-lex": "0.3.4", + "lex-parser": "0.1.4", + "nomnom": "1.5.2" + } + }, + "jison-lex": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/jison-lex/-/jison-lex-0.3.4.tgz", + "integrity": "sha1-gcoo2E+ESZ36jFlNzePYo/Jux6U=", + "dev": true, + "requires": { + "lex-parser": "0.1.4", + "nomnom": "1.5.2" + } + }, + "jsonlint": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/jsonlint/-/jsonlint-1.6.0.tgz", + "integrity": "sha1-iKpGvCiaesk7tGyuLVihh6m7SUo=", + "dev": true, + "requires": { + "JSV": "4.0.2", + "nomnom": "1.5.2" + } + }, + "lex-parser": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/lex-parser/-/lex-parser-0.1.4.tgz", + "integrity": "sha1-ZMTwJfF/1Tv7RXY/rrFvAVp0dVA=", + "dev": true + }, + "nomnom": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/nomnom/-/nomnom-1.5.2.tgz", + "integrity": "sha1-9DRUSKhTz71cDSYyDyR3qwUm/i8=", + "dev": true, + "requires": { + "colors": "0.5.1", + "underscore": "1.1.7" + } + }, + "source-map": { + "version": "0.1.43", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz", + "integrity": "sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y=", + "dev": true, + "optional": true, + "requires": { + "amdefine": "1.0.1" + } + }, + "test": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/test/-/test-0.6.0.tgz", + "integrity": "sha1-WYasRF7Bd1QyJRLRBLoyyKY+k44=", + "dev": true, + "requires": { + "ansi-font": "0.0.2" + } + }, + "uglify-js": { + "version": "3.3.9", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.3.9.tgz", + "integrity": "sha512-J2t8B5tj9JdPTW4+sNZXmiIWHzTvcoITkaqzTiilu/biZF/9crqf/Fi7k5hqbOmVRh9/hVNxAxBYIMF7N6SqMQ==", + "dev": true, + "requires": { + "commander": "2.13.0", + "source-map": "0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "underscore": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.1.7.tgz", + "integrity": "sha1-QLq4S60Z0jAJbo1u9ii/8FXYPbA=", + "dev": true + } + } +} diff --git a/package.json b/package.json index b94e7b6..365c19d 100644 --- a/package.json +++ b/package.json @@ -25,8 +25,8 @@ "node": ">= 0.6" }, "dependencies": { - "nomnom": ">= 1.5.x", - "JSV": ">= 4.0.x" + "JSV": "^4.0.2", + "commander": "^2.13.0" }, "devDependencies": { "test": "*", From 5de417d6f96ff9229a09d56e5792d85ddcbb9d5f Mon Sep 17 00:00:00 2001 From: AJ Jordan Date: Sun, 18 Feb 2018 16:53:03 -0500 Subject: [PATCH 2/4] Use ^ in package.json versions This ensures that semver-major upgrades don't get pulled in. This became a critical bug recently because npm decided to publish a placeholder package as nomnom@2, causing *all new installs* of jsonlint to crash. --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index b94e7b6..25eed04 100644 --- a/package.json +++ b/package.json @@ -25,8 +25,8 @@ "node": ">= 0.6" }, "dependencies": { - "nomnom": ">= 1.5.x", - "JSV": ">= 4.0.x" + "nomnom": "^1.5.x", + "JSV": "^4.0.x" }, "devDependencies": { "test": "*", From 843cad2bbd87139bb75806c1c24fe0d821a41ff4 Mon Sep 17 00:00:00 2001 From: Zachary Carter Date: Wed, 21 Feb 2018 13:56:45 -0800 Subject: [PATCH 3/4] 1.6.3 --- package-lock.json | 243 ++++++++++++++++++++++++++++++++++++++++++++++ package.json | 2 +- 2 files changed, 244 insertions(+), 1 deletion(-) create mode 100644 package-lock.json diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..5139c33 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,243 @@ +{ + "name": "jsonlint", + "version": "1.6.3", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "JSONSelect": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/JSONSelect/-/JSONSelect-0.4.0.tgz", + "integrity": "sha1-oI7cxn6z/L6Z7WMIVTRKDPKCu40=", + "dev": true + }, + "JSV": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/JSV/-/JSV-4.0.2.tgz", + "integrity": "sha1-0Hf2glVx+CEy+d/67Vh7QCn+/1c=" + }, + "amdefine": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", + "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", + "dev": true, + "optional": true + }, + "ansi-font": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/ansi-font/-/ansi-font-0.0.2.tgz", + "integrity": "sha1-iQMBvVhBRi/TnAt3Ca/R9SUUMzE=", + "dev": true + }, + "ansi-styles": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.0.0.tgz", + "integrity": "sha1-yxAt8cVvUSPquLZ817mAJ6AnkXg=" + }, + "chalk": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-0.4.0.tgz", + "integrity": "sha1-UZmj3c0MHv4jvAjBsCewYXbgxk8=", + "requires": { + "ansi-styles": "1.0.0", + "has-color": "0.1.7", + "strip-ansi": "0.1.1" + } + }, + "cjson": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/cjson/-/cjson-0.3.0.tgz", + "integrity": "sha1-5kObkHA9MS/24iJAl76pLOPQKhQ=", + "dev": true, + "requires": { + "jsonlint": "1.6.0" + } + }, + "colors": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/colors/-/colors-0.5.1.tgz", + "integrity": "sha1-fQAj6usVTo7p/Oddy5I9DtFmd3Q=", + "dev": true + }, + "commander": { + "version": "2.14.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.14.1.tgz", + "integrity": "sha512-+YR16o3rK53SmWHU3rEM3tPAh2rwb1yPcQX5irVn7mb0gXbwuCCrnkbV5+PBfETdfg1vui07nM6PCG1zndcjQw==", + "dev": true + }, + "ebnf-parser": { + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/ebnf-parser/-/ebnf-parser-0.1.10.tgz", + "integrity": "sha1-zR9rpHfFY4xAyX7ZtXLbW6tdgzE=", + "dev": true + }, + "escodegen": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.3.3.tgz", + "integrity": "sha1-8CQBb1qI4Eb9EgBQVek5gC5sXyM=", + "dev": true, + "requires": { + "esprima": "1.1.1", + "estraverse": "1.5.1", + "esutils": "1.0.0", + "source-map": "0.1.43" + } + }, + "esprima": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-1.1.1.tgz", + "integrity": "sha1-W28VR/TRAuZw4UDFCb5ncdautUk=", + "dev": true + }, + "estraverse": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.5.1.tgz", + "integrity": "sha1-hno+jlip+EYYr7bC3bzZFrfLr3E=", + "dev": true + }, + "esutils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-1.0.0.tgz", + "integrity": "sha1-gVHTWOIMisx/t0XnRywAJf5JZXA=", + "dev": true + }, + "has-color": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/has-color/-/has-color-0.1.7.tgz", + "integrity": "sha1-ZxRKUmDDT8PMpnfQQdr1L+e3iy8=" + }, + "jison": { + "version": "0.4.18", + "resolved": "https://registry.npmjs.org/jison/-/jison-0.4.18.tgz", + "integrity": "sha512-FKkCiJvozgC7VTHhMJ00a0/IApSxhlGsFIshLW6trWJ8ONX2TQJBBz6DlcO1Gffy4w9LT+uL+PA+CVnUSJMF7w==", + "dev": true, + "requires": { + "JSONSelect": "0.4.0", + "cjson": "0.3.0", + "ebnf-parser": "0.1.10", + "escodegen": "1.3.3", + "esprima": "1.1.1", + "jison-lex": "0.3.4", + "lex-parser": "0.1.4", + "nomnom": "1.5.2" + }, + "dependencies": { + "nomnom": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/nomnom/-/nomnom-1.5.2.tgz", + "integrity": "sha1-9DRUSKhTz71cDSYyDyR3qwUm/i8=", + "dev": true, + "requires": { + "colors": "0.5.1", + "underscore": "1.1.7" + } + }, + "underscore": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.1.7.tgz", + "integrity": "sha1-QLq4S60Z0jAJbo1u9ii/8FXYPbA=", + "dev": true + } + } + }, + "jison-lex": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/jison-lex/-/jison-lex-0.3.4.tgz", + "integrity": "sha1-gcoo2E+ESZ36jFlNzePYo/Jux6U=", + "dev": true, + "requires": { + "lex-parser": "0.1.4", + "nomnom": "1.5.2" + }, + "dependencies": { + "nomnom": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/nomnom/-/nomnom-1.5.2.tgz", + "integrity": "sha1-9DRUSKhTz71cDSYyDyR3qwUm/i8=", + "dev": true, + "requires": { + "colors": "0.5.1", + "underscore": "1.1.7" + } + }, + "underscore": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.1.7.tgz", + "integrity": "sha1-QLq4S60Z0jAJbo1u9ii/8FXYPbA=", + "dev": true + } + } + }, + "jsonlint": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/jsonlint/-/jsonlint-1.6.0.tgz", + "integrity": "sha1-iKpGvCiaesk7tGyuLVihh6m7SUo=", + "dev": true, + "requires": { + "JSV": "4.0.2", + "nomnom": "1.8.1" + } + }, + "lex-parser": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/lex-parser/-/lex-parser-0.1.4.tgz", + "integrity": "sha1-ZMTwJfF/1Tv7RXY/rrFvAVp0dVA=", + "dev": true + }, + "nomnom": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/nomnom/-/nomnom-1.8.1.tgz", + "integrity": "sha1-IVH3Ikcrp55Qp2/BJbuMjy5Nwqc=", + "requires": { + "chalk": "0.4.0", + "underscore": "1.6.0" + } + }, + "source-map": { + "version": "0.1.43", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz", + "integrity": "sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y=", + "dev": true, + "optional": true, + "requires": { + "amdefine": "1.0.1" + } + }, + "strip-ansi": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.1.1.tgz", + "integrity": "sha1-OeipjQRNFQZgq+SmgIrPcLt7yZE=" + }, + "test": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/test/-/test-0.6.0.tgz", + "integrity": "sha1-WYasRF7Bd1QyJRLRBLoyyKY+k44=", + "dev": true, + "requires": { + "ansi-font": "0.0.2" + } + }, + "uglify-js": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.3.11.tgz", + "integrity": "sha512-AKLsYcdV+sS5eAE4NtVXF6f2u/DCQynQm0jTGxF261+Vltu1dYNuHzjqDmk11gInj+H/zJIM2EAwXG3MzPb3VA==", + "dev": true, + "requires": { + "commander": "2.14.1", + "source-map": "0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "underscore": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.6.0.tgz", + "integrity": "sha1-izixDKze9jM3uLJOT/htRa6lKag=" + } + } +} diff --git a/package.json b/package.json index 25eed04..1525d9a 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "lint", "jsonlint" ], - "version": "1.6.2", + "version": "1.6.3", "preferGlobal": true, "repository": { "type": "git", From 3079db23f95ebb165035210ccfee126a33d1ac9f Mon Sep 17 00:00:00 2001 From: PoppinL Date: Wed, 31 Jan 2018 17:31:15 +0800 Subject: [PATCH 4/4] Support globs and fix some issues --- lib/cli.js | 176 +++++++++++++++++++--------------------------- package-lock.json | 90 ++++-------------------- package.json | 4 +- 3 files changed, 89 insertions(+), 181 deletions(-) diff --git a/lib/cli.js b/lib/cli.js index 981c15f..6471cfb 100755 --- a/lib/cli.js +++ b/lib/cli.js @@ -2,87 +2,80 @@ var fs = require("fs"); var path = require("path"); -var parser = require("./jsonlint").parser; +var program = require("commander"); var JSV = require("JSV").JSV; +var parser = require("./jsonlint").parser; var formatter = require("./formatter.js").formatter; - -var options = require("nomnom") - .script("jsonlint") - .options({ - file: { - position: 0, - help: "file to parse; otherwise uses stdin" - }, - version: { - flag : true, - string: '-v, --version', - help: 'print version and exit', - callback: function() { - return require("../package").version; +var pkg = require('../package.json'); + +var hasError = false; + +program + .version(pkg.version, '-v, --version') + .description(pkg.description) + .name(pkg.name) + .arguments('[file...]') + .action(main) + .option('-s, --sort-keys', 'sort object keys') + .option('-i, --in-place', 'overwrite the file') + .option('-t, --indent ', 'character(s) to use for indentation', ' ') + .option('-c, --compact', 'compact error display') + .option('-V, --validate', 'a JSON schema to use for validation') + .option('-e, --environment ', 'which specification of JSON Schema the validation file uses', 'json-schema-draft-03') + .option('-q, --quiet', 'do not print the parsed json to STDOUT') + .option('-p, --pretty-print', 'force pretty printing even if invalid') + .allowUnknownOption() + .parse(process.argv); + +function main(files) { + var options = program.opts(); + + if (files) { + files.forEach(function (file) { + var filePath = path.normalize(file); + var code = parse(fs.readFileSync(filePath, 'utf8'), file, options); + + if (options.inPlace) { + fs.writeSync(fs.openSync(json, 'w+'), code, 0, "utf8"); + } else { + if (!options.quiet) { console.log(code) }; } - }, - sort : { - flag : true, - string: '-s, --sort-keys', - help: 'sort object keys' - }, - inplace : { - flag : true, - string: '-i, --in-place', - help: 'overwrite the file' - }, - indent : { - string: '-t CHAR, --indent CHAR', - "default": " ", - help: 'character(s) to use for indentation' - }, - compact : { - flag : true, - string: '-c, --compact', - help : 'compact error display' - }, - validate : { - string: '-V, --validate', - help : 'a JSON schema to use for validation' - }, - env : { - string: '-e, --environment', - "default": "json-schema-draft-03", - help: 'which specification of JSON Schema the validation file uses' - }, - quiet: { - flag: true, - key: "value", - string: '-q, --quiet', - "default": false, - help: 'do not print the parsed json to STDOUT' - }, - forcePrettyPrint: { - flag: true, - string: '-p, --pretty-print', - help: 'force pretty printing even if invalid' - } - }).parse(); + }); + } else { + var stdin = process.openStdin(); + var code = ''; -if (options.compact) { - var fileName = options.file? options.file + ': ' : ''; - parser.parseError = parser.lexer.parseError = function(str, hash) { - console.error(fileName + 'line '+ hash.loc.first_line +', col '+ hash.loc.last_column +', found: \''+ hash.token +'\' - expected: '+ hash.expected.join(', ') +'.'); - throw new Error(str); - }; + stdin.setEncoding('utf8'); + stdin.on('data', function (chunk) { + code += chunk.toString('utf8'); + }); + stdin.on('end', function () { + if (!options.quiet) { console.log(parse(code, null, options)) }; + }); + } + + hasError && process.exit(1); } -function parse (source) { +function parse(source, file, options) { var parsed, - formatted; + formatted; + + if (options.compact) { + var fileName = file ? file + ': ' : ''; + parser.parseError = parser.lexer.parseError = function (str, hash) { + console.error(fileName + 'line ' + hash.loc.first_line + ', col ' + hash.loc.last_column + ', found: \'' + hash.token + '\' - expected: ' + hash.expected.join(', ') + '.'); + throw new Error(str); + }; + } try { - parsed = options.sort ? + parsed = options.sortKeys ? sortObject(parser.parse(source)) : parser.parse(source); if (options.validate) { - var env = JSV.createEnvironment(options.env); + var env = JSV.createEnvironment(options.environment); var schema = JSON.parse(fs.readFileSync(path.normalize(options.validate), "utf8")); var report = env.validate(parsed, schema); if (report.errors.length) { @@ -92,7 +85,7 @@ function parse (source) { return JSON.stringify(parsed, null, options.indent); } catch (e) { - if (options.forcePrettyPrint) { + if (options.prettyPrint) { /* From https://github.com/umbrae/jsonlintdotcom: * If we failed to validate, run our manual formatter and then re-validate so that we * can get a better line number. On a successful validate, we don't want to run our @@ -104,51 +97,28 @@ function parse (source) { // Re-parse so exception output gets better line numbers parsed = parser.parse(formatted); } catch (e) { - if (! options.compact) { + if (!options.compact) { console.error(e); } // force the pretty print before exiting console.log(formatted); } } else { - if (! options.compact) { + if (!options.compact) { console.error(e); } } - process.exit(1); + hasError = true; } } -function schemaError (str, err) { +function schemaError(str, err) { return str + - "\n\n"+err.message + - "\nuri: " + err.uri + - "\nschemaUri: " + err.schemaUri + - "\nattribute: " + err.attribute + - "\ndetails: " + JSON.stringify(err.details); -} - -function main (args) { - var source = ''; - if (options.file) { - var json = path.normalize(options.file); - source = parse(fs.readFileSync(json, "utf8")); - if (options.inplace) { - fs.writeSync(fs.openSync(json,'w+'), source, 0, "utf8"); - } else { - if (! options.quiet) { console.log(source)}; - } - } else { - var stdin = process.openStdin(); - stdin.setEncoding('utf8'); - - stdin.on('data', function (chunk) { - source += chunk.toString('utf8'); - }); - stdin.on('end', function () { - if (! options.quiet) {console.log(parse(source))}; - }); - } + "\n\n" + err.message + + "\nuri: " + err.uri + + "\nschemaUri: " + err.schemaUri + + "\nattribute: " + err.attribute + + "\ndetails: " + JSON.stringify(err.details); } // from http://stackoverflow.com/questions/1359761/sorting-a-json-object-in-javascript @@ -160,7 +130,7 @@ function sortObject(o) { } var sorted = {}, - key, a = []; + key, a = []; for (key in o) { if (o.hasOwnProperty(key)) { @@ -175,5 +145,3 @@ function sortObject(o) { } return sorted; } - -main(process.argv.slice(1)); diff --git a/package-lock.json b/package-lock.json index 5139c33..770acb9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -28,21 +28,6 @@ "integrity": "sha1-iQMBvVhBRi/TnAt3Ca/R9SUUMzE=", "dev": true }, - "ansi-styles": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.0.0.tgz", - "integrity": "sha1-yxAt8cVvUSPquLZ817mAJ6AnkXg=" - }, - "chalk": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-0.4.0.tgz", - "integrity": "sha1-UZmj3c0MHv4jvAjBsCewYXbgxk8=", - "requires": { - "ansi-styles": "1.0.0", - "has-color": "0.1.7", - "strip-ansi": "0.1.1" - } - }, "cjson": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/cjson/-/cjson-0.3.0.tgz", @@ -61,8 +46,7 @@ "commander": { "version": "2.14.1", "resolved": "https://registry.npmjs.org/commander/-/commander-2.14.1.tgz", - "integrity": "sha512-+YR16o3rK53SmWHU3rEM3tPAh2rwb1yPcQX5irVn7mb0gXbwuCCrnkbV5+PBfETdfg1vui07nM6PCG1zndcjQw==", - "dev": true + "integrity": "sha512-+YR16o3rK53SmWHU3rEM3tPAh2rwb1yPcQX5irVn7mb0gXbwuCCrnkbV5+PBfETdfg1vui07nM6PCG1zndcjQw==" }, "ebnf-parser": { "version": "0.1.10", @@ -100,11 +84,6 @@ "integrity": "sha1-gVHTWOIMisx/t0XnRywAJf5JZXA=", "dev": true }, - "has-color": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/has-color/-/has-color-0.1.7.tgz", - "integrity": "sha1-ZxRKUmDDT8PMpnfQQdr1L+e3iy8=" - }, "jison": { "version": "0.4.18", "resolved": "https://registry.npmjs.org/jison/-/jison-0.4.18.tgz", @@ -119,24 +98,6 @@ "jison-lex": "0.3.4", "lex-parser": "0.1.4", "nomnom": "1.5.2" - }, - "dependencies": { - "nomnom": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/nomnom/-/nomnom-1.5.2.tgz", - "integrity": "sha1-9DRUSKhTz71cDSYyDyR3qwUm/i8=", - "dev": true, - "requires": { - "colors": "0.5.1", - "underscore": "1.1.7" - } - }, - "underscore": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.1.7.tgz", - "integrity": "sha1-QLq4S60Z0jAJbo1u9ii/8FXYPbA=", - "dev": true - } } }, "jison-lex": { @@ -147,24 +108,6 @@ "requires": { "lex-parser": "0.1.4", "nomnom": "1.5.2" - }, - "dependencies": { - "nomnom": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/nomnom/-/nomnom-1.5.2.tgz", - "integrity": "sha1-9DRUSKhTz71cDSYyDyR3qwUm/i8=", - "dev": true, - "requires": { - "colors": "0.5.1", - "underscore": "1.1.7" - } - }, - "underscore": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.1.7.tgz", - "integrity": "sha1-QLq4S60Z0jAJbo1u9ii/8FXYPbA=", - "dev": true - } } }, "jsonlint": { @@ -174,7 +117,7 @@ "dev": true, "requires": { "JSV": "4.0.2", - "nomnom": "1.8.1" + "nomnom": "1.5.2" } }, "lex-parser": { @@ -184,12 +127,13 @@ "dev": true }, "nomnom": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/nomnom/-/nomnom-1.8.1.tgz", - "integrity": "sha1-IVH3Ikcrp55Qp2/BJbuMjy5Nwqc=", + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/nomnom/-/nomnom-1.5.2.tgz", + "integrity": "sha1-9DRUSKhTz71cDSYyDyR3qwUm/i8=", + "dev": true, "requires": { - "chalk": "0.4.0", - "underscore": "1.6.0" + "colors": "0.5.1", + "underscore": "1.1.7" } }, "source-map": { @@ -202,11 +146,6 @@ "amdefine": "1.0.1" } }, - "strip-ansi": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.1.1.tgz", - "integrity": "sha1-OeipjQRNFQZgq+SmgIrPcLt7yZE=" - }, "test": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/test/-/test-0.6.0.tgz", @@ -217,9 +156,9 @@ } }, "uglify-js": { - "version": "3.3.11", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.3.11.tgz", - "integrity": "sha512-AKLsYcdV+sS5eAE4NtVXF6f2u/DCQynQm0jTGxF261+Vltu1dYNuHzjqDmk11gInj+H/zJIM2EAwXG3MzPb3VA==", + "version": "3.3.12", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.3.12.tgz", + "integrity": "sha512-4jxrTXlV0HaXTsNILfXW0eey7Qo8qHYM6ih5ZNh45erDWU2GHmKDmekwBTskDb12h+kdd2DBvdzqVb47YzNmTA==", "dev": true, "requires": { "commander": "2.14.1", @@ -235,9 +174,10 @@ } }, "underscore": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.6.0.tgz", - "integrity": "sha1-izixDKze9jM3uLJOT/htRa6lKag=" + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.1.7.tgz", + "integrity": "sha1-QLq4S60Z0jAJbo1u9ii/8FXYPbA=", + "dev": true } } } diff --git a/package.json b/package.json index 1525d9a..d6c18d3 100644 --- a/package.json +++ b/package.json @@ -25,8 +25,8 @@ "node": ">= 0.6" }, "dependencies": { - "nomnom": "^1.5.x", - "JSV": "^4.0.x" + "JSV": "^4.0.2", + "commander": "^2.13.0" }, "devDependencies": { "test": "*",