geera 1.2.3

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.
@@ -0,0 +1,63 @@
1
+ module Geera
2
+ class Client
3
+ attr_reader :username
4
+ attr_reader :ctx
5
+
6
+ def initialize url
7
+ @ctx = Jira4R::JiraTool.new 2, url
8
+
9
+ # Make jira4r quiet
10
+ @ctx.logger = Logger.new nil
11
+ @username = nil
12
+ end
13
+
14
+ ###
15
+ # Login with +user+ and +password+
16
+ def login user, password
17
+ @username = user
18
+ @ctx.login user, password
19
+ end
20
+
21
+ ###
22
+ # Get the ticket with +number+. Returns a Geera::Ticket object.
23
+ #
24
+ # client.ticket 'BZ-123' # => #<Geera::Ticket>
25
+ def ticket number
26
+ Geera::Ticket.new self, number
27
+ end
28
+
29
+ ###
30
+ # Create a ticket using +params+. +params+ should be a hash, and *must*
31
+ # have a +project+, +summary+, and +description+ field.
32
+ #
33
+ # For example:
34
+ #
35
+ # client.create_ticket :project => 'AB',
36
+ # :summary => 'foo',
37
+ # :description => 'bar'
38
+ #
39
+ def create_ticket params
40
+ [:project, :summary].each do |param|
41
+ raise(ArgumentError, "#{param} required") unless params[param]
42
+ end
43
+
44
+ issue = Jira4R::V2::RemoteIssue.new
45
+ issue.project = params[:project]
46
+ issue.summary = params[:summary]
47
+ issue.description = params[:description]
48
+ issue.assignee = params[:assignee] || @username
49
+ issue.type = '1' #FIXME: wtf is this for?
50
+ issue.priority = '5'
51
+ issue = @ctx.createIssue issue
52
+ ticket issue.key
53
+ end
54
+
55
+ def filters
56
+ @ctx.getSavedFilters
57
+ end
58
+
59
+ def list filter
60
+ @ctx.getIssuesFromFilter filter
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,13 @@
1
+ module Geera
2
+ module Commands
3
+ class Assign < Geera::Commands::Command
4
+ def self.handle? command
5
+ 'assign' == command
6
+ end
7
+
8
+ def execute!
9
+ ticket.assign_to argv.shift
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,19 @@
1
+ module Geera
2
+ module Commands
3
+ class Command
4
+ attr_reader :geera, :number, :config, :argv
5
+
6
+ def initialize config, number, geera, argv
7
+ @argv = argv
8
+ @config = config
9
+ @number = number
10
+ @geera = geera
11
+ @ticket = nil
12
+ end
13
+
14
+ def ticket
15
+ @ticket ||= geera.ticket number
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,13 @@
1
+ module Geera
2
+ module Commands
3
+ class Estimate < Geera::Commands::Command
4
+ def self.handle? command
5
+ 'estimate' == command
6
+ end
7
+
8
+ def execute!
9
+ ticket.estimate = argv.shift
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,16 @@
1
+ module Geera
2
+ module Commands
3
+ class Filters < Geera::Commands::Command
4
+ def self.handle? command
5
+ 'filters' == command
6
+ end
7
+
8
+ def execute!
9
+ puts "# Your filters"
10
+ geera.filters.each do |filter|
11
+ puts " * #{filter.name.inspect}"
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,15 @@
1
+ module Geera
2
+ module Commands
3
+ class Fix < Geera::Commands::Command
4
+ def self.handle? command
5
+ 'fix' == command
6
+ end
7
+
8
+ def execute!
9
+ ticket.start! if ticket.startable?
10
+ ticket.fix! if ticket.fixable?
11
+ ticket.assign_to config['qa'] if config['qa']
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,29 @@
1
+ module Geera
2
+ module Commands
3
+ class List < Geera::Commands::Command
4
+ def self.handle? command
5
+ 'list' == command
6
+ end
7
+
8
+ def number
9
+ ## Ensure that +number+ is actually a number
10
+ begin
11
+ @number = Integer(super)
12
+ rescue ArgumentError
13
+ @number = geera.filters.find { |f| f.name == super }.id
14
+ end
15
+ end
16
+
17
+ def execute!
18
+ tickets = geera.list number
19
+ if tickets.empty?
20
+ puts "No Tickets found"
21
+ else
22
+ tickets.first(10).each do |ticket|
23
+ puts "#{ticket.key.ljust(8)} #{ticket.summary}"
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,13 @@
1
+ module Geera
2
+ module Commands
3
+ class Show < Geera::Commands::Command
4
+ def self.handle? command
5
+ 'show' == command
6
+ end
7
+
8
+ def execute!
9
+ puts ticket.inspect
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,17 @@
1
+ module Geera
2
+ module Commands
3
+ class Start < Geera::Commands::Command
4
+ def self.handle? command
5
+ 'start' == command
6
+ end
7
+
8
+ def execute!
9
+ unless ticket.startable?
10
+ abort "Ticket #{@number} is not startable. Available actions:\n" \
11
+ " - #{ticket.available_actions.map { |x| x.name + "\n" }.join(" - ")}"
12
+ end
13
+ ticket.start!
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,13 @@
1
+ module Geera
2
+ module Commands
3
+ class Take < Geera::Commands::Command
4
+ def self.handle? command
5
+ 'take' == command
6
+ end
7
+
8
+ def execute!
9
+ ticket.assign_to config['username']
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,10 @@
1
+ module Geera
2
+ class Executable
3
+ attr_reader :geera
4
+
5
+ def initialize config, argv, cmd_opts
6
+ @geera = Geera::Client.new(config['url'])
7
+ @geera.login(config['username'], config['password'])
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,116 @@
1
+ require 'erb'
2
+
3
+ module Geera
4
+ class Ticket
5
+ attr_reader :number
6
+
7
+ ###
8
+ # Create a new Ticket using Geera::Client +client+ and +ticket_number+.
9
+ # This constructor should not be called directly, use Geera::Client#ticket
10
+ # instead.
11
+ def initialize client, ticket_number
12
+ @client = client
13
+ @ctx = client.ctx
14
+ @number = ticket_number
15
+ @issue = nil
16
+ end
17
+
18
+ ###
19
+ # Add a comment to this ticket with +text+.
20
+ def comment text
21
+ @ctx.addComment @number, Jira4R::V2::RemoteComment.new(nil, text)
22
+ end
23
+
24
+ ###
25
+ # Returns a list of the actions that can be performed on this ticket.
26
+ def available_actions
27
+ @ctx.getAvailableActions @number
28
+ end
29
+
30
+ def startable?
31
+ available_actions.map { |a| a.name }.include?('Start')
32
+ end
33
+
34
+ ###
35
+ # Start this ticket.
36
+ def start!
37
+ action = available_actions.find { |x| x.name == 'Start' }
38
+ @ctx.progressWorkflowAction(@number, action.id, passthrough_attributes)
39
+ end
40
+
41
+ ###
42
+ # Is this ticket in a Fix able state?
43
+ def fixable?
44
+ available_actions.map { |a| a.name }.include?('Fix')
45
+ end
46
+
47
+ ###
48
+ # Fix this ticket.
49
+ def fix!
50
+ action = available_actions.find { |x| x.name == 'Fix' }
51
+ @ctx.progressWorkflowAction(@number, action.id, passthrough_attributes + [
52
+ Jira4R::V2::RemoteFieldValue.new('customfield_10176', @client.username),
53
+ ])
54
+ end
55
+
56
+ ###
57
+ # Assign this ticket to +username+
58
+ def assign_to username
59
+ assign = Jira4R::V2::RemoteFieldValue.new('assignee', username)
60
+ @ctx.updateIssue(@number, [assign])
61
+ end
62
+
63
+ def estimate= amount
64
+ assign = Jira4R::V2::RemoteFieldValue.new('timetracking', amount)
65
+ @ctx.updateIssue(@number, [assign])
66
+ end
67
+
68
+ def description
69
+ issue.description
70
+ end
71
+
72
+ def inspect
73
+ template = ERB.new <<-eoinspect
74
+ ## Reporter: <%= issue.reporter %>
75
+ ## Assignee: <%= issue.assignee %>
76
+ ## Priority: <%= issue.priority %>
77
+ ## Fix Versions: <%= issue.fixVersions.map {|fv| fv.name}.join(', ') %>
78
+
79
+ ## Summary
80
+
81
+ <%= issue.summary %>
82
+
83
+ ## Description:
84
+
85
+ <%= issue.description %>
86
+
87
+ ## Comments:
88
+ <% comments.each do |comment| %>
89
+ * <%= comment.author %>
90
+ <% comment.body.split(/[\r\n]+/).each do |line| %>
91
+ > <%= line %><% end %>
92
+ <% end %>
93
+
94
+ eoinspect
95
+ template.result binding
96
+ end
97
+
98
+ private
99
+ def issue
100
+ @issue ||= @ctx.getIssue(@number)
101
+ end
102
+
103
+ def comments
104
+ @ctx.getComments @number
105
+ end
106
+
107
+ def passthrough_attributes
108
+ [
109
+ Jira4R::V2::RemoteFieldValue.new('assignee', @client.username),
110
+ Jira4R::V2::RemoteFieldValue.new('description', description),
111
+ Jira4R::V2::RemoteFieldValue.new('priority', issue.priority),
112
+ ]
113
+ end
114
+
115
+ end
116
+ end
@@ -0,0 +1,12 @@
1
+ Summary: Enter your ticket summary here
2
+
3
+ ##### Description is below here #####
4
+
5
+ What I did:
6
+
7
+
8
+ What I expected:
9
+
10
+
11
+ What actually happened:
12
+
@@ -0,0 +1,27 @@
1
+ require "test/unit"
2
+ require "geera"
3
+ require 'flexmock/test_unit'
4
+
5
+ module Geera
6
+ module Commands
7
+ class TestAssign < Test::Unit::TestCase
8
+ def test_handle?
9
+ assert Assign.handle?('assign')
10
+ end
11
+
12
+ def test_execute!
13
+ recorder = Object.new
14
+ flexmock(recorder) do |thing|
15
+ thing.should_receive(:assign_to).with('foo').once
16
+ end
17
+
18
+ Class.new(Geera::Commands::Assign) {
19
+ def initialize ticket, argv
20
+ super(nil, nil, nil, argv)
21
+ @ticket = ticket
22
+ end
23
+ }.new(recorder, ['foo']).execute!
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,27 @@
1
+ require "test/unit"
2
+ require "geera"
3
+ require 'flexmock/test_unit'
4
+
5
+ module Geera
6
+ module Commands
7
+ class TestEstimate < Test::Unit::TestCase
8
+ def test_handle?
9
+ assert Estimate.handle?('estimate')
10
+ end
11
+
12
+ def test_execute!
13
+ recorder = Object.new
14
+ flexmock(recorder) do |thing|
15
+ thing.should_receive(:estimate=).with('3h').once
16
+ end
17
+
18
+ Class.new(Geera::Commands::Estimate) {
19
+ def initialize ticket, argv
20
+ super(nil, nil, nil, argv)
21
+ @ticket = ticket
22
+ end
23
+ }.new(recorder, %w{3h}).execute!
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,34 @@
1
+ require "test/unit"
2
+ require "geera"
3
+ require 'flexmock/test_unit'
4
+
5
+ module Geera
6
+ module Commands
7
+ class TestFilters < Test::Unit::TestCase
8
+ def test_handle?
9
+ assert Filters.handle?('filters')
10
+ end
11
+
12
+ def test_execute!
13
+ filter = Struct.new(:name).new('hi')
14
+
15
+ recorder = Object.new
16
+ flexmock(recorder) do |thing|
17
+ thing.should_receive(:filters).once.and_return([filter])
18
+ end
19
+
20
+ cmd = fake_command.new(recorder)
21
+ flexmock(cmd).should_receive(:puts)
22
+ cmd.execute!
23
+ end
24
+
25
+ def fake_command
26
+ Class.new(Geera::Commands::Filters) {
27
+ def initialize geera
28
+ super(nil, nil, geera, nil)
29
+ end
30
+ }
31
+ end
32
+ end
33
+ end
34
+ end