diff --git a/package-lock.json b/package-lock.json index 3eb81f1..6a29438 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2803,14 +2803,12 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, - "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -2825,20 +2823,17 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "core-util-is": { "version": "1.0.2", @@ -2955,8 +2950,7 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "ini": { "version": "1.3.5", @@ -2968,7 +2962,6 @@ "version": "1.0.0", "bundled": true, "dev": true, - "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -2983,7 +2976,6 @@ "version": "3.0.4", "bundled": true, "dev": true, - "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -2991,14 +2983,12 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "minipass": { "version": "2.2.4", "bundled": true, "dev": true, - "optional": true, "requires": { "safe-buffer": "^5.1.1", "yallist": "^3.0.0" @@ -3017,7 +3007,6 @@ "version": "0.5.1", "bundled": true, "dev": true, - "optional": true, "requires": { "minimist": "0.0.8" } @@ -3098,8 +3087,7 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "object-assign": { "version": "4.1.1", @@ -3111,7 +3099,6 @@ "version": "1.4.0", "bundled": true, "dev": true, - "optional": true, "requires": { "wrappy": "1" } @@ -3233,7 +3220,6 @@ "version": "1.0.2", "bundled": true, "dev": true, - "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", diff --git a/src/index.js b/src/index.js index e1ec786..4da3a30 100755 --- a/src/index.js +++ b/src/index.js @@ -43,6 +43,7 @@ jira.init().then(function(){ .command('search [search terms]') .description('Search issues') .alias('s') + .option("-j, --jql ", "Search issues with raw jql") .action((c, o) => { jira.cmdSearch(c, o); }); @@ -71,11 +72,13 @@ jira.init().then(function(){ .command('issue [command]') .description('Issue commands') .alias('i') + .option("-d, --details", "Print issue detailed info") .option("-r, --release ", "Get the given release issues") .option("-p, --project ", "Set the current project") .option("-u, --user ", "Set the user name") .option("-a, --assign ", "Assign issue to a user") .option("-t, --transition [transitionName]", "Make issue transition") + .option("--trs, --transitions", "Get list of issue possible transitions") .option("-h, --help", "") .action((c, o) => { jira.cmdIssue(c, o); diff --git a/src/issues.js b/src/issues.js index 21452f4..8022bb3 100644 --- a/src/issues.js +++ b/src/issues.js @@ -200,6 +200,26 @@ export default class JiraIssues { }); } + /** + * search issue viq raw jql + */ + + jqlSearch ( jql_string ) { + const _this = this; + jira.api.searchJira( jql_string ).then(function( r ){ + if( r.total ){ + _this.showIssues( r.issues ); + console.log( color.bold( " Total issues found: " + color.green( r.total ) ) ); + console.log(''); + } else { + jira.showError( "No issues found with search terms: '" + args + "'" ); + } + }).catch(function( res ){ + jira.showErrors( res ); + process.exit(); + }); + } + /** * Open issue in default browser */ @@ -236,7 +256,7 @@ export default class JiraIssues { /** * Show issue detail in pretty format */ - showIssue( issue ) { + showIssue( issue, detailed ) { const table = new Table({ chars: jira.tableChars }); const detailTable = new Table({ chars: jira.tableChars }); let status; @@ -260,12 +280,18 @@ export default class JiraIssues { break; } + table.push({ 'Summary': issue.fields.summary.trim() }); + if ( detailed ) { + table.push({ 'Desc': issue.fields.description }) + }; table.push( - { 'Summary': issue.fields.summary.trim() } - , { 'Status': status } + { 'Status': status } , { 'Type': issue.fields.issuetype.name } , { 'Project': issue.fields.project.name + ' (' + issue.fields.project.key + ')' } , { 'Reporter': issue.fields.reporter.name }); + if ( detailed ) { + table.push({ 'Attachnemt count': issue.fields.attachment.length }) + }; // If issue has assignee if( issue.fields.assignee != null ) { @@ -300,6 +326,17 @@ export default class JiraIssues { } console.log( table.toString() ); + if ( detailed ) { + console.log('Comments:') + issue.fields.comment.comments.map((comment) => { + console.log(color.yellow('--------------------')); + console.log(color.italic(comment.body)); + console.log(); + console.log('Created: ' + moment(comment.created).format('MMMM Do YYYY, h:mm:ss a')) + console.log('Author: ' + comment.author.name); + console.log(); + }) + } } /** @@ -347,11 +384,11 @@ export default class JiraIssues { /** * Find specific issue */ - findIssue( issue ) { + findIssue( issue, detailed ) { const _this = this; jira.api.findIssue( issue ).then(function( r ){ - _this.showIssue( r ); + _this.showIssue( r, detailed ); }).catch(function( res ){ jira.showErrors( res ); process.exit(); @@ -432,14 +469,48 @@ export default class JiraIssues { }); } + /** + * list of issue transitions + */ + async listTransitions( issueId ) { + const transitions = await this.getIssueTransitions(issueId); + const table = new Table({ chars: jira.tableChars, head: ['id', 'name', 'to'] }); + transitions.map(function(tr) { + table.push( + [ + color.green(tr['id']), + tr['name'], + tr['to'] + ] + ) + }); + console.log(color.bold.blue( issueId.toUpperCase() ) + ' available transitions:'); + console.log(table.toString()); + return transitions + } + /** * Make issue transition */ - async makeTransition( issueId ){ + async makeTransition( issueId, transitionValue ){ const transitions = await this.getIssueTransitions(issueId); const _this = this; + const passedTransition = transitions.find(function(tr) { + if ( tr.id == transitionValue || tr.name == transitionValue ) { + return tr; + } + }); + if ( transitionValue && typeof(transitionValue) != typeof(true) && !passedTransition ) { + const listOfPossible = transitions.map((tr) => { return(`id: ${tr.id}, name: ${tr.name}`) }) + const listOfPossibleForPrint = JSON.stringify(listOfPossible, null, 2) + jira.showErrors( + `Transition '${transitionValue}' does not found. list of possible transition:\n${listOfPossibleForPrint}` + ); + return + } + if ( transitions.length == 1 ) { const obj = { @@ -451,6 +522,16 @@ export default class JiraIssues { return this.transitionIssue( issueId, obj ); + } else if (passedTransition) { + + const obj = { + transition: { + id: passedTransition.id + }, + to: passedTransition.to + } + return this.transitionIssue( issueId, obj ); + } else { var question = [ diff --git a/src/jira.js b/src/jira.js index 89cd00f..49537f4 100644 --- a/src/jira.js +++ b/src/jira.js @@ -186,8 +186,12 @@ class JiraCLI { /** * Search */ - cmdSearch( args ){ - this.issues.search( args ); + cmdSearch( args, options ){ + if ( options.jql ) { + this.issues.jqlSearch( options.jql ); + } else { + this.issues.search( args ); + } } /** @@ -281,8 +285,11 @@ class JiraCLI { // Assign issue to a user this.issues.assignIssue( args, options.assign ); } else if ( options.transition ) { - //Make issue transition + // Make issue transition this.issues.makeTransition( args, options.transition); + } else if ( options.transitions ) { + // Show all posible issue transitions + this.issues.listTransitions( args ); } else { // If none of the above options is passed then search for specific issue this.issues.findIssue( args );