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.
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