diff --git a/bin/dw-utils.js b/bin/dw-utils.js index 714f9c9..6e71e25 100755 --- a/bin/dw-utils.js +++ b/bin/dw-utils.js @@ -13,7 +13,7 @@ var path = require('path') var root = findProjectRoot(process.cwd(), { maxDepth: 12, - markers : ['.git', '.hg', 'project.json'] + markers : ['dw.json', '.git', '.hg', 'package.json'] }) //cli.debug('project root: ' + root) @@ -33,13 +33,14 @@ var copts = cli.parse({ username : ['u', 'Username for WebDav (Same as Business Manager)', 'string'], cartridges : ['C', 'Path to Cartridges from project root (Default is cartridges)', 'path'], save : [false, 'Save settings for future use', 'bool'], - activate : ['a', 'Activate selected version', 'bool'], + activate : ['a', '[clean] Activate selected version', 'bool'], prompt : ['p', 'Prompt for password', 'bool'], stability : ['s', 'Stability theshold in ms for file watching', 'number', /^win/.test(process.platform)?500:100], - interval : ['i', 'Polling interval (in seconds) for log watching', 'number', 5], + interval : ['i', '[log] Polling interval (in seconds) for log watching', 'number', 5], + follow : ['f', '[log] Only show new messages', 'bool', opts.follow], + all : [false, '[log] Display all log messages even if follow is set in the `dw.json` file'], }, ['activate', 'clean', 'upload-version', 'init', 'watch', 'log']) - function usage(flag){ cli.error('please provide a ' + flag) cli.getUsage() @@ -48,7 +49,7 @@ function usage(flag){ function arg(){ if (cli.args.length > 0){ return cli.args.shift() - } + } return undefined } @@ -78,8 +79,9 @@ if (cli.command == 'init'){ opts.version = arg() || usage('version to activate') break; case 'log': - opts.level = arg() - opts.interval = copts.interval * 1000 + opts.level = arg() + opts.interval = copts.interval * 1000; + opts.follow = copts.all ? false : copts.follow; break } @@ -96,9 +98,9 @@ if (cli.command == 'init'){ fs.writeFileSync(path.join(root, 'dw.json'), JSON.stringify(opts, null, 2)) } - opts.root = root - opts.cartridges = path.join(root, opts.cartridges) - opts.prompt = prompt.getPassword + opts.root = root + opts.cartridges = path.join(root, opts.cartridges) + opts.prompt = prompt.getPassword opts.stabilityThreshold = copts.stability switch (cli.command){ @@ -117,7 +119,7 @@ if (cli.command == 'init'){ case 'log': log(opts) break - default: + default: usage('command') } }) diff --git a/helpers/Tail.js b/helpers/Tail.js index a40bbdb..89cfab2 100644 --- a/helpers/Tail.js +++ b/helpers/Tail.js @@ -4,42 +4,45 @@ var stream = require('stream') class Tail extends stream.Readable{ constructor(options, server, url){ super(options); - this.url = url; - this.poll_interval = options.poll_interval || 2000; // 2 second default - this.cursor = 0; - this.ETag = ''; - this.supports_range = true; - this.server = server + this.url = url; + this.poll_interval = options.poll_interval || 2000; // 2 second default + this.cursor = 0; + this.ETag = ''; + this.supports_range = true; + this.server = server; + this.follow = ('follow' in options) ? options.follow : true; - this.fetch(); + this.fetch(true); } _read(){ // ignore everything } - process_response(error, response, body){ + process_response(error, response, body, ignore) { //console.log(response.headers) - if (response.statusCode == 200 || response.statusCode == 206){ + if (response.statusCode == 200 || response.statusCode == 206) { this.ETag = response.headers['etag'] || response.headers['date'] this.lastmodified = response.headers['date'] this.cursor += Number(response.headers['content-length']) - this.push(body) + if (!ignore) { + this.push(body) + } } - if (response.statusCode == 200){ + if (response.statusCode == 200) { this.cursor = Number(response.headers['content-length']) } } - fetch(){ + fetch(first) { let headers = {} - if (this.cursor > 0){ + if (this.cursor > 0) { headers['Range'] = `bytes=${this.cursor}-` } this.server.get_stream(this.url, { headers : headers, cb : (error, response, body) => { - this.process_response(error, response, body) + this.process_response(error, response, body, (first && this.follow)) } }) .on('end', () => { diff --git a/helpers/format.js b/helpers/format.js index 6d34f8b..108d6d7 100644 --- a/helpers/format.js +++ b/helpers/format.js @@ -39,7 +39,7 @@ class DWLogFormatter extends Transform{ this.lineBuffer = '' // holds partial lines (unlikely) } match(line){ - let transition = false; + let transition = false; for (let i = 0; i < states.length; i++){ let state = states[i]; if (stateRegexes[state].test(line)){ @@ -68,12 +68,12 @@ class DWLogFormatter extends Transform{ } _transform(chunk, encoding, cb){ let out = ""; - out += (chalk.magenta(center('[', '-', + out += (chalk.magenta(center('[', '-', `| ${chalk.underline((new Date()).toTimeString().substring(0,8))} |`, ']') + '\n')) let lines = (chunk.toString().split('\n')) - + for (var i = 0; i < lines.length; i++){ let line = lines[i]; out += (this.match(line)) @@ -83,4 +83,5 @@ class DWLogFormatter extends Transform{ } } +DWLogFormatter.center = center; module.exports = DWLogFormatter diff --git a/log.js b/log.js index 7e24d72..d427d96 100644 --- a/log.js +++ b/log.js @@ -3,15 +3,16 @@ var dwServer = require('dw-webdav') var Tail = require('./helpers/Tail'); var formatter = require('./helpers/format.js') var AnimateChunk = require('./helpers/aninateChunk.js') +var chalk = require('chalk') function log(config){ let host = config.hostname let username = config.username let password = config.password let level = config.level || '(custom)?error' - + let server = new dwServer(host, 'dw-utils', username, password) - + let gotEntries = server.ls('../Logs'); let regex = new RegExp(`^${level}-blade`) let seenLevels = {}; @@ -40,12 +41,25 @@ function log(config){ }) + let title = newest_logs + .map(log => chalk.white.underline(log.propstat.prop.displayname.replace(/-blade.*-/, "-"))) + .join(', '); + + console.log(chalk.yellow( + formatter.center('[','-', (`| ${title} |`), ']') + )); + for (let i = 0; i < newest_logs.length; i++){ - let logFile = new Tail({poll_interval: config.interval}, server, '../Logs/' + newest_logs[i].propstat.prop.displayname) + let logFile = new Tail({ + poll_interval: config.interval, + follow : config.follow, + }, server, '../Logs/' + newest_logs[i].propstat.prop.displayname) + logFile .pipe(new formatter({name :newest_logs[i].propstat.prop.displayname})) .pipe(animateOut) } + }) }