dragnet 5.2.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.
Files changed (86) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/release.yml +45 -0
  3. data/.github/workflows/ruby-linters.yml +41 -0
  4. data/.github/workflows/ruby-tests.yml +38 -0
  5. data/.github/workflows/sphinx-doc.yml +79 -0
  6. data/.gitignore +13 -0
  7. data/.reek.yml +15 -0
  8. data/.rspec +3 -0
  9. data/.rubocop.yml +14 -0
  10. data/.ruby-version +1 -0
  11. data/.travis.yml +6 -0
  12. data/CHANGELOG.md +178 -0
  13. data/Gemfile +18 -0
  14. data/README.md +119 -0
  15. data/Rakefile +8 -0
  16. data/bin/console +14 -0
  17. data/bin/setup +8 -0
  18. data/default.reek +7 -0
  19. data/dragnet.gemspec +39 -0
  20. data/exe/dragnet +9 -0
  21. data/lib/dragnet/base_repository.rb +69 -0
  22. data/lib/dragnet/cli/base.rb +72 -0
  23. data/lib/dragnet/cli/logger.rb +72 -0
  24. data/lib/dragnet/cli/master.rb +173 -0
  25. data/lib/dragnet/cli.rb +8 -0
  26. data/lib/dragnet/errors/error.rb +8 -0
  27. data/lib/dragnet/errors/file_not_found_error.rb +11 -0
  28. data/lib/dragnet/errors/incompatible_repository_error.rb +10 -0
  29. data/lib/dragnet/errors/missing_timestamp_attribute_error.rb +11 -0
  30. data/lib/dragnet/errors/no_mtr_files_found_error.rb +11 -0
  31. data/lib/dragnet/errors/not_a_repository_error.rb +11 -0
  32. data/lib/dragnet/errors/repo_path_not_found_error.rb +10 -0
  33. data/lib/dragnet/errors/unable_to_write_report_error.rb +11 -0
  34. data/lib/dragnet/errors/unknown_export_format_error.rb +11 -0
  35. data/lib/dragnet/errors/validation_error.rb +11 -0
  36. data/lib/dragnet/errors/yaml_format_error.rb +9 -0
  37. data/lib/dragnet/errors.rb +9 -0
  38. data/lib/dragnet/explorer.rb +103 -0
  39. data/lib/dragnet/exporter.rb +130 -0
  40. data/lib/dragnet/exporters/exporter.rb +29 -0
  41. data/lib/dragnet/exporters/html_exporter.rb +158 -0
  42. data/lib/dragnet/exporters/id_generator.rb +35 -0
  43. data/lib/dragnet/exporters/json_exporter.rb +34 -0
  44. data/lib/dragnet/exporters/serializers/repo_serializer.rb +40 -0
  45. data/lib/dragnet/exporters/serializers/test_record_serializer.rb +101 -0
  46. data/lib/dragnet/exporters/serializers/verification_result_serializer.rb +34 -0
  47. data/lib/dragnet/exporters/serializers.rb +12 -0
  48. data/lib/dragnet/exporters/templates/template.html.erb +518 -0
  49. data/lib/dragnet/exporters.rb +13 -0
  50. data/lib/dragnet/helpers/repository_helper.rb +27 -0
  51. data/lib/dragnet/multi_repository.rb +48 -0
  52. data/lib/dragnet/repo.rb +31 -0
  53. data/lib/dragnet/repository.rb +77 -0
  54. data/lib/dragnet/test_record.rb +91 -0
  55. data/lib/dragnet/validator.rb +79 -0
  56. data/lib/dragnet/validators/data_validator.rb +75 -0
  57. data/lib/dragnet/validators/entities/repo_validator.rb +31 -0
  58. data/lib/dragnet/validators/entities/test_record_validator.rb +93 -0
  59. data/lib/dragnet/validators/entities.rb +12 -0
  60. data/lib/dragnet/validators/fields/description_validator.rb +24 -0
  61. data/lib/dragnet/validators/fields/field_validator.rb +69 -0
  62. data/lib/dragnet/validators/fields/files_validator.rb +29 -0
  63. data/lib/dragnet/validators/fields/id_validator.rb +36 -0
  64. data/lib/dragnet/validators/fields/meta_data_field_validator.rb +36 -0
  65. data/lib/dragnet/validators/fields/path_validator.rb +22 -0
  66. data/lib/dragnet/validators/fields/repos_validator.rb +62 -0
  67. data/lib/dragnet/validators/fields/result_validator.rb +33 -0
  68. data/lib/dragnet/validators/fields/sha1_validator.rb +42 -0
  69. data/lib/dragnet/validators/fields.rb +17 -0
  70. data/lib/dragnet/validators/files_validator.rb +85 -0
  71. data/lib/dragnet/validators/repos_validator.rb +74 -0
  72. data/lib/dragnet/validators/validator.rb +20 -0
  73. data/lib/dragnet/validators.rb +12 -0
  74. data/lib/dragnet/verification_result.rb +125 -0
  75. data/lib/dragnet/verifier.rb +64 -0
  76. data/lib/dragnet/verifiers/changes_verifier.rb +70 -0
  77. data/lib/dragnet/verifiers/files_verifier.rb +51 -0
  78. data/lib/dragnet/verifiers/repos_verifier.rb +92 -0
  79. data/lib/dragnet/verifiers/repository_verifier.rb +27 -0
  80. data/lib/dragnet/verifiers/result_verifier.rb +32 -0
  81. data/lib/dragnet/verifiers/test_record_verifier.rb +85 -0
  82. data/lib/dragnet/verifiers/verifier.rb +37 -0
  83. data/lib/dragnet/verifiers.rb +8 -0
  84. data/lib/dragnet/version.rb +5 -0
  85. data/lib/dragnet.rb +18 -0
  86. metadata +190 -0
@@ -0,0 +1,518 @@
1
+ <html lang="en">
2
+ <head>
3
+ <meta charset="UTF-8" />
4
+ <title>Dragnet Report for <%= repository.multi? ? "Multiple Repositories" : shorten_sha1(repository.head.sha) %></title>
5
+ <script src="https://unpkg.com/@tabler/core@1.0.0-beta2/dist/js/tabler.min.js"></script>
6
+ <link rel="stylesheet" href="https://unpkg.com/@tabler/core@1.0.0-beta2/dist/css/tabler.min.css">
7
+ </head>
8
+ <body class="antialiased"> <!-- theme-dark -->
9
+ <div class="wrapper">
10
+ <div class="sticky-top">
11
+ <header class="navbar navbar-expand-md navbar-light d-print-none">
12
+ <div class="container-xl">
13
+ <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbar-menu">
14
+ <span class="navbar-toggler-icon"></span>
15
+ </button>
16
+ <h1 class="navbar-brand navbar-brand-autodark d-none-navbar-horizontal pe-0 pe-md-3">
17
+ <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-arrow-right-bar" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
18
+ <path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
19
+ <path d="M18 15l3 -3l-3 -3"></path>
20
+ <path d="M3 12h18"></path>
21
+ <path d="M3 9v6"></path>
22
+ </svg>
23
+ Dragnet
24
+ </h1>
25
+ </div>
26
+ </header>
27
+ <div class="navbar-expand-md">
28
+ <div class="collapse navbar-collapse" id="navbar-menu">
29
+ <div class="navbar navbar-light">
30
+ <div class="container-xl">
31
+ <ul class="navbar-nav">
32
+ <li class="nav-item">
33
+ <a class="nav-link" href="#mtr-files">
34
+ <span class="nav-link-icon d-md-none d-lg-inline-block">
35
+ <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-file-check" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
36
+ <path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
37
+ <path d="M14 3v4a1 1 0 0 0 1 1h4"></path>
38
+ <path d="M17 21h-10a2 2 0 0 1 -2 -2v-14a2 2 0 0 1 2 -2h7l5 5v11a2 2 0 0 1 -2 2z"></path>
39
+ <path d="M9 15l2 2l4 -4"></path>
40
+ </svg>
41
+ </span>
42
+ <span class="nav-link-title">MTR Files</span>
43
+ </a>
44
+ </li>
45
+ <li class="nav-item">
46
+ <a class="nav-link" href="#test_results">
47
+ <span class="nav-link-icon d-md-none d-lg-inline-block">
48
+ <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-file-check" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
49
+ <path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
50
+ <path d="M14 3v4a1 1 0 0 0 1 1h4"></path>
51
+ <path d="M17 21h-10a2 2 0 0 1 -2 -2v-14a2 2 0 0 1 2 -2h7l5 5v11a2 2 0 0 1 -2 2z"></path>
52
+ <path d="M9 15l2 2l4 -4"></path>
53
+ </svg>
54
+ </span>
55
+ <span class="nav-link-title">Test results</span>
56
+ </a>
57
+ </li>
58
+ </ul>
59
+ <div class="my-2 my-md-0 flex-grow-1 flex-md-grow-0 order-first order-md-last">
60
+ <ul class="navbar-nav">
61
+ <li class="nav-item">
62
+ <a class="nav-link" href="#">
63
+ <span class="nav-link-icon d-md-none d-lg-inline-block"><!-- Download SVG icon from http://tabler-icons.io/i/home -->
64
+ <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-chevrons-up" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
65
+ <path stroke="none" d="M0 0h24v24H0z" fill="none"/>
66
+ <polyline points="7 11 12 6 17 11"/>
67
+ <polyline points="7 17 12 12 17 17"/>
68
+ </svg>
69
+ </span>
70
+ <span class="nav-link-title">Top</span>
71
+ </a>
72
+ </li>
73
+ </ul>
74
+ </div>
75
+ </div>
76
+ </div>
77
+ </div>
78
+ </div>
79
+ </div>
80
+ <div class="page-wrapper">
81
+ <div class="page-body">
82
+ <div class="container-xl">
83
+ <div class="alert alert-warning alert-dismissible" role="alert">
84
+ <div class="d-flex">
85
+ <div>
86
+ <h4 class="alert-title">Not a customer report</h4>
87
+ <div class="text-muted">Please be aware that this report should not be shared with external stakeholders. Exports for customers can be provided by other tools.</div>
88
+ </div>
89
+ </div>
90
+ <a class="btn-close" data-bs-dismiss="alert" aria-label="close"></a>
91
+ </div>
92
+
93
+ <div class="row row-deck row-cards mb-3">
94
+ <div class="col-sm-12">
95
+ <div class="card">
96
+ <div class="card-header">
97
+ <h3 class="card-title">Configuration</h3>
98
+ </div>
99
+ <div class="card-body">
100
+
101
+ <% if repository.multi? %>
102
+
103
+ <div class="table-responsive">
104
+ <table class="table table-vcenter card-table">
105
+ <thead>
106
+ <tr>
107
+ <th>Repository</th>
108
+ <th>Configuration</th>
109
+ </tr>
110
+ </thead>
111
+ <tbody>
112
+
113
+ <% repository.repositories.each do |repository_path, repository| %>
114
+
115
+ <tr>
116
+ <td><%= repository_path %></td>
117
+ <td>
118
+ <dl class="row">
119
+ <dt class="col-4">Remote:</dt>
120
+ <dd class="col-8"><%= repository.remote_uri_path %></dd>
121
+ <dt class="col-4">Software branch(es):</dt>
122
+ <dd class="col-8"><%= software_branches(repository).join(', ') %></dd>
123
+ <dt class="col-4">Git sha1:</dt>
124
+ <dd class="col-8"><%= repository.head.sha %></dd>
125
+ <dt class="col-4">Build:</dt>
126
+ <dd class="col-8"> -- Not implemented --</dd>
127
+ </dl>
128
+ </td>
129
+ </tr>
130
+
131
+ <% end %>
132
+
133
+ </tbody>
134
+ </table>
135
+ </div>
136
+
137
+ <% else %>
138
+
139
+ <dl class="row">
140
+ <dt class="col-4">Repository:</dt>
141
+ <dd class="col-8"><%= repository.remote_uri_path %></dd>
142
+ <dt class="col-4">Software branch(es):</dt>
143
+ <dd class="col-8"><%= software_branches(repository).join(', ') %></dd>
144
+ <dt class="col-4">Git sha1:</dt>
145
+ <dd class="col-8"><%= repository.head.sha %></dd>
146
+ <dt class="col-4">Build:</dt>
147
+ <dd class="col-8"> -- Not implemented --</dd>
148
+ </dl>
149
+
150
+ <% end %>
151
+
152
+ </div>
153
+ </div>
154
+ </div>
155
+ </div>
156
+
157
+ <div class="row row-deck row-cards mb-3">
158
+
159
+ <% if test_records_by_requirement.any? %>
160
+
161
+ <div class="col-sm-6 col-lg-6">
162
+ <div class="card">
163
+ <div class="card-body">
164
+ <div class="d-flex align-items-center">
165
+ <div class="subheader">Requirements</div>
166
+ </div>
167
+
168
+ <% total_requirements = test_records_by_requirement.size %>
169
+
170
+ <div class="h1 mb-3"><%= total_requirements %></div>
171
+
172
+ <%
173
+ requirements_by_status = test_records_by_requirement.group_by do |_requirement, test_records|
174
+ if test_records.all? { |test_record| test_record.verification_result.passed? }
175
+ :passed
176
+ elsif test_records.any? { |test_record| test_record.verification_result.failed? }
177
+ :failed
178
+ else
179
+ :skipped
180
+ end
181
+ end
182
+
183
+ total_passed = requirements_by_status[:passed]&.size || 0
184
+ total_skipped = requirements_by_status[:skipped]&.size || 0
185
+ total_failed = requirements_by_status[:failed]&.size || 0
186
+ passed_percent = percentage(total_passed, total_requirements)
187
+ skipped_percent = percentage(total_skipped, total_requirements)
188
+ failed_percent = percentage(total_failed, total_requirements)
189
+ %>
190
+
191
+ <div class="progress progress-separated mb-3">
192
+ <div class="progress-bar bg-green" role="progressbar" style="width: <%= passed_percent %>%"></div>
193
+ <div class="progress-bar bg-red" role="progressbar" style="width: <%= failed_percent %>%"></div>
194
+ <div class="progress-bar bg-yellow" role="progressbar" style="width: <%= skipped_percent %>%"></div>
195
+ </div>
196
+ <div class="row">
197
+ <div class="col-auto d-flex align-items-center pe-2">
198
+ <span class="legend me-2 bg-green"></span>
199
+ <span>Passed</span>
200
+ <span class="d-none d-md-inline d-lg-none d-xxl-inline ms-2 text-muted"><%= total_passed %> (<%= passed_percent %>%)</span>
201
+ </div>
202
+ <div class="col-auto d-flex align-items-center px-2">
203
+ <span class="legend me-2 bg-red"></span>
204
+ <span>Failed</span>
205
+ <span class="d-none d-md-inline d-lg-none d-xxl-inline ms-2 text-muted"><%= total_failed %> (<%= failed_percent %>%)</span>
206
+ </div>
207
+ <div class="col-auto d-flex align-items-center px-2">
208
+ <span class="legend me-2 bg-yellow"></span>
209
+ <span>Skipped</span>
210
+ <span class="d-none d-md-inline d-lg-none d-xxl-inline ms-2 text-muted"><%= total_skipped %> (<%= skipped_percent %>%)</span>
211
+ </div>
212
+ </div>
213
+ </div>
214
+ </div>
215
+ </div>
216
+
217
+ <% end %>
218
+
219
+ <div class="col-sm-6 col-lg-6">
220
+ <div class="card">
221
+ <div class="card-body">
222
+ <div class="d-flex align-items-center">
223
+ <div class="subheader">Test cases</div>
224
+ </div>
225
+
226
+ <% total_test_records = test_records.size %>
227
+
228
+ <div class="h1 mb-3"><%= total_test_records %></div>
229
+ <div class="progress progress-separated mb-3">
230
+
231
+ <%
232
+ test_records_by_status = test_records.group_by do |test_record|
233
+ if test_record.reviewed?
234
+ test_record.findings? ? :skipped : :passed
235
+ else
236
+ :failed
237
+ end
238
+ end
239
+
240
+ total_passed = test_records_by_status[:passed]&.size || 0
241
+ total_skipped = test_records_by_status[:skipped]&.size || 0
242
+ total_failed = test_records_by_status[:failed]&.size || 0
243
+ passed_percent = percentage(total_passed, total_test_records)
244
+ skipped_percent = percentage(total_skipped, total_test_records)
245
+ failed_percent = percentage(total_failed, total_test_records)
246
+ %>
247
+
248
+ <div class="progress-bar bg-green" role="progressbar" style="width: <%= passed_percent %>%"></div>
249
+ <div class="progress-bar bg-red" role="progressbar" style="width: <%= failed_percent %>%"></div>
250
+ <div class="progress-bar bg-yellow" role="progressbar" style="width: <%= skipped_percent %>%"></div>
251
+ </div>
252
+ <div class="row">
253
+ <div class="col-auto d-flex align-items-center pe-2">
254
+ <span class="legend me-2 bg-green"></span>
255
+ <span>Reviewed</span>
256
+ <span class="d-none d-md-inline d-lg-none d-xxl-inline ms-2 text-muted"><%= total_passed %> (<%= passed_percent %>%)</span>
257
+ </div>
258
+ <div class="col-auto d-flex align-items-center px-2">
259
+ <span class="legend me-2 bg-red"></span>
260
+ <span>Not reviewed</span>
261
+ <span class="d-none d-md-inline d-lg-none d-xxl-inline ms-2 text-muted"><%= total_failed %> (<%= failed_percent %>%)</span>
262
+ </div>
263
+ <div class="col-auto d-flex align-items-center px-2">
264
+ <span class="legend me-2 bg-yellow"></span>
265
+ <span>Findings</span>
266
+ <span class="d-none d-md-inline d-lg-none d-xxl-inline ms-2 text-muted"><%= total_skipped %> (<%= skipped_percent %>%)</span>
267
+ </div>
268
+ </div>
269
+ </div>
270
+ </div>
271
+ </div>
272
+ </div>
273
+
274
+ <div class="row">
275
+ <h1 id="mtr-files">MTR Files</h1>
276
+ <div class="col-12">
277
+ <div class="card">
278
+ <div class="card-header">
279
+ <h3 class="card-title">Overview</h3>
280
+ </div>
281
+ <div class="table-responsive">
282
+ <table class="table table-vcenter table-hover">
283
+ <thead>
284
+ <tr>
285
+ <th>File</th>
286
+ <th>Status</th>
287
+ <th>Reason</th>
288
+ </tr>
289
+ </thead>
290
+ <tbody>
291
+
292
+ <% errors.each do |error| %>
293
+
294
+ <tr>
295
+ <td><%= relative_to_repo(error[:file]) %></td>
296
+ <td><span class="badge bg-red">Failed</span></td>
297
+ <td><%= error[:message] %><br><%= error[:exception].message %></td>
298
+ </tr>
299
+
300
+ <% end %>
301
+
302
+ <% test_records.each do |test_record| %>
303
+
304
+ <tr>
305
+ <td><%= relative_to_repo(test_record.source_file) %></td>
306
+ <td><span class="badge bg-green">Successfully Loaded</span></td>
307
+ <td>-</td>
308
+ </tr>
309
+
310
+ <% end %>
311
+
312
+ </tbody>
313
+ </table>
314
+ </div>
315
+ </div>
316
+ </div>
317
+
318
+ <h1 class="mt-3" id="test_results">Test results</h1>
319
+
320
+ <div class="row">
321
+ <div class="col-12">
322
+ <div class="card">
323
+ <div class="card-header">
324
+ <h3 class="card-title">Overview</h3>
325
+ </div>
326
+ <div class="table-responsive">
327
+ <table class="table table-vcenter table-hover">
328
+ <thead>
329
+ <tr>
330
+ <th>#</th>
331
+ <th>Requirement ID</th>
332
+ <th>SHA1</th>
333
+ <th>Files</th>
334
+ <th>Review Status</th>
335
+ <th>Test Result</th>
336
+ <th>Details</th>
337
+ </tr>
338
+ </thead>
339
+ <tbody>
340
+
341
+ <% test_records.each_with_index do |test_record, index| %>
342
+
343
+ <tr>
344
+ <td><%= index + 1 %></td>
345
+ <td><%= test_record_id_to_string(test_record) %></td>
346
+ <td><%= test_record.sha1 ? shorten_sha1(test_record.sha1) : '(None)' %></td>
347
+ <td>
348
+
349
+ <% if test_record.files&.any? %>
350
+
351
+ <%= test_record.files.map { |file| relative_to_repo(file) }.join('<br/>') %>
352
+
353
+ <% else %>
354
+
355
+ (None)
356
+
357
+ <% end %>
358
+
359
+ </td>
360
+ <td><%= review_status_badge(test_record) %></td>
361
+ <td><%= verification_result_badge(test_record.verification_result) %></td>
362
+ <td><a href="#test-record-<%= index %>">
363
+ <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-chevrons-down" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
364
+ <path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
365
+ <polyline points="7 7 12 12 17 7"></polyline>
366
+ <polyline points="7 13 12 18 17 13"></polyline>
367
+ </svg>
368
+ </a></td>
369
+ </tr>
370
+
371
+ <% end %>
372
+
373
+ </tbody>
374
+ </table>
375
+ </div>
376
+ </div>
377
+ </div>
378
+ </div>
379
+
380
+ <% test_records.each_with_index do |test_record, index| %>
381
+
382
+ <div class="row mt-3">
383
+ <div class="col-12">
384
+ <div class="card">
385
+ <div class="card-status-start bg-<%= card_color(test_record.verification_result) %>"></div>
386
+ <div class="card-header">
387
+ <h3 class="card-title" id="test-record-<%= index %>"><%= test_record_id_to_string(test_record) %></h3>
388
+ </div>
389
+ <div class="card-body">
390
+ <dl class="row">
391
+ <dt class="col-3">MTR file:</dt>
392
+ <dd class="col-9"><%= relative_to_repo(test_record.source_file) %></dd>
393
+
394
+ <% if test_record.name.present? %>
395
+
396
+ <dt class="col-3">Tester name:</dt>
397
+ <dd class="col-9"><%= test_record.name.join(', ') %></dd>
398
+
399
+ <% end %>
400
+
401
+ <% if test_record.test_method.present? %>
402
+
403
+ <dt class="col-3">Test method:</dt>
404
+ <dd class="col-9"><%= test_record.test_method.join(', ') %></dd>
405
+
406
+ <% end %>
407
+
408
+ <% if test_record.tc_derivation_method.present? %>
409
+
410
+ <dt class="col-3">Derivation method:</dt>
411
+ <dd class="col-9"><%= test_record.tc_derivation_method.join(', ') %></dd>
412
+
413
+ <% end %>
414
+
415
+ <% if test_record.repos %>
416
+
417
+ <dt class="col-3">Repositories:</dt>
418
+ <dd class="col-9">
419
+ <ul>
420
+
421
+ <% test_record.repos.each do |repo| %>
422
+
423
+ <li>
424
+
425
+ <%= repo.path %><br />
426
+ <%= repo.sha1 %><br />
427
+
428
+ <% repo.files&.each do |file| %>
429
+
430
+ <ul>
431
+
432
+ <li><%= relative_to_repo(file).sub("#{repo.path}/", '') %></li>
433
+
434
+ </ul>
435
+
436
+ <% end %>
437
+
438
+ </li>
439
+
440
+ <% end %>
441
+
442
+ </ul>
443
+ </dd>
444
+
445
+ <% else %>
446
+
447
+ <dt class="col-3">SHA1:</dt>
448
+ <dd class="col-9"><%= test_record.sha1 %></dd>
449
+ <dt class="col-3">Files:</dt>
450
+ <dd class="col-9">
451
+
452
+ <% if test_record.files&.any? %>
453
+
454
+ <%= test_record.files.map { |file| relative_to_repo(file) }.join('<br/>') %>
455
+
456
+ <% else %>
457
+
458
+ (None)
459
+
460
+ <% end %>
461
+
462
+ </dd>
463
+
464
+ <% end %>
465
+
466
+ <dt class="col-3">ASIL:</dt>
467
+ <dd class="col-9"> -- Not implemented -- </dd>
468
+ <dt class="col-3">SECL:</dt>
469
+ <dd class="col-9"> -- Not implemented -- </dd>
470
+ <dt class="col-3">Description:</dt>
471
+ <dd class="col-9">
472
+ <%= test_record.description %>
473
+ </dd>
474
+ <dt class="col-3">Test Result:</dt>
475
+ <dd class="col-9"><%= verification_result_badge(test_record.verification_result) %></dd>
476
+
477
+ <% unless test_record.verification_result.passed? %>
478
+
479
+ <dt class="col-3">Reason:</dt>
480
+ <dd class="col-9"><%= test_record.verification_result.reason %></dd>
481
+
482
+ <% end %>
483
+
484
+ <dt class="col-3">Review Status:</dt>
485
+ <dd class="col-9"><%= review_status_badge(test_record) %></dd>
486
+ <dt class="col-3">Review Comments:</dt>
487
+ <dd class="col-9"><%= test_record.review_comments || '(None)' %></dd>
488
+ </dl>
489
+ </div>
490
+ </div>
491
+ </div>
492
+ </div>
493
+
494
+ <% end %>
495
+
496
+ </div>
497
+ </div>
498
+ </div>
499
+ <footer class="footer footer-transparent d-print-none">
500
+ <div class="container">
501
+ <div class="row text-center align-items-center flex-row-reverse">
502
+ <div class="col-12 col-lg-auto mt-3 mt-lg-0">
503
+ <ul class="list-inline list-inline-dots mb-0">
504
+ <li class="list-inline-item">
505
+ Generated on <%= Time.now.strftime("%F %T") %> by Dragnet
506
+ </li>
507
+ <li class="list-inline-item">
508
+ <a target="_blank" href="https://github.com/esrlabs/dragnet/blob/master/CHANGELOG.md" class="link-secondary" rel="noopener">Version <%= Dragnet::VERSION %></a>
509
+ </li>
510
+ </ul>
511
+ </div>
512
+ </div>
513
+ </div>
514
+ </footer>
515
+ </div>
516
+ </div>
517
+ </body>
518
+ </html>
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'exporters/exporter'
4
+ require_relative 'exporters/html_exporter'
5
+ require_relative 'exporters/id_generator'
6
+ require_relative 'exporters/json_exporter'
7
+ require_relative 'exporters/serializers'
8
+
9
+ module Dragnet
10
+ # Namespace for the exporters: classes that produce files, or reports out of
11
+ # the results of the Manual Test Record verification execution.
12
+ module Exporters; end
13
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Dragnet
4
+ module Helpers
5
+ # Some helper methods to use when working with repositories.
6
+ module RepositoryHelper
7
+ # @return [String] The first 10 characters of the given string (normally
8
+ # used to shorten SHA1s when building messages).
9
+ def shorten_sha1(sha1)
10
+ sha1[0...10]
11
+ end
12
+
13
+ # @return [Pathname] The base path of the repository where the MTR and the
14
+ # source files are located. Used to present relative paths.
15
+ def repo_base
16
+ @repo_base ||= repository.path
17
+ end
18
+
19
+ # Transforms the given path into a path relative to the repository's root
20
+ # @param [Pathname] path The absolute path.
21
+ # @return [Pathname] A path relative to the repository's root.
22
+ def relative_to_repo(path)
23
+ path.relative_path_from(repo_base)
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'base_repository'
4
+
5
+ module Dragnet
6
+ # This is a dummy class that acts as a placeholder when Dragnet is executed
7
+ # on a multi-repo set-up. Since there is no Git repository in the directory
8
+ # where git-repo runs git commands cannot be executed there only in the inner
9
+ # repositories.
10
+ #
11
+ # This class's job is to raise a particular error when a git operation is
12
+ # attempted directly on this directory so that Dragnet can recognize the cause
13
+ # of the error and display it correctly.
14
+ #
15
+ # It also acts as a collection of repositories. It stores a collection of
16
+ # +Dragnet::Repository+ objects, which point to the actual repositories (this
17
+ # is just so that the same repository isn't initialized multiple times).
18
+ class MultiRepository < Dragnet::BaseRepository
19
+ attr_reader :repositories
20
+
21
+ # @param [Pathname] path Path to the directory where the inner repositories
22
+ # reside.
23
+ def initialize(path:)
24
+ super
25
+ @repositories = {}
26
+ end
27
+
28
+ # @return [TrueClass] It always returns true
29
+ def multi?
30
+ true
31
+ end
32
+
33
+ private
34
+
35
+ # @param [Symbol] method_name The name of the method that was invoked.
36
+ # @raise [Dragnet::Errors::IncompatibleRepositoryError] Is always raised
37
+ # with a description of the method that was invoked and a possible cause
38
+ # for the failure.
39
+ def incompatible_repository(method_name)
40
+ super(
41
+ "Failed to perform the action '#{method_name}' on '#{path}'."\
42
+ " There isn't a git repository there. If you are running with the"\
43
+ ' --multi-repo command line switch make sure that all of your MTRs'\
44
+ " contain a valid 'repos' attribute."
45
+ )
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'validators/entities/repo_validator'
4
+
5
+ module Dragnet
6
+ # Represents a repository, (for MTRs which reference multiple repositories in
7
+ # a multi-repo project, often managed with git-repo)
8
+ class Repo
9
+ attr_accessor :path, :sha1, :files
10
+
11
+ # @param [Hash] args The data for the Repo
12
+ # @option args [String] :path The path where the repository is stored.
13
+ # @option args [String] :sha1 The SHA1 the repository had when the MTR was
14
+ # created.
15
+ # @option args [String, Array<String>, nil] :files The file or array of
16
+ # files covered by the MTR.
17
+ def initialize(args)
18
+ @path = args[:path]
19
+ @sha1 = args[:sha1]
20
+ @files = args[:files]
21
+ end
22
+
23
+ # Validates the +Repo+ instance (by checking each of its attributes).
24
+ # @raise [Dragnet::Errors::ValidationError] If any of the attributes of the
25
+ # +Repo+ object is invalid.
26
+ # @see Dragnet::Validators::Entities::RepoValidator#validate
27
+ def validate
28
+ Dragnet::Validators::Entities::RepoValidator.new(self).validate
29
+ end
30
+ end
31
+ end