UNPKG

xqlint

Version:

XQuery & JSONiq Quality Checker

169 lines (157 loc) 5.61 kB
'use strict'; var fs = require('fs'); var ffs = require('final-fs'); var path = require('path'); var cli = require('commander'); require('colors'); var XQLint = require('../xqlint').XQLint; var JSONiqLexer = require('../lexers/jsoniq_lexer').JSONiqLexer; var XQueryLexer = require('../lexers/xquery_lexer').XQueryLexer; var ANSIOutput = require('./outputs/ansi').ANSIOutput; var CodeFormatter = require('../formatter/formatter').CodeFormatter; var pkg = require('../../package.json'); var getFiles = function(p){ p = path.resolve(path.normalize(p)); var files = []; if(fs.statSync(p).isFile()){ files.push(p); } else { var list = ffs.readdirRecursiveSync(p, true, p); list.forEach(function(file){ if(['jq', 'xq'].indexOf(file.substring(file.length - 2)) !== -1) { files.push(file); } }); } return files; }; var formatCmd = cli.command('format <path>'); formatCmd.description('Format queries') .action(function(p){ var files = getFiles(p); files.forEach(function(file){ var source = fs.readFileSync(file, 'utf-8'); var linter = new XQLint(file, source, undefined, { styleCheck: false }); var formatter = new CodeFormatter(linter.getAST()); var formatted = formatter.format(); console.log(formatted.trim()); }); }); var highlightCmd = cli.command('highlight <path>'); /* highlightCmd.option( '-o, --output <html, ansi>', function(value){ return value.toLowerCase(); } ) */ highlightCmd .description('Highlight queries') .action(function(p){ var files = getFiles(p); files.forEach(function(file){ var source = fs.readFileSync(file, 'utf-8'); var lines = source.split('\n'); var isJSONiq = ((file.substring(file.length - '.jq'.length).indexOf('.jq') !== -1) && source.indexOf('xquery version') !== 0) || source.indexOf('jsoniq version') === 0; var lexer = isJSONiq ? new JSONiqLexer() : new XQueryLexer(); var result = [], tokens, state; lines.forEach(function(line){ tokens = lexer.getLineTokens(line, state); state = tokens.state; result.push(tokens); }); ANSIOutput(result); }); }); var astCmd = cli.command('ast <path>'); astCmd .description('Print AST') .action(function(p){ var files = getFiles(p); files.forEach(function(file){ var source = fs.readFileSync(file, 'utf-8'); var linter = new XQLint(source, { fileName: file, styleCheck: false }); console.log(linter.printAST()); }); }); var xqdocCmd = cli.command('xqdoc <path>'); xqdocCmd .description('Print Module XQDoc') .action(function(p){ var files = getFiles(p); files.forEach(function(file){ var source = fs.readFileSync(file, 'utf-8'); var linter = new XQLint(source, { fileName: file, styleCheck: false }); var xqdoc = linter.getXQDoc(); console.log(JSON.stringify(xqdoc, null, 2)); }); }); var lintCmd = cli.command('lint <path>'); lintCmd.option( '-e, --emacs', 'Format for Gnu/Emacs flymake.' ) .option( '-s, --style-check <yes, no>', 'Check for code formatting.', function(value){ return value === 'yes'; } ) .option( '-p, --processor <name>', 'XQuery/JSONiq Processor (e.g. 28msec)', function(value) { return value.toLowerCase(); } ) .description('Check queries') .action(function(p) { var files = getFiles(p); var errors = 0; var warnings = 0; var spaces = function(count){ var result = ''; for(var i = 1; i <= count; i++){ result += ' '; } return result; }; files.forEach(function(file){ var source = fs.readFileSync(file, 'utf-8').replace(/^\uFEFF/, ''); var linter = new XQLint(source, { fileName: file, styleCheck: lintCmd.styleCheck, processor: lintCmd.processor }); var markers = linter.getMarkers().sort(function(a, b){ return a.sl - b.sl; }); var lines = source.split('\n'); if(markers.length !== 0) { if (!lintCmd.emacs) { console.log(('\n' + file).bold); linter.getErrors().forEach(function(error){ errors++; console.log('\t' + (error.pos.sl + 1) + ' |' + (lines[error.pos.sl].grey)); console.log('\t' + spaces((error.pos.sl + 1 + '').length + 1) + spaces(error.pos.sc + 1) + ('^ ' + error.message).red); }); linter.getWarnings().forEach(function(error){ warnings++; console.log('\t' + (error.pos.sl + 1) + ' |' + (lines[error.pos.sl].grey)); console.log('\t' + spaces((error.pos.sl + 1 + '').length + 1) + spaces(error.pos.sc + 1) + ('^ ' + error.message).yellow); }); } else { // --emacs markers.forEach(function(marker){ console.log(marker.type.toUpperCase() + ': ' + file + ':' + (marker.pos.sl + 1) + ':' + (marker.pos.sc) + ':' + marker.type + ' ' + marker.message); }); } } }); if (!lintCmd.emacs) { if(errors === 0 && warnings === 0) { console.log(('Linted ' + files.length + ' files').green); } else if(errors > 0) { throw new Error(('Linted ' + files.length + ' files. Found ' + errors + ' errors and ' + warnings + ' warnings.').red); } else if(warnings > 0) { throw new Error(('Linted ' + files.length + ' files. Found ' + errors + ' errors and ' + warnings + ' warnings.').yellow); } } }); cli.version(pkg.version); module.exports = cli;