jira-cli 0.2.2 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +18 -28
- data/bin/jira +3 -1
- data/lib/jira.rb +12 -6
- data/lib/jira/api.rb +10 -5
- data/lib/jira/auth_api.rb +11 -0
- data/lib/jira/command.rb +21 -1
- data/lib/jira/commands/all.rb +2 -2
- data/lib/jira/commands/assign.rb +2 -2
- data/lib/jira/commands/comment.rb +8 -98
- data/lib/jira/commands/comment/add.rb +46 -0
- data/lib/jira/commands/comment/delete.rb +80 -0
- data/lib/jira/commands/comment/list.rb +69 -0
- data/lib/jira/commands/comment/update.rb +88 -0
- data/lib/jira/commands/delete.rb +0 -2
- data/lib/jira/commands/describe.rb +0 -2
- data/lib/jira/commands/install.rb +39 -17
- data/lib/jira/commands/link.rb +4 -3
- data/lib/jira/commands/log.rb +7 -72
- data/lib/jira/commands/log/add.rb +50 -0
- data/lib/jira/commands/log/delete.rb +80 -0
- data/lib/jira/commands/log/list.rb +69 -0
- data/lib/jira/commands/log/update.rb +89 -0
- data/lib/jira/commands/new.rb +4 -6
- data/lib/jira/commands/rename.rb +0 -2
- data/lib/jira/commands/sprint.rb +3 -3
- data/lib/jira/commands/tickets.rb +0 -2
- data/lib/jira/commands/transition.rb +0 -2
- data/lib/jira/commands/vote.rb +5 -107
- data/lib/jira/commands/vote/add.rb +43 -0
- data/lib/jira/commands/vote/delete.rb +46 -0
- data/lib/jira/commands/vote/list.rb +59 -0
- data/lib/jira/commands/watch.rb +5 -108
- data/lib/jira/commands/watch/add.rb +43 -0
- data/lib/jira/commands/watch/delete.rb +46 -0
- data/lib/jira/commands/watch/list.rb +59 -0
- data/lib/jira/constants.rb +1 -1
- data/lib/jira/core.rb +9 -1
- data/lib/jira/sprint_api.rb +2 -18
- metadata +17 -5
- data/lib/jira/commands/commit.rb +0 -14
- data/lib/jira/legacy_api.rb +0 -102
- data/lib/jira/mixins.rb +0 -56
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 90eee20531277d150c8a465d36bd465f87aadc09
|
4
|
+
data.tar.gz: 40144b5a1cb60ff669124475a6a651fa45b6691a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 74fad1cbbdc11727a57c82fa39e3184eb7d80a5b199aac67eabbc9fe14acc510412f3b30a83ad805abd89ea30dc19eddd3517195a43829bfd400ff10d04f01f4
|
7
|
+
data.tar.gz: fb6e29c2710f0b74bb3000cb767799aff6f0bc82c5bb9199ed9cad29a91acb7646f0ab7eb1c59f543bc2dcfe7da546853f103dd47a49d9d40dd3abb18528df71
|
data/README.md
CHANGED
@@ -10,34 +10,24 @@ Ruby gem CLI tool used to manage JIRA workflows leveraging git
|
|
10
10
|
|
11
11
|
### Available Commands
|
12
12
|
|
13
|
-
jira all
|
14
|
-
jira assign
|
15
|
-
jira attachments
|
16
|
-
jira comment
|
17
|
-
jira
|
18
|
-
jira
|
19
|
-
jira
|
20
|
-
jira
|
21
|
-
jira
|
22
|
-
jira
|
23
|
-
jira
|
24
|
-
jira
|
25
|
-
jira
|
26
|
-
jira
|
27
|
-
jira
|
28
|
-
jira
|
29
|
-
jira
|
30
|
-
jira
|
31
|
-
jira tickets # List the tickets of the input username
|
32
|
-
jira transition # Transitions the input ticket to the next state
|
33
|
-
jira unvote # Unvote against the input ticket
|
34
|
-
jira unwatch # Unwatch against the input ticket
|
35
|
-
jira version # Displays the version
|
36
|
-
jira vote # Vote against the input ticket
|
37
|
-
jira votes # List the votes of the input ticket
|
38
|
-
jira watch # Watch against the input ticket
|
39
|
-
jira watchers # List the watchers of the input ticket
|
40
|
-
jira help [COMMAND] # Describe available commands or one specific command
|
13
|
+
jira all # Describes all local branches that match JIRA ticketing syntax
|
14
|
+
jira assign # Assign a ticket to a user
|
15
|
+
jira attachments # View ticket attachments
|
16
|
+
jira comment <command> # Commands for comment operations in JIRA
|
17
|
+
jira delete # Deletes a ticket in JIRA and the git branch
|
18
|
+
jira describe # Describes the input ticket
|
19
|
+
jira help [COMMAND] # Describe available commands or one specific command
|
20
|
+
jira install # Guides the user through JIRA CLI installation
|
21
|
+
jira link # Creates a link between two tickets in JIRA
|
22
|
+
jira log <command> # Commands for logging operations in JIRA
|
23
|
+
jira new # Creates a new ticket in JIRA and checks out the git branch
|
24
|
+
jira rename # Updates the summary of the input ticket
|
25
|
+
jira sprint # Lists sprint info
|
26
|
+
jira tickets # List the tickets of the input username
|
27
|
+
jira transition # Transitions the input ticket to the next state
|
28
|
+
jira version # Displays the version
|
29
|
+
jira vote <command> # Commands for voting operations in JIRA
|
30
|
+
jira watch <command> # Commands for watching tickets in JIRA
|
41
31
|
|
42
32
|
### Gem Installation
|
43
33
|
|
data/bin/jira
CHANGED
@@ -3,10 +3,12 @@
|
|
3
3
|
require 'jira'
|
4
4
|
begin
|
5
5
|
Jira::CLI.start
|
6
|
+
rescue Faraday::Error
|
7
|
+
puts "JIRA failed connect, you may need to rerun 'jira install'"
|
6
8
|
rescue GitException
|
7
9
|
puts "JIRA commands can only be run within a git repository."
|
8
10
|
rescue InstallationException
|
9
11
|
puts "Please run #{Jira::Format.summary('jira install')} before "\
|
10
|
-
|
12
|
+
"running this command."
|
11
13
|
rescue Interrupt
|
12
14
|
end
|
data/lib/jira.rb
CHANGED
@@ -1,10 +1,16 @@
|
|
1
|
-
# dependencies
|
1
|
+
# external dependencies
|
2
2
|
require 'thor'
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
3
|
+
require 'tty-table'
|
4
|
+
require 'inifile'
|
5
|
+
require 'tty-prompt'
|
6
|
+
require 'json'
|
7
|
+
require 'faraday'
|
8
|
+
require 'faraday_middleware'
|
9
|
+
# internal dependencies
|
10
|
+
require 'jira/exceptions'
|
11
|
+
require 'jira/constants'
|
12
|
+
require 'jira/command'
|
13
|
+
require 'jira/format'
|
8
14
|
|
9
15
|
module Jira
|
10
16
|
class CLI < Thor
|
data/lib/jira/api.rb
CHANGED
@@ -1,6 +1,3 @@
|
|
1
|
-
require 'faraday'
|
2
|
-
require 'faraday_middleware'
|
3
|
-
|
4
1
|
module Jira
|
5
2
|
class API
|
6
3
|
|
@@ -24,7 +21,7 @@ module Jira
|
|
24
21
|
process(response, options)
|
25
22
|
end
|
26
23
|
|
27
|
-
|
24
|
+
protected
|
28
25
|
|
29
26
|
def process(response, options)
|
30
27
|
json = response.body || {}
|
@@ -62,7 +59,15 @@ module Jira
|
|
62
59
|
end
|
63
60
|
|
64
61
|
def headers
|
65
|
-
{ 'Content-Type' => 'application/json' }
|
62
|
+
{ 'Content-Type' => 'application/json' }.merge(cookies)
|
63
|
+
end
|
64
|
+
|
65
|
+
def cookies
|
66
|
+
cookie = Jira::Core.cookie
|
67
|
+
unless cookie.empty?
|
68
|
+
return { 'cookie' => "#{cookie[:name]}=#{cookie[:value]}" }
|
69
|
+
end
|
70
|
+
{}
|
66
71
|
end
|
67
72
|
|
68
73
|
end
|
data/lib/jira/command.rb
CHANGED
@@ -1,4 +1,8 @@
|
|
1
|
-
|
1
|
+
# internal dependencies
|
2
|
+
require 'jira/api'
|
3
|
+
require 'jira/sprint_api'
|
4
|
+
require 'jira/auth_api'
|
5
|
+
require 'jira/core'
|
2
6
|
|
3
7
|
module Jira
|
4
8
|
module Command
|
@@ -14,6 +18,18 @@ module Jira
|
|
14
18
|
@api ||= Jira::API.new
|
15
19
|
end
|
16
20
|
|
21
|
+
def auth_api
|
22
|
+
@auth_api ||= Jira::AuthAPI.new
|
23
|
+
end
|
24
|
+
|
25
|
+
def body
|
26
|
+
@body ||= (
|
27
|
+
comment = io.ask("Leave a comment for ticket #{ticket}:").strip
|
28
|
+
comment = comment.gsub(/\@[a-zA-Z]+/,'[~\0]') || comment
|
29
|
+
comment.gsub('[~@','[~') || comment
|
30
|
+
)
|
31
|
+
end
|
32
|
+
|
17
33
|
def sprint_api
|
18
34
|
@sprint_api ||= Jira::SprintAPI.new
|
19
35
|
end
|
@@ -34,3 +50,7 @@ module Jira
|
|
34
50
|
end
|
35
51
|
end
|
36
52
|
end
|
53
|
+
|
54
|
+
# load commands
|
55
|
+
commands_directory = File.join(File.dirname(__FILE__), 'commands', '*.rb')
|
56
|
+
Dir[commands_directory].each { |file| require file }
|
data/lib/jira/commands/all.rb
CHANGED
@@ -28,8 +28,8 @@ module Jira
|
|
28
28
|
json['issues'].map do |issue|
|
29
29
|
[
|
30
30
|
issue['key'],
|
31
|
-
issue['fields']['assignee']['name'],
|
32
|
-
issue['fields']['status']['name'],
|
31
|
+
issue['fields']['assignee']['name'] || 'Unassigned',
|
32
|
+
issue['fields']['status']['name'] || 'Unknown',
|
33
33
|
truncate(issue['fields']['summary'], 45)
|
34
34
|
]
|
35
35
|
end
|
data/lib/jira/commands/assign.rb
CHANGED
@@ -1,104 +1,14 @@
|
|
1
|
+
require 'jira/commands/comment/add'
|
2
|
+
require 'jira/commands/comment/delete'
|
3
|
+
require 'jira/commands/comment/list'
|
4
|
+
require 'jira/commands/comment/update'
|
5
|
+
|
1
6
|
module Jira
|
2
7
|
class CLI < Thor
|
3
8
|
|
4
|
-
desc
|
5
|
-
|
6
|
-
comment = self.get_comment_body(ticket)
|
7
|
-
puts "No comment posted." and return if comment.empty?
|
8
|
-
|
9
|
-
self.api.post("issue/#{ticket}/comment", { body: comment }) do |json|
|
10
|
-
puts "Successfully posted your comment."
|
11
|
-
return
|
12
|
-
end
|
13
|
-
puts "No comment posted."
|
14
|
-
end
|
15
|
-
|
16
|
-
desc "commentd", "Delete a comment to the input ticket"
|
17
|
-
def commentd(ticket=Jira::Core.ticket)
|
18
|
-
self.comment_delete(ticket)
|
19
|
-
end
|
20
|
-
|
21
|
-
desc "comments", "Lists the comments of the input ticket"
|
22
|
-
def comments(ticket=Jira::Core.ticket)
|
23
|
-
self.api.get("issue/#{ticket}") do |json|
|
24
|
-
comments = json['fields']['comment']['comments']
|
25
|
-
if comments.count > 0
|
26
|
-
comments.each do |comment|
|
27
|
-
author = comment['author']['displayName']
|
28
|
-
time = Time.parse(comment['updated'])
|
29
|
-
body = comment['body']
|
30
|
-
|
31
|
-
printf "[%2d]", comments.index(comment)
|
32
|
-
puts " #{Jira::Format.user(author)} @ "\
|
33
|
-
"#{Jira::Format.time(time)}:\n"\
|
34
|
-
"#{Jira::Format.comment(body)}"
|
35
|
-
end
|
36
|
-
else
|
37
|
-
puts "There are no comments on ticket #{ticket}."
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
desc "commentu", "Update a comment to the input ticket"
|
43
|
-
def commentu(ticket=Jira::Core.ticket)
|
44
|
-
self.comment_update(ticket)
|
45
|
-
end
|
46
|
-
|
47
|
-
protected
|
48
|
-
|
49
|
-
def comment_delete(ticket)
|
50
|
-
comments(ticket) if self.io.yes?("List comments for ticket #{ticket}?")
|
51
|
-
|
52
|
-
index = self.get_type_of_index("comment", "delete")
|
53
|
-
puts "No comment deleted." and return if index < 0
|
54
|
-
|
55
|
-
self.api.get("issue/#{ticket}") do |json|
|
56
|
-
comments = json['fields']['comment']['comments']
|
57
|
-
if index < comments.count
|
58
|
-
id = comments[index]['id']
|
59
|
-
self.api.delete("issue/#{ticket}/comment/#{id}") do |json|
|
60
|
-
puts "Successfully deleted your comment."
|
61
|
-
return
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
65
|
-
puts "No comment deleted."
|
66
|
-
end
|
67
|
-
|
68
|
-
def comment_update(ticket)
|
69
|
-
comments(ticket) if self.io.yes?("List comments for ticket #{ticket}?")
|
70
|
-
|
71
|
-
index = self.get_type_of_index("comment", "update")
|
72
|
-
puts "No comment updated." and return if index < 0
|
73
|
-
|
74
|
-
comment = self.get_comment_body(ticket)
|
75
|
-
puts "No comment updated." and return if comment.empty?
|
76
|
-
|
77
|
-
self.api.get("issue/#{ticket}") do |json|
|
78
|
-
comments = json['fields']['comment']['comments']
|
79
|
-
id = comments[index]['id']
|
80
|
-
self.api.put("issue/#{ticket}/comment/#{id}", { body: comment }) do |json|
|
81
|
-
puts "Successfully updated your comment."
|
82
|
-
return
|
83
|
-
end
|
84
|
-
end
|
85
|
-
puts "No comment updated."
|
86
|
-
end
|
87
|
-
|
88
|
-
#
|
89
|
-
# Prompts the user for a comment body, strips it, then
|
90
|
-
# returns a substituted version of it
|
91
|
-
#
|
92
|
-
# @return comment [String] asked comment body
|
93
|
-
#
|
94
|
-
def get_comment_body(ticket)
|
95
|
-
comment = self.io.ask("Leave a comment for ticket #{ticket}:").strip
|
96
|
-
temp = comment.gsub(/\@[a-zA-Z]+/,'[~\0]')
|
97
|
-
temp = comment if temp.nil?
|
98
|
-
temp = temp.gsub('[~@','[~')
|
99
|
-
comment = temp if !temp.nil?
|
100
|
-
comment
|
101
|
-
end
|
9
|
+
desc 'comment <command>', 'Commands for comment operations in JIRA'
|
10
|
+
subcommand 'comment', Comment
|
102
11
|
|
103
12
|
end
|
13
|
+
|
104
14
|
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module Jira
|
2
|
+
class Comment < Thor
|
3
|
+
|
4
|
+
desc 'add', 'Add a comment to the input ticket'
|
5
|
+
def add(ticket=Jira::Core.ticket)
|
6
|
+
Command::Comment::Add.new(ticket).run
|
7
|
+
end
|
8
|
+
|
9
|
+
end
|
10
|
+
|
11
|
+
module Command
|
12
|
+
module Comment
|
13
|
+
class Add < Base
|
14
|
+
|
15
|
+
attr_accessor :ticket
|
16
|
+
|
17
|
+
def initialize(ticket)
|
18
|
+
self.ticket = ticket
|
19
|
+
end
|
20
|
+
|
21
|
+
def run
|
22
|
+
return if body.empty?
|
23
|
+
api.post "issue/#{ticket}/comment",
|
24
|
+
params: params,
|
25
|
+
success: on_success,
|
26
|
+
failure: on_failure
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def params
|
32
|
+
{ body: body }
|
33
|
+
end
|
34
|
+
|
35
|
+
def on_success
|
36
|
+
->{ puts "Successfully posted your comment." }
|
37
|
+
end
|
38
|
+
|
39
|
+
def on_failure
|
40
|
+
->{ puts "No comment posted." }
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
module Jira
|
2
|
+
class Comment < Thor
|
3
|
+
|
4
|
+
desc 'delete', 'Delete a comment to the input ticket'
|
5
|
+
def delete(ticket=Jira::Core.ticket)
|
6
|
+
Command::Comment::Delete.new(ticket).run
|
7
|
+
end
|
8
|
+
|
9
|
+
end
|
10
|
+
|
11
|
+
module Command
|
12
|
+
module Comment
|
13
|
+
class Delete < Base
|
14
|
+
|
15
|
+
attr_accessor :ticket
|
16
|
+
|
17
|
+
def initialize(ticket)
|
18
|
+
self.ticket = ticket
|
19
|
+
end
|
20
|
+
|
21
|
+
def run
|
22
|
+
return unless comments?
|
23
|
+
api.delete endpoint,
|
24
|
+
success: on_success,
|
25
|
+
failure: on_failure
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def comments?
|
31
|
+
if json.empty?
|
32
|
+
puts "Ticket #{ticket} has no comments."
|
33
|
+
return false
|
34
|
+
end
|
35
|
+
true
|
36
|
+
end
|
37
|
+
|
38
|
+
def endpoint
|
39
|
+
"issue/#{ticket}/comment/#{to_delete['id']}"
|
40
|
+
end
|
41
|
+
|
42
|
+
def on_success
|
43
|
+
->{ puts "Successfully deleted comment from #{to_delete['updateAuthor']['displayName']}" }
|
44
|
+
end
|
45
|
+
|
46
|
+
def on_failure
|
47
|
+
->{ puts "No comment deleted." }
|
48
|
+
end
|
49
|
+
|
50
|
+
def to_delete
|
51
|
+
@to_delete ||= comments[
|
52
|
+
io.select("Select a comment to delete:", comments.keys)
|
53
|
+
]
|
54
|
+
end
|
55
|
+
|
56
|
+
def comments
|
57
|
+
@comments ||= (
|
58
|
+
comments = {}
|
59
|
+
json.each do |comment|
|
60
|
+
comments[description_for(comment)] = comment
|
61
|
+
end
|
62
|
+
comments
|
63
|
+
)
|
64
|
+
end
|
65
|
+
|
66
|
+
def description_for(comment)
|
67
|
+
author = comment['updateAuthor']['displayName']
|
68
|
+
updated_at = Jira::Format.time(Time.parse(comment['updated']))
|
69
|
+
body = comment['body'].gsub("\r\n|\r|\n", ";")
|
70
|
+
truncate("#{author} @ #{updated_at}: #{body}", 160)
|
71
|
+
end
|
72
|
+
|
73
|
+
def json
|
74
|
+
@json ||= api.get("issue/#{ticket}/comment")['comments']
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|