jira_command 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +11 -0
- data/.rspec +3 -0
- data/.rubocop.yml +113 -0
- data/.travis.yml +6 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +13 -0
- data/Gemfile.lock +88 -0
- data/LICENSE.txt +21 -0
- data/README.md +140 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/exe/jira_command +5 -0
- data/jira_command.gemspec +31 -0
- data/lib/jira_command.rb +7 -0
- data/lib/jira_command/cli.rb +21 -0
- data/lib/jira_command/command/assign.rb +48 -0
- data/lib/jira_command/command/config.rb +72 -0
- data/lib/jira_command/command/issue.rb +80 -0
- data/lib/jira_command/command/list.rb +70 -0
- data/lib/jira_command/command/status.rb +21 -0
- data/lib/jira_command/command/transition.rb +68 -0
- data/lib/jira_command/command/user.rb +22 -0
- data/lib/jira_command/config.rb +38 -0
- data/lib/jira_command/jira/assign.rb +32 -0
- data/lib/jira_command/jira/base.rb +26 -0
- data/lib/jira_command/jira/issue.rb +40 -0
- data/lib/jira_command/jira/issuetype.rb +19 -0
- data/lib/jira_command/jira/list.rb +23 -0
- data/lib/jira_command/jira/project.rb +19 -0
- data/lib/jira_command/jira/status.rb +30 -0
- data/lib/jira_command/jira/transition.rb +29 -0
- data/lib/jira_command/jira/user.rb +31 -0
- data/lib/jira_command/version.rb +3 -0
- metadata +95 -0
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'bundler/setup'
|
4
|
+
require 'jira_command'
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require 'irb'
|
14
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
data/exe/jira_command
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
require_relative 'lib/jira_command/version'
|
2
|
+
|
3
|
+
Gem::Specification.new do |spec|
|
4
|
+
spec.name = 'jira_command'
|
5
|
+
spec.version = JiraCommand::VERSION
|
6
|
+
spec.authors = ['shengbo.xu']
|
7
|
+
spec.email = ['shengbo.xu@xincere.jp']
|
8
|
+
|
9
|
+
spec.summary = 'jira cli'
|
10
|
+
spec.description = 'jira cli tool'
|
11
|
+
spec.homepage = 'https://github.com/xincere-inc/jira_command'
|
12
|
+
spec.license = 'MIT'
|
13
|
+
spec.required_ruby_version = Gem::Requirement.new('>= 2.3.0')
|
14
|
+
|
15
|
+
# spec.metadata['allowed_push_host'] = "TODO: Set to 'http://mygemserver.com'"
|
16
|
+
|
17
|
+
spec.metadata['homepage_uri'] = spec.homepage
|
18
|
+
spec.metadata['source_code_uri'] = 'https://github.com/xincere-inc/jira_command'
|
19
|
+
spec.metadata['changelog_uri'] = 'https://github.com/xincere-inc/jira_command'
|
20
|
+
|
21
|
+
# Specify which files should be added to the gem when it is released.
|
22
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
23
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
24
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
25
|
+
end
|
26
|
+
spec.bindir = 'exe'
|
27
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
28
|
+
spec.require_paths = ['lib']
|
29
|
+
|
30
|
+
spec.add_dependency 'thor'
|
31
|
+
end
|
data/lib/jira_command.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'jira_command'
|
2
|
+
require 'thor'
|
3
|
+
require_relative 'command/list'
|
4
|
+
require_relative 'command/config'
|
5
|
+
require_relative 'command/user'
|
6
|
+
require_relative 'command/assign'
|
7
|
+
require_relative 'command/status'
|
8
|
+
require_relative 'command/transition'
|
9
|
+
require_relative 'command/issue'
|
10
|
+
|
11
|
+
module JiraCommand
|
12
|
+
class CLI < Thor
|
13
|
+
register(JiraCommand::Command::List, 'list', 'list', 'list up issues')
|
14
|
+
register(JiraCommand::Command::Config, 'config', 'config', 'create or clear configuration')
|
15
|
+
register(JiraCommand::Command::User, 'user', 'user', 'list all users')
|
16
|
+
register(JiraCommand::Command::Assign, 'assign', 'assign', 'set or unset assign in issue')
|
17
|
+
register(JiraCommand::Command::Status, 'status', 'status', 'show all status in project')
|
18
|
+
register(JiraCommand::Command::Transition, 'transition', 'transition', 'transition issues')
|
19
|
+
register(JiraCommand::Command::Issue, 'issue', 'issue', 'create a issue')
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'thor'
|
2
|
+
require 'optparse'
|
3
|
+
require 'tty-prompt'
|
4
|
+
require_relative '../config'
|
5
|
+
require_relative '../jira/assign'
|
6
|
+
|
7
|
+
module JiraCommand
|
8
|
+
module Command
|
9
|
+
class Assign < Thor
|
10
|
+
desc 'exec', 'assign to user'
|
11
|
+
option 'issue', aliases: 'i', required: true
|
12
|
+
option 'refresh-user', aliases: 'ru', required: false
|
13
|
+
def exec
|
14
|
+
config = JiraCommand::Config.new.read
|
15
|
+
|
16
|
+
user_api = JiraCommand::Jira::User.new(config)
|
17
|
+
user_list = user_api.all_list(project: options['issue'].split('-').first)
|
18
|
+
|
19
|
+
user_list = if options['refresh-user'].nil?
|
20
|
+
config['users']
|
21
|
+
else
|
22
|
+
user_api = JiraCommand::Jira::User.new(config)
|
23
|
+
user_api.all_list(project: project[:key])
|
24
|
+
end
|
25
|
+
|
26
|
+
prompt = TTY::Prompt.new
|
27
|
+
|
28
|
+
assignee = prompt.select('Who do you want to assign?') do |menu|
|
29
|
+
user_list.each do |user|
|
30
|
+
menu.choice name: user[:name], value: user[:account_id]
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
assign = JiraCommand::Jira::Assign.new(config)
|
35
|
+
user_list = assign.execute(issue_key: options['issue'], assignee: assignee)
|
36
|
+
end
|
37
|
+
|
38
|
+
desc 'clear', 'set to unassigned'
|
39
|
+
option 'issue', aliases: 'i', required: false
|
40
|
+
def clear
|
41
|
+
config = JiraCommand::Config.new.read
|
42
|
+
|
43
|
+
assign = JiraCommand::Jira::Assign.new(config)
|
44
|
+
assign.unassigne(issue_key: options['issue'])
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
require 'jira_command'
|
2
|
+
require 'thor'
|
3
|
+
require 'optparse'
|
4
|
+
require 'tty-prompt'
|
5
|
+
require_relative '../config'
|
6
|
+
require_relative '../jira/issuetype'
|
7
|
+
require_relative '../jira/project'
|
8
|
+
require_relative '../jira/user'
|
9
|
+
require 'base64'
|
10
|
+
|
11
|
+
module JiraCommand
|
12
|
+
module Command
|
13
|
+
class Config < Thor
|
14
|
+
desc 'create', 'create config file'
|
15
|
+
def create
|
16
|
+
if JiraCommand::Config.check_exist
|
17
|
+
puts 'config file has been already existed. if you want to renew it, please execute `jira_command config clear` first'
|
18
|
+
exit 1
|
19
|
+
end
|
20
|
+
|
21
|
+
prompt = TTY::Prompt.new
|
22
|
+
|
23
|
+
jira_url = prompt.ask('Please input your site url:')
|
24
|
+
email = prompt.ask('Please input your registered email address:')
|
25
|
+
token = prompt.mask('Please input your token:')
|
26
|
+
|
27
|
+
jira_url += '/' unless jira_url.end_with?('/')
|
28
|
+
config = { jira_url: jira_url, header_token: Base64.strict_encode64("#{email}:#{token}") }
|
29
|
+
|
30
|
+
JiraCommand::Config.new.write(config)
|
31
|
+
end
|
32
|
+
|
33
|
+
desc 'update_projects', 'update default projects in config file'
|
34
|
+
def update_projects
|
35
|
+
config = JiraCommand::Config.new.read
|
36
|
+
|
37
|
+
jira_project = JiraCommand::Jira::Project.new(config)
|
38
|
+
config.merge!({
|
39
|
+
projects: jira_project.list
|
40
|
+
})
|
41
|
+
JiraCommand::Config.new.write(config)
|
42
|
+
end
|
43
|
+
|
44
|
+
desc 'update_users', 'update default users in config file'
|
45
|
+
option 'project', aliases: 'p', required: true
|
46
|
+
def update_users
|
47
|
+
config = JiraCommand::Config.new.read
|
48
|
+
user_api = JiraCommand::Jira::User.new(config)
|
49
|
+
config.merge!({
|
50
|
+
users: user_api.all_list(project: options[:project])
|
51
|
+
})
|
52
|
+
JiraCommand::Config.new.write(config)
|
53
|
+
end
|
54
|
+
|
55
|
+
desc 'update_it', 'update default issue_type in config file'
|
56
|
+
def update_it
|
57
|
+
config = JiraCommand::Config.new.read
|
58
|
+
jira_issue_type = JiraCommand::Jira::IssueType.new(config)
|
59
|
+
config.merge!({
|
60
|
+
issue_types: jira_issue_type.list
|
61
|
+
})
|
62
|
+
JiraCommand::Config.new.write(config)
|
63
|
+
end
|
64
|
+
|
65
|
+
desc 'clear', 'clear config file'
|
66
|
+
def clear
|
67
|
+
prompt = TTY::Prompt.new
|
68
|
+
JiraCommand::Config.new.clear if prompt.yes?('Are you sure to clear?')
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'jira_command'
|
2
|
+
require_relative '../config'
|
3
|
+
require_relative '../jira/issuetype'
|
4
|
+
require_relative '../jira/project'
|
5
|
+
require_relative '../jira/issue'
|
6
|
+
|
7
|
+
module JiraCommand
|
8
|
+
module Command
|
9
|
+
class Issue < Thor
|
10
|
+
desc 'create', 'create new issue'
|
11
|
+
option 'refresh-project', aliases: 'rp', required: false
|
12
|
+
option 'refresh-issue-type', aliases: 'rit', required: false
|
13
|
+
option 'refresh-user', aliases: 'ru', required: false
|
14
|
+
def create
|
15
|
+
config = JiraCommand::Config.new.read
|
16
|
+
|
17
|
+
issue_types = if options['refresh-issue-type'].nil?
|
18
|
+
config['issue_types']
|
19
|
+
else
|
20
|
+
jira_issue_type = JiraCommand::Jira::IssueType.new(config)
|
21
|
+
jira_issue_type.list
|
22
|
+
end
|
23
|
+
|
24
|
+
prompt = TTY::Prompt.new
|
25
|
+
|
26
|
+
issue_type = prompt.select('Which issue type do you want to create?') do |menu|
|
27
|
+
issue_types.each do |item|
|
28
|
+
menu.choice name: item['name'], value: item['id']
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
projects = if options['refresh-project'].nil?
|
33
|
+
config['projects']
|
34
|
+
else
|
35
|
+
jira_project = JiraCommand::Jira::Project.new(config)
|
36
|
+
jira_project.list
|
37
|
+
end
|
38
|
+
|
39
|
+
project = prompt.select('Which project does the issue belong to?') do |menu|
|
40
|
+
projects.each do |item|
|
41
|
+
menu.choice name: item['name'], value: { id: item['id'], key: item['key'] }
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
user_list = if options['refresh-user'].nil?
|
46
|
+
config['users']
|
47
|
+
else
|
48
|
+
user_api = JiraCommand::Jira::User.new(config)
|
49
|
+
user_api.all_list(project: project[:key])
|
50
|
+
end
|
51
|
+
|
52
|
+
assignee = prompt.select('Who do you want to assign?') do |menu|
|
53
|
+
user_list.each do |user|
|
54
|
+
menu.choice name: user['name'], value: user['account_id']
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
reporter = prompt.select('Who are you?') do |menu|
|
59
|
+
user_list.each do |user|
|
60
|
+
menu.choice name: user['name'], value: user['account_id']
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
summary = prompt.ask('Please input issue summary: ')
|
65
|
+
description = prompt.ask('Please input issue description: ')
|
66
|
+
|
67
|
+
jira_issue = JiraCommand::Jira::Issue.new(config)
|
68
|
+
|
69
|
+
puts 'the created issue url: ' + jira_issue.create(
|
70
|
+
summary: summary,
|
71
|
+
description: description,
|
72
|
+
assignee: assignee,
|
73
|
+
reporter: reporter,
|
74
|
+
project_id: project[:id],
|
75
|
+
issuetype_id: issue_type
|
76
|
+
)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'jira_command'
|
2
|
+
require 'thor'
|
3
|
+
require 'optparse'
|
4
|
+
require 'pry'
|
5
|
+
require_relative '../config'
|
6
|
+
require_relative '../jira/list'
|
7
|
+
require 'tty-prompt'
|
8
|
+
require 'base64'
|
9
|
+
require 'terminal-table'
|
10
|
+
|
11
|
+
module JiraCommand
|
12
|
+
module Command
|
13
|
+
class List < Thor
|
14
|
+
default_command :unresolved
|
15
|
+
|
16
|
+
desc 'all', 'list issues'
|
17
|
+
def all
|
18
|
+
config = JiraCommand::Config.new.read
|
19
|
+
list = JiraCommand::Jira::List.new(config)
|
20
|
+
issues_list = list.list({ fields: 'id,key,status,issuetype,assignee,summary' })
|
21
|
+
show_in_console(config['jira_url'], issues_list['issues'])
|
22
|
+
end
|
23
|
+
|
24
|
+
desc 'unresolved', 'list issues'
|
25
|
+
def unresolved
|
26
|
+
config = JiraCommand::Config.new.read
|
27
|
+
list = JiraCommand::Jira::List.new(config)
|
28
|
+
issues_list = list.list({ fields: 'id,key,status,issuetype,assignee,summary',
|
29
|
+
jql: 'status not in (resolved)' })
|
30
|
+
|
31
|
+
show_in_console(config['jira_url'], issues_list['issues'])
|
32
|
+
end
|
33
|
+
|
34
|
+
desc 'my', 'list your issues'
|
35
|
+
option 'current', aliases: 'c', required: false
|
36
|
+
option 'unresolved', aliases: 'u', required: false
|
37
|
+
def my
|
38
|
+
jql = ['assignee=currentUser()']
|
39
|
+
jql << 'sprint in openSprints()' unless options['current'].nil?
|
40
|
+
jql << 'status not in (resolved)' unless options['unresolved'].nil?
|
41
|
+
|
42
|
+
config = JiraCommand::Config.new.read
|
43
|
+
list = JiraCommand::Jira::List.new(config)
|
44
|
+
issues_list = list.list({ fields: 'id,key,status,issuetype,assignee,summary',
|
45
|
+
jql: jql.join('&') })
|
46
|
+
|
47
|
+
show_in_console(config['jira_url'], issues_list['issues'])
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
def show_in_console(jira_url, issues)
|
53
|
+
issue_list = issues.map do |issue|
|
54
|
+
{ key: issue['key'],
|
55
|
+
summary: issue['fields']['summary'],
|
56
|
+
assignee: issue['fields']['assignee'].nil? ? 'not assinged' : issue['fields']['assignee']['displayName'],
|
57
|
+
type: issue['fields']['issuetype']['name'],
|
58
|
+
status: issue['fields']['status']['name'],
|
59
|
+
link: jira_url + 'browse/' + issue['key'] }
|
60
|
+
end
|
61
|
+
|
62
|
+
table = Terminal::Table.new
|
63
|
+
table.headings = issue_list.first.keys
|
64
|
+
table.rows = issue_list.sort_by { |data| "#{data['status']}-#{data['key']}-#{data['type']}" }.map(&:values)
|
65
|
+
|
66
|
+
puts table
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'thor'
|
2
|
+
require 'optparse'
|
3
|
+
require_relative '../config'
|
4
|
+
require_relative '../jira/status'
|
5
|
+
|
6
|
+
module JiraCommand
|
7
|
+
module Command
|
8
|
+
class Status < Thor
|
9
|
+
desc 'project', 'list status in specified project'
|
10
|
+
option 'project', aliases: 'p', required: true
|
11
|
+
def project
|
12
|
+
config = JiraCommand::Config.new.read
|
13
|
+
|
14
|
+
jira = JiraCommand::Jira::Status.new(config)
|
15
|
+
res = jira.list(project: options['project'])
|
16
|
+
|
17
|
+
puts res.map(:name)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'thor'
|
2
|
+
require 'optparse'
|
3
|
+
require 'tty-prompt'
|
4
|
+
require_relative '../config'
|
5
|
+
require_relative '../jira/transition'
|
6
|
+
|
7
|
+
module JiraCommand
|
8
|
+
module Command
|
9
|
+
class Transition < Thor
|
10
|
+
default_command :exec
|
11
|
+
|
12
|
+
desc 'exec', 'transit issue status'
|
13
|
+
option 'issue', aliases: 'i', required: true
|
14
|
+
def exec
|
15
|
+
config = JiraCommand::Config.new.read
|
16
|
+
|
17
|
+
jira = JiraCommand::Jira::Transition.new(config)
|
18
|
+
res = jira.list(issue_key: options['issue'])
|
19
|
+
|
20
|
+
prompt = TTY::Prompt.new
|
21
|
+
|
22
|
+
target_transition_id = prompt.select('Which status do you want to transite?') do |menu|
|
23
|
+
res.each do |transition|
|
24
|
+
menu.choice name: transition[:name], value: transition[:id]
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
jira.transite(issue_key: options['issue'], target_transition_id: target_transition_id)
|
29
|
+
end
|
30
|
+
|
31
|
+
desc 'issue', 'transite issue status'
|
32
|
+
option 'current', aliases: 'c', required: false
|
33
|
+
option 'mine', aliases: 'm', required: false
|
34
|
+
def issue
|
35
|
+
jql = []
|
36
|
+
jql << 'sprint in openSprints()' unless options['current'].nil?
|
37
|
+
jql << 'assignee=currentUser()' unless options['mine'].nil?
|
38
|
+
|
39
|
+
config = JiraCommand::Config.new.read
|
40
|
+
|
41
|
+
list = JiraCommand::Jira::List.new(config)
|
42
|
+
issues_list = list.list({ fields: 'key,status,assignee,summary',
|
43
|
+
jql: jql.join('&') })
|
44
|
+
|
45
|
+
prompt = TTY::Prompt.new
|
46
|
+
|
47
|
+
issue_key = prompt.select('Which issue do you want to transite?') do |menu|
|
48
|
+
issues_list['issues'].map do |i|
|
49
|
+
assignee = i['fields']['assignee']
|
50
|
+
menu.choice(name: "#{assignee.nil? ? 'not assigned' : assignee['displayName']}: #{i['fields']['summary']}(#{i['fields']['status']['name']})",
|
51
|
+
value: i['key'])
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
jira = JiraCommand::Jira::Transition.new(config)
|
56
|
+
res = jira.list(issue_key: issue_key)
|
57
|
+
|
58
|
+
target_transition_id = prompt.select('Which status do you want to transite?') do |menu|
|
59
|
+
res.each do |transition|
|
60
|
+
menu.choice name: transition[:name], value: transition[:id]
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
jira.transite(issue_key: issue_key, target_transition_id: target_transition_id)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|