Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add license checker and fixer #293

Open
1 task done
jaapio opened this issue Jan 19, 2024 · 3 comments
Open
1 task done

Add license checker and fixer #293

jaapio opened this issue Jan 19, 2024 · 3 comments

Comments

@jaapio
Copy link

jaapio commented Jan 19, 2024

Is your feature request related to a problem?

In many of my projects I require each file to have a file level license docblock. PHP_codeSniffer has 2 sniffs that are able to check the presence of a file level comment however it cannot strictly check the comment.

Describe the solution you'd like

As a bunch of code does say more than a thousand words:

<?php

declare(strict_types=1);

namespace CodingStandard\Sniffs\Commenting;

use PHP_CodeSniffer\Files\File;
use PHP_CodeSniffer\Sniffs\Sniff;

class LicenseDocBlockSniff implements Sniff
{
    const LICENSE = <<<LICENSE
This file is part of phpDocumentor.
 
For the full copyright and license information, please view the LICENSE
file that was distributed with this source code.
 
@link https://phpdoc.org
LICENSE;

    public function register(): array
    {
        return [T_OPEN_TAG];
    }

    public function process(File $phpcsFile, $stackPtr): void
    {
        $tokens = $phpcsFile->getTokens();
        $commentStart = $phpcsFile->findNext(T_WHITESPACE, ($stackPtr + 1), null, true);

        // Allow declare() statements at the top of the file.
        if ($tokens[$commentStart]['code'] === T_DECLARE) {
            $semicolon    = $phpcsFile->findNext(T_SEMICOLON, ($commentStart + 1));
            $commentStart = $phpcsFile->findNext(T_WHITESPACE, ($semicolon + 1), null, true);
        }

        if ($commentStart === false || $tokens[$commentStart]['code'] !== T_DOC_COMMENT_OPEN_TAG) {
            $phpcsFile->addFixableError('License docblock is missing', $stackPtr, 'Missing');
            return;
        }

        $commentEnd = $tokens[$commentStart]['comment_closer'];
        $licenseContent = '';

        for ($i = $commentStart; $i <= $commentEnd; $i++) {
            if ($tokens[$i]['code'] === T_DOC_COMMENT_STAR || $tokens[$i]['code'] === T_DOC_COMMENT_CLOSE_TAG || $tokens[$i]['code'] === T_DOC_COMMENT_OPEN_TAG) {
                continue;
            }

            $licenseContent .= $tokens[$i]['content'];
        }

        $trimmedLicense = '';
        foreach (explode("\n", $licenseContent) as $line) {
            $trimmedLicense .= trim($line);
        }

        $expectedLicense = '';
        foreach (explode("\n", self::LICENSE) as $line) {
            $expectedLicense .= trim($line);
        }

        if ($trimmedLicense !== $expectedLicense) {
            $phpcsFile->addFixableError('License docblock is invalid', $stackPtr, 'Invalid');
            $this->fix($phpcsFile, $commentStart);
            return;
        }
    }
}

Additional context (optional)

  • I intend to create a pull request to implement this feature.
@jrfnl
Copy link
Member

jrfnl commented Jan 19, 2024

@jaapio I understand what you are looking for and no, that's currently not available in this repo.

However, I do not intend to accept new Commenting sniffs in this repo anymore.
The current Commenting sniffs are (IMO) pretty outdated, contain lots of duplicate code, are difficult to configure and are completely unwieldy.

To get out of that situation, my intentions are to:

  1. Add a bunch of DocBlock and comment related utility functions to PHPCSUtils.
  2. Create a new repo in this organisation to contain Docs specific sniffs, which will use these utilities from PHPCSUtils.
    Sniffs in that repo will go in a generic "Docs sniff" container to allow for pick and choose standards.
  3. Create separate PSR5 and PSR19 standards in that repo that use the sniffs.
  4. Once all of that is set up and available, deprecate and eventually remove the Commenting sniffs from PHPCS itself.

I would very much welcome a sniff like you are proposing in that new repo once that gets set up, though the code would have to be made more flexible, like use a public property instead of a class constant for the text to look for, to make it configurable.

@jaapio
Copy link
Author

jaapio commented Jan 19, 2024

Thanks for your quick response, the example I shared was just my own brew sniff to demonstrate what I'm looking for.

For now I solved it with some bash scripts, which are also working but it would be nice to have this sniff some day. Please let me know when I can help with the docblock parts, I seem to know something about that. :-P

@jrfnl
Copy link
Member

jrfnl commented Jan 19, 2024

@jaapio I know where to find you 😆 and would welcome your input and help once I get started with the above, but first things first - let's get this package to 4.0.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants