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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 69d3616c8893bba879da6ebdc366da41d27c024a
4
- data.tar.gz: 8374ec2e15f699f16d84045d9ba017d981a95de9
3
+ metadata.gz: a25d4e42aca093fd16ddd3aa3a653132f7716549
4
+ data.tar.gz: f1d2c6ff0b4c3aa3ee421f73d0d153cb67fc73f0
5
5
  SHA512:
6
- metadata.gz: c3648d9c23d61e971ac7c64b2e76eef62aa959add14127f456f6d4e86c8c9b842a0abb4a7f22e96715f648d5f34cf42546bc30a522c3c263239f92aa1667075c
7
- data.tar.gz: a49aa79742ff2a2d4074eebf9c510827d2dcb1f36b6fcc5b4ee201871e52c195146cda609a6f139bed3f86ab85861827c8fe206b406fc424e55fce03427e9659
6
+ metadata.gz: f621c41ba152ddada71cd29cfd993ebbef00351a5a56e54ec4b9989db2de2297232c48fc977bc7dd86cd35741d49f362aadff7cf34081508310c41cae179b60c
7
+ data.tar.gz: a78015b6021e980146aa79dd1b55a7cf7a89975df31ddee8076b68126748b3088e3ce205956efa29a73f1c0acec26fe780565ed6409aef70d45a2c41bb283dcf
data/.gitignore CHANGED
@@ -1,3 +1,5 @@
1
+ full_test
2
+
1
3
  .vagrant
2
4
 
3
5
  *.gem
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- terjira (0.2.5)
4
+ terjira (0.2.6)
5
5
  activesupport (= 4.0.13)
6
6
  jira-ruby (~> 1.1)
7
7
  pastel (~> 0.6.1)
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
- ## Domo
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
@@ -33,7 +33,7 @@ module Terjira
33
33
  Client::Base.expire_auth_options
34
34
  end
35
35
 
36
- desc 'project SUBCOMMAND ...ARGS', 'Manage proejcts'
36
+ desc 'project SUBCOMMAND ...ARGS', 'Manage projects'
37
37
  subcommand 'project', ProjectCLI
38
38
 
39
39
  desc 'board SUBCOMMAND ...ARGS', 'Manage boards'
@@ -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
 
@@ -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
- all.find { |field| field.name == 'Epic Name' }
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 epiclink
22
- all.find { |field| field.name == 'Epic Link' }
31
+ def story_points
32
+ find_by_name('Story Points')
23
33
  end
24
34
 
25
35
  def file_cache
26
- Terjira::FileCache.new("resource/fields", 60 * 60 * 24)
36
+ Terjira::FileCache.new(CACHE_PATH, 60 * 60 * 24)
27
37
  end
28
38
  end
29
39
  end
@@ -4,12 +4,12 @@ module Terjira
4
4
  module Client
5
5
  class Issue < Base
6
6
  class << self
7
- delegate :build, :find, to: :resource
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
- resource.jql(build_jql(options), max_results: max_results)
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
 
@@ -34,7 +34,7 @@ module Terjira
34
34
  map ls: :list
35
35
  def list
36
36
  opts = suggest_options
37
- opts[:statusCategory] ||= %w(To\ Do In\ Progress) unless opts[:status]
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
@@ -90,7 +90,7 @@ module Terjira
90
90
  end
91
91
 
92
92
  if opts[:epiclink]
93
- epiclink_field = Client::Field.epiclink
93
+ epiclink_field = Client::Field.epic_link
94
94
  opts[epiclink_field.key] ||= opts.delete(:epiclink)
95
95
  end
96
96
 
@@ -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('priority') %>: <%= colorize_priority(issue.priority, title: true) %>
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
- <%= bold('Epic Link') %>: <%= issue.try(:epic).try(:key) %> <%= issue.try(:epic).try(:name) || dim_none %>
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)
@@ -41,7 +41,7 @@ module Terjira
41
41
  end
42
42
 
43
43
  def colorize_sprint_state(state)
44
- state = state.to_s.capitalize
44
+ state = " #{state.to_s.capitalize} "
45
45
  if state =~ /active/i
46
46
  pastel.on_blue.bold(state)
47
47
  elsif state =~ /close/i
@@ -1,7 +1,7 @@
1
1
  require 'terjira/utils/file_cache'
2
2
 
3
3
  module Terjira
4
- VERSION = '0.2.5'.freeze
4
+ VERSION = '0.2.6'.freeze
5
5
 
6
6
  class VersionChecker
7
7
  VERSION_CHECK_DURATION = (60 * 60 * 24 * 5).freeze
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.5
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-19 00:00:00.000000000 Z
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