Search code examples
phpcomposer-phpphpcodesniffer

Can I specify a CodeSniffer standard as a dev composer dependency?


Say I have two or three projects, and they all use different PHP CodeSniffer standards (custom made).

I'd like to be able to include them as require-dev dependencies with Composer, so that when spinning up a project repository they will be installed along with PHPUnit and my other dev requirements.

Currently I have all of the standards on my machine's global phpcs standards folder and I'm telling each project which standard to use via a phpcs.xml configuration file in the project root.

Can I specify a path to the standard, so that it can be installed and used via composer?


Solution

  • You can specify an additional path for phpcs to look for standards in using the installed_paths setting. Here's an example phpcs.xml configuration:

    <?xml verison="1.0"?>
    <ruleset name="MyProject">
      <description>My cool project, using a custom PHPCS standard</description>
      <rule ref="MyCoolStandard" />
      <config name="installed_paths" value="vendor/myvendorhere" />
    </ruleset>
    

    Then assuming your custom PHPCS standard has a file structure like this:

    + MyCoolStandard
      - Sniffs
        - Classes
          - MyClassSniff.php
      - ruleset.xml

    You can add a basic composer.json file to it and give it a name. An important part here is that you will need to tell it to install into a path that matches the standard name - or more simply just name the package as your standard (note: needs to match ruleset.xml in the standard, case included):

    {
        "name": "myvendorhere/MyCoolStandard",
        "description": "My cool PHPCS standard",
        "require": {}
    }
    

    Now you can just include it as a VCS repository in your project:

    # Project: composer.json
    ...
        "repositories": [
            {
                "type": "vcs",
                "url": "[email protected]:myvendorhere/myreponame.git"
            }
        ],
        "require-dev": {
            "myvendorhere/MyCoolStandard": "dev-master"
        }
    ...
    

    TL;DR:

    • Use the installed_paths CodeSniffer configuration setting to specify your composer's vendor path (up until the folder named after your standard) as a standards path
    • In your standard's repository, name the composer package after the standard (case sensitive). It must be the same as the name you use in your ruleset.xml so that phpcs can find it, otherwise you'll get errors saying it couldn't befound.
    • Include your custom standard as a VCS repo in the project's composer config (or a better way...!)