dri 0.1.0 → 0.1.1
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 +42 -2
- data/lib/dri/api_client.rb +1 -1
- data/lib/dri/commands/fetch/failures.rb +20 -3
- data/lib/dri/commands/fetch/triaged.rb +61 -0
- data/lib/dri/commands/fetch.rb +14 -0
- data/lib/dri/commands/publish/report.rb +9 -2
- data/lib/dri/commands/publish.rb +2 -0
- data/lib/dri/commands/rm/profile.rb +33 -0
- data/lib/dri/commands/rm/reports.rb +20 -0
- data/lib/dri/commands/rm.rb +24 -0
- data/lib/dri/report.rb +65 -18
- data/lib/dri/version.rb +1 -1
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e352230c90233014a517cb67addf17a051a2b2eb05c93f0e88bcaab45c40e723
|
4
|
+
data.tar.gz: 51bbd9e7f07e20668fa8b6161e41b3995ae47b8d1866be6ad81fd07fc0c37bf1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 00b8bcfe9d1d884523f2f5d3963cfa8ab3b7f33f04f819fd17b253838bf899d67394de91524d3dfa40ff692b48c5768f039dc8b6ed44abbcd5faa14b1606eb60
|
7
|
+
data.tar.gz: 58a9c606cd89a5282f25b9fe89fcf16bcf9c70d53df868876884d10149e34786de5c3341d216dd227bbb3d44e16649e26032117c1f12e33e61de52168fd54ebe
|
data/README.md
CHANGED
@@ -7,9 +7,9 @@ Welcome to your new gem! DRI is a CLI ready to help:
|
|
7
7
|
- Fetching failing test cases by pipeline
|
8
8
|
- Reporting at the end of the timezone shift
|
9
9
|
- View today's newest and untriaged failures
|
10
|
-
-
|
10
|
+
- Mark actions on failures
|
11
11
|
|
12
|
-
... and more
|
12
|
+
... and more
|
13
13
|
|
14
14
|
## Installation
|
15
15
|
|
@@ -55,10 +55,13 @@ $ dri profile
|
|
55
55
|
- [3. fetch](#3-fetch)
|
56
56
|
- failures
|
57
57
|
- testcases
|
58
|
+
- triaged
|
58
59
|
- [4. publish](#4-publish)
|
59
60
|
- report
|
60
61
|
- [5. rm](#5-rm)
|
61
62
|
- emoji
|
63
|
+
- profile
|
64
|
+
- reports
|
62
65
|
- [6. version](#6-version)
|
63
66
|
|
64
67
|
#### 1. init
|
@@ -87,6 +90,9 @@ $ dri fetch failures
|
|
87
90
|
Fetches today's opened failures and lists them according to their triage status.
|
88
91
|
Helpful to understand if there are missing recent failures to be reviewed.
|
89
92
|
|
93
|
+
To surface most urgent issues pass the `--urgent` flag to see issues that are both
|
94
|
+
in `canary` and `staging-canary` pipelines just during today's timespan.
|
95
|
+
|
90
96
|
```shell
|
91
97
|
$ dri fetch testcases
|
92
98
|
```
|
@@ -95,6 +101,12 @@ Fetches test cases that failing currently and groups them by pipeline.
|
|
95
101
|
To filter the pipelines, pass the `--filter-pipelines` options to multi-select the pipelines you wish to consult.
|
96
102
|
(Use `Space` to select an option)
|
97
103
|
|
104
|
+
```shell
|
105
|
+
$ dri fetch triaged
|
106
|
+
```
|
107
|
+
|
108
|
+
Fetches triaged failures which use the triage emoji specified in `dri profile`.
|
109
|
+
|
98
110
|
#### 4. publish
|
99
111
|
|
100
112
|
```shell
|
@@ -109,8 +121,22 @@ Publishes a handover report on the latest triage issue, in the [pipeline-triage]
|
|
109
121
|
$ dri publish report --format=list # formats the report in a list
|
110
122
|
$ dri publish report --format=table # formats the report in a table (default)
|
111
123
|
$ dri publish report --dry-run # the report is only generated locally
|
124
|
+
$ dri publish report --actions # activate the actions prompt for each failure
|
112
125
|
```
|
113
126
|
|
127
|
+
**Note:** These options above can be combined like:
|
128
|
+
|
129
|
+
```shell
|
130
|
+
$ dri publish report --format=list --dry-run --actions
|
131
|
+
```
|
132
|
+
|
133
|
+
**Actions**
|
134
|
+
|
135
|
+
When using `--actions` a set of actions are prompt on each failure. Use `Space` to
|
136
|
+
mark several actions: `pinged SET`, `quarantined`, `reproduced`, `transient`.
|
137
|
+
Hitting `Enter` without a selected action will skip marking the actions for a given
|
138
|
+
failure.
|
139
|
+
|
114
140
|
#### 5. rm
|
115
141
|
|
116
142
|
```shell
|
@@ -119,6 +145,20 @@ $ dri rm emoji
|
|
119
145
|
|
120
146
|
Removes the triage emoji from all triaged issues.
|
121
147
|
|
148
|
+
```shell
|
149
|
+
$ dri rm reports
|
150
|
+
```
|
151
|
+
|
152
|
+
When using `$ dri publish report --dry-run` to download the reports locally instead
|
153
|
+
of uploading to the latest Pipeline Triage Issue, an `/handover_reports/` folder
|
154
|
+
created to store these reports. This command removes this folder and subsequent reports stored in it.
|
155
|
+
|
156
|
+
```shell
|
157
|
+
$ dri rm profile
|
158
|
+
```
|
159
|
+
|
160
|
+
Removes the profile currently in use.
|
161
|
+
|
122
162
|
#### 6. version
|
123
163
|
|
124
164
|
```shell
|
data/lib/dri/api_client.rb
CHANGED
@@ -22,6 +22,7 @@ module Dri
|
|
22
22
|
url = add_color('URL', :bright_yellow)
|
23
23
|
|
24
24
|
failures = []
|
25
|
+
urgent = []
|
25
26
|
labels = [ title, triaged, author, url ]
|
26
27
|
triaged_counter = 0
|
27
28
|
|
@@ -49,13 +50,29 @@ module Dri
|
|
49
50
|
e['name'] == emoji && e['user']['username'] == @username
|
50
51
|
end
|
51
52
|
|
53
|
+
if @options[:urgent]
|
54
|
+
labels = failure["labels"]
|
55
|
+
|
56
|
+
labels.each do |label|
|
57
|
+
if label.include? ("found:canary.gitlab.com" && "found:canary.staging.gitlab.com")
|
58
|
+
urgent << [title, triaged, author, url]
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
52
63
|
failures << [title, triaged, author, url]
|
53
64
|
end
|
54
65
|
end
|
55
66
|
|
56
|
-
|
57
|
-
|
58
|
-
|
67
|
+
if @options[:urgent]
|
68
|
+
table = TTY::Table.new(labels, urgent)
|
69
|
+
puts table.render(:ascii, resize: true, alignments: [:center, :center, :center, :center])
|
70
|
+
output.puts "\nFound: #{urgent.size} urgent failures, found in both canary.gitlab.com and canary.staging.gitlab.com."
|
71
|
+
else
|
72
|
+
table = TTY::Table.new(labels, failures)
|
73
|
+
puts table.render(:ascii, resize: true, alignments: [:center, :center, :center, :center])
|
74
|
+
output.puts "\nFound: #{failures.size} failures, of these #{triaged_counter} have been triaged with a #{emoji}."
|
75
|
+
end
|
59
76
|
end
|
60
77
|
|
61
78
|
private
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require_relative '../../command'
|
2
|
+
require 'tty-table'
|
3
|
+
|
4
|
+
module Dri
|
5
|
+
module Commands
|
6
|
+
class Fetch
|
7
|
+
class Triaged < Dri::Command
|
8
|
+
def initialize(options)
|
9
|
+
@options = options
|
10
|
+
end
|
11
|
+
|
12
|
+
def execute(input: $stdin, output: $stdout)
|
13
|
+
verify_config_exists
|
14
|
+
|
15
|
+
title = add_color('Title', :bright_yellow)
|
16
|
+
url = add_color('URL', :bright_yellow)
|
17
|
+
type_label = add_color('Type', :bright_yellow)
|
18
|
+
|
19
|
+
table_labels = [ title, url, type_label ]
|
20
|
+
failures_triaged = []
|
21
|
+
|
22
|
+
logger.info "Fetching your triaged failures..."
|
23
|
+
spinner.start
|
24
|
+
|
25
|
+
response = api_client.fetch_triaged_failures(emoji: emoji, state: 'opened')
|
26
|
+
|
27
|
+
if response.empty?
|
28
|
+
logger.info "There are no failures triaged yet with #{add_color(emoji, :black, :on_white)}."
|
29
|
+
exit 0
|
30
|
+
end
|
31
|
+
|
32
|
+
response.each do |triaged|
|
33
|
+
title = truncate(triaged["title"], 90)
|
34
|
+
url = triaged["web_url"]
|
35
|
+
labels = triaged["labels"]
|
36
|
+
type = ""
|
37
|
+
|
38
|
+
labels.each do |label|
|
39
|
+
type = label.gsub!('failure::', ' ').to_s if label.include? "failure::"
|
40
|
+
end
|
41
|
+
|
42
|
+
labels = triaged["labels"]
|
43
|
+
|
44
|
+
failures_triaged << [title, url, type]
|
45
|
+
end
|
46
|
+
|
47
|
+
spinner.stop
|
48
|
+
|
49
|
+
table = TTY::Table.new(table_labels,failures_triaged)
|
50
|
+
puts table.render(:ascii, resize: true, alignments: [:center, :center, :center])
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
def truncate(string, max)
|
56
|
+
string.length > max ? "#{string[0...max]}..." : string
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
data/lib/dri/commands/fetch.rb
CHANGED
@@ -7,6 +7,18 @@ module Dri
|
|
7
7
|
class Fetch < Thor
|
8
8
|
namespace :fetch
|
9
9
|
|
10
|
+
desc 'triaged', 'Command description...'
|
11
|
+
method_option :help, aliases: '-h', type: :boolean,
|
12
|
+
desc: 'Display usage information'
|
13
|
+
def triaged(*)
|
14
|
+
if options[:help]
|
15
|
+
invoke :help, ['triaged']
|
16
|
+
else
|
17
|
+
require_relative 'fetch/triaged'
|
18
|
+
Dri::Commands::Fetch::Triaged.new(options).execute
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
10
22
|
desc 'testcases', 'Display failing testcases'
|
11
23
|
method_option :help, aliases: '-h', type: :boolean,
|
12
24
|
desc: 'Display usage information'
|
@@ -24,6 +36,8 @@ module Dri
|
|
24
36
|
desc 'failures', 'Display failures opened today'
|
25
37
|
method_option :help, aliases: '-h', type: :boolean,
|
26
38
|
desc: 'Display usage information'
|
39
|
+
method_option :urgent, type: :boolean,
|
40
|
+
desc: 'Shows failures that quickly escalated'
|
27
41
|
def failures(*)
|
28
42
|
if options[:help]
|
29
43
|
invoke :help, ['failures']
|
@@ -34,9 +34,16 @@ module Dri
|
|
34
34
|
|
35
35
|
logger.info "Assembling the report... "
|
36
36
|
# sets each failure on the table
|
37
|
+
action_options = ["pinged SET", "reproduced", "transient", "quarantined"]
|
38
|
+
|
37
39
|
spinner.start
|
38
40
|
issues.each do |issue|
|
39
|
-
|
41
|
+
actions = []
|
42
|
+
|
43
|
+
if @options[:actions]
|
44
|
+
actions = prompt.multi_select("Please mark the actions on #{add_color(issue['title'], :yellow)}: ", action_options)
|
45
|
+
end
|
46
|
+
report.add_failure(issue, actions)
|
40
47
|
end
|
41
48
|
|
42
49
|
if @options[:format] == 'list'
|
@@ -78,7 +85,7 @@ module Dri
|
|
78
85
|
response = api_client.post_triage_report_note(iid: current_issue_iid, body: note)
|
79
86
|
|
80
87
|
output.puts "Done! ✅\n"
|
81
|
-
logger.success "Thanks @#{username}, your report was posted at https://gitlab.com/gitlab-org/quality/
|
88
|
+
logger.success "Thanks @#{username}, your report was posted at https://gitlab.com/gitlab-org/quality/pipeline-triage/-/issues/#{current_issue_iid} 🎉"
|
82
89
|
end
|
83
90
|
end
|
84
91
|
end
|
data/lib/dri/commands/publish.rb
CHANGED
@@ -13,6 +13,8 @@ module Dri
|
|
13
13
|
desc: 'Generates a report locally'
|
14
14
|
method_option :format, aliases: '-f', type: :string, :default => "table",
|
15
15
|
desc: 'Formats the report'
|
16
|
+
method_option :actions, type: :boolean,
|
17
|
+
desc: 'Updates actions on failures'
|
16
18
|
def report(*)
|
17
19
|
if options[:help]
|
18
20
|
invoke :help, ['report']
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../../command'
|
4
|
+
require 'fileutils'
|
5
|
+
|
6
|
+
module Dri
|
7
|
+
module Commands
|
8
|
+
class Rm
|
9
|
+
class Profile < Dri::Command
|
10
|
+
def initialize(options)
|
11
|
+
@options = options
|
12
|
+
end
|
13
|
+
|
14
|
+
def execute(input: $stdin, output: $stdout)
|
15
|
+
verify_config_exists
|
16
|
+
|
17
|
+
remove = prompt.yes? "Are you sure you want to remove existing profile?"
|
18
|
+
|
19
|
+
unless remove
|
20
|
+
logger.info "Profile kept in place 👍"
|
21
|
+
exit 0
|
22
|
+
end
|
23
|
+
|
24
|
+
logger.info "Removing profile..."
|
25
|
+
|
26
|
+
FileUtils.rm("#{Dir.pwd}/.dri_profile.yml")
|
27
|
+
|
28
|
+
logger.success "Done ✅"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../../command'
|
4
|
+
require 'fileutils'
|
5
|
+
|
6
|
+
module Dri
|
7
|
+
module Commands
|
8
|
+
class Rm
|
9
|
+
class Reports < Dri::Command
|
10
|
+
def initialize(options)
|
11
|
+
@options = options
|
12
|
+
end
|
13
|
+
|
14
|
+
def execute(input: $stdin, output: $stdout)
|
15
|
+
FileUtils.rm_rf("#{Dir.pwd}/handover_reports")
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
data/lib/dri/commands/rm.rb
CHANGED
@@ -8,6 +8,30 @@ module Dri
|
|
8
8
|
|
9
9
|
namespace :rm
|
10
10
|
|
11
|
+
desc 'profile', 'Command description...'
|
12
|
+
method_option :help, aliases: '-h', type: :boolean,
|
13
|
+
desc: 'Display usage information'
|
14
|
+
def profile(*)
|
15
|
+
if options[:help]
|
16
|
+
invoke :help, ['profile']
|
17
|
+
else
|
18
|
+
require_relative 'rm/profile'
|
19
|
+
Dri::Commands::Rm::Profile.new(options).execute
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
desc 'reports', 'Command description...'
|
24
|
+
method_option :help, aliases: '-h', type: :boolean,
|
25
|
+
desc: 'Display usage information'
|
26
|
+
def reports(*)
|
27
|
+
if options[:help]
|
28
|
+
invoke :help, ['reports']
|
29
|
+
else
|
30
|
+
require_relative 'rm/reports'
|
31
|
+
Dri::Commands::Rm::Reports.new(options).execute
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
11
35
|
desc 'emoji', 'Remove triage emoji from all failures'
|
12
36
|
method_option :help, aliases: '-h', type: :boolean,
|
13
37
|
desc: 'Display usage information'
|
data/lib/dri/report.rb
CHANGED
@@ -17,7 +17,7 @@ module Dri
|
|
17
17
|
@header = "# #{timezone}, #{@weekday} - #{@date}\n posted by: @#{username}"
|
18
18
|
end
|
19
19
|
|
20
|
-
def add_failure(failure)
|
20
|
+
def add_failure(failure, actions_opts = [])
|
21
21
|
iid = failure["iid"]
|
22
22
|
title = failure["title"]
|
23
23
|
link = failure["web_url"]
|
@@ -38,10 +38,10 @@ module Dri
|
|
38
38
|
assigned_status = assigned?(assignees)
|
39
39
|
pipelines = filter_pipeline_labels(labels)
|
40
40
|
|
41
|
-
linked_pipelines = link_pipelines(iid, pipelines)
|
41
|
+
linked_pipelines = link_pipelines(iid, pipelines, description)
|
42
42
|
|
43
43
|
actions = ""
|
44
|
-
actions.concat actions_status_template(failure_type, assigned_status)
|
44
|
+
actions.concat actions_status_template(failure_type, assigned_status, actions_opts)
|
45
45
|
actions.concat actions_fixes_template(related_mrs)
|
46
46
|
|
47
47
|
@failures << [title, emojified_link, linked_pipelines, stack_trace, actions]
|
@@ -49,28 +49,75 @@ module Dri
|
|
49
49
|
|
50
50
|
private
|
51
51
|
|
52
|
-
def link_pipelines(iid, pipelines)
|
52
|
+
def link_pipelines(iid, pipelines, description)
|
53
|
+
linked = []
|
54
|
+
label_pipeline_map = {
|
55
|
+
'gitlab.com' => '/quality/production',
|
56
|
+
'canary.gitlab.com' => '/quality/canary',
|
57
|
+
# 'canary.staging.gitlab.com' => '',
|
58
|
+
'main' => '/gitlab-org/gitlab-qa-mirror',
|
59
|
+
'master' => '/gitlab-org/gitlab-qa-mirror',
|
60
|
+
'nightly' => '/quality/nightly',
|
61
|
+
'pre.gitlab.com' => '/quality/preprod',
|
62
|
+
'staging-ref' => '/quality/staging-ref',
|
63
|
+
'staging.gitlab.com' => '/quality/staging',
|
64
|
+
'release' => '/quality/release'
|
65
|
+
}
|
66
|
+
|
53
67
|
failure_notes = @api_client.fetch_failure_notes(issue_iid: iid)
|
54
68
|
|
55
|
-
|
69
|
+
return if pipelines.empty?
|
56
70
|
|
57
71
|
pipelines.each do |pipeline|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
72
|
+
next if !label_pipeline_map.has_key? pipeline
|
73
|
+
|
74
|
+
pipeline_in_notes_found = false
|
75
|
+
pipeline_link = ''
|
76
|
+
pipeline_link_sanitized = ''
|
77
|
+
pipeline_markdown = ''
|
78
|
+
|
79
|
+
failure_notes.each do |note|
|
80
|
+
if note["body"].include? label_pipeline_map.fetch(pipeline)
|
81
|
+
pipeline_in_notes_found = true
|
82
|
+
pipeline_link = URI.extract(note["body"], %w(https))
|
83
|
+
break
|
65
84
|
end
|
85
|
+
end
|
86
|
+
|
87
|
+
unless pipeline_in_notes_found
|
88
|
+
links_description = URI.extract(description, %w(https))
|
89
|
+
pipeline_link = links_description.select { |link| link.include? label_pipeline_map.fetch(pipeline) }
|
90
|
+
end
|
66
91
|
|
67
|
-
|
92
|
+
if !pipeline_link.empty?
|
93
|
+
pipeline_link_sanitized = pipeline_link.join.strip.chop
|
94
|
+
pipeline_markdown = "[#{pipeline.gsub(/.gitlab.com/, '')}](#{pipeline_link_sanitized})"
|
95
|
+
linked << pipeline_markdown
|
96
|
+
end
|
68
97
|
end
|
69
|
-
linked
|
98
|
+
linked.join(', ')
|
70
99
|
end
|
71
100
|
|
72
|
-
def actions_status_template(failure_type, assigned_status)
|
73
|
-
|
101
|
+
def actions_status_template(failure_type, assigned_status, actions_opts)
|
102
|
+
notified_set = ''
|
103
|
+
quarantined = ''
|
104
|
+
reproduced = ''
|
105
|
+
transient = ''
|
106
|
+
|
107
|
+
notified_set = '<li>[x] notified SET</li>' if actions_opts.include? 'pinged SET'
|
108
|
+
quarantined = '<li>[x] quarantined</li>' if actions_opts.include? 'quarantined'
|
109
|
+
reproduced = '<li>[x] reproduced</li>' if actions_opts.include? 'reproduced'
|
110
|
+
transient = '<li>[x] transient</li>' if actions_opts.include? 'transient'
|
111
|
+
|
112
|
+
action_status = "<i>Status:</i><ul>"
|
113
|
+
action_status << "<li>#{failure_type}</li>"
|
114
|
+
action_status << "</li><li>#{assigned_status}</li>"
|
115
|
+
action_status << notified_set
|
116
|
+
action_status << quarantined
|
117
|
+
action_status << reproduced
|
118
|
+
action_status << transient
|
119
|
+
|
120
|
+
action_status
|
74
121
|
end
|
75
122
|
|
76
123
|
def actions_fixes_template(related_mrs)
|
@@ -90,10 +137,10 @@ module Dri
|
|
90
137
|
pipelines = []
|
91
138
|
|
92
139
|
labels.each do |label|
|
93
|
-
matchers = { 'found:' => ' '
|
140
|
+
matchers = { 'found:' => ' '}
|
94
141
|
|
95
142
|
if label.include? "found:"
|
96
|
-
pipeline = label.gsub(/found
|
143
|
+
pipeline = label.gsub(/found:/) { |match| matchers[match] }
|
97
144
|
pipelines << pipeline.strip
|
98
145
|
end
|
99
146
|
end
|
data/lib/dri/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dri
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- GitLab Quality
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-03-
|
11
|
+
date: 2022-03-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: tty-config
|
@@ -276,12 +276,15 @@ files:
|
|
276
276
|
- lib/dri/commands/fetch.rb
|
277
277
|
- lib/dri/commands/fetch/failures.rb
|
278
278
|
- lib/dri/commands/fetch/testcases.rb
|
279
|
+
- lib/dri/commands/fetch/triaged.rb
|
279
280
|
- lib/dri/commands/init.rb
|
280
281
|
- lib/dri/commands/profile.rb
|
281
282
|
- lib/dri/commands/publish.rb
|
282
283
|
- lib/dri/commands/publish/report.rb
|
283
284
|
- lib/dri/commands/rm.rb
|
284
285
|
- lib/dri/commands/rm/emoji.rb
|
286
|
+
- lib/dri/commands/rm/profile.rb
|
287
|
+
- lib/dri/commands/rm/reports.rb
|
285
288
|
- lib/dri/report.rb
|
286
289
|
- lib/dri/utils/markdown_lists.rb
|
287
290
|
- lib/dri/version.rb
|