From eaed036bcb1878316758b3eb1c4cf704802aa28c Mon Sep 17 00:00:00 2001 From: Manuel Spigolon Date: Sun, 15 Nov 2020 09:55:13 +0100 Subject: [PATCH] feat: update code to expose @pkgjs/support --- README.md | 11 +--- lib/args.js | 25 --------- lib/cli.js | 10 +--- lib/commands/help.js | 7 --- lib/commands/validate.js | 75 ------------------------- lib/index.js | 2 +- lib/man.js | 11 ---- lib/support-schema.json | 58 ------------------- lib/support-validation.js | 29 ---------- man/help | 13 ----- man/validate | 8 --- package-support.json | 16 ++++++ package.json | 13 +---- test/args.test.js | 64 --------------------- test/cli.test.js | 21 +++++-- test/help.test.js | 30 ---------- test/helper.js | 17 ------ test/invalid-package.json | 8 --- test/missing-package.json | 5 -- test/public-api.test.js | 11 ---- test/support-validation.test.js | 98 --------------------------------- test/validate.test.js | 93 ------------------------------- 22 files changed, 39 insertions(+), 586 deletions(-) delete mode 100644 lib/args.js delete mode 100644 lib/commands/help.js delete mode 100644 lib/commands/validate.js delete mode 100644 lib/man.js delete mode 100644 lib/support-schema.json delete mode 100644 lib/support-validation.js delete mode 100644 man/help delete mode 100644 man/validate create mode 100644 package-support.json delete mode 100644 test/args.test.js delete mode 100644 test/help.test.js delete mode 100644 test/helper.js delete mode 100644 test/invalid-package.json delete mode 100644 test/missing-package.json delete mode 100644 test/public-api.test.js delete mode 100644 test/support-validation.test.js delete mode 100644 test/validate.test.js diff --git a/README.md b/README.md index a0143a1..0c8a65d 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,8 @@ Validate the `support` property in the `package.json` following the [package-maintenance guidelines][validation]! +⚠ This project has been deprecated. Use [`@pkgjs/support`](https://github.com/pkgjs/support) instead. + ## Install You can use this package as a CLI or as a Module if you need to use the core function of this module. @@ -70,17 +72,10 @@ packageCompliant.validateSupportField(aPackageJson.support, (err, valid) => { Read the [CONTRIBUTING](./CONTRIBUTING.md) guidelines to start help us! -### Add new commands - -+ Add to `commands` array in `lib\index.js` the command name (Ex: `awesome`) -+ Create a `lib/commands/.js` file that expose this API `module.exports = function (args) { /* YOUR CODE */ }` -+ Create a `man/` file with all the information to run the command -+ Create a `test/.test.js` where you test your command - ## License -Copyright [Manuel Spigolon](https://github.com/Eomm), Licensed under [MIT](./LICENSE). +Licensed under [MIT](./LICENSE). [validation]: https://raw.githubusercontent.com/nodejs/package-maintenance/781a6bb752f4928e9e5e916b10ba38eb5289f316/docs/drafts/Baseline%20practive%20-%20Document%20support%20levels.md \ No newline at end of file diff --git a/lib/args.js b/lib/args.js deleted file mode 100644 index 7a98c70..0000000 --- a/lib/args.js +++ /dev/null @@ -1,25 +0,0 @@ -'use strict' - -const argv = require('yargs-parser') - -module.exports = function parseArgs (args) { - const parsedArgs = argv(args, { - boolean: ['help'], - string: ['file'], - alias: { - file: ['f'], - help: ['h'] - }, - default: { - file: 'package.json', - help: false - } - }) - - // remove the aliases this way - return Object.assign({}, { - _: parsedArgs._, - file: parsedArgs.file, - help: parsedArgs.help - }) -} diff --git a/lib/cli.js b/lib/cli.js index aab8e55..063b331 100644 --- a/lib/cli.js +++ b/lib/cli.js @@ -1,12 +1,4 @@ #!/usr/bin/env node 'use strict' -const commist = require('commist')() - -const commands = ['validate', 'help'] -commands.forEach(command => { commist.register(command, require(`./commands/${command}`)) }) - -const res = commist.parse(process.argv.splice(2)) -if (res) { - require('./commands/help')() -} +require('@pkgjs/support/lib/cli')()(process.argv.slice(2)) diff --git a/lib/commands/help.js b/lib/commands/help.js deleted file mode 100644 index acd2472..0000000 --- a/lib/commands/help.js +++ /dev/null @@ -1,7 +0,0 @@ -'use strict' - -const { needToShowHelp } = require('../man') - -module.exports = function (args) { - needToShowHelp('help', { help: true }) -} diff --git a/lib/commands/validate.js b/lib/commands/validate.js deleted file mode 100644 index 62fd9a5..0000000 --- a/lib/commands/validate.js +++ /dev/null @@ -1,75 +0,0 @@ -'use strict' - -const { readFileSync } = require('fs') -const chalk = require('chalk') -const parseArgs = require('../args') -const { needToShowHelp } = require('../man') -const validate = require('../support-validation') -const pkg = require('../../package.json') - -module.exports = function (args) { - try { - const opts = parseArgs(args) - needToShowHelp('validate', opts) - - const fileContent = readFile(opts.file, 'utf8') - const supportProp = parseJson(fileContent) - - if (supportProp.support == null) { - const pkgError = new Error(chalk`{red Error} missing {blue support} field in your {blue ${opts.file}} file`) - pkgError.code = 'PS-MISSING' - throw pkgError - } - - if (validateSupportField(supportProp.support)) { - console.log(chalk`Your {blue ${opts.file}} is {green valid}`) - } - } catch (error) { - if ((error.code || '').startsWith('PS-')) { - console.log(error.message) - } else { - console.error(`Fatal error please report it to ${pkg.bugs.url}\n`, error) - } - process.exit(1) - } -} - -function readFile (file, enc) { - try { - return readFileSync(file, enc) - } catch (error) { - const pkgError = new Error(chalk`{red Error} reading file {blue ${file}}: ${error.message}`) - pkgError.code = 'PS-READ' - pkgError.stack = error.stack - throw pkgError - } -} - -function parseJson (jsonString) { - try { - return JSON.parse(jsonString) - } catch (error) { - const pkgError = new Error(chalk`{red Error} parsing JSON: ${error.message}`) - pkgError.code = 'PS-PARSE' - pkgError.stack = error.stack - throw pkgError - } -} - -function validateSupportField (supportJson) { - try { - return validate(supportJson) - } catch (error) { - const errorsMessages = error.errors.map(e => { - let domain = '' - if (e.params && e.params.allowedValues) { - domain = e.params.allowedValues.join(', ') - } - return chalk`{blue ${e.dataPath || 'support JSON'}} {red ${e.message}} ${domain}` - }).join('\n') - - const pkgError = new Error(errorsMessages) - pkgError.code = 'PS-VALIDATION' - throw pkgError - } -} diff --git a/lib/index.js b/lib/index.js index f3b2053..1ac8cc6 100644 --- a/lib/index.js +++ b/lib/index.js @@ -2,4 +2,4 @@ // this file is the main interface to use this package as a module -module.exports.validateSupportField = require('./support-validation') +module.exports.validateSupportField = require('@pkgjs/support').validate diff --git a/lib/man.js b/lib/man.js deleted file mode 100644 index ccd4b6d..0000000 --- a/lib/man.js +++ /dev/null @@ -1,11 +0,0 @@ -'use strict' - -const path = require('path') -const { readFileSync } = require('fs') - -module.exports.needToShowHelp = function (file, opts) { - if (opts.help || opts._.length > 0) { - console.log(readFileSync(path.join(__dirname, '..', 'man', file), 'utf8')) - process.exit() - } -} diff --git a/lib/support-schema.json b/lib/support-schema.json deleted file mode 100644 index 9718a3c..0000000 --- a/lib/support-schema.json +++ /dev/null @@ -1,58 +0,0 @@ -{ - "$id": "support-schema", - "type": "object", - "required": [ - "target", - "response", - "backing" - ], - "definitions": { - "response-def": { - "type": "string", - "enum": [ - "NONE", - "BEST-EFFORT", - "REGULAR-7", - "REGULAR-1", - "24-7" - ] - } - }, - "properties": { - "target": { - "type": "string", - "enum": [ - "ABANDONED", - "NONE", - "LATEST", - "LTS", - "SUPERSET" - ] - }, - "response": { - "$ref": "#/definitions/response-def" - }, - "backing": { - "type": "string", - "enum": [ - "NONE", - "HOBBY", - "SPONSORED", - "BOUNTY", - "PROJECT", - "FOUNDATION", - "COMPANY", - "COMMERCIAL", - "PAID-SUPPORT", - "FREEMIUM" - ] - }, - "url": { - "type": "string", - "format": "uri" - }, - "response-paid": { - "$ref": "#/definitions/response-def" - } - } -} \ No newline at end of file diff --git a/lib/support-validation.js b/lib/support-validation.js deleted file mode 100644 index 0dbe82d..0000000 --- a/lib/support-validation.js +++ /dev/null @@ -1,29 +0,0 @@ -'use strict' - -const Ajv = require('ajv') -const supportSchema = require('./support-schema') - -const ajv = new Ajv({ allErrors: true }) -const validate = ajv.compile(supportSchema) - -/** - * Validate the package.json agains a JSON schema. - * If a callback isn't provided, an error will be thrown if the json isn't valid. - * @param {object} packageJson.support a package.json object - * @param {function} cb an optional callback - */ -function validateSupportField (packageJson, cb) { - const valid = validate(packageJson) - if (cb) { - cb(validate.errors, valid) - } else { - if (!valid) { - const validationError = new Error() - validationError.errors = validate.errors - throw validationError - } - return valid - } -} - -module.exports = validateSupportField diff --git a/man/help b/man/help deleted file mode 100644 index 8a65981..0000000 --- a/man/help +++ /dev/null @@ -1,13 +0,0 @@ -Install via npm: - npm i package-compliant -g - -Usage: package-compliant - -where is one of: - validate, help - -package-compliant -h - will show quick help on - -Usage via npx: - npx package-compliant validate \ No newline at end of file diff --git a/man/validate b/man/validate deleted file mode 100644 index 9faaf68..0000000 --- a/man/validate +++ /dev/null @@ -1,8 +0,0 @@ -Usage: package-compliant validate [--file|-f ] [--help|-h] - validate the package.json support property - - -f, --file - package.json to validate agains package-maintenance guidelines - - -h, --help - Show this message \ No newline at end of file diff --git a/package-support.json b/package-support.json new file mode 100644 index 0000000..fbd4598 --- /dev/null +++ b/package-support.json @@ -0,0 +1,16 @@ +{ + "versions": [ + { + "version": "*", + "target": { + "node": "abandoned" + }, + "response": { + "type": "best-effort" + }, + "backing": { + "hobby": "https://github.com/nodejs/package-compliant" + } + } + ] +} \ No newline at end of file diff --git a/package.json b/package.json index d350c1e..efe074a 100644 --- a/package.json +++ b/package.json @@ -6,11 +6,7 @@ "bin": { "package-compliant": "lib/cli.js" }, - "support": { - "target": "NONE", - "response": "BEST-EFFORT", - "backing": "HOBBY" - }, + "support": true, "scripts": { "test": "standard && tap -J --coverage test/**/*.test.js" }, @@ -34,13 +30,10 @@ "node": ">=6" }, "dependencies": { - "ajv": "^6.9.2", - "chalk": "^2.4.2", - "commist": "^1.1.0", - "yargs-parser": "^13.0.0" + "@pkgjs/support": "0.0.3" }, "devDependencies": { "standard": "^12.0.1", "tap": "^12.6.3" } -} +} \ No newline at end of file diff --git a/test/args.test.js b/test/args.test.js deleted file mode 100644 index 9ce2c1f..0000000 --- a/test/args.test.js +++ /dev/null @@ -1,64 +0,0 @@ -'use strict' - -const t = require('tap') -const test = t.test -const parseArgs = require('../lib/args') - -test('parse all args', t => { - t.plan(1) - - const argv = [ - '--help', 'true', - '--file', 'hello.json' - ] - const parsedArgs = parseArgs(argv) - - t.strictDeepEqual(parsedArgs, { - _: [], - help: true, - file: 'hello.json' - }) -}) - -test('check default values', t => { - t.plan(1) - const parsedArgs = parseArgs([]) - - t.strictDeepEqual(parsedArgs, { - _: [], - help: false, - file: 'package.json' - }) -}) - -test('parse args with = assignment', t => { - t.plan(1) - - const argv = [ - '--help', - '--file=hello.json' - ] - const parsedArgs = parseArgs(argv) - - t.strictDeepEqual(parsedArgs, { - _: [], - help: true, - file: 'hello.json' - }) -}) - -test('parse args aliases', t => { - t.plan(1) - - const argv = [ - '-h', - '-f=hello.json' - ] - const parsedArgs = parseArgs(argv) - - t.strictDeepEqual(parsedArgs, { - _: [], - help: true, - file: 'hello.json' - }) -}) diff --git a/test/cli.test.js b/test/cli.test.js index 45068ed..dc061ef 100644 --- a/test/cli.test.js +++ b/test/cli.test.js @@ -2,18 +2,27 @@ const { test } = require('tap') const { spawn } = require('child_process') - -const h = require('./helper') +const packageCompliant = require('../lib/index') const node = process.execPath -test('show help when no command found', t => { +test('validate command', t => { t.plan(2) - const cli = spawn(node, ['lib/cli']) + const cli = spawn(node, ['lib/cli', 'validate']) cli.stdout.setEncoding('utf8') cli.stdout.on('data', (output) => { - const contentHelp = h.readFileHelp('help') - t.equals(output, contentHelp) + console.log(output) + t.like(output, 'is valid') t.pass() }) }) + +test('validate utility', t => { + t.plan(2) + const success = packageCompliant.validateSupportField(require('../package-support.json')) + t.equal(success, true) + + t.throws(() => { + packageCompliant.validateSupportField({ varsions: [{ missing: 'required-fields' }] }) + }) +}) diff --git a/test/help.test.js b/test/help.test.js deleted file mode 100644 index 853740b..0000000 --- a/test/help.test.js +++ /dev/null @@ -1,30 +0,0 @@ -'use strict' - -const { test } = require('tap') -const { spawn } = require('child_process') - -const h = require('./helper') - -const node = process.execPath - -test('help', t => { - t.plan(2) - const cli = spawn(node, ['lib/cli', 'help']) - cli.stdout.setEncoding('utf8') - cli.stdout.on('data', (output) => { - const contentHelp = h.readFileHelp('help') - t.equals(output, contentHelp) - t.pass() - }) -}) - -test('help when none params', t => { - t.plan(2) - const cli = spawn(node, ['lib/cli']) - cli.stdout.setEncoding('utf8') - cli.stdout.on('data', (output) => { - const contentHelp = h.readFileHelp('help') - t.equals(output, contentHelp) - t.pass() - }) -}) diff --git a/test/helper.js b/test/helper.js deleted file mode 100644 index 6a017fa..0000000 --- a/test/helper.js +++ /dev/null @@ -1,17 +0,0 @@ -'use strict' - -const fs = require('fs') - -function wait (ms) { - return new Promise(resolve => setTimeout(resolve, ms)) -} - -function readFileHelp (file) { - const help = fs.readFileSync(`./man/${file}`, 'utf8') - return `${help}\n` // added because shell add a new line at the end -} - -module.exports = { - wait, - readFileHelp -} diff --git a/test/invalid-package.json b/test/invalid-package.json deleted file mode 100644 index 7e2176a..0000000 --- a/test/invalid-package.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "test", - "version": "0.0.0", - "description": "This is a package.json for test", - "support": { - "target": "not valid" - } -} diff --git a/test/missing-package.json b/test/missing-package.json deleted file mode 100644 index e222d42..0000000 --- a/test/missing-package.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "test", - "version": "0.0.0", - "description": "This is a package.json for test" -} diff --git a/test/public-api.test.js b/test/public-api.test.js deleted file mode 100644 index 26feb8d..0000000 --- a/test/public-api.test.js +++ /dev/null @@ -1,11 +0,0 @@ -'use strict' - -const t = require('tap') -const publicApi = require('../lib/index') -const test = t.test - -test('validateSupportField function', t => { - t.plan(1) - const func = publicApi.validateSupportField - t.type(func, 'function') -}) diff --git a/test/support-validation.test.js b/test/support-validation.test.js deleted file mode 100644 index 0c12f24..0000000 --- a/test/support-validation.test.js +++ /dev/null @@ -1,98 +0,0 @@ -'use strict' - -const t = require('tap') -const validate = require('../lib/support-validation') -const test = t.test - -test('basic validation', t => { - t.plan(3) - - const toValidate = { - target: 'NONE', - response: 'BEST-EFFORT', - backing: 'HOBBY' - } - - t.ok(validate(toValidate)) - - validate(toValidate, (err, res) => { - t.error(err) - t.ok(res) - }) -}) - -test('required fields', t => { - t.plan(3) - - t.throws(() => validate({}), { errors: [] }) - - validate({}, (err, res) => { - t.equals(err.length, 3) - t.notOk(res) - }) -}) - -test('complete valid support property', t => { - t.plan(3) - - const toValidate = { - target: 'LTS', - response: 'REGULAR-7', - 'response-paid': 'REGULAR-1', - backing: 'COMPANY', - url: 'http://mygreatmodule.org/supportinfo.html' - } - - t.ok(validate(toValidate)) - - validate(toValidate, (err, res) => { - t.error(err) - t.ok(res) - }) -}) - -test('bad values on required fields', t => { - t.plan(6) - - const toValidate = { - target: 'foo', - response: 'bar', - backing: 'foobar' - } - - t.throws(() => validate(toValidate), { errors: [] }) - - validate(toValidate, (err, res) => { - t.equals(err.length, 3) - t.equals(err[0].dataPath, '.target') - t.equals(err[1].dataPath, '.response') - t.equals(err[2].dataPath, '.backing') - t.notOk(res) - }) -}) - -test('bad url', t => { - t.plan(4) - - const toValidate = { - target: 'LTS', - response: 'REGULAR-7', - 'response-paid': 'REGULAR-1', - backing: 'COMPANY', - url: 'invalid-url' - } - - t.throws(() => validate(toValidate), { errors: [{ - keyword: /.*/, - dataPath: /.*/, - schemaPath: /.*/, - params: { format: /.*/ }, - message: /.*/ - }] }) - - validate(toValidate, (err, res) => { - t.equals(err.length, 1) - t.equals(err[0].dataPath, '.url') - t.notOk(res) - }) -}) diff --git a/test/validate.test.js b/test/validate.test.js deleted file mode 100644 index 1ccfe01..0000000 --- a/test/validate.test.js +++ /dev/null @@ -1,93 +0,0 @@ -'use strict' - -const { test } = require('tap') -const { spawn } = require('child_process') -const h = require('./helper') - -const node = process.execPath - -test('show help', t => { - t.plan(2) - const cli = spawn(node, ['lib/cli', 'validate', '--help']) - cli.stdout.setEncoding('utf8') - cli.stdout.on('data', (output) => { - const contentHelp = h.readFileHelp('validate') - t.equals(output, contentHelp) - t.pass() - }) -}) - -test('validate a valid package.json', t => { - t.plan(2) - const cli = spawn(node, ['lib/cli', 'validate']) - cli.stdout.setEncoding('utf8') - let stdout = '' - cli.stdout.on('data', (data) => { stdout += data }) - cli.on('close', (code) => { - t.match(stdout, /.*is valid.*/i) - t.equals(code, 0) - }) -}) - -test('validate an invalid package.json', t => { - t.plan(5) - const cli = spawn(node, ['lib/cli', 'validate', '-f=./test/invalid-package.json']) - cli.stdout.setEncoding('utf8') - let stdout = '' - cli.stdout.on('data', (data) => { stdout += data }) - cli.on('close', (code) => { - t.equals(code, 1) - - function * outErrors () { - yield /.target should be equal to one of the allowed values ABANDONED, NONE, LATEST, LTS, SUPERSET/ - yield /support JSON should have required property 'response'/ - yield /support JSON should have required property 'backing'/ - } - - const gen = outErrors() - - const errors = stdout.split('\n') - t.equals(errors.length, 3 + 1) - - errors.filter(_ => _ !== '') - .forEach(error => { - t.match(error, gen.next().value) - }) - }) -}) - -test('validate an invalid package.json - missing support', t => { - t.plan(2) - const cli = spawn(node, ['lib/cli', 'validate', '-f=./test/missing-package.json']) - cli.stdout.setEncoding('utf8') - let stdout = '' - cli.stdout.on('data', (data) => { stdout += data }) - cli.on('close', (code) => { - t.match(stdout, /^Error missing support field:*/i) - t.equals(code, 1) - }) -}) - -test('read an unexisting file', t => { - t.plan(2) - const cli = spawn(node, ['lib/cli', 'validate', '-f=this-file-does-not-exist']) - cli.stdout.setEncoding('utf8') - let stdout = '' - cli.stdout.on('data', (data) => { stdout += data }) - cli.on('close', (code) => { - t.match(stdout, /^Error .*file this-file-does-not-exist.*/i) - t.equals(code, 1) - }) -}) - -test('read a not JSON file', t => { - t.plan(2) - const cli = spawn(node, ['lib/cli', 'validate', '-f=README.md']) - cli.stdout.setEncoding('utf8') - let stdout = '' - cli.stdout.on('data', (data) => { stdout += data }) - cli.on('close', (code) => { - t.match(stdout, /^Error parsing JSON.*/i) - t.equals(code, 1) - }) -})