redmine_cli 0.4.1 → 0.5.0

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: bc624f0adc7b3abfb235b72185d411a86b58185b
4
- data.tar.gz: 00c6f9dbd1619f0ec3b02737e4572a2b4e872121
3
+ metadata.gz: 32498eec5c1276546c816822dde138b72a826d22
4
+ data.tar.gz: 50336d81f2a26124ea63d2b2ed48d7fcdd0bb38d
5
5
  SHA512:
6
- metadata.gz: 365203c3d24ef79f74b270c55e4c2a8be5dd5f66b1f82266de543ed6f2c01d5242331881b19572043b5e1816ed98e7f99bbb7bd0267b084c654f31ba3b76f0e7
7
- data.tar.gz: e496799303f3561a3f90152613b113641eb5ded66cea3ea0a95924ef152d624d59c1dfabc15bbfbfb03c3b33cedd9c47e4b0f20b0cd4b752b2dbb8e667039632
6
+ metadata.gz: 248f44ffd06f6d859a850d2026c94ab4f9bb2b431679e3dbc3c6452f9b7de2a9c08946d33d0bf8cde8e1802c6618840e63d27fe9e009061db94d8b5c3e3f3079
7
+ data.tar.gz: ae9920568649936d6eeaa43cc448cd61b23f7d1c05064a7867191b60cf124001a4e1c8d1f290c9a345bc84c80c2f9c9b362cb4cffa89871287c205b58520cae2
data/README.md CHANGED
@@ -22,6 +22,19 @@ Why? 'cause web-browser + mouse sucks
22
22
  redmine user find 123
23
23
  redmine user find pupkin@yet.another.mail.com
24
24
 
25
+ redmine project list
26
+ redmine project members 1
27
+ redmine project members trololo
28
+
29
+ Don't forget about console aliases!
30
+ I use something like this:
31
+
32
+ # alias i='redmine issue'
33
+ # by the way, Thor can guess your commands so:
34
+
35
+ $ i s 123
36
+ $ i u --assign 'vasya pupkin'
37
+
25
38
 
26
39
  ## Contributing
27
40
 
@@ -4,6 +4,7 @@ en:
4
4
  issue: 'Works with issues. See "redmine issue help"'
5
5
  conf: 'Works with config file. See "redmine conf help"'
6
6
  user: 'Works with users. See "redmine user help"'
7
+ project: 'Works with projects. See "redmine project help"'
7
8
  issue:
8
9
  list: 'Lists issues of user. By default it is you'
9
10
  show: 'More info about issue'
@@ -14,7 +15,7 @@ en:
14
15
  limit: 'Amount of comments (last journals).'
15
16
  update:
16
17
  done: 'Readiness percentage'
17
- assign: 'ID of user issue will be assigned to'
18
+ assign: 'ID of name part of user issue will be assigned to'
18
19
  time: 'Add time entry. Formats: HH:MM; M (minutes); H.h (hours in float)'
19
20
  status: 'Change status of issue. Search by status name substring'
20
21
  comment: 'Leave comment. It will open your text editor.'
@@ -23,7 +24,9 @@ en:
23
24
  init: 'Asks you few question to make your config file useful'
24
25
  user:
25
26
  find: 'Finds users by id|email|name. Without arguments it will show your info'
26
-
27
+ project:
28
+ list: 'Just lists project name with IDs'
29
+ members: 'Lists members of given project'
27
30
  commands:
28
31
  conf:
29
32
  init:
@@ -0,0 +1,16 @@
1
+ % if list.size.zero?
2
+ Empty list
3
+ % end
4
+ %
5
+ %
6
+ % head_id = '(id)'
7
+ % max_id_len = list.map(&:id).map(&:size).max || 0
8
+ % max_id_len = [max_id_len, head_id.size].max
9
+ %
10
+ % head_name = '(name)'
11
+ %
12
+ <%= head_id.yellow %> | <%= head_name.yellow %>
13
+
14
+ % list.each do |object|
15
+ <%= object.id.rjust(max_id_len) %> - <%= object.name %><%= "\n" %>
16
+ % end
@@ -32,6 +32,14 @@
32
32
  * <%= issue_id == issue.id ? 'this' : issue_id %> <%= relation_type %> <%= issue_to_id == issue.id ? 'this' : issue_to_id %>
33
33
  % end
34
34
 
35
+ % end
36
+ %
37
+ % if issue.attachments?
38
+ <%= 'Attachments:'.yellow %>
39
+
40
+ % issue.attachments.each do |a|
41
+ <%= '*'.yellow %> <%= a.filename %> - <%= a.content_url %>
42
+ % end
35
43
  % end
36
44
  %
37
45
  % if issue.description? && !issue.description.empty?
@@ -1,4 +1,5 @@
1
1
  module RedmineCLI
2
+ class ProjectNotFound < StandardError; end
2
3
  class UserNotFound < StandardError; end
3
4
  class BadInputTime < StandardError; end
4
5
  class EmptyList < StandardError; end
@@ -12,16 +12,10 @@ module RedmineCLI
12
12
  include Helpers::Output
13
13
 
14
14
  def ask_for_user(message, params = {})
15
- params[:limited_to] = proc do |input|
16
- begin
17
- @ask_for_user_cache = RedmineRest::Models::User.find(input) # save record
18
- rescue
19
- nil
20
- end
21
- end
15
+ params[:limited_to] = ->(input) { @cached_user = RedmineRest::Models::User.find_by_id(input) }
22
16
 
23
17
  ask(message, params)
24
- @ask_for_user_cache
18
+ @cached_user
25
19
  end
26
20
 
27
21
  def ask_from_text_editor(welcome_message = '')
@@ -58,25 +52,6 @@ module RedmineCLI
58
52
  object_list[input.to_i]
59
53
  end
60
54
 
61
- #
62
- # Parses time from user's input.
63
- # Formats: HH:MM; M; H.h
64
- #
65
- # @param input [String]
66
- #
67
- def parse_time(input)
68
- fail(BadInputTime) unless input =~ /^\d+[\:\.]?\d*/
69
-
70
- if input.include?(':')
71
- h, m = input.split(':').map(&:to_i)
72
- (60 * h + m) / 60.0
73
- elsif input.include?('.')
74
- input.to_f
75
- else
76
- input.to_i
77
- end
78
- end
79
-
80
55
  #
81
56
  # #ask with :limited_to set to url regexp.
82
57
  # TODO: make good regexp
@@ -32,12 +32,9 @@ module RedmineCLI
32
32
 
33
33
  def update_assigned_to(issue)
34
34
  return unless options[:assign]
35
+ issue.assigned_to_id = InputParser.parse_user(options[:assign], project: issue.project).id
35
36
 
36
- # it can raise exception if there's no such user
37
- Models::User.find(options[:assign])
38
- issue.assigned_to_id = options[:assign]
39
-
40
- rescue ActiveResource::ResourceNotFound
37
+ rescue UserNotFound
41
38
  @errors.push "Assigned: #{m(:not_found)}"
42
39
  end
43
40
 
@@ -70,7 +67,7 @@ module RedmineCLI
70
67
  def add_time_entry_to_issue(issue)
71
68
  return unless options[:time]
72
69
 
73
- hours = parse_time(options[:time])
70
+ hours = InputParser.parse_time(options[:time])
74
71
  entry = Models::TimeEntry.create issue_id: issue.id,
75
72
  hours: hours
76
73
 
@@ -7,4 +7,10 @@ class String
7
7
 
8
8
  self[0...max_chars - 3] + '...'
9
9
  end
10
+
11
+ def numeric?
12
+ Integer(self)
13
+ rescue
14
+ false
15
+ end
10
16
  end
@@ -0,0 +1,71 @@
1
+ module RedmineCLI
2
+ #
3
+ # class with some methods for user input processing
4
+ #
5
+ class InputParser
6
+ extend Helpers::Input
7
+
8
+ #
9
+ # Processes string and tries to find project
10
+ #
11
+ def self.parse_project(value)
12
+ by_id = RedmineRest::Models::Project.find_by_id(value) if value.numeric?
13
+ return by_id if by_id
14
+
15
+ found_projects = RedmineRest::Models::Project.all.filter_by_name_substring(value)
16
+ case found_projects.size
17
+ when 0 then fail(ProjectNotFound)
18
+ when 1 then found_projects.first
19
+ else ask_for_object(found_projects)
20
+ end
21
+
22
+ rescue ActiveResource::ResourceNotFound, ActiveResource::ForbiddenAccess
23
+ raise ProjectNotFound
24
+ end
25
+
26
+ #
27
+ # Processes string and tries to find user
28
+ #
29
+ # @return [RedmineRest::Models::User]
30
+ # @raise [UserNotFound]
31
+ #
32
+ def self.parse_user(value, project: nil)
33
+ return RedmineRest::Models::User.find(value) if value.numeric? || value == 'current'
34
+ fail UserNotFound unless project
35
+
36
+ user_from_project(project, value)
37
+
38
+ rescue ActiveResource::ResourceNotFound
39
+ raise UserNotFound
40
+ end
41
+
42
+ def self.user_from_project(project, name_substring = '')
43
+ found_members = project.members.filter_by_name_substring(name_substring)
44
+
45
+ case found_members.size
46
+ when 0 then fail(UserNotFound)
47
+ when 1 then found_members.first
48
+ else ask_for_object(found_members)
49
+ end
50
+ end
51
+
52
+ #
53
+ # Parses time from user's input.
54
+ # Formats: HH:MM; M; H.h
55
+ #
56
+ # @param input [String]
57
+ #
58
+ def self.parse_time(input)
59
+ fail(BadInputTime) unless input =~ /^\d+[\:\.]?\d*/
60
+
61
+ if input.include?(':')
62
+ h, m = input.split(':').map(&:to_i)
63
+ (60 * h + m) / 60.0
64
+ elsif input.include?('.')
65
+ input.to_f
66
+ else
67
+ input.to_i
68
+ end
69
+ end
70
+ end
71
+ end
@@ -16,7 +16,10 @@ module RedmineCLI
16
16
  def list(id = 'current')
17
17
  fail('new config') if Config.new?
18
18
 
19
- puts erb('issue/list', issues: Models::User.find(id).issues)
19
+ user = InputParser.parse_user(id)
20
+ puts erb('issue/list', issues: user.issues)
21
+ rescue UserNotFound
22
+ puts "User #{m(:not_found)}"
20
23
  end
21
24
 
22
25
  desc 'show <id>', m('desc.issue.show')
@@ -40,7 +43,7 @@ module RedmineCLI
40
43
  #
41
44
  desc 'update <id>', m('desc.issue.update')
42
45
  option :done, type: :numeric, aliases: '-d', desc: m('desc.issue.options.update.done')
43
- option :assign, type: :numeric, aliases: '-a', desc: m('desc.issue.options.update.assign')
46
+ option :assign, type: :string, aliases: '-a', desc: m('desc.issue.options.update.assign')
44
47
  option :time, type: :string, aliases: '-t', desc: m('desc.issue.options.update.time')
45
48
  option :status, type: :string, aliases: '-s', desc: m('desc.issue.options.update.status')
46
49
  option :comment, type: :boolean, aliases: '-c', desc: m('desc.issue.options.update.comment')
@@ -0,0 +1,36 @@
1
+ require 'thor'
2
+ require 'redmine_rest'
3
+ module RedmineCLI
4
+ module Subcommands
5
+ #
6
+ # Methods for working with projects
7
+ #
8
+ class Project < Thor
9
+ extend Helpers::Output
10
+
11
+ include RedmineRest
12
+ include Helpers::Output
13
+ include Helpers::Input
14
+
15
+ map 'users' => 'members'
16
+
17
+ desc 'list', m('desc.project.list')
18
+ def list
19
+ puts erb('id_and_name_list', list: Models::Project.all)
20
+ end
21
+
22
+ desc 'members <id | name part>', m('desc.project.members')
23
+ def members(project)
24
+ project = InputParser.parse_project(project)
25
+
26
+ users = project.members
27
+ .map(&:reload)
28
+ .sort { |a, b| a.id.to_i <=> b.id.to_i }
29
+
30
+ puts erb('user/find', users: users)
31
+ rescue ProjectNotFound
32
+ puts "Project #{m(:not_found)}"
33
+ end
34
+ end
35
+ end
36
+ end
@@ -1,3 +1,3 @@
1
1
  module RedmineCLI
2
- VERSION = '0.4.1'.freeze
2
+ VERSION = '0.5.0'.freeze
3
3
  end
data/lib/redmine_cli.rb CHANGED
@@ -10,6 +10,7 @@ Dir[File.expand_path('../redmine_cli/helpers/**/*.rb', __FILE__)].each { |f| req
10
10
  require 'redmine_cli/version'
11
11
  require 'redmine_cli/exceptions'
12
12
  require 'redmine_cli/config'
13
+ require 'redmine_cli/input_parser'
13
14
  I18n.locale = RedmineCLI::Config['locale']
14
15
 
15
16
  require 'redmine_cli/template_renderer'
@@ -43,5 +44,8 @@ module RedmineCLI
43
44
 
44
45
  desc 'user ...', m('desc.client.user')
45
46
  subcommand 'user', Subcommands::User
47
+
48
+ desc 'project ...', m('desc.client.project')
49
+ subcommand 'project', Subcommands::Project
46
50
  end
47
51
  end
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.6.1'
30
+ spec.add_dependency 'redmine_rest', '0.7.0'
31
31
  spec.add_dependency 'non_config', '0.1.2'
32
32
  spec.add_dependency 'colorize', '~> 0.7'
33
33
  spec.add_dependency 'unicode', '~> 0.4'
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.1
4
+ version: 0.5.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-25 00:00:00.000000000 Z
11
+ date: 2016-03-31 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.6.1
103
+ version: 0.7.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.6.1
110
+ version: 0.7.0
111
111
  - !ruby/object:Gem::Dependency
112
112
  name: non_config
113
113
  requirement: !ruby/object:Gem::Requirement
@@ -171,6 +171,7 @@ files:
171
171
  - exe/redmine
172
172
  - lib/assets/default_config.yml
173
173
  - lib/assets/messages/en.yml
174
+ - lib/assets/templates/en/id_and_name_list.erb
174
175
  - lib/assets/templates/en/issue/list.erb
175
176
  - lib/assets/templates/en/issue/show.erb
176
177
  - lib/assets/templates/en/user/find.erb
@@ -182,8 +183,10 @@ files:
182
183
  - lib/redmine_cli/helpers/issue/update.rb
183
184
  - lib/redmine_cli/helpers/monkey_patching.rb
184
185
  - lib/redmine_cli/helpers/output.rb
186
+ - lib/redmine_cli/input_parser.rb
185
187
  - lib/redmine_cli/subcommands/conf.rb
186
188
  - lib/redmine_cli/subcommands/issue.rb
189
+ - lib/redmine_cli/subcommands/project.rb
187
190
  - lib/redmine_cli/subcommands/user.rb
188
191
  - lib/redmine_cli/template_renderer.rb
189
192
  - lib/redmine_cli/version.rb