jira-cli 0.2.2 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +18 -28
  3. data/bin/jira +3 -1
  4. data/lib/jira.rb +12 -6
  5. data/lib/jira/api.rb +10 -5
  6. data/lib/jira/auth_api.rb +11 -0
  7. data/lib/jira/command.rb +21 -1
  8. data/lib/jira/commands/all.rb +2 -2
  9. data/lib/jira/commands/assign.rb +2 -2
  10. data/lib/jira/commands/comment.rb +8 -98
  11. data/lib/jira/commands/comment/add.rb +46 -0
  12. data/lib/jira/commands/comment/delete.rb +80 -0
  13. data/lib/jira/commands/comment/list.rb +69 -0
  14. data/lib/jira/commands/comment/update.rb +88 -0
  15. data/lib/jira/commands/delete.rb +0 -2
  16. data/lib/jira/commands/describe.rb +0 -2
  17. data/lib/jira/commands/install.rb +39 -17
  18. data/lib/jira/commands/link.rb +4 -3
  19. data/lib/jira/commands/log.rb +7 -72
  20. data/lib/jira/commands/log/add.rb +50 -0
  21. data/lib/jira/commands/log/delete.rb +80 -0
  22. data/lib/jira/commands/log/list.rb +69 -0
  23. data/lib/jira/commands/log/update.rb +89 -0
  24. data/lib/jira/commands/new.rb +4 -6
  25. data/lib/jira/commands/rename.rb +0 -2
  26. data/lib/jira/commands/sprint.rb +3 -3
  27. data/lib/jira/commands/tickets.rb +0 -2
  28. data/lib/jira/commands/transition.rb +0 -2
  29. data/lib/jira/commands/vote.rb +5 -107
  30. data/lib/jira/commands/vote/add.rb +43 -0
  31. data/lib/jira/commands/vote/delete.rb +46 -0
  32. data/lib/jira/commands/vote/list.rb +59 -0
  33. data/lib/jira/commands/watch.rb +5 -108
  34. data/lib/jira/commands/watch/add.rb +43 -0
  35. data/lib/jira/commands/watch/delete.rb +46 -0
  36. data/lib/jira/commands/watch/list.rb +59 -0
  37. data/lib/jira/constants.rb +1 -1
  38. data/lib/jira/core.rb +9 -1
  39. data/lib/jira/sprint_api.rb +2 -18
  40. metadata +17 -5
  41. data/lib/jira/commands/commit.rb +0 -14
  42. data/lib/jira/legacy_api.rb +0 -102
  43. data/lib/jira/mixins.rb +0 -56
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8113060c03e8b470d3c0582958c574651b0aa650
4
- data.tar.gz: a9ed25712ca61c36f13e263b129922579cf78f46
3
+ metadata.gz: 90eee20531277d150c8a465d36bd465f87aadc09
4
+ data.tar.gz: 40144b5a1cb60ff669124475a6a651fa45b6691a
5
5
  SHA512:
6
- metadata.gz: 7fc9c0bcc93c5f425bbcc1dd076656d7b3ca3c50e2111ac814a34d7d10a02574c74f70c0202b55af585871bf29e1ac0c1bc5975252971cdcc79892733bb1471c
7
- data.tar.gz: 5ee4cb4c5adc1f38f3f4dece433a0b52cfadd3257c99e48e1b7d4073476f044a6b14eda73e5663233a674540325937eb9b00d4de72e88352acdf78deed18730a
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 # 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 # Add a comment to the input ticket
17
- jira commentd # Delete a comment to the input ticket
18
- jira comments # Lists the comments of the input ticket
19
- jira commentu # Update a comment to the input ticket
20
- jira commit # Commits uncommitted work with the ticket name and summary.
21
- jira delete # Deletes a ticket in JIRA and the git branch
22
- jira describe # Describes the input ticket
23
- jira install # Guides the user through JIRA installation
24
- jira link # Creates a link between two tickets in JIRA
25
- jira log # Logs work against the input ticket
26
- jira logd # Deletes work against the input ticket
27
- jira logs # Lists work against the input ticket
28
- jira logu # Updates work against the input ticket
29
- jira new # Creates a new ticket in JIRA and checks out the git branch
30
- jira rename # Updates the summary of the input ticket
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
- "running this command."
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
- # core logic and commands
4
- Dir.glob(
5
- File.dirname(File.absolute_path(__FILE__)) + '/jira/**/*.rb',
6
- &method(:require)
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
- private
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
@@ -0,0 +1,11 @@
1
+ module Jira
2
+ class AuthAPI < API
3
+
4
+ protected
5
+
6
+ def endpoint
7
+ "#{Jira::Core.url}/rest/auth/1"
8
+ end
9
+
10
+ end
11
+ end
data/lib/jira/command.rb CHANGED
@@ -1,4 +1,8 @@
1
- require 'tty-table'
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 }
@@ -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
@@ -1,5 +1,3 @@
1
- require_relative '../command'
2
-
3
1
  module Jira
4
2
  class CLI < Thor
5
3
 
@@ -26,6 +24,8 @@ module Jira
26
24
  failure: on_failure
27
25
  end
28
26
 
27
+ private
28
+
29
29
  def on_success
30
30
  -> do
31
31
  puts "Ticket #{ticket} assigned to #{name}."
@@ -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 "comment", "Add a comment to the input ticket"
5
- def comment(ticket=Jira::Core.ticket)
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