redmine_cli 0.1.0 → 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/README.md +10 -14
- data/lib/assets/default_config.yml +0 -1
- data/lib/assets/messages/en.yml +21 -3
- data/lib/assets/templates/issue/list.erb +2 -2
- data/lib/assets/templates/issue/show.erb +24 -0
- data/lib/assets/templates/user/find.erb +12 -0
- data/lib/redmine_cli.rb +14 -0
- data/lib/redmine_cli/helpers/input.rb +84 -0
- data/lib/redmine_cli/helpers/output.rb +9 -0
- data/lib/redmine_cli/subcommands/conf.rb +27 -0
- data/lib/redmine_cli/subcommands/issue.rb +7 -0
- data/lib/redmine_cli/subcommands/user.rb +33 -0
- data/lib/redmine_cli/version.rb +1 -1
- data/redmine_cli.gemspec +1 -1
- metadata +9 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2f33a25599255db90496beb40a22b6b2bf43fd5f
|
4
|
+
data.tar.gz: 20990a7478cd142ffd4b44dc8415b1cf827e466a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e25ba315ea686838a6bf2efdae21b825c85a71f169119d178231e12b8b3ca312c47ad0f9b75c8757edffb3290ba8c13a461d4e7f1db384e97e3a8f48721ab005
|
7
|
+
data.tar.gz: 1218d34fce41ae549cba4560f0ad5abf8923d484a25ffdc77f515faed325a246a35650169229b91f4312c29ef4061b5924321ca940af85a506339e5afe908e10
|
data/README.md
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# RedmineCLI
|
2
|
+
[](https://badge.fury.io/rb/redmine_cli)
|
2
3
|
|
3
4
|
Command-Line Interface for Redmine.
|
4
5
|
|
@@ -6,27 +7,22 @@ Why? Because web-browser + mouse sucks
|
|
6
7
|
|
7
8
|
## Installation
|
8
9
|
|
9
|
-
Add this line to your application's Gemfile:
|
10
|
-
|
11
|
-
```ruby
|
12
|
-
gem 'redmine_cli'
|
13
|
-
```
|
14
|
-
|
15
|
-
And then execute:
|
16
|
-
|
17
|
-
$ bundle
|
18
|
-
|
19
|
-
Or install it yourself as:
|
20
|
-
|
21
10
|
$ gem install redmine_cli
|
22
11
|
|
23
12
|
## Usage
|
24
13
|
|
14
|
+
redmine help
|
15
|
+
redmine conf init
|
16
|
+
redmine issue list [user id]
|
17
|
+
redmine issue show <issue id>
|
18
|
+
redmine user find vasya
|
19
|
+
redmine user find 123
|
20
|
+
redmine user find pupkin@yet.another.mail.com
|
25
21
|
|
26
|
-
## Contributing
|
27
22
|
|
28
|
-
|
23
|
+
## Contributing
|
29
24
|
|
25
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/Nondv/redmine_cli.
|
30
26
|
|
31
27
|
## License
|
32
28
|
|
data/lib/assets/messages/en.yml
CHANGED
@@ -1,7 +1,25 @@
|
|
1
1
|
en:
|
2
|
-
test: '1234'
|
3
2
|
desc:
|
4
3
|
client:
|
5
|
-
|
4
|
+
issue: 'Works with issues. See "redmine issue help"'
|
5
|
+
conf: 'Works with config file. See "redmine conf help"'
|
6
|
+
user: 'Works with users. See "redmine user help"'
|
6
7
|
issue:
|
7
|
-
list: 'Lists issues of user. By default it is you'
|
8
|
+
list: 'Lists issues of user. By default it is you'
|
9
|
+
show: 'More info about issue'
|
10
|
+
conf:
|
11
|
+
init: 'Asks you few question to make your config file useful'
|
12
|
+
user:
|
13
|
+
find: 'Finds users by id|email|name. Without arguments it will show your info'
|
14
|
+
|
15
|
+
commands:
|
16
|
+
conf:
|
17
|
+
init:
|
18
|
+
enter_user: 'Enter your login to Redmine: '
|
19
|
+
enter_password: 'Enter your password: '
|
20
|
+
enter_site: 'Enter URL to your Redmine: '
|
21
|
+
|
22
|
+
thank_you: 'Thank you!'
|
23
|
+
error_try_again: 'Error! Try again.'
|
24
|
+
error_input_required: 'Input cant be empty.'
|
25
|
+
not_found: 'Not found'
|
@@ -1,9 +1,9 @@
|
|
1
1
|
% max_id_len = issues.max_by { |i| i.id.size }.id.size
|
2
2
|
% subject_limit = 60
|
3
3
|
%
|
4
|
-
% issues.
|
4
|
+
% issues.group_by_project.each do |project, project_issues|
|
5
5
|
|
6
|
-
<%= "[ #{project} ]".center(max_id_len + 3 + subject_limit + 3 + 8).red + "\n" %>
|
6
|
+
<%= "[ #{project.name} ]".center(max_id_len + 3 + subject_limit + 3 + 8).red + "\n" %>
|
7
7
|
<%= '(id)'.center(max_id_len).yellow %> | <%= '(subject)'.center(subject_limit).yellow %> | <%= "(status)\n".yellow %>
|
8
8
|
<% project_issues.each do |i| %>
|
9
9
|
<%= i.id.ljust(max_id_len) %> <%= i.subject.cut(subject_limit).ljust(subject_limit) %> <%= i.status.name %><%= "\n" %>
|
@@ -0,0 +1,24 @@
|
|
1
|
+
|
2
|
+
ID: <%= issue.id %>
|
3
|
+
Subject: <%= issue.subject %>
|
4
|
+
Status: <%= issue.status.name %>
|
5
|
+
Priority: <%= issue.priority.name %>
|
6
|
+
Readiness: <%= issue.done_ratio + '%' %>
|
7
|
+
% if issue.project?
|
8
|
+
Project: <%= issue.project.name %>
|
9
|
+
% end
|
10
|
+
% if issue.version?
|
11
|
+
Version: <%= issue.version.name %>
|
12
|
+
% end
|
13
|
+
Assigned to: <%= issue.assigned_to.name %> (<%= issue.assigned_to.id %>)
|
14
|
+
Author: <%= issue.author.name %> (<%= issue.author.id %>)
|
15
|
+
% if issue.description? && !issue.description.empty?
|
16
|
+
|
17
|
+
*****
|
18
|
+
|
19
|
+
<%= issue.description %>
|
20
|
+
|
21
|
+
|
22
|
+
*****
|
23
|
+
% end
|
24
|
+
|
@@ -0,0 +1,12 @@
|
|
1
|
+
% max_id_len = users.map { |u| u.id.size }.max
|
2
|
+
% max_name_len = users.map { |u| u.firstname.size + u.lastname.size + 1 }.max
|
3
|
+
% max_email_len = users.map { |u| u.mail? ? u.mail.size : 0 }.max
|
4
|
+
%
|
5
|
+
% if users.size > 1
|
6
|
+
<%= 'id'.ljust(max_id_len).yellow %> | <%= 'name'.center(max_name_len).yellow %> | <%= 'e-mail'.center(max_email_len).yellow + "\n" %>
|
7
|
+
% end
|
8
|
+
%
|
9
|
+
% users.each do |u|
|
10
|
+
% name = u.firstname + ' ' + u.lastname
|
11
|
+
<%= u.id.ljust(max_id_len) %> <%= name.ljust(max_name_len) %> <%= "#{u.mail? && u.mail}\n" %>
|
12
|
+
% end
|
data/lib/redmine_cli.rb
CHANGED
@@ -26,7 +26,21 @@ module RedmineCLI
|
|
26
26
|
class Client < Thor
|
27
27
|
extend Helpers::Output
|
28
28
|
|
29
|
+
map %w(--version -v) => :__print_version
|
30
|
+
|
31
|
+
desc '--version, -v', 'print the version'
|
32
|
+
# two underscores hides method from help
|
33
|
+
def __print_version
|
34
|
+
puts "redmine_cli version #{VERSION}"
|
35
|
+
end
|
36
|
+
|
29
37
|
desc 'issue ...', m('desc.client.issue')
|
30
38
|
subcommand 'issue', Subcommands::Issue
|
39
|
+
|
40
|
+
desc 'conf ...', m('desc.client.conf')
|
41
|
+
subcommand 'conf', Subcommands::Conf
|
42
|
+
|
43
|
+
desc 'user ...', m('desc.client.user')
|
44
|
+
subcommand 'user', Subcommands::User
|
31
45
|
end
|
32
46
|
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
require 'uri'
|
2
|
+
|
3
|
+
require_relative 'output'
|
4
|
+
|
5
|
+
module RedmineCLI
|
6
|
+
module Helpers
|
7
|
+
#
|
8
|
+
# Helpers for input
|
9
|
+
#
|
10
|
+
module Input
|
11
|
+
include Helpers::Output
|
12
|
+
|
13
|
+
#
|
14
|
+
# #ask with :limited_to set to url regexp
|
15
|
+
#
|
16
|
+
def ask_url(text, params = {})
|
17
|
+
params[:limited_to] = /\A#{URI.regexp(%w('http', 'https'))}\z/
|
18
|
+
ask(text, params)
|
19
|
+
end
|
20
|
+
|
21
|
+
#
|
22
|
+
# Asks user for something.
|
23
|
+
#
|
24
|
+
# Params:
|
25
|
+
# * `:default`
|
26
|
+
# * `:limited_to` - can be `Array<String>` or `Regexp`
|
27
|
+
# * `:required` - force user input until it's not empty
|
28
|
+
#
|
29
|
+
def ask(text, params = {})
|
30
|
+
default_set = params.key?(:default)
|
31
|
+
if params[:required]
|
32
|
+
fail('required + default options') if default_set
|
33
|
+
fail('required + array with limits') if params[:limited_to].is_a? Array
|
34
|
+
end
|
35
|
+
|
36
|
+
print_prompt_message(text, params)
|
37
|
+
input = read(params)
|
38
|
+
|
39
|
+
return params[:default] if default_set && input.empty?
|
40
|
+
input
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def read(params)
|
46
|
+
return read_with_limitations(params) if params[:limited_to]
|
47
|
+
return read_until_not_empty if params[:required]
|
48
|
+
|
49
|
+
gets.chomp
|
50
|
+
end
|
51
|
+
|
52
|
+
def read_until_not_empty
|
53
|
+
loop do
|
54
|
+
input = gets.chomp
|
55
|
+
return input unless input.empty?
|
56
|
+
|
57
|
+
puts m(:error_input_required)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def read_with_limitations(params)
|
62
|
+
input = nil
|
63
|
+
|
64
|
+
loop do
|
65
|
+
input = gets.chomp
|
66
|
+
break if fit_in_limit?(input, params[:limited_to])
|
67
|
+
return params[:default] if input.empty? && params.key?(:default)
|
68
|
+
|
69
|
+
puts m(:error_try_again)
|
70
|
+
end
|
71
|
+
|
72
|
+
input
|
73
|
+
end
|
74
|
+
|
75
|
+
def fit_in_limit?(input, limit)
|
76
|
+
fail('limit should be Array or Regexp') unless limit.is_a?(Array) || limit.is_a?(Regexp)
|
77
|
+
|
78
|
+
return limit.include?(input) if limit.is_a? Array
|
79
|
+
|
80
|
+
limit =~ input
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -4,6 +4,15 @@ module RedmineCLI
|
|
4
4
|
# Helpers for output
|
5
5
|
#
|
6
6
|
module Output
|
7
|
+
#
|
8
|
+
# for Helpers::Input
|
9
|
+
#
|
10
|
+
def print_prompt_message(text, params = {})
|
11
|
+
print text
|
12
|
+
print "[#{params[:default]}] " if params.key? :default
|
13
|
+
print "(#{params[:limited_to].join(', ')}) " if params[:limited_to].is_a? Array
|
14
|
+
end
|
15
|
+
|
7
16
|
#
|
8
17
|
# Alias for TemplateRenderer#render
|
9
18
|
#
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'thor'
|
2
|
+
|
3
|
+
module RedmineCLI
|
4
|
+
module Subcommands
|
5
|
+
#
|
6
|
+
# All methods for working with config file
|
7
|
+
#
|
8
|
+
class Conf < Thor
|
9
|
+
extend Helpers::Output
|
10
|
+
|
11
|
+
include Helpers::Output
|
12
|
+
include Helpers::Input
|
13
|
+
|
14
|
+
desc 'init', m('desc.conf.init')
|
15
|
+
def init
|
16
|
+
Config['user'] = ask m('commands.conf.init.enter_user'), default: Config['user']
|
17
|
+
Config['password'] = ask m('commands.conf.init.enter_password'), default: Config['password']
|
18
|
+
Config['site'] = ask_url m('commands.conf.init.enter_site'), default: Config['site']
|
19
|
+
Config['just_created'] = false
|
20
|
+
|
21
|
+
Config.save
|
22
|
+
|
23
|
+
puts m(:thank_you)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -18,6 +18,13 @@ module RedmineCLI
|
|
18
18
|
|
19
19
|
puts erb('issue/list', issues: Models::User.find(id).issues)
|
20
20
|
end
|
21
|
+
|
22
|
+
desc 'show <id>', m('desc.issue.show')
|
23
|
+
def show(id)
|
24
|
+
puts erb('issue/show', issue: Models::Issue.find(id))
|
25
|
+
rescue ActiveResource::ResourceNotFound
|
26
|
+
puts m(:not_found)
|
27
|
+
end
|
21
28
|
end
|
22
29
|
end
|
23
30
|
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'thor'
|
2
|
+
require 'redmine_rest'
|
3
|
+
module RedmineCLI
|
4
|
+
module Subcommands
|
5
|
+
#
|
6
|
+
# All methods for working with users
|
7
|
+
#
|
8
|
+
class User < Thor
|
9
|
+
extend Helpers::Output
|
10
|
+
|
11
|
+
include RedmineRest
|
12
|
+
include Helpers::Output
|
13
|
+
include Helpers::Input
|
14
|
+
|
15
|
+
desc 'find [id|name|email]', m('desc.user.find')
|
16
|
+
def find(*args)
|
17
|
+
input = args.join ' '
|
18
|
+
|
19
|
+
puts erb('user/find', users: users_from_input(input))
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def users_from_input(input)
|
25
|
+
if input.empty? || !input.to_i.zero? # TODO: numeric?
|
26
|
+
[Models::User.find(input.empty? ? 'current' : input.to_i)]
|
27
|
+
else
|
28
|
+
Models::User.all_by_name_or_mail(input).sort { |a, b| a.id.to_i <=> b.id.to_i }
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/lib/redmine_cli/version.rb
CHANGED
data/redmine_cli.gemspec
CHANGED
@@ -27,7 +27,7 @@ Gem::Specification.new do |spec|
|
|
27
27
|
|
28
28
|
spec.add_dependency 'thor', '~> 0.19'
|
29
29
|
spec.add_dependency 'i18n', '~> 0.7'
|
30
|
-
spec.add_dependency 'redmine_rest', '0.
|
30
|
+
spec.add_dependency 'redmine_rest', '0.2.0'
|
31
31
|
spec.add_dependency 'non_config', '0.1.2'
|
32
32
|
spec.add_dependency 'colorize', '~> 0.7'
|
33
33
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: redmine_cli
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dmitriy Non
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-03-
|
11
|
+
date: 2016-03-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -100,14 +100,14 @@ dependencies:
|
|
100
100
|
requirements:
|
101
101
|
- - '='
|
102
102
|
- !ruby/object:Gem::Version
|
103
|
-
version: 0.
|
103
|
+
version: 0.2.0
|
104
104
|
type: :runtime
|
105
105
|
prerelease: false
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
107
107
|
requirements:
|
108
108
|
- - '='
|
109
109
|
- !ruby/object:Gem::Version
|
110
|
-
version: 0.
|
110
|
+
version: 0.2.0
|
111
111
|
- !ruby/object:Gem::Dependency
|
112
112
|
name: non_config
|
113
113
|
requirement: !ruby/object:Gem::Requirement
|
@@ -158,11 +158,16 @@ files:
|
|
158
158
|
- lib/assets/default_config.yml
|
159
159
|
- lib/assets/messages/en.yml
|
160
160
|
- lib/assets/templates/issue/list.erb
|
161
|
+
- lib/assets/templates/issue/show.erb
|
162
|
+
- lib/assets/templates/user/find.erb
|
161
163
|
- lib/redmine_cli.rb
|
162
164
|
- lib/redmine_cli/config.rb
|
165
|
+
- lib/redmine_cli/helpers/input.rb
|
163
166
|
- lib/redmine_cli/helpers/monkey_patching.rb
|
164
167
|
- lib/redmine_cli/helpers/output.rb
|
168
|
+
- lib/redmine_cli/subcommands/conf.rb
|
165
169
|
- lib/redmine_cli/subcommands/issue.rb
|
170
|
+
- lib/redmine_cli/subcommands/user.rb
|
166
171
|
- lib/redmine_cli/template_renderer.rb
|
167
172
|
- lib/redmine_cli/version.rb
|
168
173
|
- redmine_cli.gemspec
|