1. 2
  1. 7

    pre-commit hook … is a perfect mechanism to enforce linting and tests before a developer’s code is added to the repository.

    I would disagree here. Pre-commit hooks are fundamentally client-side validation. They don’t enforce anything, they are advisory

    Instead, I suggest the following, for the purpose of enforcement:

    • check any properties you want to hold for the code in a test (eg, “is code formatted” is a test)
    • use not rocket science rule: only update the tip of the master branch to commit hashes for which CI is already green

    (Now, the nebulous CI might actually be implemented as a git hook (https://www.stchris.net/tiny-ci-system.html), but that’s crucially server-side).

    It also has the benefit the properties are enforced only when it matters (code integrated into the canonical branch), and can be broken otherwise, giving a nice transactional semantics.

    1. 2

      Pre-commit hooks are fundamentally client-side validation. They don’t enforce anything, they are advisory

      Agreed. One repo I work on has what amounts to a “don’t commit directly to release” precommit hook, but it’s slow and I don’t even have perms to push to the release branch, so I habitually git commit -nm to skip it. It’s not a very good validation if there’s a single-letter command line argument to skip it.

      1. 1

        It’s true that you can bypass your local hook, and I agree that “perfect” might be an incorrect choice of word, but;

        • You have to do it explicitly, which means (unless there’s something really wrong with the linter or a developer that really doesn’t care for policy), that the default (and probably) common behavior will be to use the linter.
        • You don’t have to use local hooks alone - by using both local and remote hooks, you get the advantages of both.
      2. 2

        Link to not rocket science rule in case someone doesn’t recognize the jargon.

        1. 2

          You can use tests instead of running a linter. In the end, like the linter, you’d use them locally, remotely or both.

          I’m actually a proponent of both (and maybe I should’ve included that in the article), at least for shorter tasks, because remote enforcement alone for tasks that take seconds encourage more context switching.

          1. 1

            I’m actually a proponent of both

            Uhu, that’s why I like to drive everything through tests. That way, cargo test (or whatever is the equivalent in a language of choice) is the single thing that needs to be run either locally or remotely.

          2. 1

            Hey @matklad, I’m the author of the Tiny CI system post you linked to and I just wanted to say that it means a lot that you (whom I respect a lot for all your work and the way you explain things you’re working on) linked to it. It gives me a big moral boost towards writing more blog posts and also a follow-up on the one you mentioned.

            1. 2

              Chain of authority! I remember learning about Tiny CI from @peterbourgon comment here on lobsters, which for me means a lot.

              (Laughing to myself after noting https://www.stchris.net/gate-integration-tests.html as well, which links to the same post I’ve linked from https://matklad.github.io/2021/05/31/how-to-test.html#Make-Tests-Fast)