[ospec] feat: nicer binary with support for globs (#2141)

* feat(ospec): CLI support for file-patterns and an --ignore flag

The added dependency is only used by the node.js binary - which normally only ever installed via npm/yarn anyway.

This does not interfer with ospec proper being dependencyless.

* chore(mithril): Add glob dependency needed by the ospec binary

this is only needed while ospec is inlined in the
mithril repo. As soon as ospec is split away into a
standalone npm module, this will not be required anymore.

* refactor(ospec): Use 'match' events instead of callback

Performance should be similar, but the code looks
cleaner and easier to grok.

* Misc tweaks
This commit is contained in:
Már Örlygsson 2018-05-06 23:32:01 +00:00 committed by Pierre-Yves Gérardy
parent f161a59343
commit cfaa377c1e
4 changed files with 66 additions and 47 deletions

67
ospec/bin/ospec Normal file → Executable file
View file

@ -1,48 +1,37 @@
#!/usr/bin/env node
"use strict"
var fs = require("fs")
var path = require("path")
const o = require("../ospec")
const path = require("path")
const glob = require("glob")
var o = require("../ospec")
function traverseDirectory(pathname, callback) {
pathname = pathname.replace(/\\/g, "/")
return new Promise(function(resolve, reject) {
fs.lstat(pathname, function(err, stat) {
if (err) reject(err)
if (stat && stat.isDirectory()) {
fs.readdir(pathname, function(err, pathnames) {
if (err) reject(err)
var promises = []
for (var i = 0; i < pathnames.length; i++) {
if (pathnames[i] === "node_modules") continue
if (pathnames[i][0] === ".") continue
pathnames[i] = path.join(pathname, pathnames[i])
promises.push(traverseDirectory(pathnames[i], callback))
}
callback(pathname, stat, pathnames)
resolve(Promise.all(promises))
})
}
else {
callback(pathname, stat)
resolve(pathname)
}
})
const parseArgs = (argv) => {
argv = ["--globs"].concat(argv.slice(2))
const args = {}
let name
argv.forEach((arg) => {
if (/^--/.test(arg)) {
name = arg.substr(2)
args[name] = args[name] || []
} else {
args[name].push(arg)
}
})
return args
}
traverseDirectory(".", function(pathname) {
if (pathname.match(/(?:^|\/)tests\/.*\.js$/)) {
require(path.normalize(process.cwd()) + "/" + pathname) // eslint-disable-line global-require
}
})
.then(o.run)
.catch(function(e) {
console.log(e.stack)
})
process.on("unhandledRejection", function(e) {
console.log("Uncaught (in promise) " + e.stack)
})
const args = parseArgs(process.argv)
const globList = args.globs && args.globs.length ? args.globs : ["**/tests/**/*.js"]
const ignore = ["**/node_modules/**"].concat(args.ignore||[])
const cwd = process.cwd()
globList.forEach((globPattern) => {
glob(globPattern, {ignore})
.on("match", (fileName) => { require(path.join(cwd, fileName)) }) // eslint-disable-line global-require
.on("error", (e) => console.error(e))
.on("end", o.run)
});
process.on("unhandledRejection", (e) => { console.log("Uncaught (in promise) " + e.stack) })