lint: Add linter to error on #include <*.cpp> #13301

pull Empact wants to merge 1 commits into bitcoin:master from Empact:lint-include-cpp changing 1 files +8 −0
  1. Empact commented at 3:22 AM on May 22, 2018: member

    Files should depend on one another by interface, not by implementation. This checks for quoted includes as well.

  2. Empact force-pushed on May 22, 2018
  3. Empact commented at 3:25 AM on May 22, 2018: member

    With @practicalswift #13288 (comment)

    Pending #13288, #13291

    Current failures, via travis:

    $ if [ "$TRAVIS_EVENT_TYPE" = "pull_request" ]; then contrib/devtools/lint-all.sh; fi
    The following files #include .cpp files:
    src/test/blockchain_tests.cpp:#include "rpc/blockchain.cpp"
    src/test/torcontrol_tests.cpp:#include <torcontrol.cpp>
    ^---- failure generated from contrib/devtools/lint-include-cpp.sh
    
  4. fanquake added the label Tests on May 22, 2018
  5. ken2812221 commented at 3:29 AM on May 22, 2018: contributor

    Concept ACK

  6. practicalswift commented at 4:45 AM on May 22, 2018: contributor

    ACK 177dc4277722c2e3d5c34bab4de3951055510a88

    Very nice! :-) Love these small regression tests that make sure we'll never have to think about a given class of otherwise recurring mistakes/issues ever again.

    Tiny nit: Could be added to existing lint-includes.sh instead if we want to keep the number of linter files down.

  7. in contrib/devtools/lint-include-cpp.sh:1 in 177dc42777 outdated
       0 | @@ -0,0 +1,17 @@
       1 | +#!/bin/bash
    


    promag commented at 4:05 PM on May 22, 2018:

    nit

    #!/usr/bin/env bash
    

    Empact commented at 8:48 PM on May 23, 2018:

    Currently, every bash invocation is via #!/bin/bash. I'm seeing arguments for using bin/env for compatibility across more systems, e.g. OpenBSD, and some concerns about potential security issues if malicious code corrupts the path. Not sure how to value those.

  8. in contrib/devtools/lint-include-cpp.sh:10 in 177dc42777 outdated
       5 | +# file COPYING or http://www.opensource.org/licenses/mit-license.php.
       6 | +#
       7 | +# Check for includes of *.cpp files.
       8 | +
       9 | +EXIT_CODE=0
      10 | +INCLUDED_CPP_FILES=$(git grep -E "^#include [<\"][^>\"]+\.cpp[>\"]" -- "**/*.cpp" "**/*.h")
    


    promag commented at 4:05 PM on May 22, 2018:

    Are these glob portable?


    practicalswift commented at 5:16 PM on May 22, 2018:

    @promag They are expanded by git and not the shell, but even if they were handled by bash they would have be portable, no? :-)


    promag commented at 5:46 PM on May 22, 2018:

    @promag They are expanded by git

    👍

    but even if they were handled by bash they would have be portable, no?

    See https://github.com/bitcoin/bitcoin/pull/13228/files#r188147943.


    Empact commented at 10:30 PM on May 22, 2018:

    Provided it's run from the project root (which is how it's run on Travis), it should get all cpp/h files - it's just the top level that is missed by ** in some cases.


    practicalswift commented at 3:46 AM on May 23, 2018:

    Ah, I now understand what you meant. What about changing it from "**/*.cpp" "**/*.h" to "*.cpp" "*.h"? That will work regardless of where it is run from.

  9. promag commented at 4:06 PM on May 22, 2018: member

    Concept ACK.

  10. Empact force-pushed on May 23, 2018
  11. laanwj commented at 6:29 PM on May 23, 2018: member

    Sorry to be skeptical here, but does this really happen enough to merit adding yet another linter?

  12. Empact commented at 8:45 PM on May 23, 2018: member

    @laanwj Generally, I'm in favor of more lints as implementing practice in code means that it need not be propagated / enforced by humans - particularly when the difference is easily overlooked by humans and easily detected by code. This case has been violated twice, and overlooked twice by reviewers, so an automatic check seems helpful, if we agree that it should not be violated.

    On that point, I agree with MarcoFalke: "Including a cpp file seems extremely wrong." #13230 (review)

    That said, I'm not clear how to value the cost of having an extra file in the contrib/devtools directory, or having this command run with each CI run.

  13. MarcoFalke commented at 9:08 PM on May 23, 2018: member

    Can this be combined with the other include linter, so we don't have too many "duplicate" files?

  14. Empact force-pushed on May 23, 2018
  15. promag commented at 10:30 PM on May 23, 2018: member

    Can this be combined with the other include linter, so we don't have too many "duplicate" files?

    I wouldn't mind separate files as it would allow:

    find contrib/devtools -name "lint-*.sh" ! -name lint-all.sh | parallel -u bash :::
    

    However flake8 takes most of the time so no gain for now (hint: s/bash/time above).

  16. promag commented at 10:37 PM on May 23, 2018: member

    Should it just check if the included file is header|header.h|header.hpp?

  17. practicalswift commented at 7:13 AM on May 24, 2018: contributor

    ACK 2f2a784c7ba189628dfc5d9dbd10d1861ebaadbd

  18. laanwj commented at 10:36 AM on May 24, 2018: member

    Generally, I'm in favor of more lints as implementing practice in code means that it need not be propagated / enforced by humans

    I agree. I don't think I have a problem with it in principle. It's just the proliferation of all kinds of regexp shell scripts that might make the travis build fail, that I'm having problems with. There is a cost to this in maintenance.

    I think linters should be used to avoid sneaky problems that might result in bugs. For example one I really like is #13041, which catches potential locale-dependency bugs.

    Including a .cpp file is like including a 10000-pound elephant in the room, if reviewers don't catch this we have a really big problem.

  19. Empact commented at 10:46 AM on May 24, 2018: member

    Agreed, #13041 is a great one. I mean to cite the fact that this has happened before as evidence that these are tricky, perhaps because it is easy to gloss over includes, particularly in the context of tests. For reference, the PRs where these includes were introduced: #10408 #11748

  20. practicalswift commented at 11:08 AM on May 24, 2018: contributor

    @laanwj Adding some data: there seems to have been a total of twelve .cpp includes during the project git history:

    $ git log -u | grep -E '^\+#include.*\.cpp.$' | cut -b2- | tr '<>' '"' | sort -u
    #include "base58_tests.cpp"
    #include "base64_tests.cpp"
    #include "Checkpoints_tests.cpp"
    #include "DoS_tests.cpp"
    #include "miner_tests.cpp"
    #include "rpc/blockchain.cpp"
    #include "script_tests.cpp"
    #include "torcontrol.cpp"
    #include "transaction_tests.cpp"
    #include "uint160_tests.cpp"
    #include "uint256_tests.cpp"
    #include "util_tests.cpp"
    

    This issue has been independently introduced twice in the code base in two separate PR:s during the last twelve months alone. The PRs (#10408, #11748) were reviewed by very skilled developers before merge.

    Thus it empirically seems like an extra pair of very attentive eyes in the form of Travis would be helpful in making sure this 10000-pound elephant doesn't sneak into the code base again :-)

  21. practicalswift commented at 12:37 PM on May 24, 2018: contributor

    @laanwj Regarding the potential maintenance need for the linting shell scripts: I volunteer to maintain all the linter scripts in the repo if that is of any help. In the event of a linter causing problems just ping me in and I'll fix it quickly! :-)

  22. laanwj commented at 1:21 PM on May 24, 2018: member

    @laanwj Adding some data: there seems to have been a total of twelve .cpp includes during the project git history:

    Even on the desirability there is an alternative perspective, FWIW: at one of my previous employers we maintained a huge system, and including the .c or .cpp was standard practice for private unit tests. This allowed testing internal functions and methods and which are not exposed on the public interface of a compilation unit. (an alternative to this at a slightly higher level was to have a "test interface", but this carries a bit of run time overhead)

    Not saying that we should do that here, but it's all too easy to be blanket against something if it offends your aesthetic sensibilities.

    Thus it empirically seems like an extra pair of very attentive eyes in the form of Travis would be helpful in making sure this 10000-pound elephant doesn't sneak into the code base again :-)

    Heh :)

    @laanwj Regarding the potential maintenance need for the linting shell scripts: I volunteer to maintain all the linter scripts in the repo if that is of any help. In the event of a linter causing problems just ping me in and I'll fix it quickly! :-)

    Okay! Thanks.

  23. MarcoFalke commented at 6:46 PM on June 5, 2018: member

    I wouldn't mind separate files as it would allow: find contrib/devtools -name "lint-*.sh" ! -name lint-all.sh | parallel -u bash ::: However flake8 takes most of the time so no gain for now (hint: s/bash/time above).

    I highly doubt that a single git grep makes up a significant run-time to justify for the overhead of another script with copyright header, etc.

  24. MarcoFalke commented at 6:47 PM on June 5, 2018: member

    Oh, I see this was already combined into the existing file. utACK, but needs rebase.

  25. MarcoFalke added the label Needs rebase on Jun 6, 2018
  26. lint: Add linter to error on #include <*.cpp>
    Files should depend on one another by interface, not by implementation.
    This checks for quoted includes as well.
    
    With practicalswift
    9d6c9dbb88
  27. Empact force-pushed on Jun 6, 2018
  28. ken2812221 approved
  29. ken2812221 commented at 9:23 AM on June 6, 2018: contributor

    utACK 9d6c9dbb88593dea995072ba812f115a51ea2b4b

  30. Empact commented at 9:25 AM on June 6, 2018: member

    Rebased for #13385

  31. MarcoFalke removed the label Needs rebase on Jun 6, 2018
  32. MarcoFalke merged this on Jun 6, 2018
  33. MarcoFalke closed this on Jun 6, 2018

  34. MarcoFalke referenced this in commit e4082d59f5 on Jun 6, 2018
  35. Empact deleted the branch on Jul 2, 2018
  36. PastaPastaPasta referenced this in commit 3900e4d3ec on Jun 17, 2020
  37. PastaPastaPasta referenced this in commit 72b69a35a3 on Jul 2, 2020
  38. MarcoFalke locked this on Sep 8, 2021

github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2026-04-30 00:15 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me