GrumPHP Implementation in Adobe Commerce

Today, we will learn how to add code quality checks in Adobe Commerce Module Development. We will be achieving this by automating the code quality checks using the GrumPHP library.

Why should we Automate?

For the quality control of the code in Adobe Commerce modules, we have to manually run 6-7 tools which can be overburdening, I would try to skip these assuming the code will pass from the development pipeline.

Another main reason is that we developers are a bit lazy kind of person.🙂

How we will Automate?

GrumPHP will do it for you! This composer plugin will register some git hooks in your package repository. When somebody commits changes, GrumPHP will run some tests on the committed code. If the tests fail, you won’t be able to commit your changes.

It will also teach your co-workers to write better code following the best practices you’ve determined as a team.

Searching for an experienced
Magento 2 Company ?
Read More


Which tools we will Automate?

  1. PHP Code Sniffer
  2. PHP Code Beautifier
  3. PHP Coding Standards Fixer
  4. PHP Mess Detector
  5. PHP Stan
  6. Custom Keywords

Most of the tools are recommended by the Adobe Commerce Test Guide.

How to automate?

Installation of GrumPHP and Dependencies( tools )

We will install the following tools, in the Magento root directory. By running the following commands for the respective tools.

1. Install GrumPHP by running

composer require --dev phpro/grumphp

2. Install PHP CodeSniffer

composer require --dev "squizlabs/php_codesniffer=*"

3. Install PHP Coding Standards Fixer

composer require --dev friendsofphp/php-cs-fixer

4. Install PHP Stan

composer require --dev phpstan/phpstan

5. Install PHPMD (PHP Mess Detector)

composer require --dev phpmd/phpmd

6. Install PHP Lint

composer require --dev php-parallel-lint/php-parallel-lint

Initialize the git repository on the module level i.e <magento-2-root>/app/code/MyVendor/MyModule.

Then go to the module directory and run the command:

php vendor/bin/grumphp git:init

This above command will add the hooks to run the test (which configuration is stored in grumphp.yml ) on the files we are committing to the git repository. If all the tests pass then only it will allow the developer to commit the code.

Add bin path <magento2-root>/vendor/bin to your module composer.json .

{
    "config": {
            "bin-dir": "../../../../vendor/bin"
        }
}

GrumPHP auto detect git commit command but you can manually test by running php ../../../../vendor/bin/grumphp run inside the module.

Add the following code in the grumphp.yml file created on the Module directory structure. i.e <magento-2-root>/app/code/MyVendor/MyModule

# GrumPHP configuration for Magento 2
grumphp:
  hide_circumvention_tip: true
  process_timeout: 120
  stop_on_failure: false
  ignore_unstaged_changes: false
  tasks:
    jsonlint:
      detect_key_conflicts: true
      metadata:
        priority: 100
    xmllint:
      ignore_patterns:
        - "#test/(.*).xml#"
      metadata:
        priority: 100
    phplint:
      triggered_by: ['php', 'phtml']
      metadata:
        priority: 200
    yamllint:
      ignore_patterns:
        - "#test/(.*).yml#"
        - "#charts/.*#"
      metadata:
        priority: 100
    composer:
      file: ./composer.json
      no_check_all: true
      no_check_lock: false
      no_check_publish: false
      with_dependencies: false
      strict: false
      metadata:
        priority: 80
    # validate git commit message
    git_commit_message:
      allow_empty_message: false
      enforce_capitalized_subject: false
      enforce_no_subject_punctuations: false
      enforce_no_subject_trailing_period: true
      enforce_single_lined_subject: true
      type_scope_conventions: []
      max_body_width: 80
      max_subject_width: 80
      matchers:
        "Commit message must be alphabet and number": /[aA-zZ | 0-9]/
      case_insensitive: true
      multiline: false
      additional_modifiers: ''
    # validate git branch names
    git_branch_name:
      whitelist:        
        - "/([a-z][^0-9]+)$/"
      blacklist:        
        - "production"        
        - "master"        
      allow_detached_head: true
    # catch not allowed keywords
    git_blacklist:
      keywords:
        - "\.dev"
        - "\.local"
        - "\.test"
        - "<<<<<<<"
        - "======="
        - "DebuggerUtility"
        - "ObjectManager::getInstance"
        - "_GET\["
        - "_POST\["
        - "_REQUEST\["
        - "console.log("
        - "die("
        - "die;"
        - "exit("
        - "exit;"
        - "fileadmin"
        - "localhost"
        - "phpinfo"
        - "phpinfo("
        - "print_r("
        - "var_dump("
        - "_objectManager"
        - "ObjectManagerInterface"
      triggered_by: ['php', 'js', 'html', 'phtml']
      metadata:
        priority: 90
    # https://devdocs.magento.com/guides/v2.4/coding-standards/code-standard-php.html
    phpcs:
      standard: Magento2
      tab_width: 4
      severity: 10 # can remove this to dis allow all level of severity.
      error_severity: 10
      warning_severity: ~
      report: full
      triggered_by: [phtml, php]
      metadata:
        priority: 70
    phpcsfixer2:
      allow_risky: false
      config: '../../../../.php-cs-fixer.dist.php'
      triggered_by: ['php', 'phtml']
      using_cache: true
      cache_file: './.php_cs.cache'
      # config_contains_finder: false - to skip fixing all Magento 2 directory
      config_contains_finder: false
      verbose: true
    phpmd:
      ruleset: ['../../../../dev/tests/static/testsuite/Magento/Test/Php/_files/phpmd/ruleset.xml']
      triggered_by: ['php']
      exclude:
        - "./app/code/Magento/"
        - "./app/code/*/*/Setup/"
      metadata:
        priority: 70
    #  uncomment to skip modules using whitelist patterns
    #  whitelist_patterns:
    #     - /^app/code/MyVendor/MyModuleToSkip/(.*)/

    # https://devdocs.magento.com/guides/v2.4/test/testing.html#phpstan
    phpstan:
      autoload_file: ~
      configuration: '../../../../dev/tests/static/testsuite/Magento/Test/Php/_files/phpstan/phpstan.neon'
      level: 6
      triggered_by: ['php']
      force_patterns: []
      ignore_patterns: []
      memory_limit: "-1"
      metadata:
            priority: 90
    phpversion:
      project: '7.3'

Now, let’s take an example to demonstrate the automation test, made to check the code Quality of the module.

The module directory is an app/code/Webkul/DemoModule, now we will run the command

<code>php ../../../../vendor/bin/grumphp<span style="background-color: initial;font-family: inherit;font-size: inherit;color: initial"> run</span></code>

NOPE, errors occurred which must be resolved before the code is pushed into the development pipeline.

After going through the issues, we resolved them in the module and then again ran the command to test the code quality, and this time it passed all the checks.

grumPHP-success

That’s it In this article we tried to cover to Setup of the GrumPHP in the module development of Adobe Commerce. Hope it helps. Please share your feedback in the comments.

Happy Coding 🙂


Source link