geera 1.2.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -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