terjira 0.1.1 → 0.2.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.
- checksums.yaml +4 -4
- data/.rubocop.yml +10 -1
- data/Gemfile.lock +3 -3
- data/README.md +14 -15
- data/bin/console +1 -1
- data/bin/jira +11 -3
- data/bin/terjira +22 -0
- data/lib/terjira/base_cli.rb +5 -3
- data/lib/terjira/board_cli.rb +17 -2
- data/lib/terjira/client/agile.rb +10 -13
- data/lib/terjira/client/auth_option_builder.rb +1 -1
- data/lib/terjira/client/base.rb +9 -12
- data/lib/terjira/client/board.rb +13 -3
- data/lib/terjira/client/field.rb +12 -2
- data/lib/terjira/client/issue.rb +15 -13
- data/lib/terjira/client/issuetype.rb +18 -0
- data/lib/terjira/client/jql_builder.rb +25 -0
- data/lib/terjira/client/priority.rb +1 -1
- data/lib/terjira/client/resolution.rb +1 -1
- data/lib/terjira/client/status.rb +1 -1
- data/lib/terjira/client/user.rb +5 -6
- data/lib/terjira/ext/jira_ruby.rb +12 -4
- data/lib/terjira/ext/tty_prompt.rb +0 -3
- data/lib/terjira/issue_cli.rb +11 -7
- data/lib/terjira/option_support/option_selector.rb +20 -9
- data/lib/terjira/option_support/shared_options.rb +4 -2
- data/lib/terjira/option_supportable.rb +24 -0
- data/lib/terjira/presenters/common_presenter.rb +13 -4
- data/lib/terjira/presenters/issue_presenter.rb +115 -97
- data/lib/terjira/presenters/project_presenter.rb +1 -1
- data/lib/terjira/presenters/sprint_presenter.rb +9 -9
- data/lib/terjira/sprint_cli.rb +1 -0
- data/lib/terjira/utils/file_cache.rb +26 -26
- data/lib/terjira/version.rb +1 -1
- data/lib/terjira.rb +11 -0
- data/terjira.gemspec +4 -4
- metadata +11 -11
- data/lib/terjira/client/jql_query_builer.rb +0 -25
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1daef227221455846fa59674d6cfeb9735d1e33d
|
4
|
+
data.tar.gz: 5dd7bbe7f90499eaf61ff4300ae5518f1a3336b3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6124824ac122ea72b0e7077956371b6803cd848a8a454bbb03c4e25de2a8e99902e64a5fd01763925b1cecfa9ac7e04457749c7b56ddd2c530d178bbdfd025f8
|
7
|
+
data.tar.gz: 4ecc886b8ab99b2bc3ddfb9f9694f6baba32f5b63484f9468ac9dd6368e5428108e4cedfb74e291024f1ce8e9a0326e6a237d79284c912f4828441836358f8b2
|
data/.rubocop.yml
CHANGED
@@ -1,14 +1,23 @@
|
|
1
1
|
AllCops:
|
2
2
|
Exclude:
|
3
|
+
- 'bin/*'
|
3
4
|
- '*.gemspec'
|
5
|
+
- 'lib/terjira/ext/**/*'
|
6
|
+
- 'Rakefile'
|
4
7
|
|
5
8
|
Style/Documentation:
|
6
9
|
Enabled: false
|
7
10
|
Style/EachWithObject:
|
8
11
|
Enabled: false
|
12
|
+
Style/RescueModifier:
|
13
|
+
Enabled: false
|
9
14
|
|
10
15
|
Lint/AssignmentInCondition:
|
11
16
|
Enabled: false
|
17
|
+
Lint/Eval:
|
18
|
+
Enabled: false
|
19
|
+
Lint/ImplicitStringConcatenation:
|
20
|
+
Enabled: false
|
12
21
|
|
13
22
|
Metrics/BlockLength:
|
14
23
|
Enabled: false
|
@@ -20,7 +29,7 @@ Metrics/AbcSize:
|
|
20
29
|
Max: 20
|
21
30
|
|
22
31
|
Metrics/MethodLength:
|
23
|
-
Max:
|
32
|
+
Max: 30
|
24
33
|
|
25
34
|
Metrics/LineLength:
|
26
35
|
Max: 100
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -5,42 +5,41 @@
|
|
5
5
|
|
6
6
|
# Terjira
|
7
7
|
|
8
|
-
Terjira is
|
8
|
+
Terjira is interactive and easy to use command line interface (or Application) for Jira. You do not need to remember reosurce key or id. Terjira suggests with interactive prompt.
|
9
9
|
|
10
|
+
Your Jira must support Rest API 2.0 and Agile Rest API 1.0
|
10
11
|
|
11
|
-
|
12
|
+
|
13
|
+
**I'm working now..**
|
12
14
|
|
13
15
|
## Installation
|
14
16
|
|
15
|
-
|
17
|
+
Install it yourself as:
|
16
18
|
|
17
|
-
|
18
|
-
gem 'terjira'
|
19
|
-
```
|
19
|
+
$ gem install terjira
|
20
20
|
|
21
|
-
|
21
|
+
If you have permission problem,
|
22
22
|
|
23
|
-
$
|
23
|
+
$ sudo gem install terjira
|
24
24
|
|
25
|
-
|
25
|
+
# or
|
26
26
|
|
27
|
-
$ gem install terjira
|
27
|
+
$ gem install terjira --user-install
|
28
|
+
# You need to export your gem path
|
28
29
|
|
29
30
|
## Usage
|
30
31
|
|
31
|
-
TODO: Write usage instructions here
|
32
32
|
|
33
|
-
* Mock data is from jira-ruby
|
34
33
|
|
35
34
|
## Development
|
36
35
|
|
37
|
-
After checking out the repo, run `bin/setup` to install dependencies. Then, run `
|
36
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rspec spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
38
37
|
|
39
|
-
To install this gem onto your local machine, run `bundle exec rake install`.
|
38
|
+
To install this gem onto your local machine, run `bundle exec rake install`.
|
40
39
|
|
41
40
|
## Contributing
|
42
41
|
|
43
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/
|
42
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/keepcosmos/terjira. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
44
43
|
|
45
44
|
|
46
45
|
## License
|
data/bin/console
CHANGED
data/bin/jira
CHANGED
@@ -1,14 +1,22 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
|
2
3
|
# Do I need bundler setup?
|
3
4
|
# require 'bundler/setup'
|
4
5
|
require 'terjira'
|
5
6
|
require 'json'
|
7
|
+
require 'pastel'
|
6
8
|
|
7
9
|
begin
|
8
10
|
Terjira::CLI.start(ARGV)
|
11
|
+
rescue SystemExit, Interrupt
|
9
12
|
rescue JIRA::HTTPError => e
|
10
13
|
message = JSON.parse(e.response.body)
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
+
pastel = Pastel.new
|
15
|
+
if message['errorMessages'].present?
|
16
|
+
puts pastel.red(message['errorMessages'].join("\n"))
|
17
|
+
else
|
18
|
+
puts pastel.red(e.message.to_s + "\n" + e.response.body)
|
19
|
+
end
|
20
|
+
rescue => e
|
21
|
+
puts Pastel.new.dim(e.message)
|
14
22
|
end
|
data/bin/terjira
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# Do I need bundler setup?
|
4
|
+
require 'bundler/setup'
|
5
|
+
require 'terjira'
|
6
|
+
require 'json'
|
7
|
+
require 'pastel'
|
8
|
+
|
9
|
+
begin
|
10
|
+
Terjira::CLI.start(ARGV)
|
11
|
+
rescue SystemExit, Interrupt
|
12
|
+
rescue JIRA::HTTPError => e
|
13
|
+
message = JSON.parse(e.response.body)
|
14
|
+
pastel = Pastel.new
|
15
|
+
if message['errorMessages'].present?
|
16
|
+
puts pastel.red(message['errorMessages'].join("\n"))
|
17
|
+
else
|
18
|
+
puts pastel.red(e.message.to_s + "\n" + e.response.body)
|
19
|
+
end
|
20
|
+
rescue => e
|
21
|
+
puts Pastel.new.dim(e.message)
|
22
|
+
end
|
data/lib/terjira/base_cli.rb
CHANGED
@@ -1,11 +1,13 @@
|
|
1
1
|
require 'thor'
|
2
2
|
|
3
3
|
require_relative 'option_supportable'
|
4
|
-
Dir[File.dirname(__FILE__) +
|
4
|
+
Dir[File.dirname(__FILE__) + '/presenters/*.rb'].each { |f| require f }
|
5
5
|
|
6
6
|
module Terjira
|
7
|
+
# Jira client based on jira-ruby gem
|
7
8
|
module Client
|
8
|
-
%w
|
9
|
+
%w(Base Field Issuetype Project Board Sprint Issue User
|
10
|
+
Status Resolution Priority RapidView Agile).each do |klass|
|
9
11
|
autoload klass, "terjira/client/#{klass.gsub(/(.)([A-Z](?=[a-z]))/,'\1_\2').downcase}"
|
10
12
|
end
|
11
13
|
end
|
@@ -19,7 +21,7 @@ module Terjira
|
|
19
21
|
include BoardPresenter
|
20
22
|
include SprintPresenter
|
21
23
|
|
22
|
-
def self.banner(command,
|
24
|
+
def self.banner(command, _namespace = nil, _subcommand = false)
|
23
25
|
"#{basename} #{subcommand_prefix} #{command.usage}"
|
24
26
|
end
|
25
27
|
|
data/lib/terjira/board_cli.rb
CHANGED
@@ -2,11 +2,26 @@ require_relative 'base_cli'
|
|
2
2
|
|
3
3
|
module Terjira
|
4
4
|
class BoardCLI < BaseCLI
|
5
|
-
|
5
|
+
no_commands do
|
6
|
+
def client_class
|
7
|
+
Client::Board
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
desc "( ls | list)", "list all boards"
|
6
12
|
map ls: :list
|
7
13
|
def list
|
8
|
-
boards =
|
14
|
+
boards = client_class.all
|
9
15
|
render_boards_summary(boards.sort_by { |b| b.id })
|
10
16
|
end
|
17
|
+
|
18
|
+
desc "backlog", "Backlog from the board"
|
19
|
+
jira_options :board, :assignee, :issuetype, :priority
|
20
|
+
def backlog
|
21
|
+
opts = suggest_options(required: [:board])
|
22
|
+
board = opts.delete(:board)
|
23
|
+
issues = client_class.backlog(board.key_value, opts)
|
24
|
+
render_issues(issues)
|
25
|
+
end
|
11
26
|
end
|
12
27
|
end
|
data/lib/terjira/client/agile.rb
CHANGED
@@ -7,22 +7,22 @@ module Terjira
|
|
7
7
|
delegate :all, :get_sprints, :backlog_issues, to: :resource
|
8
8
|
|
9
9
|
def project_by_board(board_id)
|
10
|
-
|
10
|
+
agile_api_get("board/#{board_id}/project")
|
11
11
|
end
|
12
12
|
|
13
13
|
def boards
|
14
|
-
all[
|
14
|
+
all['values']
|
15
15
|
end
|
16
16
|
|
17
|
-
def sprints(board_id
|
18
|
-
sprints = get_sprints(board_id)[
|
17
|
+
def sprints(board_id)
|
18
|
+
sprints = get_sprints(board_id)['values']
|
19
19
|
sprints.sort_by do |sprint|
|
20
|
-
if sprint[
|
21
|
-
[0, sprint[
|
22
|
-
elsif sprint[
|
23
|
-
[1, sprint[
|
24
|
-
elsif sprint[
|
25
|
-
[2, sprint[
|
20
|
+
if sprint['state'] == 'active'
|
21
|
+
[0, sprint['id']]
|
22
|
+
elsif sprint['state'] == 'future'
|
23
|
+
[1, sprint['id']]
|
24
|
+
elsif sprint['state'] == 'closed'
|
25
|
+
[2, sprint['id'] * -1]
|
26
26
|
else
|
27
27
|
[3, 0]
|
28
28
|
end
|
@@ -32,9 +32,6 @@ module Terjira
|
|
32
32
|
def backlog_issues(board_id)
|
33
33
|
get_backlog_issues(board_id)
|
34
34
|
end
|
35
|
-
|
36
|
-
def sprint_issues(board_id)
|
37
|
-
end
|
38
35
|
end
|
39
36
|
end
|
40
37
|
end
|
data/lib/terjira/client/base.rb
CHANGED
@@ -1,23 +1,22 @@
|
|
1
|
-
require_relative '
|
1
|
+
require_relative 'jql_builder'
|
2
2
|
require_relative 'auth_option_builder'
|
3
3
|
|
4
4
|
module Terjira
|
5
5
|
module Client
|
6
6
|
# Abstract class to delegate jira-ruby resource class
|
7
7
|
class Base
|
8
|
-
extend
|
8
|
+
extend JQLBuilder
|
9
9
|
extend AuthOptionBuilder
|
10
10
|
|
11
11
|
DEFAULT_CACHE_SEC = 60
|
12
|
-
DEFAULT_API_PATH =
|
13
|
-
AGILE_API_PATH =
|
12
|
+
DEFAULT_API_PATH = '/rest/api/2/'.freeze
|
13
|
+
AGILE_API_PATH = '/rest/agile/1.0/'.freeze
|
14
14
|
|
15
15
|
class << self
|
16
|
-
|
17
16
|
delegate :build, to: :resource
|
18
17
|
|
19
18
|
def client
|
20
|
-
|
19
|
+
@client ||= JIRA::Client.new(build_auth_options)
|
21
20
|
end
|
22
21
|
|
23
22
|
def resource
|
@@ -29,7 +28,7 @@ module Terjira
|
|
29
28
|
end
|
30
29
|
|
31
30
|
def class_name
|
32
|
-
|
31
|
+
to_s.split('::').last
|
33
32
|
end
|
34
33
|
|
35
34
|
def cache(options = {})
|
@@ -38,16 +37,14 @@ module Terjira
|
|
38
37
|
end
|
39
38
|
|
40
39
|
# define `#api_get(post, put, delete)` and `#agile_api_get(post, put, delete)`
|
41
|
-
{ DEFAULT_API_PATH =>
|
42
|
-
AGILE_API_PATH =>
|
43
|
-
}.each do |url_prefix, method_prefix|
|
44
|
-
|
40
|
+
{ DEFAULT_API_PATH => 'api_',
|
41
|
+
AGILE_API_PATH => 'agile_api_' }.each do |url_prefix, method_prefix|
|
45
42
|
[:get, :delete].each do |http_method|
|
46
43
|
method_name = "#{method_prefix}#{http_method}"
|
47
44
|
define_method(method_name) do |path, params = {}, headers = {}|
|
48
45
|
url = url_prefix + path
|
49
46
|
if params.present?
|
50
|
-
params.reject! { |
|
47
|
+
params.reject! { |_k, v| v.blank? }
|
51
48
|
url += "?#{URI.encode_www_form(params)}"
|
52
49
|
end
|
53
50
|
parse_body client.send(http_method, url, headers)
|
data/lib/terjira/client/board.rb
CHANGED
@@ -6,13 +6,23 @@ module Terjira
|
|
6
6
|
|
7
7
|
def all(options = {})
|
8
8
|
params = options.slice(:type)
|
9
|
-
resp = agile_api_get(
|
10
|
-
resp[
|
9
|
+
resp = agile_api_get('board', params)
|
10
|
+
resp['values'].map { |value| build(value) }
|
11
11
|
end
|
12
12
|
|
13
13
|
def find(board_id)
|
14
14
|
resp = agile_api_get("board/#{board_id}")
|
15
|
-
|
15
|
+
build(resp)
|
16
|
+
end
|
17
|
+
|
18
|
+
def backlog(board_id, options = {})
|
19
|
+
jql = build_jql(options)
|
20
|
+
resp = if jql.present?
|
21
|
+
agile_api_get("board/#{board_id}/backlog", jql: jql)
|
22
|
+
else
|
23
|
+
agile_api_get("board/#{board_id}/backlog")
|
24
|
+
end
|
25
|
+
resp["issues"].map { |issue| Issue.build(issue) }
|
16
26
|
end
|
17
27
|
end
|
18
28
|
end
|
data/lib/terjira/client/field.rb
CHANGED
@@ -5,11 +5,21 @@ module Terjira
|
|
5
5
|
class Field < Base
|
6
6
|
class << self
|
7
7
|
def all
|
8
|
-
@all_fields ||=
|
8
|
+
@all_fields ||= file_cache.fetch("all") do
|
9
|
+
resource.all
|
10
|
+
end
|
9
11
|
end
|
10
12
|
|
11
13
|
def epic_name
|
12
|
-
all.find { |field| field.name ==
|
14
|
+
all.find { |field| field.name == 'Epic Name' }
|
15
|
+
end
|
16
|
+
|
17
|
+
def epiclink
|
18
|
+
all.find { |field| field.name == 'Epic Link' }
|
19
|
+
end
|
20
|
+
|
21
|
+
def file_cache
|
22
|
+
Terjira::FileCache.new("resource/fields", 60 * 60 * 24)
|
13
23
|
end
|
14
24
|
end
|
15
25
|
end
|
data/lib/terjira/client/issue.rb
CHANGED
@@ -5,22 +5,21 @@ module Terjira
|
|
5
5
|
class Issue < Base
|
6
6
|
class << self
|
7
7
|
delegate :build, :find, to: :resource
|
8
|
-
ISSUE_JQL_KEYS = [:sprint, :assignee, :reporter, :project, :issuetype, :priority, :status, :statusCategory]
|
9
8
|
|
10
9
|
def all(options = {})
|
11
|
-
opts = options.slice(*ISSUE_JQL_KEYS)
|
12
10
|
return resource.all if options.blank?
|
13
11
|
max_results = options.delete(:max_results) || 500
|
14
|
-
resource.jql(
|
12
|
+
resource.jql(build_jql(options), max_results: max_results)
|
15
13
|
end
|
16
14
|
|
17
|
-
def
|
18
|
-
resp =
|
19
|
-
build(
|
15
|
+
def all_epic_issues(epic)
|
16
|
+
resp = agile_api_get("epic/#{epic.key}/issue")
|
17
|
+
resp["issues"].map { |issue| build(issue) }
|
20
18
|
end
|
21
19
|
|
22
|
-
def
|
23
|
-
|
20
|
+
def find(issue, options = {})
|
21
|
+
resp = agile_api_get("issue/#{issue.key_value}", options)
|
22
|
+
build(resp)
|
24
23
|
end
|
25
24
|
|
26
25
|
def assign(issue, assignee)
|
@@ -29,7 +28,7 @@ module Terjira
|
|
29
28
|
end
|
30
29
|
|
31
30
|
def write_comment(issue, message)
|
32
|
-
|
31
|
+
api_post("issue/#{issue.key_value}/comment", { body: message }.to_json)
|
33
32
|
find(issue)
|
34
33
|
end
|
35
34
|
|
@@ -39,9 +38,8 @@ module Terjira
|
|
39
38
|
params.merge!(transition_param)
|
40
39
|
end
|
41
40
|
|
42
|
-
resp = api_post
|
43
|
-
|
44
|
-
find(result_id)
|
41
|
+
resp = api_post 'issue', params.to_json
|
42
|
+
find(resp['id'])
|
45
43
|
end
|
46
44
|
|
47
45
|
def update(issue, options = {})
|
@@ -80,7 +78,7 @@ module Terjira
|
|
80
78
|
params = {}
|
81
79
|
|
82
80
|
custom_fields = options.keys.select { |k| k.to_s =~ /^customfield/ }
|
83
|
-
(custom_fields + [:summary, :description]).each do |k,
|
81
|
+
(custom_fields + [:summary, :description]).each do |k, _v|
|
84
82
|
params[k] = opts.delete(k) if opts.key?(k)
|
85
83
|
end
|
86
84
|
|
@@ -88,6 +86,10 @@ module Terjira
|
|
88
86
|
params[:project] = { key: opts.delete(:project).key_value }
|
89
87
|
end
|
90
88
|
|
89
|
+
if opts.key?(:parent)
|
90
|
+
params[:parent] = { key: opts.delete(:parent).key_value }
|
91
|
+
end
|
92
|
+
|
91
93
|
opts.each do |k, v|
|
92
94
|
params[k] = convert_param_key_value_hash(v)
|
93
95
|
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require_relative 'base'
|
2
|
+
|
3
|
+
module Terjira
|
4
|
+
module Client
|
5
|
+
class Issuetype < Base
|
6
|
+
class << self
|
7
|
+
def all
|
8
|
+
resp = api_get("issuetype")
|
9
|
+
resp.map { |issuetype| build(issuetype) }
|
10
|
+
end
|
11
|
+
|
12
|
+
def subtask_issuetypes
|
13
|
+
all.select(&:subtask)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Terjira
|
2
|
+
module Client
|
3
|
+
module JQLBuilder
|
4
|
+
JQL_KEYS = %w(sprint assignee issuetype priority project status statusCategory).freeze
|
5
|
+
|
6
|
+
def build_jql(options = {})
|
7
|
+
q_options = options.inject({}) do |memo, (k, v)|
|
8
|
+
memo[k.to_s] = v
|
9
|
+
memo
|
10
|
+
end.slice(*JQL_KEYS)
|
11
|
+
|
12
|
+
query = q_options.map do |key, value|
|
13
|
+
if value.is_a? Array
|
14
|
+
values = value.map { |v| "\"#{v.key_value}\"" }.join(',')
|
15
|
+
"#{key} IN (#{values})"
|
16
|
+
else
|
17
|
+
"#{key}=#{value.key_value}"
|
18
|
+
end
|
19
|
+
end.reject(&:blank?).join(' AND ')
|
20
|
+
|
21
|
+
query
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -6,7 +6,7 @@ module Terjira
|
|
6
6
|
class << self
|
7
7
|
def all(project)
|
8
8
|
resp = api_get "project/#{project.key_value}/statuses"
|
9
|
-
statuses_json = resp.map { |issuetype| issuetype[
|
9
|
+
statuses_json = resp.map { |issuetype| issuetype['statuses'] }.flatten.uniq
|
10
10
|
statuses_json.map { |status| build(status) }
|
11
11
|
end
|
12
12
|
end
|
data/lib/terjira/client/user.rb
CHANGED
@@ -6,10 +6,10 @@ module Terjira
|
|
6
6
|
class << self
|
7
7
|
def assignables_by_project(project)
|
8
8
|
if project.is_a? Array
|
9
|
-
keys = project.map(&:key_value).join(
|
10
|
-
fetch_assignables
|
9
|
+
keys = project.map(&:key_value).join(',')
|
10
|
+
fetch_assignables 'user/assignable/multiProjectSearch', projectKeys: keys
|
11
11
|
else
|
12
|
-
fetch_assignables
|
12
|
+
fetch_assignables 'user/assignable/search', project: project.key_value
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
@@ -28,15 +28,14 @@ module Terjira
|
|
28
28
|
end
|
29
29
|
|
30
30
|
def assignables_by_issue(issue)
|
31
|
-
fetch_assignables
|
31
|
+
fetch_assignables 'user/assignable/search', issueKey: issue.key_value
|
32
32
|
end
|
33
33
|
|
34
34
|
private
|
35
35
|
|
36
36
|
def fetch_assignables(path, params)
|
37
37
|
resp = api_get(path, params)
|
38
|
-
resp.map { |user| build(user) }.
|
39
|
-
reject { |user| user.key_value =~ /^addon/ }
|
38
|
+
resp.map { |user| build(user) }.reject { |user| user.key_value =~ /^addon/ }
|
40
39
|
end
|
41
40
|
end
|
42
41
|
end
|
@@ -9,15 +9,12 @@ module JIRA
|
|
9
9
|
alias origin_make_request make_request
|
10
10
|
|
11
11
|
def make_request(http_method, path, body = '', headers = {})
|
12
|
-
title = http_method.to_s.upcase
|
13
|
-
title = Pastel.new.dim(title)
|
12
|
+
title = Pastel.new.dim(http_method.to_s.upcase)
|
14
13
|
spinner = TTY::Spinner.new ":spinner #{title}", format: :dots, clear: true
|
15
14
|
result = nil
|
16
|
-
|
17
15
|
spinner.run do
|
18
16
|
result = origin_make_request(http_method, path, body, headers)
|
19
17
|
end
|
20
|
-
|
21
18
|
result
|
22
19
|
end
|
23
20
|
end
|
@@ -33,16 +30,27 @@ module JIRA
|
|
33
30
|
class BoardFactory < JIRA::BaseFactory # :nodoc:
|
34
31
|
end
|
35
32
|
|
33
|
+
class EpicFactory < JIRA::BaseFactory # :nodoc:
|
34
|
+
end
|
35
|
+
|
36
36
|
class Board < JIRA::Base
|
37
37
|
def self.key_attribute; :id; end
|
38
38
|
end
|
39
39
|
|
40
|
+
class Epic < JIRA::Base
|
41
|
+
def self.key_attribute; :key; end
|
42
|
+
end
|
43
|
+
|
40
44
|
class User
|
41
45
|
def self.key_attribute; :name; end
|
42
46
|
end
|
43
47
|
|
44
48
|
class Issue
|
45
49
|
def self.key_attribute; :key; end
|
50
|
+
has_one :epic, class: JIRA::Resource::Epic, nested_under: 'fields'
|
51
|
+
has_one :sprint, class: JIRA::Resource::Sprint, nested_under: 'fields'
|
52
|
+
has_one :parent, class: JIRA::Resource::Issue, nested_under: 'fields'
|
53
|
+
has_many :subtasks, class: JIRA::Resource::Issue, nested_under: 'fields'
|
46
54
|
end
|
47
55
|
|
48
56
|
class Issuetype
|