Problem
- Uncertainty about when or how to apply coding standards across Drupal core versions and core vs. contrib code.
Goal
- Clarify the scope of coding standards with regard to
- major versions of core
- core vs. contrib code
- Explicitly specify/state which particular coding standards have been different for earlier versions.
Details
- In #1290258-59: The data type should be explicitly stated for all Drupal core @param and @return documentation. some (legit) confusion arose around my statement in a contrib issue:
Drupal coding standards are version-independent and "always-current". All new code should follow the current standards, regardless of (core) version. Existing code in older versions may be updated, but doesn't necessarily have to be. Especially for larger code-bases (like Drupal core), updating the code of a previous version for current standards may too huge of a task. However, code in current versions should follow the current standards. Lastly, when following this practice, make sure to not squeeze coding standards updates/clean-ups into otherwise unrelated patches.
- Based on that, the main people caring for Drupal coding standards discussed it and added the following intro text to http://drupal.org/coding-standards:
Drupal coding standards are version-independent and "always-current". All new code should follow the current standards, regardless of (core) version. Existing code in older versions may be updated, but doesn't necessarily have to be. Especially for larger code-bases (like Drupal core), updating the code of a previous version for the current standards may too huge of a task. However, code in current versions should follow the current standards.
Note: Do not squeeze coding standards updates/clean-ups into otherwise unrelated patches. Only touch code lines that are actually relevant. To update existing code for the current standards, always create separate and dedicated issues and patches.
Based on the confusion that arose in aforementioned issue, this could have probably been discussed some more. ;)
- As determined in aforementioned issue, there are coding standards - e.g., for string concatenation - which we currently apply differently for Drupal core patches depending on the core version a patch is for.
I.e., patches backported from D7 to D6 may be adjusted for the differing string concatenation rules being used throughout Drupal 6 core for consistency.
(Note, however, that I (sun) am currently not sure whether this "should" is actually turned into a "required" for backported D6 patches.)
- The above coding standards intro text was primarily intended to clarify the scope of current coding standards in contributed extensions, and also clarify how to update (or ignore) existing code.
Proposed resolutions (with pros and cons)
-
- Require all code to meet version-specific standards.
-
Pro:
-
Helps maintain consistency. D6 patches should be written to D6 standards, D7 patches should be written to D7 standards, and D8 patches to (current) D8 standards.
Con:
-
We have no currently-published version-specific standards, and no easy way to produce them.
-
-
- Require all code to be consistent with the surrounding code, regardless of standards.
-
Pro:
-
Helps maintain consistency. If there is any question as to coding standards, use the surrounding code as a standards guide.
Con:
-
The surrounding code, despite huge efforts at standardization, often lacks sufficient consistency to serve as a standard.
-
-
- Require all code to meet currently-published standards, regardless of surrounding code.
-
Pro:
-
Makes it easier to backport patches. If the style is good enough for D8, then it's good enough for D7 and D6, as well.
Con:
-
If the backported patch was written to a newer, different standard, it may not be consistent in style with the surrounding code. This will introduce the very type of inconsistencies that standards are written to avoid.
-
- 3.1 — Same as above, with certain well-known exceptions.
-
(@todo) The exceptions, no matter how well-known among senior core developers, should be documented for the sake of the rest of the community.
-
- Require all code to pass coder review as written for the target branch of core.
-
Pro:
-
This allows automation of the stylistic part of patch review, and also enforces version-specific standards which should help keep D8 patches consistent with D8, D7 patches consistent with D7, and D6 patches consistent with D6.
Con:
-
Coder review needs more active maintainers before this option can be considered.
-
-
- Use a common-sense approach.
-
Pro:
-
Allows us to decide these issues on a case-by-case basis instead of trying to come up with a Single Golden Rule That Covers All Possible Cases.
Con:
-
Even people who have "common sense" often disagree on what it means. The reason for developing rules and standards is to hear all the arguments once, then record the resultant decision so further disagreement is reduced or eliminated.
-
In #23, webchick postponed this issue until blockers to #4: Use Coder Review are resolved.
Remaining Tasks
See: #1299710: [meta] Automate the coding-standards part of patch review
Comments
Comment #1
pillarsdotnet commentedFirst of all, thanks to @sun for posting this issue!
I would like to see the following clarification:
I have had patches marked "needs work" by one reviewer because lines included in context were non-compliant. Then when I expanded the patch scope to modify the additional lines, another reviewer marked it "needs work" because the patch scope had expanded beyond the original problem statement. Having a clear standard would eliminate such frustration.
NOTE: Crossposted the issue summary to Coding Standards and Documentation groups.
Comment #2
sunThere are a couple of pros and cons on this. Your suggestion primarily targets core patches, so first of all, it's important to understand the scope of the suggestion.
The obvious pro is that backported patches don't necessarily have to be reworked and rerolled for minor coding style differences.
The obvious con is that committing code that's inconsistent with the rest of the (earlier) core major version is, well..., inconsistent, and possibly confusing for core developers and contributors.
Either argument very quickly leads to interpretation/quality problems when looking at a change that extends existing code following new standards, while the existing code follows old standards:
Obviously, a D7 vs. D6 example.
One of the fundamental questions here is whether we "care enough" to actually care.
If it was only me, then I'd happily accept such a patch for D6 (on the grounds that coding standards are version-independent and only the latest make any sense to apply to new code).
Comment #3
pillarsdotnet commentedWhat if I replaced "part" with "line" to indicate that it's a line-by-line distinction, rather than a word-by-word distinction?
Comment #4
webchickMy personal feeling is that coding standards for patches should be based on whatever the code base they're patching currently is at. Even if that code is using tabs instead of 2 spaces, camelCasedFunctionNames(), no(spaces between control structures){, and whatever other nonsense that people shouldn't be doing (according to the recommended coding standards), but still do.
Why? Because the entire point of coding standards is consistency in the code. You're doing people absolutely no favours if the entirety of a given file is indented with tabs and your little four-line patch indents with spaces. While your patch is technically correct, it introduces inconsistency with the rest of the code base, and should be rejected on those grounds. If however, in a separate patch, the entire code base you're working on is brought into line with the community's coding standards that says spaces instead of tabs, then your patch that indents with spaces instead of tabs could get accepted. Otherwise, you need to suck it up and use tabs, regardless of how "wrong" it is.
Developers, by and large, don't read documentation. By and large, they look for and then copy/paste examples that are pretty close to what they need, then modify as required. We have a motto that goes "When in doubt, do as core does." Developers look to Drupal core when there's ambiguity around how to do something and copy/paste whatever examples from that code base. This is why it's critical that within a stable release of Drupal core, we do not make radical changes to the coding standards, such as concatenation operators or requiring data types before @param/@return elements. Otherwise, the answer "What does core do?" changes on a day-to-day basis and can no longer be a trusted source of information.
So, for wide-scale coding standards changes, such as the concatenation spacing in D6, these would only apply to new code (i.e. D7), and the existing, stable code would be left untouched. Contrib has more options for what "new" code means, however, and so tools like Coder should be adjusted to accept either the old default or the new recommendation in D6, and only the new recommendation in D7.
At least that's how we've always done it, and unless there's a hugely compelling reason not to do that, I don't know why we'd want to switch it up. This gives the advantages of:
- Each stable version of core is a predictable source of what the correct standards are to use for that version.
- Contrib is able to use whichever standard they prefer: the one in place when the module was coded, or the latest recommended standard if they want to get a jump on Drupal N+1.
- The coding standard used in a given patch always conforms to the surrounding code, and doesn't introduce any inconsistencies which, even if they may be "correct" for that particular time and place, make the code harder to read and understand.
Comment #5
pillarsdotnet commented@#4 -- What about this issue where I'm clearly being asked by the Documentation co-maintainer to patch one function up so that it is inconsistent with the rest of the file?
Comment #6
webchickThat's a D8-only patch that's updating a single function to the proper coding standards, as part of a larger movement to update all of the code to coding standards. That's different than one-off patches fixing actual bugs including mis-matching coding standards which sun demonstrates in #2.
Comment #7
pillarsdotnet commentedSo I take it that by "surrounding code" you mean "in the same line or the same function" but not "in the same file". Am I correct, or have I still misunderstood you?
Comment #8
webchickIsn't that just semantics...?
If 99% of the code in D7 (the stable release of core) looks like this:
...then a patch comes along that adds one new function formatted like the following:
...then it is introducing inconsistency. Any new code in the stable release should match the existing coding standards.
Your linked example is for D8. D8 is not a stable release, so is free to update the coding standards and format code to conform to these standards, in whatever way is most convenient.
(I would argue that function-by-function coding standards conversion is not convenient, and it should be done module-by-module (or file-by-file in case of includes/) instead, but that's not really within the scope of this discussion.)
Comment #9
pillarsdotnet commentedAnyhow, it's hard to enforce the rule that if patching d6 I should be following the coding standards as they were written for d6, if I have no coding standards to look at. I really don't want to grep through the entire d6 codebase every time there's a patch to backport, just to try and deduce a rule from what is, honestly, an inconsistent standard.
Regarding consistency, I'll say this. Every single time I've submitted a patch that copies non-standards-compliant examples from other parts of the same file, it's been slapped back to "needs work". If you want to enforce this consistency rule, you really should document it somewhere so I've got a leg to stand on when debating that "needs work" status.
Comment #10
pillarsdotnet commented@webchick in #8
I challenge you to quote any standard which was followed by 99% of any Drupal core version and which has subsequently been changed. The example you mention is split 69/31 in favor of the blank line:
Blank line before
@return:No blank line before
@return:In D6, the percentages were very nearly reversed, but no less underwhelming:
If your example was intended to highlight type-hinting rather than the blank line, the ratios are D7/D8: 14/86, D6: 8/91 -- so I would probably conclude based on the ratios that type-hinted
@returnlines were forbidden in both versions, or slightly less discouraged in D7/D8. Neither conclusion would be correct.So how am I supposed to deduce an unwritten rule? Perform gyrations like the above and presume that the 69% statistic is the preferred one? Or am I supposed to have been sufficiently aware of the outdated standards that I can simply refer to memory? Either choice sets what IMHO is an unrealistically high bar for contribution to core.
I submit that such inconsistencies are the main reason that standards are changed. People start doing things a different way, despite the standard, and eventually the standard changes to reflect (current) best-practice. People like you who personally inspect nearly every new line of code that goes into core obviously have a better handle on what current best-practice entails. Therefore, it is up to you to codify such standards so the rest of us don't have to clone your brain (or duplicate your research) to achieve the same level of understanding. If you want to enforce different coding standards on different core versions, then by all means please document the differences rather than assuming they are common knowledge. We're not all as smart as you are, and even equally smart people can disagree sometimes. :-)
At last we agree, except that:
whereas it appears that:
If I am still misunderstanding you, please correct me again. I promise that I'll eventually get it right.
Comment #11
sunI agree with that statement, but I think the argumentation misses a quite essential point: Coding standards are not only for consistency, coding standards also have to be clearly defined to be standards in the first place.
Apparently, we no longer have older standards documented anywhere. And even if they were still available, they would not contain formal rules for clarifications and improvements that were only added later.
Hence, the only defined standard that exists for a particular question/rule may be the current standard.
Simply "looking at surrounding code" is not really a sustainable approach, because - despite of our relatively huge efforts to keep code on par with defined standards - we still have lots of code that does not follow the standards. Therefore, looking at surrounding code can very easily lead to ambiguous results.
This affects simple things, such as the blank phpDoc line before @return or putting "()" behind function names; and also major ugly things, such as having phpDoc summaries as a single short sentence on one line. (These examples are around documentation, but I'm confident that there are functional code examples, too.)
Lastly, our coding standards purposively try to differentiate between the terms MAY or SHOULD, and MUST - very similar to RFC specifications. That is primarily because large-scale changes to the standards cannot be introduced consistently in one fell swoop, but also when a particular standard is rather a recommendation than a requirement. This differentiation is needed from a technical, organizational, and social perspective. And it means that we will always have some "blurry" definitions in our standards, be it for transitional reasons, or for the sake of wider adoption.
Comment #12
pillarsdotnet commentedHere is my suggested workflow for accomplishing this change:
Migrate Coder review into core.EDIT: retracted as per webchick's response in the next comment.
EDIT: Partially being worked on as part of project application revamp.
or:
and possibly, in rare circumstances:
or possibly, in very rare circumstances:
Comment #12.0
pillarsdotnet commentedUpdated issue summary.
Comment #13
webchickjthorson is currently doing a lot of this work on PIFT/PIFR. See the tags under here http://drupal.org/project/issues/search/?issue_tags=project%20applicatio...
I don't think Coder Review needs to be moved into core for this to happen (in fact, that would be bad since we couldn't then use Coder Review stats on contributed modules as well). It does, however, need some more active maintainers.
Comment #14
pillarsdotnet commentedUpdated the issue summary, listing proposed resolutions and their drawbacks.
Comment #15
rafamd commented+1 for Require all code to meet currently-published standards, regardless of surrounding code.
EDIT: Basically, what the coding standard says right now (as listed in the issue summary).
IMHO, defining separate standards for the different versions of core would add to the complexity/learning curve we want to alleviate.
Comment #16
jhodgdonsubscribing, will read this later... but after reading just the summary, I am not understanding why this is an issue? We've always required new but not old versions of core to comply with new coding standards (although enforcement is not always uniform), and contrib has always been of varying quality in many ways (including coding standards). What do you want to change?
Comment #17
lars toomre commentedFor the convenience of keeping development up to date, any bugs in the current version must be fixed in development first. Hence, any new comer trying to help fill D7 bugs must learn how D8 core has changed on a logical basis as well as from a coding perspective. Then, once completing the rather daunting task of getting a D8 patch committed, the patch then has to be re-rolled for both D7 logic changes and documentation regressions to get the fix into the D7 production code. Does this really make sense??
I thought as a community we wanted more people to be involved with patches and eventually become core contributors. Since all code enhancements have to be done in D8 first, what is the harm in introducing docblock best practices back into D7 bit by bit with logical code fixes?
Comment #17.0
lars toomre commentedAttempt to summarize the solutions proposed thus far.
Comment #17.1
pillarsdotnet commentedMake the "Proposed resolutions" an ordered list for easy reference, and include "Pro" and "Con" sections for each.
Comment #17.2
pillarsdotnet commentedAdded id to proposed resolutions to make it linkable.
Comment #17.3
pillarsdotnet commentedBetter description of why we make standards in Resolution #5.
Comment #17.4
pillarsdotnet commentedBetter wording.
Comment #17.5
pillarsdotnet commentedMore wordsmithing. (Why does that term carry a negative connotation?)
Comment #18
pillarsdotnet commented@jhodgdon -- Sorry you didn't find the issue summary helpful. I have updated the list of Proposed resolutions with the main "Pro" and "Con" points raised in individual comments. Should I gather a straw poll of users in favor and opposed to each of the five possible resolutions?
My feeling is that your favorite is #5; webchick prefers #1 or #2; I initially preferred #3 but am now leaning toward #4. (Not that my opinion counts for anything.)
Comment #19
jhodgdonRE #17 - yes, that is correct. Anyone wanting to do core development seriously pretty much has to get into the in-development core version. It's always been that way, and it's always been a daunting burden to newcomers. We can't really change that, because we need to make sure that we don't have bugs that are fixed in, say, Drupal 6 but become broken again in Drupal 7/8.
A newcomer can start by porting patches from the dev version back to previous versions though, if they want to work on the version they're actually using.
Regarding docs standards, if someone is doing a D6 or D7 docs patch, I would always expect them to bring the docs up to the *current* docs standards (with the one exception of the Implementation of vs. Implements for hook implementations, which was not adopted until d7, and we made the decision at the time not to port to d6, although it could have largely been done with a script). So for docs at least, I'm in favor of #3 in the above (with that one exception) -- we don't have versions of the docs standards, just a "current" docs standard.
And that is pretty much true of the non-doc coding standards too, I think? The only major changes I'm aware of in coding standards between versions have been:
- D6 to D7 - changed "implementation of" to "implements" for doc headers for hooks.
- D6 to D7 - added whitespace around "." for concatenation
Are there more standards changes that are driving this issue? I just don't see it as a major problem. Am I missing something?
Comment #19.0
pillarsdotnet commentedMake each proposed resolution linkable.
Comment #19.1
pillarsdotnet commentedAdded sub-option to resolution #3.1 as per jhodgdon's latest comment.
Comment #19.2
pillarsdotnet commentedChanged "drawbacks" to "pros and cons" to better reflect current status.
Comment #20
pillarsdotnet commented@#19 by jhodgdon:
Nobody knows but (possibly) people like Dries, webchick, Gábor Hojtsy, and catch. The rest of the us great unwashed masses are ignorant and uneducated, and likely to stay that way until somebody documents the standards differences in an easily-referenced spot.
No, it's a normal problem, according to the issue priority. Feel free to downgrade it to minor if you must, but it's quite definitely a problem, as evidenced by the comments referenced in the summary. To be even more pedantic, it's a task, which implies that while nothing is really broken, the situation could and should be improved.
Yes! A documentation page listing standards differences that must be considered when backporting a patch from D8 to D7 to D6, both in core and contributed modules.
EDIT: Added resolution option 3.1 to the summary.
Comment #21
pillarsdotnet commentedSo, to flesh out option 3.1 and provoke further discussion, I propose the following documentation stub:
Comment #22
jhodgdonGracious, I would never make change number 2 when backporting to D6! And I would even question the wisdom of change #1. Really, the standards are the standards. They're not versioned. It's just that we're a bit more tolerant of things not being up to standards in past versions than in current versions.
Comment #23
webchickI become more and more convinced that discussions like this are a complete mis-use of time, energy, and focus, and we would all be far better off spending all of that effort on automating Coder module reviews for uploaded patches. Then we can put whatever behaviour we want *in code* and make sure it's consistently enforced across all projects.
Marking postponed. See http://drupal.org/project/issues/search/?issue_tags=project%20applicatio... for a list of blocking issues to rolling out that functionality. jthorson and rfay are both familiar with the underlying testbot architecture and could likely help anyone who wants to help with this get pointed in the right direction.
Comment #23.0
webchickAdded '@todo" to the bit in 3.1
Comment #24
pillarsdotnet commented@#23 by webchick:
Yay! That sounds like a decision!
Updated issue summary accordingly.
Comment #24.0
pillarsdotnet commentedIt appears that we have reached a decision.
Comment #25
pillarsdotnet commentedOpened #1299710: [meta] Automate the coding-standards part of patch review
And updated Issue summary accordingly.
Comment #26
sunFrom #711918-135: Documentation standard for @param and @return data types:
So we will require D8 patches to be re-rolled to make them more sloppy for D7...?
Makes no sense to me.
Comment #27
lars toomre commented@sun - I very much agree with your sentiment in #26.
Having two different coding standards and always applying patches to D8 first means that every single patch for D7 at minimum will have to be changed to make the documentation more sloppy? That as an American general once said is "Nuts!"
Comment #28
pillarsdotnet commentedI'd be okay with it as long as we actually publish two different coding standards. I am not willing to write code that adheres to an unwritten standard.
Unfortunately, this whole discussion probably makes #711918: Documentation standard for @param and @return data types a won't fix.
Comment #29
webchickI do not want the RTBC queue of D7, which is primarily focused on bug fixes, to be cluttered and clogged with "make this more nicer" style patches. We had a "polish" phase for those types of patches in D7, and that phase is long done. D7's strictly in maintenance mode now.
I also do not want to introduce massive amounts of inconsistency into D7's PHPDoc, where sometimes things have data types, sometimes they don't, sometimes they use new D8-style @param/@return spacing, sometimes they don't. It makes D7 harder to grok for the 99.999% of users who are not core developers and do not know or care what's happening in D8. They simply need to read through a given core file/function and understand what's going on, which is dramatically harder when their IDE shows completely inconsistent things depending on what particular part they're looking at.
And finally, D7 is a stable release. That means that the rules we set forth in terms of what's expected for coding standards compliance for contributed modules was established back in December 2009 or whenever the polish phase ended. We can't up and change this on contributed module developers during some arbitrary point release N months after 7.0, because they need a non-moving target to code against. See comments like http://drupal.org/node/711918#comment-2589916.
This is not some new, crazy position. We did the same thing with D6's concatenation operators when we changed those in D7. When we make a massive, developer-facing change to the coding standards those are enforced per-major version, though contributed module authors are encouraged to get a jump on the DN+1 version if they want.
So, yes, there's going to be a small inconvenience for re-rolling certain docs patches for D7, same as there's a small inconvenience for re-rolling patches that make string fixes in D8 that we don't deem important enough to break in D7. Tag 'em as Novice if you don't feel particularly inclined to do so yourself.
Comment #30
pillarsdotnet commentedclosed (won't fix) #711918: Documentation standard for @param and @return data types
Thanks for the clarification.
Comment #31
webchickAnd no, this doesn't make #711918: Documentation standard for @param and @return data types "won't fix". D8 is in code thaw, and is perfectly free to make whatever improvements to the coding standards it would like.
However, I would say that I personally vastly prefer to "postpone" any large-scale docs clean-ups on getting Coder module integrated into the testbot (which is very close) and writing rules for Coder module so it enforces D7 vs. D8 coding style automagically, since even if this was documented somewhere in the coding standards (the onus of documenting those differences is on the shoulders of whoever changes the coding standards, btw), no one will actually read it. :P~ Every minute spent arguing about things like this vs. simply building automated tools for enforcing the rules that we need is a minute wasted, IMO.
Comment #32
pillarsdotnet commentedAs a practical matter, this means installing three different versions of coder review on qa.drupal.org.
See related: #1161796: Initial d8 port of Coder and Coder Review modules.
Comment #33
dwwFor the record, I also oppose the "intentionally make D7 more sloppy" approach. D7 is already inconsistent. From the root of a fresh 7.x git clone:
To translate, there are 64 files in core that put something between
@paramand$for a total of 364 occurrences. Some of those are .js files where you see stuff like@param context. However, even with a sloppy way to avoid those in the counts, we still get a ton of hits for this in PHP code:I share the sentiment about not wanting an avalanche of doc-only patches flooding the D7 RTBC queue. But, for example, it seems pointless to strip this useful data out of patches that are already being back-ported. For example, I'm coming here from my experience at #1393234: API docs for field_access() are confusing.
I definitely don't have the energy to lead a big fight around this, but I just wanted to share my concerns that this policy seems misguided, and we should be more flexible (*gasp*) about incremental improvements like this, even in a stable release. In some ways, it's great how much our community and project considers the docs really part of the code and treats it all the same. But, IMHO, there's still a difference, and we should have different criteria for documentation fixes (and backports) than we do for the code itself.
My $0.02...
Thanks,
-Derek
Comment #33.0
dwwLinked to newly-opened issue.
Comment #34
jhodgdonCoding standards changes are now part of the TWG
Comment #35
tizzo commentedMoving this issue to the Coding Standards queue per the new workflow defined in #2428153: Create and document a process for updating coding standards.
Comment #36
quietone commentedI have read the IS and most of the comments. I admit that after #23, which I agree with, I started to skim. It was interesting to read about the challenges faces 12 years ago. Fortunately, and as far as I can tell these problems are in the past. Complying with coding standards is still a challenge but much is automated now.
Based on #23 and the lack of discussion for 12 years I am closing this issue. I think outdated is the best status.