gitlab-triage 0.7.0 → 0.8.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4ab21a6dffa12d92f9321ac3c6d2bc0c92627fad703fceb7ebf68494d8f5b259
4
- data.tar.gz: e5868058935e55d70ccadaada8030a8bec92dee6ceeeea2f9996cd60f3823cdf
3
+ metadata.gz: 0b8300cf129b3aefc203d528814c84eb8e06fa54154599b1b4e818f9365ab93c
4
+ data.tar.gz: e9d4b656207d0fa3322e10cd8618d6ac4bed5122b02f2dca34220d576cf81f57
5
5
  SHA512:
6
- metadata.gz: a875bebf70cd7dcc2a6c5f064d692535cdf98b664323fb640b22fed7f52ac4d5f49e8b21adb5b4942f626e4f4638d23f3042109ae13c495ae9c732d177e9298f
7
- data.tar.gz: 01a627062e23ba73d40be5cc7260a92aa7be9ec30b9fb694585305ae919435174099a701d6045998c03738ee7fd7dcf0cac9ebf821abfea9b4697fd6f8f55e06
6
+ metadata.gz: 2ceb150c8d07902495e80852aa914c91a14bbd82f84ab4123713f086282a5a7445bb141228eb50a9caef65d78957aecc0e889ec948a95193c046d659feaf31ba
7
+ data.tar.gz: b5e183ed3ab41aea72b54c4eb790d24e61c2422297d652139b22170da2cab69a04fe38e07e5de0ba9c99d95fd1a0a9c8c3169a7241f62bafffb94c2947a5263b
data/README.md CHANGED
@@ -46,6 +46,8 @@ resource_rules:
46
46
  state: opened
47
47
  labels:
48
48
  - No Label
49
+ limits:
50
+ most_recent: 50
49
51
  actions:
50
52
  labels:
51
53
  - needs attention
@@ -63,6 +65,7 @@ resource_rules:
63
65
  A policy consists of the following fields:
64
66
  - [Name field](#name-field)
65
67
  - [Conditions field](#conditions-field)
68
+ - [Limits field](#limits-field)
66
69
  - [Actions field](#actions-field)
67
70
 
68
71
  #### Name field
@@ -381,6 +384,30 @@ Here's a list of currently available API:
381
384
  | succ | Milestone | The next active milestone beside this milestone |
382
385
  | active? | Boolean | `true` if `state` is `active`; `false` otherwise |
383
386
 
387
+ #### Limits field
388
+
389
+ Limits restrict the number of resources on which an action is carried out. They
390
+ can be useful when combined with conditions that return a large number of
391
+ resources. For example, if the conditions are satisfied by thousands of issues a
392
+ limit can be configured to process only fifty of them to avoid making an
393
+ overwhelming number of changes at once.
394
+
395
+ Accepts a key and value pair where the key is `most_recent` or `oldest`and the
396
+ value is the number of resources to act on. The following table outlines how
397
+ each key affects the sorting and order of resources that it limits.
398
+
399
+ | Name / Key | Sorted by | Order |
400
+ | --------- | ---- | ------ |
401
+ | `most_recent` | `created_at` | descending |
402
+ | `oldest` | `created_at` | ascending |
403
+
404
+ Example:
405
+
406
+ ```yml
407
+ limits:
408
+ most_recent: 50
409
+ ```
410
+
384
411
  #### Actions field
385
412
 
386
413
  Used to declare an action to be carried out on a resource if **all** conditions are satisfied.
@@ -8,6 +8,7 @@ require_relative 'filters/no_additional_labels_conditions_filter'
8
8
  require_relative 'filters/author_member_conditions_filter'
9
9
  require_relative 'filters/assignee_member_conditions_filter'
10
10
  require_relative 'filters/ruby_conditions_filter'
11
+ require_relative 'limiters/date_field_limiter'
11
12
  require_relative 'command_builders/comment_body_builder'
12
13
  require_relative 'command_builders/comment_command_builder'
13
14
  require_relative 'command_builders/label_command_builder'
@@ -88,20 +89,27 @@ module Gitlab
88
89
  rule.fetch(:actions) { {} }
89
90
  end
90
91
 
92
+ def rule_limits(rule)
93
+ rule.fetch(:limits) { {} }
94
+ end
95
+
91
96
  def process_rule(resource_type, rule)
92
97
  ExpandCondition.perform(rule_conditions(rule)) do |conditions|
93
98
  # retrieving the resources for every rule is inefficient
94
99
  # however, previous rules may affect those upcoming
95
100
  resources = network.query_api(options.token, build_get_url(resource_type, conditions))
96
101
  puts "\n\n* Found #{resources.count} resources..."
102
+ print "* Filtering resources..."
103
+ resources = filter_resources(resources, conditions)
104
+ puts "\n* Total after filtering: #{resources.count} resources"
97
105
  print "* Limiting resources..."
98
- resources = limit_resources(resources, conditions)
99
- puts "\n* Total resource after limiting: #{resources.count} resources"
106
+ resources = limit_resources(resources, rule_limits(rule))
107
+ puts "\n* Total after limiting: #{resources.count} resources"
100
108
  process_resources(resource_type, resources, rule)
101
109
  end
102
110
  end
103
111
 
104
- def limit_resources(resources, conditions)
112
+ def filter_resources(resources, conditions)
105
113
  net = { host_url: host_url, api_version: api_version, token: options.token, network: network }
106
114
 
107
115
  resources.select do |resource|
@@ -119,6 +127,14 @@ module Gitlab
119
127
  end
120
128
  end
121
129
 
130
+ def limit_resources(resources, limits)
131
+ if limits.empty?
132
+ resources
133
+ else
134
+ Limiters::DateFieldLimiter.new(resources, limits).limit
135
+ end
136
+ end
137
+
122
138
  def process_resources(resource_type, resources, rule)
123
139
  if options.dry_run
124
140
  puts "\nThe following comments would be posted for the rule **#{rule[:name]}**:\n\n"
@@ -1,4 +1,5 @@
1
1
  require 'active_support/all'
2
+ require_relative '../validators/params_validator'
2
3
 
3
4
  module Gitlab
4
5
  module Triage
@@ -47,33 +48,10 @@ module Gitlab
47
48
  private
48
49
 
49
50
  def validate_condition(condition)
50
- validate_required_parameters(condition)
51
- validate_parameter_types(condition)
52
- validate_parameter_content(condition)
51
+ ParamsValidator.new(self.class.filter_parameters, condition).validate!
53
52
  end
54
53
 
55
54
  def initialize_variables(condition); end
56
-
57
- def validate_required_parameters(condition)
58
- self.class.filter_parameters.each do |param|
59
- raise ArgumentError, "#{param[:name]} is a required parameter" unless condition[param[:name]]
60
- end
61
- end
62
-
63
- def validate_parameter_types(condition)
64
- self.class.filter_parameters.each do |param|
65
- param_types = Array(param[:type]).flatten
66
- raise ArgumentError, "#{param[:name]} must be of type #{param[:type]}" unless param_types.any? { |type| condition[param[:name]].is_a?(type) }
67
- end
68
- end
69
-
70
- def validate_parameter_content(condition)
71
- self.class.filter_parameters.each do |param|
72
- if param[:values]
73
- raise ArgumentError, "#{param[:name]} must be of one of #{param[:values].join(',')}" unless param[:values].include?(condition[param[:name]])
74
- end
75
- end
76
- end
77
55
  end
78
56
  end
79
57
  end
@@ -0,0 +1,35 @@
1
+ require 'active_support/all'
2
+
3
+ module Gitlab
4
+ module Triage
5
+ module Limiters
6
+ class BaseLimiter
7
+ def initialize(resources, limit)
8
+ @resources = initialize_resources(resources)
9
+ validate_limit(limit)
10
+ initialize_variables(limit)
11
+ end
12
+
13
+ def limit
14
+ raise NotImplementedError
15
+ end
16
+
17
+ def self.limiter_parameters
18
+ []
19
+ end
20
+
21
+ private
22
+
23
+ def initialize_variables(limit); end
24
+
25
+ def initialize_resources(resources)
26
+ resources
27
+ end
28
+
29
+ def validate_limit(limit)
30
+ LimiterValidator.new(self.class.limiter_parameters, limit).validate!
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,45 @@
1
+ require_relative 'base_limiter'
2
+ require_relative '../validators/limiter_validator'
3
+
4
+ module Gitlab
5
+ module Triage
6
+ module Limiters
7
+ class DateFieldLimiter < BaseLimiter
8
+ LIMITS = %i[most_recent oldest].freeze
9
+
10
+ def self.limiter_parameters
11
+ [
12
+ {
13
+ name: :most_recent,
14
+ type: Integer
15
+ },
16
+ {
17
+ name: :oldest,
18
+ type: Integer
19
+ }
20
+ ]
21
+ end
22
+
23
+ def initialize_variables(limit)
24
+ @criterion = LIMITS.find(&limit.method(:[]))
25
+ @threshold = limit[@criterion]
26
+ end
27
+
28
+ def limit
29
+ case @criterion
30
+ when :most_recent
31
+ @resources.first(@threshold)
32
+ when :oldest
33
+ @resources.last(@threshold)
34
+ end
35
+ end
36
+
37
+ private
38
+
39
+ def initialize_resources(resources)
40
+ resources.sort_by { |res| res[:created_at] }
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,19 @@
1
+ require_relative 'params_validator'
2
+
3
+ module Gitlab
4
+ module Triage
5
+ class LimiterValidator < ParamsValidator
6
+ private
7
+
8
+ def params_limiter_names
9
+ @parameter_definitions.map do |param|
10
+ param[:name]
11
+ end
12
+ end
13
+
14
+ def validate_required_parameters(value)
15
+ raise ArgumentError, "For the limits field, please specify one of: `#{params_limiter_names.join('`, `')}`" unless value.keys.map(&:to_sym).one? { |key| params_limiter_names.include?(key) }
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,41 @@
1
+ module Gitlab
2
+ module Triage
3
+ class ParamsValidator
4
+ def initialize(parameter_definitions, value)
5
+ @parameter_definitions = parameter_definitions
6
+ @value = value
7
+ end
8
+
9
+ def validate!
10
+ validate_required_parameters(@value)
11
+ validate_parameter_types(@value)
12
+ validate_parameter_content(@value)
13
+ end
14
+
15
+ private
16
+
17
+ def validate_required_parameters(value)
18
+ @parameter_definitions.each do |param|
19
+ raise ArgumentError, "#{param[:name]} is a required parameter" unless value[param[:name]]
20
+ end
21
+ end
22
+
23
+ def validate_parameter_types(value)
24
+ @parameter_definitions.each do |param|
25
+ if value.has_key?(param[:name])
26
+ param_types = Array(param[:type]).flatten
27
+ raise ArgumentError, "#{param[:name]} must be of type #{param[:type]}" unless param_types.any? { |type| value[param[:name]].is_a?(type) }
28
+ end
29
+ end
30
+ end
31
+
32
+ def validate_parameter_content(value)
33
+ @parameter_definitions.each do |param|
34
+ if param[:values]
35
+ raise ArgumentError, "#{param[:name]} must be of one of #{param[:values].join(',')}" unless param[:values].include?(value[param[:name]])
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -1,5 +1,5 @@
1
1
  module Gitlab
2
2
  module Triage
3
- VERSION = '0.7.0'.freeze
3
+ VERSION = '0.8.0'.freeze
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gitlab-triage
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0
4
+ version: 0.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - GitLab
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-08-10 00:00:00.000000000 Z
11
+ date: 2018-08-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -155,6 +155,8 @@ files:
155
155
  - lib/gitlab/triage/filters/no_additional_labels_conditions_filter.rb
156
156
  - lib/gitlab/triage/filters/ruby_conditions_filter.rb
157
157
  - lib/gitlab/triage/filters/votes_conditions_filter.rb
158
+ - lib/gitlab/triage/limiters/base_limiter.rb
159
+ - lib/gitlab/triage/limiters/date_field_limiter.rb
158
160
  - lib/gitlab/triage/network.rb
159
161
  - lib/gitlab/triage/network_adapters/base_adapter.rb
160
162
  - lib/gitlab/triage/network_adapters/httparty_adapter.rb
@@ -165,6 +167,8 @@ files:
165
167
  - lib/gitlab/triage/retryable.rb
166
168
  - lib/gitlab/triage/ui.rb
167
169
  - lib/gitlab/triage/url_builders/url_builder.rb
170
+ - lib/gitlab/triage/validators/limiter_validator.rb
171
+ - lib/gitlab/triage/validators/params_validator.rb
168
172
  - lib/gitlab/triage/version.rb
169
173
  - support/.gitlab-ci.example.yml
170
174
  - support/.triage-policies.example.yml