Skip to content

Commit db76fcd

Browse files
authored
Merge pull request #17 from OSInet/6-cache_size
Port cache size check from D7
2 parents 4c4e076 + aeb90fc commit db76fcd

20 files changed

+892
-422
lines changed

LICENSE.md

Lines changed: 361 additions & 0 deletions
Large diffs are not rendered by default.

README.md

Lines changed: 75 additions & 122 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,49 @@ Quality Assurance module
44
[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/OSInet/qa/badges/quality-score.png?b=8.x-1.x)](https://scrutinizer-ci.com/g/OSInet/qa/?branch=8.x-1.x)
55

66
This module needs to be installed on your site to run checks on various aspects
7-
of your production database, configuration storage (D9/D8) and file layout.
7+
of your Drupal production database, configuration storage (D9/D8) and file layout.
88

9-
## Controls (checks)
9+
It also has branches for D7 and D6, each running on the matching version.
1010

11-
It is designed to be extended by additional modules implementing control plugins.
11+
_CAVEAT EMPTOR_ - using this module and interpreting its results requires significant
12+
understanding of core operation: just because a check reports on suspicious data
13+
does not _imply_ there is actually an problem, only that human review is needed.
14+
This tools is primarily designed to help professional auditors review sites; it
15+
is not meant for webmasters in the general case.
1216

13-
In D9/D8, these are standard core plugins. In D7/D6, these were derived from
14-
`Drupal\qa\ControlBase`, supported by a custom plugin system.
1517

18+
## Built-in checks
1619

17-
## Graphs
20+
QA is designed to be extended by additional modules implementing control plugins.
1821

19-
It also provides a few graphs:
22+
| Check | Status | Description |
23+
|--------------------------|---------|-------------|
24+
| Cache.Sizes | OK | Report on cache bins with suspicious sizes: empty, too big, too many items, items too large |
25+
| Config.Overrides | Plan | Find config not matching its default value. |
26+
| Config.Schema | Plan | Find config not matching its schema and schemaless config |
27+
| References.Integrity | OK | Find broken references in `file`, `image`, `entity_reference`, `entity_reference_revisions`, and `dynamic_entity_reference` fields |
28+
| References.TaxonomyIndex | OK | Find broken links in the `taxonomy` relating nodes and taxonomy terms |
29+
| System.External | OK | Find code loaded from directories outside the project |
30+
| System.ForceRemoved | TBP | Find incorrectly removed extensions |
31+
| System.UndeclaredDependencies | OK | Find module dependencies not declared in `<module>.info.yml` files. |
32+
| System.Unused | OK | Find entirely unused projects |
33+
| Taxonomy.Freetagging | TBP | Find unused free-tagging terms. |
34+
| Workflows.Summary | OK | Summarize content moderation workflows |
35+
| Workflows.Transitions | WIP | Find inconsistent transitions |
36+
37+
- Plan: check is expected to be developed, but not yet started
38+
- TBP: to be ported = check existing in earlier versions but not yet ported to D9/D8.
39+
- WIP: work in progress.
40+
41+
QA also includes some non-check commands.
42+
43+
| Graph | Status | Description |
44+
|---------------------|--------|-------------------------------------|
45+
| `qa:dependencies` | OK | Graph of module and theme dependencies |
46+
| `qa:workflows-list` | WIP | Graph of workflow |
47+
48+
49+
### Graphs
2050

2151
* dependency graph of enabled modules and themes, usable either
2252
on the Web UI for smaller sites or from drush for bigger graphs. This feature
@@ -37,118 +67,41 @@ typically by piping the output like this:
3767
```
3868
* The workflow graph also has a tabular version.
3969

40-
## Availability per core version
41-
<table border="1">
42-
<caption>Porting status on 2020-08-14</caption>
43-
<tr>
44-
<th>Package</th>
45-
<th>Check</th>
46-
<th>Drupal 9/8</th>
47-
<th>Drupal 7</th>
48-
<th>Drupal 6</th>
49-
</tr>
50-
<tr>
51-
<td>Cache</td>
52-
<td>Size</td>
53-
<td>Planned</td>
54-
<td>OK</td>
55-
<td></td>
56-
</tr>
57-
<tr>
58-
<td rowspan="3">References</td>
59-
<td>Integrity</td>
60-
<td>OK:<ul>
61-
<li>file</li>
62-
<li>image</li>
63-
<li>ER</li>
64-
<li>ERR</li>
65-
<li>DER</li>
66-
</ul></td>
67-
<td></td>
68-
<td></td>
69-
</tr>
70-
<tr>
71-
<td>External code</td>
72-
<td>OK</td>
73-
<td></td>
74-
<td></td>
75-
</tr>
76-
<tr>
77-
<td>Taxonomy Index</td>
78-
<td>OK</td>
79-
<td></td>
80-
<td>OK</td>
81-
</tr>
82-
<tr>
83-
<td rowspan="4">System</td>
84-
<td>Dependency (graph)</td>
85-
<td>OK</td>
86-
<td>OK</td>
87-
<td>OK</td>
88-
</tr>
89-
<tr>
90-
<td>Undeclared dependencies</td>
91-
<td>OK</td>
92-
<td></td>
93-
<td></td>
94-
</tr>
95-
<tr>
96-
<td>Unused</td>
97-
<td>OK</td>
98-
<td>OK</td>
99-
<td></td>
100-
</tr>
101-
<tr>
102-
<td>Force removed</td>
103-
<td>?</td>
104-
<td>OK</td>
105-
<td></td>
106-
</tr>
107-
<tr>
108-
<td>Taxonomy</td>
109-
<td>Freetagging</td>
110-
<td>Planned</td>
111-
<td></td>
112-
<td>OK</td>
113-
</tr>
114-
<tr>
115-
<td rowspan="2">Variables</td>
116-
<td>Size</td>
117-
<td>n.a.</td>
118-
<td>OK</td>
119-
<td></td>
120-
</tr>
121-
<tr>
122-
<td>I18N</td>
123-
<td>n.a.</td>
124-
<td></td>
125-
<td>OK</td>
126-
</tr>
127-
<tr>
128-
<td rowspan="2">Views</td>
129-
<td>Override</td>
130-
<td>n.a.</td>
131-
<td>OK</td>
132-
<td>OK</td>
133-
</tr>
134-
<tr>
135-
<td>Php</td>
136-
<td>Planned</td>
137-
<td>OK</td>
138-
<td>OK</td>
139-
</tr>
140-
<tr>
141-
<td rowspan="4">Workflows (Content Moderation)</td>
142-
<td>Summary</td>
143-
<td>OK</td>
144-
<td colspan="2" rowspan="3">n.a.</td>
145-
</tr>
146-
<tr>
147-
<td>Transition (graph)</td>
148-
<td>WIP</td>
149-
</tr>
150-
<tr>
151-
<td>Transition (table)</td>
152-
<td>WIP</td>
153-
</tr>
154-
</table>
70+
71+
## Copyright and license
72+
73+
This module is &copy; 2005-2020 [Frédéric G. MARAND](https://blog.riff.org/), for [OSInet](https://osinet.fr).
74+
75+
This program is free software; you can redistribute it and/or modify it under
76+
the terms of the GNU General Public License as published by the Free Software
77+
Foundation; either version 2 of the License, or (at your option) any later
78+
version.
79+
80+
This program is distributed in the hope that it will be useful, but WITHOUT ANY
81+
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
82+
PARTICULAR PURPOSE. See the GNU General Public License for more details.
83+
84+
You should have received a copy of the GNU General Public License along with
85+
this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
86+
Street, Fifth Floor, Boston, MA 02110-1301, USA.
87+
88+
89+
## Contributing
90+
91+
Developing additional custom checks follows this process:
92+
93+
- create a custom module
94+
- create a `QaCheck` plugin, which will implement `QaCheckInterface`, and likely
95+
be based on `QaCheckBase` for simplicity. Its properties are:
96+
- `id` : just like any Drupal plugin. The name should be like `<package>.<check_name>`,
97+
where `<package>` will be used to group related packages in the UI. Plugins
98+
are expected to be located in the `Plugin\QaCheck\<Package>` directory, instead of
99+
being just in the `Plugin\QaCheck` directory.
100+
- `label`: the short description of the plugin, used in admin lists.
101+
- `details`: optional. A longer description of the plugin purpose, used for help in the Web UI. Default: empty.
102+
- `usesBatch`: optional. Enables use of the Batch API for long-running checks (WIP). Default: `false`.
103+
- `steps`: optional. The number of different steps reported by the check. Default: 1.
104+
- add a command to `QaCommands`, calling `QaCommands::runPlugin($name)`.
105+
106+
Contributions are welcome: use Github issues and pull requests.
107+

qa.module

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@
44
* @file
55
* OSInet Quality Assurance module for Drupal.
66
*
7-
* @copyright Copyright (C) 2005-2018 Frederic G. MARAND for Ouest Systèmes
8-
* Informatiques (OSInet)
7+
* @copyright Copyright (C) 2005-2020 Frederic G. MARAND for Ouest Systèmes Informatiques (OSInet)
98
*
109
* @since DRUPAL-4-6
1110
*
@@ -26,6 +25,8 @@
2625

2726
use Drupal\Component\Utility\Xss;
2827
use Drupal\Core\Url;
28+
use Drupal\qa\BaseControl;
29+
use Drupal\qa\Exportable;
2930
use Drupal\qa\Variable\Variable;
3031
use Symfony\Component\HttpFoundation\RedirectResponse;
3132

@@ -135,8 +136,7 @@ function qa_report_form($form, $form_state) {
135136
'#description' => Xss::filterAdmin($package->description),
136137
'#collapsible' => TRUE,
137138
];
138-
$controls = $package->getClasses($package->dir,
139-
'Drupal\qa\Plugin\Qa\Control\BaseControl');
139+
$controls = $package->getClasses($package->dir, BaseControl::class);
140140

141141
foreach ($controls as $control_name => $control) {
142142
$default_value = isset($_SESSION[$control_name])

qa.routing.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ qa.reports.checks:
1414
requirements:
1515
_permission: 'access site reports'
1616

17-
1817
qa.reports.dependencies:
1918
path: '/admin/reports/qa/dependencies'
2019
defaults:

src/Commands/QaCommands.php

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
namespace Drupal\qa\Commands;
66

77
use Drupal\qa\Controller\WorkflowsReportController;
8+
use Drupal\qa\Plugin\QaCheck\Cache\Sizes;
89
use Drupal\qa\Plugin\QaCheck\Dependencies\Undeclared;
910
use Drupal\qa\Plugin\QaCheck\References\Integrity;
1011
use Drupal\qa\Plugin\QaCheck\References\TaxonomyIndex;
@@ -122,9 +123,19 @@ public function runPlugin(string $name): void {
122123
'data' => $result->data,
123124
];
124125
}
125-
$this->output->writeln(Yaml::dump($res, 5, 2));
126+
$this->output->writeln(Yaml::dump($res, 6, 2));
126127
}
127128

129+
/**
130+
* Show oversize cache data.
131+
*
132+
* @command qa:cache:sizes
133+
*
134+
* @throws \Drupal\Component\Plugin\Exception\PluginException
135+
*/
136+
public function cacheSizes() {
137+
$this->runPlugin(Sizes::NAME);
138+
}
128139

129140
/**
130141
* Show undeclared function-based dependencies.

src/Controller/CheckListController.php

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ public function __construct(QaCheckManager $qam) {
3636
*/
3737
public static function create(ContainerInterface $container) {
3838
$qam = $container->get(Data::MANAGER);
39+
assert($qam instanceof QaCheckManager);
3940
return new static($qam);
4041
}
4142

@@ -81,20 +82,4 @@ public function report() {
8182
return $checks;
8283
}
8384

84-
/**
85-
* Placeholder controller for "view".
86-
*
87-
* @param string $qaVariable
88-
* The variable to view.
89-
*
90-
* @return array
91-
* A render array.
92-
*/
93-
public function view($qaVariable) {
94-
return [
95-
'#type' => 'markup',
96-
'#markup' => $this->t('Implement method: view'),
97-
];
98-
}
99-
10085
}

src/Controller/DependenciesReportController.php

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -12,29 +12,13 @@ class DependenciesReportController extends ControllerBase {
1212
/**
1313
* Action.
1414
*
15-
* @return string
16-
* Return Hello string.
17-
*/
18-
public function report() {
19-
return [
20-
'#type' => 'markup',
21-
'#markup' => $this->t('Implement method: report'),
22-
];
23-
}
24-
25-
/**
26-
* Placeholder controller for "dependencies".
27-
*
28-
* @param string $qaVariable
29-
* The variable name.
30-
*
3115
* @return array
3216
* A render array.
3317
*/
34-
public function view($qaVariable) {
18+
public function report() {
3519
return [
3620
'#type' => 'markup',
37-
'#markup' => $this->t('Implement method: view'),
21+
'#markup' => $this->t('Implement method: report'),
3822
];
3923
}
4024

src/Controller/ProjectsReportController.php

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,9 @@ public function __construct(
4242

4343
public static function create(ContainerInterface $container) {
4444
$updateManager = $container->get('update.manager');
45+
assert($updateManager instanceof UpdateManagerInterface);
4546
$kve = $container->get('keyvalue.expirable');
47+
assert($kve instanceof KeyValueExpirableFactoryInterface);
4648
return new static($updateManager, $kve);
4749
}
4850

@@ -111,15 +113,15 @@ private final function qa_report_project(Variable $variable = NULL) {
111113
$bc[] = l($this->t('Variables'), 'admin/reports/qa/variable');
112114
drupal_set_breadcrumb($bc);
113115

114-
drupal_set_title($this->t('Variable: %name', ['%name' => $variable->name]),
115-
PASS_THROUGH);
116+
drupal_set_title($this->t('Variable: %name', ['%name' => $variable->name]), ['passthrough' => TRUE]);
116117
return $variable->dump();
117118
}
118119

119120
/**
120121
* Page callback for projects list.
121122
*
122-
* @return string
123+
* @return array
124+
* A render array.
123125
*
124126
* @FIXME This still uses the D7 info structure.
125127
*
@@ -187,9 +189,11 @@ private final function qa_report_projects() {
187189
$rows[] = $row;
188190
}
189191
}
190-
return theme('table', [
191-
'header' => $header,
192-
'rows' => $rows,
193-
]);
192+
return [
193+
'#theme' => 'table',
194+
'#header' => $header,
195+
'#rows' => $rows,
196+
];
194197
}
198+
195199
}

0 commit comments

Comments
 (0)