redmine_cli 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
[![Gem Version](https://badge.fury.io/rb/redmine_cli.svg)](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
|