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

Feature Request: Line Number with Checkstyle Format #3601

Closed
ChrGriffin opened this issue Mar 14, 2018 · 31 comments
Closed

Feature Request: Line Number with Checkstyle Format #3601

ChrGriffin opened this issue Mar 14, 2018 · 31 comments

Comments

@ChrGriffin
Copy link

ChrGriffin commented Mar 14, 2018

I'd love if this tool could be used to flag errors for developers to fix, rather than fixing them automatically (in the interest of teaching junior devs to format code properly the first time, rather than rely on an automated tool to catch it for them). We can sort of do that now by executing php-cs-fixer fix ./ --dry-run --diff, but the given output is very large and doesn't actually identify what the error was, just the change that was made. In a perfect world I'd be able to write php-cs-fixer fix ./app --dry-run --diff > output.txt and see a much more truncated list with the filename, line number, and rule that is being violated.

I'm aware of one other such tool, CodeSniffer, that would offer me (sort of) this functionality, but in all honesty I far prefer this package's configuration method.

EDIT: on further review, the --format=checkstyle option almost gives me what I want -- my only issue is that I can't get the line number with each item.

@ChrGriffin ChrGriffin changed the title Feature Request: Flag without Fixing, and Truncated Flag List Feature Request: Line Number with Checkstyle Format Mar 14, 2018
@keradus
Copy link
Member

keradus commented Mar 14, 2018

when the formats were introduced one after another (last one - checkstyle indeed), there were no good differ available. Thanks to amazing job of @SpacePossum, we can now generate diff in udiff format.

We are already prepared that checkstyle format could contain linenumber (vide https://github.com/FriendsOfPHP/PHP-CS-Fixer/blob/2.10/doc/checkstyle.xsd#L30), we were thinking about it even without having good differ.

Would you like to update https://github.com/FriendsOfPHP/PHP-CS-Fixer/blob/2.10/src/Report/CheckstyleReporter.php to expose line ? :)

@ChrGriffin
Copy link
Author

Sure thing, I'll take a crack at it.

@SpacePossum
Copy link
Contributor

Currently the check style report contains entries for each fixer, this makes the line number not useful in some situations. For example one fixer may change a series of tokens on line 2 and than the next fixer moves the tokens to line 20 or removes all tokens leaving no "line 2" in the file. Not sure how to proceed here in a meaningful matter.

@nesl247
Copy link

nesl247 commented Jul 30, 2018

I think at least when --dry-run is used, the line number the error is on is all that matters since fixers are not run. When one issue is fixed, the line numbers the errors were on will obviously change.

@SpacePossum
Copy link
Contributor

If you run with just one rule, than yeah the line numbers will always map back to that one rule and you should be good :)

If you run multiple rules (fixers) you still run into the same issue, in dry-run or not, as the fixed result from the first rule is the input of the next, of which the fixed/changed output is the input of the 3rd etc.
So if the first rule shuffles all your code around the fix done by the second might look as being on line X while that line start out to be line number Y.

@nesl247
Copy link

nesl247 commented Jul 30, 2018

Right, I was specifically just talking about when doing --dry-run which doesn't modify code. Having the line numbers here at least would be useful for CI. We don't automatically fix code, just validate.

I'm not sure if doing it for --dry-run only for now, and then doing this for the default mode would be possible.

@dmvdbrugge
Copy link
Contributor

Right, I was specifically just talking about when doing --dry-run which doesn't modify code

And this is a misconception on your part: --dry-run does modify the code, it just doesn't save it to the file afterwards.

So, as SpacePossum said, the fixed result from the first rule is still the input of the next, etc. Because otherwise it would not be a representative dry run.

@nesl247
Copy link

nesl247 commented Jul 30, 2018

Ah ok. I had no idea --dry-run actually modified anything. I thought it just output what would have been changed. Is this what other linters do (eslint, prettier, etc.)?

I ask because I actually came to this ticket as I was having issues with https://github.com/haya14busa/reviewdog and I think it's due to the missing line numbers. It depends on having the line number in the error match up with the line number in the git diff. If --dry-run actually modifies anything this will break reviewdog I believe as it won't match up.

@dmvdbrugge
Copy link
Contributor

dmvdbrugge commented Jul 30, 2018

I thought it just output what would have been changed.

The only way to know this is to actually do the fixing (for all configured rules), and diff that with starting code. That is usually how dry runs work: do everything you'd normally do, just don't save (write, commit, publish, etc) the end-result.

However as I understand correctly (haven't used it that way myself), you can specify the diff format to output just regular diffs, and those should have line numbers etc. You then just can't speak as to what specific fixer caused which specific change (unless only 1 fixer actually made changes).

having the line number in the error match up with the line number in the git diff

PHP-CS-Fixer doesn't work on a line by line basis (luckily, otherwise a lot of fixers wouldn't be possible), so if this is necessary, it won't ever work. Take for example this code

/**
 * @param int $foo
 */
function bar($foo);

If your change (and thus git diff) would be

/**
 * @param int $foo
 */
-function bar($foo);
+function bar(int $foo);

And your fixer config includes no_superfluous_phpdoc_tags and no_empty_phpdoc, the result after running PHP-CS-Fixer would be just

function bar(int $foo);

Making the PHP-CS-Fixer diff

-/**
- * @param int $foo
- */
function bar(int $foo);

How could you map that to your git diff?

@d42ohpaz
Copy link

d42ohpaz commented Sep 4, 2018

I would like to add to the discussion to suggest an alternate approach to solving this problem. Since php-cs-fixer was built to fix code, it naturally does not make sense to try to wedge reporting into that command. I believe that this is essentially what both @SpacePossum and @dmvdbrugge are getting at in their comments. Instead, it would make more sense to add a new command with a sole purpose of generating checkstyle (and other) reports that need meta information like the line number.

While I am not an expert on the code base, it would stand to reason that the same logic that is used when running the fixers on rule violations could also be used to capture the file, line, and rule violation (minus running the fixers). If it's possible that some rule violations might be masked by other rule violations, then so be it -- the user/system can re-run php-cs-fixer after manually fixing the code until such a point where there are no more violations. After all, something is better than nothing.

@keradus
Copy link
Member

keradus commented Sep 4, 2018

I would like to add to the discussion to suggest an alternate approach to solving this problem.

running php-cs-fixer fix ... vs php-cs-fixer other-command ... does not solve the issue, it's just moving issue from one command to another

(...) the same logic that is used when running the fixers on rule violations could also be used to capture the file, line, and rule violation (minus running the fixers).

That's the thing, to know which line is violating the rule, the rule has to be executed on a file. executing the rule = fixing. Executing without store fixed output = dry-run mode.

@d42ohpaz
Copy link

d42ohpaz commented Sep 5, 2018

running php-cs-fixer fix ... vs php-cs-fixer other-command ... does not solve the issue, it's just moving issue from one command to another

Yes, and the suggestion was intentional. The suggestion is two-fold:

  1. Keep backward compatibility with the current fix command, and
  2. Separation of concerns: fix is for fixing, and the new command is for reporting

Yes, --dry-run is currently being used as the reporting feature, but as pointed out, it modifies the code in memory and because of this, line numbers cannot be reliably captured.

That's the thing, to know which line is violating the rule, the rule has to be executed on a file. executing the rule = fixing. Executing without store fixed output = dry-run mode.

I took the liberty of forking the code earlier today and I poked around a little bit to see what it would take to add line numbers to the output. I do understand what you're saying about having to run the fixers to know the line numbers. I still believe this feature is trivial to implement; albeit, it will mean modifying each existing fixer, plus a handful of other files, to get it to work.

Here is what I was thinking:

  • Modify src/Fixer/FixerInterface.php and add a new method that would return an array of line numbers for each violation of said fixer
    • public function analyze(\SplFileInfo $file, Tokens $tokens)
      -token_get_all() returns the line number as element 2 (not always true, would need to document examples of when it doesn't work)
  • Modify src/Runner/Runner.php and add a new method that would return the same array as Runner::fix(), except with line numbers
    • Runner::fix() currently returns the following data structure:
array(
    'relative/path/to/file.php' => array(
        'appliedFixers' => array(
            'fixer-1', 'fixer-2',...
        ),
        'diff' => '... diff content ...'
    )
);
    • Modify the data structure so that the appliedFixers uses the fixer name as the key, and the array of line numbers as the value
      • Update Runner::fixFile() so that the appliedFixers structure follows the same format, but with an empty array
  • Add new command src/Console/Command/SummaryCommand.php (or whatever you want to call it)
    • Start off by copying the FixCommand and remove the options that do not make sense (e.g., --dry-run, --diff, --diff-format, etc)
    • Instead of calling Runner::fix(), call Runner::summary() (or whatever)
  • Modify the reporters to handle the change in the ReportSummary::$changed data structure by adding the line number to the output

Granted, I am still new to this code base, so I could have missed something, or you might have a better/cleaner idea than what I've laid out. These are just cursory thoughts based on an afternoon digging around the code.

@ntzm
Copy link
Contributor

ntzm commented Sep 5, 2018

👎 for modifying FixerInterface, it should be an extended interface like DefinedFixerInterface so as to not break backwards compatibility.

Also, you're proposing to modify every single fixer to add a new method to report line number violations - which would be a hell of a lot of work, and that's without considering testing on top of that.

I haven't thought about this long and hard, but I was thinking possibly a decorator for Tokens, that when any tokens are attempted to be modified, it counts it as a "violation", but doesn't actually modify the tokens. I think that would work for a majority of the fixers, but obviously not for the ones that rely on previous tokens being modified.

@keradus
Copy link
Member

keradus commented Sep 5, 2018

Yes, --dry-run is currently being used as the reporting feature, but as pointed out, it modifies the code in memory and because of this, line numbers cannot be reliably captured.

You need to modify the code in memory, as if you won't, not all changes will be detected (there are changes that would be applied only if other fixer would be applied earlier)

public function analyze

I'm really eager to hear who gonna implement this method for built-in 200 fixers and more in the wild

I haven't thought about this long and hard, but I was thinking possibly a decorator for Tokens, that when any tokens are attempted to be modified, it counts it as a "violation", but doesn't actually modify the tokens.

Imagine single violation that private method should be moved after public methods. Now, we got 500 tokens moved around, but we shall have it reported only as single violation


we already have a differ that can produce line numbers, why not simply use it ?

@d42ohpaz
Copy link

d42ohpaz commented Sep 5, 2018

@ntzm

Also, you're proposing to modify every single fixer to add a new method to report line number violations

Yes, but who else in the codebase aside of the fixers has the knowledge to know when a token is also a violation? With a new interface or modifying an existing interface, there are going to be roughly 200 classes either added or modified due to the way the existing infrastructure works. In other words, the fixers are tightly coupled with the logic used to determine what's a violation.

which would be a hell of a lot of work, and that's without considering testing on top of that.

If it were easy, we probably wouldn't be having this discussion; as the line numbers would probably already be available in the summary reports. In other words, we shouldn't let that stop us. :)

but obviously not for the ones that rely on previous tokens being modified.

Are there already use cases that demonstrate violations that are hidden due to other violations? I'm hard-pressed to think of any good use case.

Let me counter your argument by using the analogy of the built-in PHP linter/lexer: it does not try to guess at every possible problem in the code -- it finds the first one and halts. If that problem happened to be hiding another problem, then the user is expected to re-run the code so it can be discovered.

Don't get me wrong; I'm not suggesting we halt on the first problem we uncover. I'm simply suggesting that, for the sake of complexity (and speed), we not spin our wheels trying to uncover every single possible problem that could be lurking in the depths of somebody's code.

Besides, there will come a point when doing so overshoots the goal of providing line numbers. For example, if a fixer would sort methods alphanumerically (irrespective of visibility), only to violate a rule about ordering by visibility, you wouldn't flag the violation on the new line numbers that happen after the original sorting. You would flag the violation at the original line numbers and move on - no modification needed.

@keradus

You need to modify the code in memory, as if you won't, not all changes will be detected (there are changes that would be applied only if other fixer would be applied earlier)

What I'm proposing is not about fixing the code. It's only about reporting violations that are found on the existing code as a report. Fixing code is complex, and as you and a lot of others allude to, there really is no good way to get around how complex and 3-dimensional fixing code can be. So instead, we simply report on what we can reasonably report on and leave the fixing up to the user.

I'll be honest: my goal is to allow php-cs-fixer to be used in a continuous integration platform to generate reports on the coding standards of each build we generate. We don't believe in automatically fixing the code for our developers for two main reasons:

  1. It creates a lot of unnecessary noise in our commits/PRs that could be avoided if the developers didn't write non-standardized code to begin with (i.e., they code however they want, commit, get rejected at code review, fix the code they originally wrote, commit...)
  2. Developers will not be incentivized to learn the coding standards if they have the code reformatted for them, which feeds back into the original point: more noise

I'm really eager to hear who gonna implement this method for built-in 200 fixers and more in the wild

I volunteer as tribute to help with php-cs-fixer. As for any fixers in the wild, this is why we have version semantics. This kind of change would be very significant, so therefore it should target a major release. Any fixers that are not up to snuff would avoid the new version until they become compatible. I would never suggest otherwise. :)

Imagine single violation that private method should be moved after public methods. Now, we got 500 tokens moved around, but we shall have it reported only as single violation

If a class has 500 methods that violate a rule, then yes, we should have 500 violations. I would argue that the number of violations is not what should concern us, it's the quality of the violations. For example, if your class has 2 private methods, followed by one public method then the violation(s) are either:

  1. the private methods: they should appear after protected and public
  2. the public method: it should appear before protected and private

Never should we suggest all three methods are in violation. It could be as simple as a hard-fast rule that public methods are never in violation, or it could be more dynamic as to suggest whichever visibility of method has the fewest violations is the visibility that is not in violation. So in our given example, the public method would be considered correct while the private methods are in violation.

we already have a differ that can produce line numbers, why not simply use it ?

Because the differ works on modified code, and that modified code could have any number of fixers applied to them. How would you know with any level of certainty which fixer was applied to any given line of code from the original source? All you would know is that line N in path/to/file.php has a violation. Now we're back to square one, but with a different problem: what was the violation?

I would argue that separating out the logic that detects the violations from the logic that fixes the violations would better serve this project going forward. I never said it would be easy, and I certainly don't expect it to happen over night. Though that would be nice. :)

@keradus
Copy link
Member

keradus commented Sep 5, 2018

What I'm proposing is not about fixing the code. It's only about reporting violations that are found on the existing code as a report. Fixing code is complex, and as you and a lot of others allude to, there really is no good way to get around how complex and 3-dimensional fixing code can be. So instead, we simply report on what we can reasonably report on and leave the fixing up to the user.

So, again. That's the whole point. PHP CS Fixer had been built as... FIXER. It does not look for violations. There is no code for that. We don't have the logic to find violation as standalone code - it's part of fixing functionality that cannot be easily extracted. And rewriting a 200 rules to do so is way we will not take.

I'll be honest: my goal is to allow php-cs-fixer to be used in a continuous integration platform to generate reports on the coding standards of each build we generate.

Awesome ! Then... do it ! PHP CS Fixer in dry-run mode does exactly that. Symfony, Zend, Yahoo are using it. Scrutinizer CI offers it out of the box, ppl are using it across Travis, CircleCI, Jenkins, Bamboo... your goal has been already achieved.

I volunteer as tribute to help with php-cs-fixer.

then let me help with that. separating logic of detecting vs fixing for existing codebase would take few months of full-time job for any of us. are you willing to commit that deep? if so - it's wrong, dev shall be lazy and think about simpler solution.

Imagine single violation that private method should be moved after public methods.
Now, we got 500 tokens moved around, but we shall have it reported only as single violation

If a class has 500 methods that violate a rule, then yes, we should have 500 violations.

500 tokens are not 500 methods. in my example we had a single method to be moved, and that method is defined by 500 tokens. That was killer point for ntzm's idea of wrapping Tokens.

we already have a differ that can produce line numbers, why not simply use it ?

Because the differ works on modified code, and that modified code could have any number of fixers applied to them.

Differ works on whatever one would run it against. You don't need to run differ after each of fixer has been applied.


I would argue that separating out the logic that detects the violations from the logic that fixes the violations would better serve this project going forward.

This one is way bigger topic than lines reporting. Please give the reasoning for that.
When we built the tool, we thought exactly opposite.
How would it serve the project in going forward, explicitly ?
I can see huge time consumption for that task (which can be spend better), and I don't see benefits of that action. Possibility of providing lines is not decent benefit that could be use as an excuse to go that way - as feature of gathering lines can be implemented in multiple ways.

@d42ohpaz
Copy link

d42ohpaz commented Sep 5, 2018

So, again. That's the whole point. PHP CS Fixer had been built as... FIXER. It does not look for violations. There is no code for that. We don't have the logic to find violation as standalone code - it's part of fixing functionality that cannot be easily extracted. And rewriting a 200 rules to do so is way we will not take.

PHP was never meant to be object oriented. There never was any code for that, until two university students - against the advisement of their professor - came along and rewrote PHP's internal engine, which paved the way to PHP as we know it today. I knew a guy who once bragged back in the late 90's how UNIX was never meant to be used with a mouse, and yet he had successfully set up gpm so he could do just that with his installation of FreeBSD. Git was meant to be decentralized, and yet here we are having this discussion on Github - a centralized server used for git hosting.

With all due respect, and I'll be frank here, your response is cowardly and short-sighted. Which leads me into...

Awesome ! Then... do it ! PHP CS Fixer in dry-run mode does exactly that. Symfony, Zend, Yahoo are using it. Scrutinizer CI offers it out of the box, ppl are using it across Travis, CircleCI, Jenkins, Bamboo... your goal has been already achieved.

I've done it. And all of my reports say each violation happens at line 0 of each file. So now my team, as well as anyone else who does this, has to spend the majority of their efforts skimming the code trying to find each and every violation, no matter how subtle.

Again, with all due respect and brutal honesty: if it weren't for the breadth of the ruleset, I'd be using phpcs (a tool that was never meant to fix code, but now does) right now instead of spending my effort trying to convince a brick wall that a door can be added to allow easy access to the other side of this problem.

So, tell me where would I begin with the following violation?

example

then let me help with that. separating logic of detecting vs fixing for existing codebase would take few months of full-time job for any of us. are you willing to commit that deep?

Yes, I would, as long as it's the right thing to do.

if so - it's wrong, dev shall be lazy and think about simpler solution.

I'm 100% open to suggestions.

For example, I liked @ntzm's suggestion about adding a new interface that extends FixerInterface instead of modifying it. In turn, instead of modifying the existing fixers we would add checkers that would be used by the new command, leaving the existing code untouched. Yes, on the surface, that means duplicating logic.

@keradus
Copy link
Member

keradus commented Sep 6, 2018

So, from the very beginning.
We are for having the feature of reporting line numbers in checkstyle and so.
I was, personally, simply against your proposal of how to achieve it, due to change of whole idea behind how tool was written, thus huge time that has to be consumed for this task.

I've done it. And all of my reports say each violation happens at line 0 of each file. So now my team, as
well as anyone else who does this, has to spend the majority of their efforts skimming the code trying
to find each and every violation, no matter how subtle.

That's exactly how the tool was not designed to be used like. Why you ask your team to manually do it? let them run fix command and that's it. If they just want to see violations without applying them, they can use dry-run, eg --dry-run --diff --diff-format=udiff, so they would also see line numbers.

I'm 100% open to suggestions.

Already did, that's what we brought udiff alive in the first place.

@d42ohpaz
Copy link

d42ohpaz commented Sep 6, 2018

That's exactly how the tool was not designed to be used like.

I appreciate that. But what I don't understand is this stonewall against evolving the software beyond its original intentions; especially since I'm offering to help with the work. I can't imagine there is no room for compromise on this point.

Why you ask your team to manually do it?

So that they learn the coding standards and not commit poor code quality in the first place. This keeps commit logs focused on meaningful code and not the noise from poor code quality. This is especially important in code reviews, which we do very regularly with every PR.

Again, I chose php-cs-fixer due to the breadth of rules available (e.g., Symfony, migration, risky, et al). Other tools don't give us the coverage we need for our projects. And unless I am mistaken, the rules are not interoperable with other tools.

If they just want to see violations without applying them, they can use dry-run, eg --dry-run --diff --diff-format=udiff, so they would also see line numbers.

--diff --diff-format=udiff and --format=checkstyle are mutually exclusive, with the latter overriding the former and the latter does not support line numbers. This is the crux of the entire feature request: make line numbers available to the checkstyle format.

Which, by the way, the line numbers are made available from token_get_all() function, so diffing is wholly unnecessary and a waste of cycles and memory.

Here are a couple of screenshots of what the checkstyle report looks like in Jenkins. As you can see, the diff feature is incompatible in this case.

Overview

overview

New Tab

file-view

@dennisdahlc
Copy link

I for one would also really like to know which lines has been altered by which fixer.
Knowing the file has been fixed by a certain fixer does not tell me it has fixed something.

I know I can diff afterwards, but if more fixers has fixed issues, it is no longer clear which fixer has done what.

Attaching the line number to a token during the tokenization would be sufficient in most cases, since you would be able spot it in the diff anyway.

@SpacePossum
Copy link
Contributor

With all due respect, and I'll be frank here, your response is cowardly and short-sighted.

I don't have the energy to work with this

@PHP-CS-Fixer PHP-CS-Fixer locked and limited conversation to collaborators Sep 6, 2018
@PHP-CS-Fixer PHP-CS-Fixer unlocked this conversation Sep 6, 2018
@d42ohpaz
Copy link

d42ohpaz commented Sep 6, 2018

Please re-open. What reason do you have for closing this ticket?

@keradus
Copy link
Member

keradus commented Sep 6, 2018

lock was accidental and Space already unlocked it 20 minutes before your request.

to fast finish the talk about "how" to achieve it.
with collaboration with PHPStorm, now PHPStorm supports PHP CS Fixer out of the box, including changed lines support (via provided by us udiffer)

https://blog.jetbrains.com/phpstorm/2018/09/phpstorm-2018-3-early-access-program-is-open/

example

@d42ohpaz
Copy link

d42ohpaz commented Sep 6, 2018

lock was accidental and Space already unlocked it 20 minutes before your request.

I appreciate the lock being lifted. I was referring to resetting the ticket status from Closed to Open.

to fast finish the talk about "how" to achieve it.
with collaboration with PHPStorm, now PHPStorm supports PHP CS Fixer out of the box, including changed lines support (via provided by us udiffer)

That's really cool. I love seeing the cross-compatibility between projects such as this. However, that side-steps the original request: add line numbers to checkstyle report.

@keradus
Copy link
Member

keradus commented Sep 7, 2018

However, that side-steps the original request: add line numbers to checkstyle report.

thank you for pointing this out... #3601 (comment)

@d42ohpaz
Copy link

d42ohpaz commented Sep 7, 2018

@keradus

So, from the very beginning.
We are for having the feature of reporting line numbers in checkstyle and so.

I somehow missed this. I will see what I can do about tracking line numbers, taking into account fixer modification concerns already discussed.

In the meantime, would you or @SpacePossum reopen this ticket? Or would a new ticket be preferred?

Thank you for talking this through with me. It has helped. :)

@drzraf
Copy link

drzraf commented Nov 10, 2018

I'm pretty convinced this ticket should be kept open.
dry-run + checkstyle + line numbers represent a legitimate need.

@paslandau
Copy link

paslandau commented Jan 2, 2019

Not sure what the current status is, but I'd also +1 the request for line numbers. I'm currently looking into integrating code style tools into our dev process, starting from the IDE (PHPStorm in our case), pre-commit hooks (via grumphp) to continous integration via jenkins.

Especially the PHPStorm integration brought me here, because the inspections are currently rather not useful, if there is more than one violation. I believe this is due to the way that php-cs-fixer reports violations. To make things more clear, here is a concrete example:

<?php
//hello

function foo_bar($baz=null, $bar)
{
    echo "foo"; echo "bar";
}

The file contains multiple violations and this is how PHPStorm reports those violations with php-cs-fixer configured:

php-cs-fixer

The arrow-position of the bubble is "my cursor" and I get a list of all style violations. Unfortunately "I don't now" which of those actually applies to the given line. The command that PHPStorm runs behind the scenes is

vendor/bin/php-cs-fixer' 'fix' 'test.php' '--dry-run' '--diff' '--diff-format=udiff' '--format=xml' '-vv' '--allow-risky=yes'

Generating the following output:

<?xml version="1.0" encoding="UTF-8"?>
<report>
  <files>
    <file id="1" name="test.php">
      <applied_fixers>
        <applied_fixer name="blank_line_after_opening_tag"/>
        <applied_fixer name="no_unreachable_default_argument_value"/>
        <applied_fixer name="no_extra_blank_lines"/>
        <applied_fixer name="braces"/>
      </applied_fixers>
      <diff><![CDATA[--- Original
+++ New
@@ -1,14 +1,12 @@
 <?php
+
 //hello

-function foo_bar($baz=null, $bar)
+function foo_bar($baz, $bar)
 {
-    echo "foo"; echo "bar";
+    echo "foo";
+    echo "bar";
 }
-
-
]]></diff>
    </file>
  </files>
  <time unit="s">
    <total value="0.117"/>
  </time>
  <memory value="6" unit="MB"/>
</report>

As you can see, there is no information about "where which violation occured", but only "which fixers got applied". So I guess there's nothing that can be done from the PHPStorm side.

In comparison, this is the same file but with a PHPCodeSniffer inspection instead of php-cs-fixer

phpcs

The error message is actually taylored to the style violation that affects the specific line in question.

Command run bv PhpStorm

vendor/bin/phpcs test.php --encoding=utf-8 --report=xml

Output

<?xml version="1.0" encoding="UTF-8"?>
<phpcs version="3.4.0">
<file name="/var/www/current/test.php" errors="5" warnings="0" fixable="3">
    <error line="4" column="22" source="Squiz.Functions.FunctionDeclarationArgumentSpacing.SpaceBeforeEquals" severity="5" fixable="1">Incorrect spacing between argument &quot;$baz&quot; and equals sign; expected 1 but found 0</error>
    <error line="4" column="22" source="Squiz.Functions.FunctionDeclarationArgumentSpacing.SpaceAfterDefault" severity="5" fixable="1">Incorrect spacing between default value and equals sign for argument &quot;$baz&quot;; expected 1 but found 0</error>
    <error line="4" column="29" source="PEAR.Functions.ValidDefaultValue.NotAtEnd" severity="5" fixable="0">Arguments with default values must be at the end of the argument list</error>
    <error line="6" column="27" source="Generic.Formatting.DisallowMultipleStatements.SameLine" severity="5" fixable="1">Each PHP statement must be on a line by itself</error>
</file>
</phpcs>

I've two concrete examples why this is useful:

  1. Code reviews + learning effects for junior devs
  2. During the inital setup of the rules

Nr. 1 has already been explained here. As for 2... well, that's my current pain point :) I'm trying to understand each rule/fixer by applying them to our existing codebase and getting (unsurprisingly) a lot of violations. Since I have no clue which violations refers to which line in the code, exploring those rules is very cumbersome, because I can't just "hover" over the violation in PHPStorm to understand what the actual issue is and look it up in the documentation.

I am aware that php-cs-fixer is.. well.. a fixer and not a style checker. However, from an end user perspective I would like to use one tool and define one ruleset instead of maintaining multiple (incompatible) ones. php-cs-fixer is already integrated in our favorite IDE and offers a ton of great options, so this would be a perfect fit.

PS: Thx for the discussions in here - especially @dohpaz42: Very well explained. i hope you didn't move on already (or if so... to what ;)).

@scaytrase
Copy link

Can we have this reopened?

SpacePossum added a commit that referenced this issue Apr 5, 2019
This PR was squashed before being merged into the 2.15-dev branch (closes #4288).

Discussion
----------

Add Gitlab Reporter

Gitlab does support a subset of the CodeClimate JSON Format.
I initially called the Reporter "CodeClimate", but that would "require" more fields that we currently cannot fill appropriately from a report generator, I think.
So I decided to rename it to "Gitlab Reporter".

It will result in a pull request annotation like this:
![image](https://user-images.githubusercontent.com/156839/52041883-f8dc5c00-253b-11e9-9f04-07faa7eaa351.png)

I will be happy to maintain this reporter, if problems arise.

In a next step I would be happy to add meaningful line numbers, if someone can assist me on that, but after reading #3601 it does not seem to be so easy, and I think the current state is enough for an "MVP" ;-)

Commits
-------

5b54f5c Add Gitlab Reporter
@drzraf
Copy link

drzraf commented May 20, 2019

Maybe some udiff-to-checkstyle.awk is possible to fill the gap. Still the udiff lacks most information checkstyle provides:

  • severity (eg: "warning")
  • source (eg: "PHP-CS-Fixer.braces")
  • message (eg: "Found violation(s) of type: braces")
    (which udiff could(?) provide within diff hunks)

@SpacePossum
Copy link
Contributor

Closing as the PR has to many ideas that deserve each their own issue and something have already changed in the last 2 years.
As such, if anything left please create new on the point small request with up to date samples. Thanks all!

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