diff --git a/lib/cli/do_comment.js b/lib/cli/do_comment.js new file mode 100644 index 0000000..14e30d2 --- /dev/null +++ b/lib/cli/do_comment.js @@ -0,0 +1,25 @@ +/* + * Copyright 2019 Joyent, Inc. + * + * `jirash comment ...` shortcut for `jirash issue comment ...`. + */ + +var targ = require('./do_issue/do_comment'); + +function do_comment(_subcmd, opts, args, callback) { + this.handlerFromSubcmd('issue').dispatch( + { + subcmd: 'comment', + opts: opts, + args: args + }, + callback + ); +} + +do_comment.help = 'A shortcut for "jirash issue comment ...".\n' + targ.help; +do_comment.synopses = targ.synopses; +do_comment.options = targ.options; +do_comment.completionArgtypes = targ.completionArgtypes; + +module.exports = do_comment; diff --git a/lib/cli/do_issue/do_comment.js b/lib/cli/do_issue/do_comment.js index e25fc69..1e462c2 100644 --- a/lib/cli/do_issue/do_comment.js +++ b/lib/cli/do_issue/do_comment.js @@ -1,59 +1,120 @@ /* - * Copyright (c) 2019, Joyent, Inc. + * Copyright 2019 Joyent, Inc. * * `jirash issue comment ISSUE |-` */ +var assert = require('assert-plus'); +var fs = require('fs'); +var format = require('util').format; var UsageError = require('cmdln').UsageError; var vasync = require('vasync'); -var fs = require('fs'); + +var common = require('../../common'); + + +function textFromEditor(opts, cb) { + assert.object(opts, 'opts'); + assert.string(opts.issueKey, 'opts.issueKey'); + assert.object(opts.log, 'opts.log'); + assert.func(cb, 'cb'); + + var timestamp = new Date() + .toISOString() + .split('.')[0] + .replace(/[:.-]/g, ''); // "YYYYMMDDTHHMMSS" + var editFilename = format( + './jirash-%s-%s.comment', + timestamp, + opts.issueKey + ); + + common.editInEditor( + { + text: '', + filename: editFilename, + noUnlink: true, + log: opts.log + }, + function onEdit(err, text) { + cb(err, text); + } + ); +} + function do_comment(subcmd, opts, args, cb) { if (opts.help) { this.do_help('help', {}, [subcmd], cb); return; - } else if (args.length !== 2) { + } else if (args.length === 1 && !opts.edit) { + cb(new UsageError('must use "-e" or provide a FILE argument')); + return; + } else if (args.length > 2 || args.length < 1) { cb(new UsageError('incorrect number of args')); return; } - var context = { - cli: this.top - }; + var top = this.top; + var issueKey = args[0]; - var key = args[0]; - var commentFile = args[1]; - - if (commentFile === '-') { - commentFile = '/dev/stdin'; - } + vasync.pipeline( + { + arg: { + cli: top + }, + funcs: [ + function getTextFromFile(ctx, next) { + if (args.length !== 2) { + next(); + return; + } - fs.readFile(commentFile, 'utf-8', function addComment(err, data) { - if (err) { - cb(new Error('unable to read file: ' + err)); - return; - } - vasync.pipeline( - { - arg: context, - funcs: [ - function commentIssue(ctx, next) { - ctx.cli.jirashApi.commentIssue( - { - issueIdOrKey: key, - issueComment: data - }, - function onIssue(ierr, issue) { - ctx.issue = issue; - next(ierr); - } - ); + var file = args[1]; + if (file === '-') { + file = '/dev/stdin'; } - ] - }, - cb - ); - }); + fs.readFile(file, 'utf-8', function readTheFile(err, data) { + ctx.text = data; + next(err); + }); + }, + function getTextFromEditor(ctx, next) { + if (args.length !== 1) { + next(); + return; + } + assert.ok(opts.edit, 'opts.edit'); + + textFromEditor( + { + log: top.log, + issueKey: issueKey + }, + function onEdit(err, text) { + ctx.text = text; + next(err); + } + ); + }, + function commentIssue(ctx, next) { + ctx.cli.jirashApi.commentIssue( + { + issueIdOrKey: 'XXX' + issueKey, + issueComment: ctx.text + }, + function onIssue(err, _issue) { + // XXX on error, print the name of file to restart with + // that comment. + // XXX allow '-e' *and* a file arg: `jirash comment TRITON-123 -e foo.comment` + next(err); + } + ); + } + ] + }, + cb + ); } do_comment.options = [ @@ -61,10 +122,18 @@ do_comment.options = [ names: ['help', 'h'], type: 'bool', help: 'Show this help.' + }, + { + names: ['edit', 'e'], + type: 'bool', + help: 'Edit the comment text in your $EDITOR.' } ]; -do_comment.synopses = ['{{name}} {{cmd}} [OPTIONS] ISSUE FILE']; +do_comment.synopses = [ + '{{name}} {{cmd}} [OPTIONS] ISSUE FILE', + '{{name}} {{cmd}} [OPTIONS] -e ISSUE' +]; do_comment.completionArgtypes = ['jirashissue', 'none']; @@ -74,11 +143,13 @@ do_comment.help = [ '{{usage}}', '', '{{options}}', - 'Reads a file or stdin and adds that text to the issue', + 'Where FILE a path from which to read comment text. Use "-" to read from', + 'stdin.', '', 'Examples:', ' cat comment.txt | jirash issue comment TOOLS-2179 -', - ' jirash issue comment TOOLS-2179 mycomment.md' + ' jirash issue comment TOOLS-2179 mycomment.md', + ' jirash issue comment TOOLS-2179 -e # edit in $EDITOR' ].join('\n'); module.exports = do_comment; diff --git a/lib/cli/index.js b/lib/cli/index.js index 7ab0644..fdf7b18 100644 --- a/lib/cli/index.js +++ b/lib/cli/index.js @@ -84,11 +84,11 @@ function JirashCli() { {group: 'Issues'}, 'issue', 'issues', + 'comment', 'create', // 'link', // // 'linktypes', // // 'issuetypes', - // // 'comment', // // 'resolve', {group: 'Other Commands'}, 'filter', @@ -278,6 +278,7 @@ JirashCli.prototype.do_api = require('./do_api'); JirashCli.prototype.do_issue = require('./do_issue'); JirashCli.prototype.do_issues = require('./do_issues'); +JirashCli.prototype.do_comment = require('./do_comment'); JirashCli.prototype.do_create = require('./do_create'); JirashCli.prototype.do_filter = require('./do_filter'); JirashCli.prototype.do_filters = require('./do_filters');