payping-gitlab-triage 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (108) hide show
  1. checksums.yaml +7 -0
  2. data/.codeclimate.yml +19 -0
  3. data/.gitignore +15 -0
  4. data/.gitlab/CODEOWNERS +2 -0
  5. data/.gitlab/changelog_config.yml +13 -0
  6. data/.gitlab/issue_templates/Default.md +13 -0
  7. data/.gitlab/merge_request_templates/Default.md +11 -0
  8. data/.gitlab/merge_request_templates/Release.md +13 -0
  9. data/.gitlab-ci.yml +146 -0
  10. data/.rubocop.yml +21 -0
  11. data/.rubocop_todo.yml +145 -0
  12. data/.ruby-version +1 -0
  13. data/.tool-versions +1 -0
  14. data/.yardopts +4 -0
  15. data/CONTRIBUTING.md +31 -0
  16. data/Dangerfile +5 -0
  17. data/Gemfile +15 -0
  18. data/Guardfile +70 -0
  19. data/LICENSE.md +25 -0
  20. data/README.md +1480 -0
  21. data/Rakefile +6 -0
  22. data/bin/gitlab-triage +19 -0
  23. data/gitlab-triage.gemspec +41 -0
  24. data/lib/gitlab/triage/action/base.rb +14 -0
  25. data/lib/gitlab/triage/action/comment.rb +104 -0
  26. data/lib/gitlab/triage/action/comment_on_summary.rb +83 -0
  27. data/lib/gitlab/triage/action/delete.rb +56 -0
  28. data/lib/gitlab/triage/action/issue.rb +64 -0
  29. data/lib/gitlab/triage/action/summarize.rb +82 -0
  30. data/lib/gitlab/triage/action.rb +36 -0
  31. data/lib/gitlab/triage/api_query_builders/base_query_param_builder.rb +27 -0
  32. data/lib/gitlab/triage/api_query_builders/date_query_param_builder.rb +42 -0
  33. data/lib/gitlab/triage/api_query_builders/multi_query_param_builder.rb +28 -0
  34. data/lib/gitlab/triage/api_query_builders/single_query_param_builder.rb +13 -0
  35. data/lib/gitlab/triage/command_builders/base_command_builder.rb +40 -0
  36. data/lib/gitlab/triage/command_builders/cc_command_builder.rb +19 -0
  37. data/lib/gitlab/triage/command_builders/comment_command_builder.rb +19 -0
  38. data/lib/gitlab/triage/command_builders/label_command_builder.rb +40 -0
  39. data/lib/gitlab/triage/command_builders/move_command_builder.rb +19 -0
  40. data/lib/gitlab/triage/command_builders/remove_label_command_builder.rb +15 -0
  41. data/lib/gitlab/triage/command_builders/status_command_builder.rb +23 -0
  42. data/lib/gitlab/triage/command_builders/text_content_builder.rb +138 -0
  43. data/lib/gitlab/triage/engine.rb +635 -0
  44. data/lib/gitlab/triage/entity_builders/issue_builder.rb +54 -0
  45. data/lib/gitlab/triage/entity_builders/summary_builder.rb +82 -0
  46. data/lib/gitlab/triage/errors/network.rb +11 -0
  47. data/lib/gitlab/triage/errors.rb +1 -0
  48. data/lib/gitlab/triage/expand_condition/expansion.rb +203 -0
  49. data/lib/gitlab/triage/expand_condition/list.rb +25 -0
  50. data/lib/gitlab/triage/expand_condition/sequence.rb +25 -0
  51. data/lib/gitlab/triage/expand_condition.rb +23 -0
  52. data/lib/gitlab/triage/filters/assignee_member_conditions_filter.rb +13 -0
  53. data/lib/gitlab/triage/filters/author_member_conditions_filter.rb +13 -0
  54. data/lib/gitlab/triage/filters/base_conditions_filter.rb +58 -0
  55. data/lib/gitlab/triage/filters/branch_date_filter.rb +73 -0
  56. data/lib/gitlab/triage/filters/branch_protected_filter.rb +26 -0
  57. data/lib/gitlab/triage/filters/discussions_conditions_filter.rb +58 -0
  58. data/lib/gitlab/triage/filters/issue_date_conditions_filter.rb +78 -0
  59. data/lib/gitlab/triage/filters/member_conditions_filter.rb +84 -0
  60. data/lib/gitlab/triage/filters/merge_request_date_conditions_filter.rb +13 -0
  61. data/lib/gitlab/triage/filters/name_conditions_filter.rb +26 -0
  62. data/lib/gitlab/triage/filters/no_additional_labels_conditions_filter.rb +30 -0
  63. data/lib/gitlab/triage/filters/ruby_conditions_filter.rb +33 -0
  64. data/lib/gitlab/triage/filters/votes_conditions_filter.rb +54 -0
  65. data/lib/gitlab/triage/graphql_network.rb +81 -0
  66. data/lib/gitlab/triage/graphql_queries/query_builder.rb +158 -0
  67. data/lib/gitlab/triage/graphql_queries/query_param_builders/base_param_builder.rb +30 -0
  68. data/lib/gitlab/triage/graphql_queries/query_param_builders/date_param_builder.rb +35 -0
  69. data/lib/gitlab/triage/graphql_queries/query_param_builders/labels_param_builder.rb +18 -0
  70. data/lib/gitlab/triage/limiters/base_limiter.rb +35 -0
  71. data/lib/gitlab/triage/limiters/date_field_limiter.rb +45 -0
  72. data/lib/gitlab/triage/network.rb +39 -0
  73. data/lib/gitlab/triage/network_adapters/base_adapter.rb +17 -0
  74. data/lib/gitlab/triage/network_adapters/graphql_adapter.rb +92 -0
  75. data/lib/gitlab/triage/network_adapters/httparty_adapter.rb +116 -0
  76. data/lib/gitlab/triage/network_adapters/test_adapter.rb +39 -0
  77. data/lib/gitlab/triage/option_parser.rb +105 -0
  78. data/lib/gitlab/triage/options.rb +30 -0
  79. data/lib/gitlab/triage/param_builders/date_param_builder.rb +64 -0
  80. data/lib/gitlab/triage/policies/base_policy.rb +80 -0
  81. data/lib/gitlab/triage/policies/rule_policy.rb +36 -0
  82. data/lib/gitlab/triage/policies/summary_policy.rb +29 -0
  83. data/lib/gitlab/triage/policies_resources/rule_resources.rb +11 -0
  84. data/lib/gitlab/triage/policies_resources/summary_resources.rb +11 -0
  85. data/lib/gitlab/triage/resource/base.rb +102 -0
  86. data/lib/gitlab/triage/resource/branch.rb +13 -0
  87. data/lib/gitlab/triage/resource/context.rb +47 -0
  88. data/lib/gitlab/triage/resource/epic.rb +20 -0
  89. data/lib/gitlab/triage/resource/instance_version.rb +35 -0
  90. data/lib/gitlab/triage/resource/issue.rb +52 -0
  91. data/lib/gitlab/triage/resource/label.rb +56 -0
  92. data/lib/gitlab/triage/resource/label_event.rb +48 -0
  93. data/lib/gitlab/triage/resource/linked_issue.rb +15 -0
  94. data/lib/gitlab/triage/resource/merge_request.rb +23 -0
  95. data/lib/gitlab/triage/resource/milestone.rb +98 -0
  96. data/lib/gitlab/triage/resource/shared/issuable.rb +119 -0
  97. data/lib/gitlab/triage/rest_api_network.rb +125 -0
  98. data/lib/gitlab/triage/retryable.rb +33 -0
  99. data/lib/gitlab/triage/ui.rb +23 -0
  100. data/lib/gitlab/triage/url_builders/url_builder.rb +54 -0
  101. data/lib/gitlab/triage/utils.rb +13 -0
  102. data/lib/gitlab/triage/validators/limiter_validator.rb +21 -0
  103. data/lib/gitlab/triage/validators/params_validator.rb +43 -0
  104. data/lib/gitlab/triage/version.rb +7 -0
  105. data/lib/gitlab/triage.rb +6 -0
  106. data/support/.gitlab-ci.example.yml +22 -0
  107. data/support/.triage-policies.example.yml +51 -0
  108. metadata +280 -0
@@ -0,0 +1,19 @@
1
+ require_relative 'base_command_builder'
2
+
3
+ module Gitlab
4
+ module Triage
5
+ module CommandBuilders
6
+ class CommentCommandBuilder < BaseCommandBuilder
7
+ private
8
+
9
+ def separator
10
+ "\n\n"
11
+ end
12
+
13
+ def format_item(item)
14
+ item
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,40 @@
1
+ require_relative 'base_command_builder'
2
+
3
+ module Gitlab
4
+ module Triage
5
+ module CommandBuilders
6
+ class LabelCommandBuilder < BaseCommandBuilder
7
+ def build_command
8
+ ensure_labels_exist!
9
+
10
+ super
11
+ end
12
+
13
+ private
14
+
15
+ def ensure_labels_exist!
16
+ items.each do |label|
17
+ source_id_key = resource.key?(:group_id) ? :group_id : :project_id
18
+ label_opts = {
19
+ source_id_key => resource[source_id_key],
20
+ name: label
21
+ }
22
+
23
+ unless Resource::Label.new(label_opts, network: network).exist?
24
+ raise Resource::Label::LabelDoesntExistError,
25
+ "Label `#{label}` doesn't exist!"
26
+ end
27
+ end
28
+ end
29
+
30
+ def slash_command_string
31
+ "/label"
32
+ end
33
+
34
+ def format_item(item)
35
+ "~\"#{item}\""
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,19 @@
1
+ require_relative 'base_command_builder'
2
+
3
+ module Gitlab
4
+ module Triage
5
+ module CommandBuilders
6
+ class MoveCommandBuilder < BaseCommandBuilder
7
+ private
8
+
9
+ def slash_command_string
10
+ "/move"
11
+ end
12
+
13
+ def format_item(item)
14
+ item
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,15 @@
1
+ require_relative 'base_command_builder'
2
+
3
+ module Gitlab
4
+ module Triage
5
+ module CommandBuilders
6
+ class RemoveLabelCommandBuilder < LabelCommandBuilder
7
+ private
8
+
9
+ def slash_command_string
10
+ '/unlabel'
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,23 @@
1
+ require_relative 'base_command_builder'
2
+
3
+ module Gitlab
4
+ module Triage
5
+ module CommandBuilders
6
+ class StatusCommandBuilder < BaseCommandBuilder
7
+ private
8
+
9
+ def separator
10
+ ''
11
+ end
12
+
13
+ def slash_command_string
14
+ "/"
15
+ end
16
+
17
+ def format_item(item)
18
+ item
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,138 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support/core_ext/array/wrap'
4
+ require 'cgi'
5
+
6
+ require_relative 'base_command_builder'
7
+ require_relative '../resource/context'
8
+
9
+ module Gitlab
10
+ module Triage
11
+ module CommandBuilders
12
+ class TextContentBuilder < BaseCommandBuilder
13
+ SUPPORTED_PLACEHOLDERS = {
14
+ created_at: "{{created_at}}",
15
+ updated_at: "{{updated_at}}",
16
+ closed_at: "{{closed_at}}",
17
+ merged_at: "{{merged_at}}",
18
+ state: "{{state}}",
19
+ author: "@{{author.username}}",
20
+ assignee: "@{{assignee.username}}",
21
+ assignees: "@{{assignees.username}}",
22
+ source_branch: "{{source_branch}}",
23
+ target_branch: "{{target_branch}}",
24
+ closed_by: "@{{closed_by.username}}",
25
+ merged_by: "@{{merged_by.username}}",
26
+ milestone: %(%"{{milestone.title}}"),
27
+ labels: %(~"{{labels}}"),
28
+ upvotes: "{{upvotes}}",
29
+ downvotes: "{{downvotes}}",
30
+ title: "{{title}}",
31
+ web_url: "{{web_url}}",
32
+ full_reference: "{{references.full}}",
33
+ type: "{{type}}",
34
+ items: "{{items}}",
35
+ name: "{{name}}"
36
+ }.freeze
37
+ PLACEHOLDER_REGEX = /{{([\w\.]+)}}/.freeze
38
+
39
+ def initialize(
40
+ items, resource: nil, network: nil, redact_confidentials: true)
41
+ super(items, resource: resource, network: network)
42
+ @redact_confidentials = redact_confidentials
43
+ end
44
+
45
+ private
46
+
47
+ def separator
48
+ "\n\n"
49
+ end
50
+
51
+ def format_item(item)
52
+ return item unless resource
53
+
54
+ replace_placeholders(eval_interpolation(item))
55
+ end
56
+
57
+ def eval_interpolation(item)
58
+ quoted_comment = "%Q{#{item}}"
59
+
60
+ Resource::Context.build(
61
+ resource,
62
+ network: network,
63
+ redact_confidentials: @redact_confidentials
64
+ ).eval(quoted_comment)
65
+ end
66
+
67
+ def replace_placeholders(item)
68
+ SUPPORTED_PLACEHOLDERS.inject(item) do |comment, (placeholder, template)|
69
+ next comment unless comment.include?("{{#{placeholder}}}")
70
+
71
+ path = template[/.*#{PLACEHOLDER_REGEX}.*/, 1]
72
+ attributes = extract_attributes(path)
73
+
74
+ formatted_text = attributes.map do |attribute|
75
+ template.sub(PLACEHOLDER_REGEX, attribute.to_s)
76
+ end.join(', ')
77
+
78
+ escaped_text =
79
+ case placeholder
80
+ when :items
81
+ # We don't need to escape it because it's recursive,
82
+ # which the contents should all be escaped already.
83
+ # Or put it another way, items isn't an attribute
84
+ # retrieved externally. It's a generated value which
85
+ # should be safe to begin with. At some point we
86
+ # may want to make this more distinguishable,
87
+ # separating values from API and values generated.
88
+ formatted_text
89
+ else
90
+ CGI.escape_html(formatted_text)
91
+ end
92
+
93
+ comment.gsub("{{#{placeholder}}}", escaped_text)
94
+ end
95
+ end
96
+
97
+ def extract_attributes(path)
98
+ redact_attributes(path, resource_dig_and_map(path.split('.')))
99
+ end
100
+
101
+ # If we don't have to map arrays, we can simply do:
102
+ #
103
+ # resource.dig(*indices)
104
+ #
105
+ # Thus this method name. The only array here is `assignees`
106
+ def resource_dig_and_map(indices)
107
+ attributes = indices.inject(resource) do |result, index|
108
+ break unless result
109
+
110
+ case result
111
+ when Array
112
+ result.flat_map { |sub_resource| sub_resource[index] }
113
+ else
114
+ result[index]
115
+ end
116
+ end
117
+
118
+ Array.wrap(attributes)
119
+ end
120
+
121
+ def redact_attributes(path, attributes)
122
+ return attributes unless redact_confidential_attributes?
123
+
124
+ case path
125
+ when 'web_url', 'items', 'type', 'references.full'
126
+ attributes # No need to redact them
127
+ else
128
+ [Resource::Base::CONFIDENTIAL_TEXT]
129
+ end
130
+ end
131
+
132
+ def redact_confidential_attributes?
133
+ @redact_confidentials && resource[:confidential]
134
+ end
135
+ end
136
+ end
137
+ end
138
+ end