- Issue created by @jumpsuitgreen
- 🇮🇹Italy apaderno Brescia, 🇮🇹
Thank you for applying!
Please read Review process for security advisory coverage: What to expect → for more details and Security advisory coverage application checklist → to understand what reviewers look for. Tips for ensuring a smooth review → gives some hints for a smoother review.
The important notes are the following.
- If you have not done it yet, enable GitLab CI for the project, and fix what reported from the phpcs job. This help to fix most of what reviewers would report.
- For the time this application is open, only your commits are allowed. No other people, including other maintainers/co-maintainers can make commits.
- The purpose of this application is giving you a new drupal.org role that allows you to opt projects into security advisory coverage, either projects you already created, or projects you will create. The project status won't be changed by this application.
- Nobody else will get the permission to opt projects into security advisory policy. If there are other maintainers/co-maintainers who will to get that permission, they need to apply with a different module.
- We only accept an application per user. If you change your mind about the project to use for this application, or it is necessary to use a different project for the application, please update the issue summary with the link to the correct project and the issue title with the project name and the branch to review.
To the reviewers
Please read How to review security advisory coverage applications → , Application workflow → , What to cover in an application review → , and Tools to use for reviews → .
The important notes are the following.
- It is preferable to wait for a Code Review Administrator before commenting on newly created applications. Code Review Administrators will do some preliminary checks that are necessary before any change on the project files is suggested.
- Reviewers should show the output of a CLI tool → only once per application. The configuration used for these tools needs to be the same configuration used by GitLab CI, stored in the GitLab Templates repository.
- It may be best to have the applicant fix things before further review.
For new reviewers, I would also suggest to first read In which way the issue queue for coverage applications is different from other project queues → .
- 🇮🇹Italy apaderno Brescia, 🇮🇹
There is a module without code. Projects used for these applications need to be complete; that does not mean the code must be bug-free, but it does mean there cannot be .info.yml files without PHP code.
- 🇮🇹Italy apaderno Brescia, 🇮🇹
- The following points are just a start and don't necessarily encompass all of the changes that may be necessary
- A specific point may just be an example and may apply in other places
- A review is about code that does not follow the coding standards, contains possible security issue, or does not correctly use the Drupal API
- The single review points are not ordered, not even by importance
backstop_generator.module
if ($route_name === 'help.page.backstop_generator') { $module_path = \Drupal::service('extension.list.module')->getPath('backstop_generator'); $help_file_path = $module_path . '/backstop_generator_doc.html'; if (file_exists($help_file_path)) { return [ '#type' => 'markup', '#markup' => file_get_contents($help_file_path), '#allowed_tags' => [ 'a', 'b', 'br', 'code', 'div', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'hr', 'i', 'li', 'ol', 'p', 'pre', 'span', 'strong', 'style', 'table', 'tbody', 'td', 'th', 'thead', 'tr', 'ul', ], ]; } return ['#markup' => t('Help content not found.')]; }
Text shown to users must be translatable. The content read from a file cannot be translatable.
/** * Helper function to get the breakpoints from the default theme. * * @param string $theme_name The machine name of the theme. * @param string $theme_path The path of the theme. * * @return array * An array of breakpoints. * * function _backstop_generator_get_theme_breakpoints($theme_name, $theme_path){ * // Load breakpoints.yml if it exists in the theme. * $breakpoints_file = $theme_path . "/$theme_name.breakpoints.yml"; * if (file_exists($breakpoints_file)) { * $yaml_content = file_get_contents($breakpoints_file); * return Yaml::parse($yaml_content); * } * * return []; * } */
Projects used for these applications cannot have commented out functions or methods. The code development must be at the point that the public API is already defined.
src/Controller/BackstopGeneratorController.php
Since that class does not use methods/properties from the parent class, it does not need to use
ControllerBase
as parent class. Controllers do not need to have a parent class; as long as they implement\Drupal\Core\DependencyInjection\ContainerInjectionInterface
, they are fine.src/Entity/BackstopProfile.php
catch (\Exception $e) { // Log the error. $this->logger->error($e->getMessage()); return FALSE; }
The
$message
parameter passed to theLoggerInterface
methods must be a literal string that uses placeholders. It's not a translatable string returned fromt()
or$this->t()
, a string concatenation, nor a value returned from a function/method.src/Form/BackstopProfileForm.php
$this->messenger()->addStatus(t('Removed unchecked scenarios.')); $form_state->setRebuild();
Classes should not use
t()
.src/Form/SettingsForm.php
case count($updated_profiles) == 1: $message = $this->t( 'The %label backstop.json file has been updated.', ['%label' => implode(', ', $updated_profiles)] ); break; case count($updated_profiles) > 1: $message = $this->t( 'The %label backstop.json files have been updated.', ['%label' => implode(', ', $updated_profiles)] ); break;
Drupal core has a method for messages that depends on a value (plural or singular).
backstop_generator.info.yml
core: 8.x core_version_requirement: ^8 || ^9 || ^10 || ^11
core: 8.x
cannot be used togethercore_version_requirement: ^8 || ^9 || ^10 || ^11
; Drupal core throws an error.
A new project should not declare itself compatible with a Drupal release that is no longer supported. No site should be using Drupal 8 nor Drupal 9, and people should not be encouraged to use those Drupal releases.modules/backstop_generator_advanced_settings/backstop_generator_advanced_settings.info.yml
Projects used for these applications are expected to be complete. They should not contain modules without code.
Custom is a package name that is not used for modules hosted on drupal.org.
- 🇮🇳India vishal.kadam Mumbai
1.
2.0.x-1
,8.x-1.x-dev
,2.0
, and240829
are wrong names for a branch and should be removed. Release branch names always end with the literal .x as described in Release branches → .2. FILE: README.md
README.md file should follow the content and formatting described in README.md template → . It is missing the required sections → - Requirements and Installation.
3. FILE: backstop_generator.libraries.yml
# js: # js/backstop_forms.js: {}
FILE: backstop_generator.links.menu.yml
#backstop_generator.default_profile_form: # title: Default Profile # parent: backstop_generator.settings_form # description: 'Configure the default backstop profile.' # route_name: backstop_generator.default_profile_form # weight: 1
FILE: backstop_generator.links.task.yml
#backstop_generator.default_profile_form: # title: Default Profile # route_name: backstop_generator.default_profile_form # base_route: backstop_generator.settings_form # weight: 0
Remove commented code.
4. FILE: backstop_generator.module
/** * @file * Primary module hooks for BackstopJS module. * * @DCG * This file is no longer required in Drupal 8. * @see https://www.drupal.org/node/2217931 */
Drupal does not have primary and secondary hooks. Instead of that, it is preferable to use the usual description: “Hook implementations for the [module name] module”, where [module name] is the name of the module given in its .info.yml file.
5. FILE: src/BackstopJsonTemplate.php
/** * Set default values for properties unavailable through the UI. * * @param string $id * The ID to check. */ public function __construct(string $id) {
FILE: src/Controller/BackstopGeneratorController.php
/** * The controller constructor. * * @param \Drupal\Core\File\FileSystemInterface $file_system * The file system service. * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager * The entity type manager service. * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory * The config factory service. */ public function __construct(FileSystemInterface $file_system, EntityTypeManagerInterface $entity_type_manager, ConfigFactoryInterface $config_factory) {
FILE: src/Form/SettingsForm.php
/** * SettingsForm constructor. * * @param \Drupal\Core\File\FileSystemInterface $fileSystem * The file system service. * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager * The entity type manager. * @param \Drupal\Core\Config\ConfigFactoryInterface $configFactory * The config factory service. * @param \Drupal\Core\Extension\ModuleHandlerInterface $moduleHandler * The module handler service. * @param \Drupal\backstop_generator\Services\BackstopFormBuilder $backstopFormBuilder * The BackstopFormBuilder service. * @param \Drupal\Core\Config\TypedConfigManagerInterface $typedConfigManager * The typed config manager service. */ public function __construct(
The documentation comment for constructors is not mandatory anymore, If it is given, the description must be “Constructs a new [class name] object”, where [class name] includes the class namespace.
- 🇺🇸United States jumpsuitgreen
Thanks to both of you for reviewing this project!
@avpaderno a couple of notes/questions:
- backstop_generator.module: I'm not sure there is anything to fix in your first comment regarding the translated text. The
#markup
key only returns translated text if the file doesn't exist. - BackstopGeneratorController: Line 77 calls
$this->t()
in the build() method; Line 93 calls$this->config
which comes from the parent class. - The Backstop Generator Advanced Settings is simply a way to make Advanced Settings available in various forms when it's been enabled. Do I still need to do away with that submodule and reconfigure?
@vishal.kadam I have removed the disallowed branches and edited the constructor comments. I left the descriptions of the parameters, though. Should those be removed so that the comment only consists of: Constructs a new [class name] object
/* * Constructs a new [class name] object. */
- backstop_generator.module: I'm not sure there is anything to fix in your first comment regarding the translated text. The
- 🇮🇹Italy apaderno Brescia, 🇮🇹
The #markup key only returns translated text if the file doesn't exist.
Text shown to users should always be translatable, not just when the text is an error/warning message.
BackstopGeneratorController: Line 77 calls $this->t() in the build() method; Line 93 calls $this->config which comes from the parent class.
Yet, that class is not using the parent class's properties. In fact, it redefines the same properties already defined from the parent class.
The Backstop Generator Advanced Settings is simply a way to make Advanced Settings available in various forms when it's been enabled.
Since that module does not contain code, it does not show any setting in forms.
- 🇮🇳India vishal.kadam Mumbai
@jumpsuitgreen There's no need to remove the parameter descriptions.
- 🇺🇸United States jumpsuitgreen
Thanks, @vishal.kadam!
@avpaderno,
backstop_generator.module
I think I understand what I need to do regarding the translation. The content of the HTML file that is referenced needs to be translatable which, as you point out, currently isn't. So I need to figure that out.BackstopGeneratorController.php
I now see what you're referring to and will make those fixes.backstop_generator_advanced_settings module
I should have provided a more complete explanation of what's happening, because how it works is buried in code. Here's what is going on:
There are form elements (such as scenarioDefaults) that appear in 3 different places and all three need to be identical—SettingsForm.php, BackstopProfileForm.php, and BackstopScenarioForm.php. Keeping all three forms in sync with each other was difficult during development so I consolidated all of the repetitive form elements in a Service class called BackstopFormBuilder.php. The construction of both Basic and Advanced settings can be found in this class. Advanced Settings are present in the form but are hidden from view if the Advanced Settings module is not enabled:<pre> # Visibility is controlled by the showAdvancedSettings() method which checks if the Backstop Generator Advanced Settings module is enabled. (Line #620 in BackstopFormBuilder.php) 'advanced_settings' => [ '#type' => 'details', '#title' => $this->t('Advanced settings'), '#open' => FALSE, '#attributes' => [ 'style' => $this->showAdvancedSettings() ? '' : 'display:none', ], ],
In summary, all the form code is consolidated in the BackstopFormBuilder class for the sake of long-term maintenance, and the Advanced Settings module is basically a switch. There was concern about the UI being too complicated for new users. So we chose to hide the Advanced Settings to keep things a clean as possible and use the Advanced Settings module as a way to make them available. I'm not completely convinced this is the best way to handle the issue. It's operational, but I understand the potential for confusion. Probably, I need to document why that sub-module doesn't contain any code. Let me know if you have any insight or recommendations.