terjira 0.2.5 → 0.2.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/Gemfile.lock +1 -1
- data/README.md +6 -2
- data/lib/terjira.rb +1 -1
- data/lib/terjira/base_cli.rb +1 -8
- data/lib/terjira/client/field.rb +14 -4
- data/lib/terjira/client/issue.rb +2 -2
- data/lib/terjira/client/status_category.rb +20 -0
- data/lib/terjira/ext/jira_ruby.rb +21 -6
- data/lib/terjira/issue_cli.rb +16 -1
- data/lib/terjira/option_supportable.rb +1 -1
- data/lib/terjira/presenters/issue_presenter.rb +24 -11
- data/lib/terjira/presenters/sprint_presenter.rb +1 -1
- data/lib/terjira/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a25d4e42aca093fd16ddd3aa3a653132f7716549
|
4
|
+
data.tar.gz: f1d2c6ff0b4c3aa3ee421f73d0d153cb67fc73f0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f621c41ba152ddada71cd29cfd993ebbef00351a5a56e54ec4b9989db2de2297232c48fc977bc7dd86cd35741d49f362aadff7cf34081508310c41cae179b60c
|
7
|
+
data.tar.gz: a78015b6021e980146aa79dd1b55a7cf7a89975df31ddee8076b68126748b3088e3ce205956efa29a73f1c0acec26fe780565ed6409aef70d45a2c41bb283dcf
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
# Terjira
|
7
7
|
|
8
|
-
Terjira is an interactive and easy to use command line interface (or Application) for Jira. You do not need to remember resource key or id. Terjira suggests it with interactive prompt.
|
8
|
+
Terjira is an interactive and easy to use command line interface (or Application) for Jira. You do not need to remember the resource key or id. Terjira suggests it with an interactive prompt.
|
9
9
|
|
10
10
|
Your Jira must support Rest API 2.0 and Agile Rest API 1.0
|
11
11
|
|
12
|
-
##
|
12
|
+
## Demo
|
13
13
|
[Watch full demo](https://www.youtube.com/watch?v=T0hbhaXtH-Y)
|
14
14
|
|
15
15
|
[![Sample](./dev/demo.gif)](https://www.youtube.com/watch?v=T0hbhaXtH-Y)
|
@@ -58,6 +58,9 @@ Issue:
|
|
58
58
|
# default assignee option is current loggined user
|
59
59
|
# To show issues of all users(include no assignee)
|
60
60
|
# pass `--assignee ALL` option.
|
61
|
+
jira issue jql "[QUERY]" # Search issues with JQL
|
62
|
+
# ex)
|
63
|
+
# jira issue jql "project = 'TEST' AND summary ~ 'authentication'"
|
61
64
|
jira issue [ISSUE_KEY] # Show detail of the issue
|
62
65
|
jira issue assign [ISSUE_KEY] ([ASSIGNEE]) # Assign the issue to user
|
63
66
|
jira issue comment [ISSUE_KEY] # Write comment on the issue
|
@@ -72,6 +75,7 @@ Issue:
|
|
72
75
|
|
73
76
|
## Todo
|
74
77
|
**Contributions are welcome!**
|
78
|
+
- [x] Add JQL command for find issues
|
75
79
|
- [ ] Manage worklog and estimate of issues
|
76
80
|
- [ ] Manage component and version of issues
|
77
81
|
- [ ] Track history of transitions
|
data/lib/terjira.rb
CHANGED
@@ -33,7 +33,7 @@ module Terjira
|
|
33
33
|
Client::Base.expire_auth_options
|
34
34
|
end
|
35
35
|
|
36
|
-
desc 'project SUBCOMMAND ...ARGS', 'Manage
|
36
|
+
desc 'project SUBCOMMAND ...ARGS', 'Manage projects'
|
37
37
|
subcommand 'project', ProjectCLI
|
38
38
|
|
39
39
|
desc 'board SUBCOMMAND ...ARGS', 'Manage boards'
|
data/lib/terjira/base_cli.rb
CHANGED
@@ -2,16 +2,9 @@ require 'thor'
|
|
2
2
|
|
3
3
|
require_relative 'option_supportable'
|
4
4
|
Dir[File.dirname(__FILE__) + '/presenters/*.rb'].each { |f| require f }
|
5
|
+
Dir[File.dirname(__FILE__) + '/client/*.rb'].each { |f| require f }
|
5
6
|
|
6
7
|
module Terjira
|
7
|
-
# Jira client based on jira-ruby gem
|
8
|
-
module Client
|
9
|
-
%w(Base Field Issuetype Project Board Sprint Issue User
|
10
|
-
Status Resolution Priority RapidView Agile).each do |klass|
|
11
|
-
autoload klass, "terjira/client/#{klass.gsub(/(.)([A-Z](?=[a-z]))/,'\1_\2').downcase}"
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
8
|
class BaseCLI < Thor
|
16
9
|
include OptionSupportable
|
17
10
|
|
data/lib/terjira/client/field.rb
CHANGED
@@ -3,6 +3,8 @@ require_relative 'base'
|
|
3
3
|
module Terjira
|
4
4
|
module Client
|
5
5
|
class Field < Base
|
6
|
+
CACHE_PATH = "resource/fields".freeze
|
7
|
+
|
6
8
|
class << self
|
7
9
|
def all
|
8
10
|
@all_fields ||= file_cache.fetch("all") do
|
@@ -14,16 +16,24 @@ module Terjira
|
|
14
16
|
all.find { |field| field.key == key }
|
15
17
|
end
|
16
18
|
|
19
|
+
def find_by_name(name)
|
20
|
+
all.find { |field| field.name == name }
|
21
|
+
end
|
22
|
+
|
17
23
|
def epic_name
|
18
|
-
|
24
|
+
find_by_name('Epic Name')
|
25
|
+
end
|
26
|
+
|
27
|
+
def epic_link
|
28
|
+
find_by_name('Epic Link')
|
19
29
|
end
|
20
30
|
|
21
|
-
def
|
22
|
-
|
31
|
+
def story_points
|
32
|
+
find_by_name('Story Points')
|
23
33
|
end
|
24
34
|
|
25
35
|
def file_cache
|
26
|
-
Terjira::FileCache.new(
|
36
|
+
Terjira::FileCache.new(CACHE_PATH, 60 * 60 * 24)
|
27
37
|
end
|
28
38
|
end
|
29
39
|
end
|
data/lib/terjira/client/issue.rb
CHANGED
@@ -4,12 +4,12 @@ module Terjira
|
|
4
4
|
module Client
|
5
5
|
class Issue < Base
|
6
6
|
class << self
|
7
|
-
delegate :
|
7
|
+
delegate :jql, :find, to: :resource
|
8
8
|
|
9
9
|
def all(options = {})
|
10
10
|
return resource.all if options.blank?
|
11
11
|
max_results = options.delete(:max_results) || 500
|
12
|
-
|
12
|
+
jql(build_jql(options), max_results: max_results)
|
13
13
|
end
|
14
14
|
|
15
15
|
def all_epic_issues(epic)
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require_relative 'base'
|
2
|
+
|
3
|
+
module Terjira
|
4
|
+
module Client
|
5
|
+
class StatusCategory < Base
|
6
|
+
class << self
|
7
|
+
def all
|
8
|
+
@all_statuscategory ||= file_cache.fetch("all") do
|
9
|
+
resp = api_get "statuscategory"
|
10
|
+
resp.map { |category| build(category) }
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def file_cache
|
15
|
+
Terjira::FileCache.new("resource/statuscategory", 60 * 60 * 48)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -27,12 +27,6 @@ module JIRA
|
|
27
27
|
end
|
28
28
|
|
29
29
|
module Resource
|
30
|
-
class BoardFactory < JIRA::BaseFactory # :nodoc:
|
31
|
-
end
|
32
|
-
|
33
|
-
class EpicFactory < JIRA::BaseFactory # :nodoc:
|
34
|
-
end
|
35
|
-
|
36
30
|
class Board < JIRA::Base
|
37
31
|
def self.key_attribute; :id; end
|
38
32
|
end
|
@@ -41,6 +35,10 @@ module JIRA
|
|
41
35
|
def self.key_attribute; :key; end
|
42
36
|
end
|
43
37
|
|
38
|
+
class StatusCategory < JIRA::Base
|
39
|
+
def self.key_attribute; :name; end
|
40
|
+
end
|
41
|
+
|
44
42
|
class User
|
45
43
|
def self.key_attribute; :name; end
|
46
44
|
end
|
@@ -60,12 +58,29 @@ module JIRA
|
|
60
58
|
class Resolution
|
61
59
|
def self.key_attribute; :name; end
|
62
60
|
end
|
61
|
+
|
62
|
+
class BoardFactory < JIRA::BaseFactory
|
63
|
+
end
|
64
|
+
|
65
|
+
class EpicFactory < JIRA::BaseFactory
|
66
|
+
end
|
67
|
+
|
68
|
+
class StatusCategoryFactory < JIRA::BaseFactory
|
69
|
+
end
|
63
70
|
end
|
64
71
|
|
65
72
|
class Client
|
66
73
|
def Board # :nodoc:
|
67
74
|
JIRA::Resource::BoardFactory.new(self)
|
68
75
|
end
|
76
|
+
|
77
|
+
def Epic
|
78
|
+
JIRA::Resource::EpicFactory.new(self)
|
79
|
+
end
|
80
|
+
|
81
|
+
def StatusCategory
|
82
|
+
JIRA::Resource::StatusCategoryFactory.new(self)
|
83
|
+
end
|
69
84
|
end
|
70
85
|
end
|
71
86
|
|
data/lib/terjira/issue_cli.rb
CHANGED
@@ -34,7 +34,7 @@ module Terjira
|
|
34
34
|
map ls: :list
|
35
35
|
def list
|
36
36
|
opts = suggest_options
|
37
|
-
opts[:statusCategory] ||=
|
37
|
+
opts[:statusCategory] ||= default_status_categories unless opts[:status]
|
38
38
|
opts[:assignee] ||= current_username
|
39
39
|
opts.delete(:assignee) if opts[:assignee] =~ /^all/i
|
40
40
|
|
@@ -42,6 +42,15 @@ module Terjira
|
|
42
42
|
render_issues(issues)
|
43
43
|
end
|
44
44
|
|
45
|
+
desc 'jql "[QUERY]"', "Search issues with JQL"
|
46
|
+
long_desc <<-EXAMPLE
|
47
|
+
jira issue jql "project = 'IST' AND assignee = currentuser()"
|
48
|
+
EXAMPLE
|
49
|
+
def jql(*query)
|
50
|
+
jql = query.join(" ")
|
51
|
+
render_issues Client::Issue.jql(jql)
|
52
|
+
end
|
53
|
+
|
45
54
|
desc 'new', 'Create an issue'
|
46
55
|
jira_options :summary, :description, :project, :issuetype,
|
47
56
|
:priority, :assignee, :parent, :epiclink
|
@@ -121,5 +130,11 @@ module Terjira
|
|
121
130
|
issue = client_class.trans(issue, opts)
|
122
131
|
render_issue_detail(issue)
|
123
132
|
end
|
133
|
+
|
134
|
+
no_commands do
|
135
|
+
def default_status_categories
|
136
|
+
Client::StatusCategory.all.reject { |category| category.key =~ /done/i }.map(&:name)
|
137
|
+
end
|
138
|
+
end
|
124
139
|
end
|
125
140
|
end
|
@@ -64,9 +64,10 @@ module Terjira
|
|
64
64
|
|
65
65
|
<%= pastel.underline.bold(issue.summary) %>
|
66
66
|
|
67
|
-
<%= bold('Type') %>: <%= colorize_issue_type(issue.issuetype) %>\s\s\s<%= bold('Status') %>: <%= colorize_issue_stastus(issue.status) %>\s\s\s<%= bold('
|
67
|
+
<%= bold('Type') %>: <%= colorize_issue_type(issue.issuetype) %>\s\s\s<%= bold('Status') %>: <%= colorize_issue_stastus(issue.status) %>\s\s\s<%= bold('Priority') %>: <%= colorize_priority(issue.priority, title: true) %>
|
68
68
|
<% if issue.parent.nil? -%>
|
69
|
-
|
69
|
+
|
70
|
+
<%= bold('Epic Link') %>: <%= issue.try(:epic).try(:key) %> <%= issue.try(:epic).try(:name) || dim_none %>
|
70
71
|
<% end -%>
|
71
72
|
<% if issue.try(:parent) && issue.epic.nil? -%>
|
72
73
|
<%= bold('Parent') %>: <%= issue.parent.key %>
|
@@ -74,21 +75,16 @@ module Terjira
|
|
74
75
|
<% if issue.try(:sprint) -%>
|
75
76
|
<%= bold('Sprint') %>: <%= colorize_sprint_state(issue.try(:sprint).try(:state)) %> <%= issue.try(:sprint).try(:id) %>. <%= issue.try(:sprint).try(:name) %>
|
76
77
|
<% end -%>
|
78
|
+
<% if estimate = issue_estimate(issue) -%>
|
79
|
+
|
80
|
+
<%= estimate[0] %>: <%= estimate[1] %>
|
81
|
+
<% end -%>
|
77
82
|
|
78
83
|
<%= bold('Assignee') %>: <%= username(issue.assignee) %>
|
79
84
|
<%= bold('Reporter') %>: <%= username(issue.reporter) %>
|
80
85
|
|
81
86
|
<%= bold('Description') %>
|
82
87
|
<%= issue.description || dim_none %>
|
83
|
-
<% if issue.try(:timetracking).is_a? Hash -%>
|
84
|
-
|
85
|
-
<%= bold('Estimate') %>
|
86
|
-
<% if issue.timetracking['originalEstimate'] -%>
|
87
|
-
<%= issue.timetracking['originalEstimate'] %> / <%= issue.timetracking['remainingEstimate'] %>
|
88
|
-
<% else -%>
|
89
|
-
<%= dim_none %>
|
90
|
-
<% end -%>
|
91
|
-
<% end -%>
|
92
88
|
<% if issue.try(:environment) -%>
|
93
89
|
|
94
90
|
<%= bold('Environment') %>
|
@@ -184,6 +180,23 @@ module Terjira
|
|
184
180
|
pastel.decorate(title, infos[0])
|
185
181
|
end
|
186
182
|
|
183
|
+
# Extract estimate or story points
|
184
|
+
# @return Array, first element is title and second is value
|
185
|
+
def issue_estimate(issue)
|
186
|
+
field = Client::Field.story_points
|
187
|
+
story_points = issue.try(field.key) if field.respond_to? :key
|
188
|
+
return [bold('Story Points'), story_points] if story_points
|
189
|
+
|
190
|
+
return unless issue.try(:timetracking).is_a? Hash
|
191
|
+
|
192
|
+
if origin = issue.timetracking['originalEstimate']
|
193
|
+
remain = issue.timetracking['remainingEstimate']
|
194
|
+
[bold('Estimate'), "#{remain} / #{origin}"]
|
195
|
+
else
|
196
|
+
[bold('Estimate'), dim_none]
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
187
200
|
def extract_status_names(issues)
|
188
201
|
issue_names = issues.sort_by do |issue|
|
189
202
|
status_key = %w(new indeterminate done)
|
data/lib/terjira/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: terjira
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jaehyun Shin
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-12-
|
11
|
+
date: 2016-12-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thor
|
@@ -235,6 +235,7 @@ files:
|
|
235
235
|
- lib/terjira/client/resolution.rb
|
236
236
|
- lib/terjira/client/sprint.rb
|
237
237
|
- lib/terjira/client/status.rb
|
238
|
+
- lib/terjira/client/status_category.rb
|
238
239
|
- lib/terjira/client/user.rb
|
239
240
|
- lib/terjira/ext/jira_ruby.rb
|
240
241
|
- lib/terjira/ext/tty_prompt.rb
|