Commit Graph

79 Commits

Author SHA1 Message Date
Joel Brobecker
fe8c5b5009 Add support for new config option: hooks.max-filepath-length
Note that, as part of the implementation, this commit introduces
a couple of calls to Git for each commit meant to retrieve the entire
list of files in a given commit. Luckily, one of these two calls
was already part of another check (filename collisions), and
the result of that call is cached in a CommitInfo object, so
the delta is only one extra Git call. Some performance measurements
seem to indicate that this is a fast-enough operation that users
should not notice the difference in performance, even for repositories
with a very large number of files [1]. If real-life usage proves
this assessment wrong, however, we'll revisit the documented behavior
so as to allow the use of a cheaper approach (e.g perform the check
on all modified files, rather than just the new ones).

[1]: Tested for instance on the GCC repository, which has more than
     87,000 files in total; the first call took roughly 100ms, and
     the next ones took about 60-70ms.

Change-Id: If0eea2c4990a945a3006cdd74d7a9aca2fc770d9
TN: T811-015
2020-09-11 10:47:51 -07:00
Joel Brobecker
111da4bad3 Add support for new config option: hooks.no-rh-character-range-check
Change-Id: Ic64b5b0f9007605bd339402b93689a944fd13485
TN: T829-004
2020-08-30 09:23:10 -07:00
Joel Brobecker
a62e4bcad0 Add support for new config option hooks.email-new-commits-only
This enhancement should answer issue #9 on GitHub:
https://github.com/AdaCore/git-hooks/issues/9

Change-Id: I4b45f8fc62cb858eefd8b8b417bbdbaa7e80bf91
TN: T815-009
2020-08-15 14:20:30 -07:00
Joel Brobecker
2ebb722e13 Allow projects to customzie the contents of commit emails
This commit introduces a new config option hooks.commit-email-formatter
which allows projects to customize the emails being sent for new commits.

Change-Id: Ibd6b4991f15e204e0a076bb705fc8106f08ff8b4
TN: T209-006
2020-08-10 06:35:24 -07:00
Joel Brobecker
1de3eb14c7 Add support for new config option hooks.commit-extra-check
This option allows projects to ask the git-hooks to perform custom
checks of any kind to validate every new commit being pushed.

This commit also contains a change in hooks/updates/emails.py which
enhances the email-sending debug tracing mechanism used by the testsuite,
adding support for a tracing mode where the traces are just one line
per email. Technically, this change is independent from the rest,
but it is merged with this commit nonetheless because these changes
would show up as uncovered by the testsuite without the testcases
we're adding here. That way, we maintain the principle that we always
have 100% testing coverage for any commit.

Change-Id: I0e446a95d05f5578f977af3eaa547144187eb86b
TN: T209-005
2020-07-19 19:38:58 -07:00
Joel Brobecker
07642e1591 Factorize code to call third-party hooks even more
This commit introduces a new class (ThirdPartyHook), which centralizes
the handling of third-party hooks (scripts that project set up via
the configuration file). Most of the code is simply a move of the code
from maybe_call_thirdparty_hook, with a couple of enhancements:
  - Ability to specify the directory from which to call the hook;
  - Handling of the situation when calling the hook itself fails.

We can already see the benefits of this in function style_check_files,
where the code now necessary to call the style_checker is both clearer
and more compact.

In the future, the intent is to push this class one step further to
allow users to specify hooks to be fetched from the repository, rather
than requiring that the hooks be installed (usually by an admin) on
the machine hosting the repository. The current class' API should
allow us to implement this in a way that's transparent to all users.

Change-Id: Ie8bf8accbbfd75a91b914628fad27d780532dac4
TN: T209-005
2020-07-19 19:38:40 -07:00
Joel Brobecker
453f2581f1 Add support for hooks.rejected-branch-deletion-tip config option
This is a followup on the previous commit, which introduced a feature
allowing projects to control which branches can be deleted.

This feature is added separately, as it is only a minor enhancement,
and this allows to keep the previous commit more focused.

Change-Id: I90d630e0a5b37d092db408379193e7a863201f8b
TN: T209-004
2020-06-29 11:14:14 -07:00
Joel Brobecker
c601254862 add options to allow repositories to control branch deletion
Note that tag deletion privileges are controlled via a different
and already existing option (hooks.allow-delete-tag). Also, notes
are not covered as notes deletion is currently not allowed at all.

Change-Id: I1ecfd83cf27861885f98c31bdc416f67d2dddb5e
TN: T209-004
2020-06-29 11:10:57 -07:00
Joel Brobecker
ce54843dc4 Change the hooks.filer-email default to be empty
Now that the default is changed, we can remove a couple of XFAILs
that were temporarily added.

Change-Id: Id15e0b5ccdf83e82329e02327773687b2c94be42
TN: T512-052
2020-06-15 11:32:45 -07:00
Joel Brobecker
b8b95fd4c5 replace hooks.bcc-file-ci (true/false) by hooks.filer-email (tuple)
This commit puts in place the necessary infrastructure to replace
replace the hooks.bcc-file-ci configuration in favor of a new
configuration option called hooks.filer-email.  The difference
is that the latter is a tuple/list.

For this commit, the default for the new option is such that, for
repositories that don't use the hooks.bcc-file-ci, nothing changes.
This default will be changed in a subsequent commit, and a comment
in the code explain why we're doing it this way.

This change affects two tests we have in the testsuite, which both
were using the hooks.bcc-file-ci config option:

  - "no_file_ci_bcc": We could have made this test pass by replacing
    the hooks.bcc-file-ci option by an empty hooks.filer-email.
    However, this would not be representative of the configuration
    of a real repository. So, instead, we just adjust the repository's
    configuration to match what it would typically look like, and
    accept (XFAIL) that this test is failing until we change
    the default for hooks.filer-email.

  - "to_file-ci_only": This test is in a similar situation as the test
    above, except that it has the additional distinction of now really
    becoming pointless. However, pointless or not, it's a test which
    requires little maintenance (if at all), so the decision was to
    keep that test and apply the same treatment as above.

A new test is also added, to verify that it's possible to provide
more than one email address in hooks.filer-email.

Change-Id: I1733e57b204c49cd189c5a6e1d3f4c47846b40d6
TN: T512-052
2020-06-15 11:32:45 -07:00
Joel Brobecker
5c9e7d2029 GIT_CONFIG_OPTS: consistently use a tuple as default for tuple options
This commit is a simple cleanup commit, so as to make sure that,
for all options listed has being a "tuple" option, the default
value for the option is actually a tuple.

In practice, the code is such that it doesn't matter (it works with
None, or the empty string). But it's not the cleanest approach,
and there is no reason for it. It's just as easy as using an empty
tuple.

Doing so actually reduces coverage by one line, inside function
"to_tuple" in type_conversion.py. The uncovered code is actually
useful outside of in the handling of the default values extracted
from the GIT_CONFIG_OPTS dict. So, a test is added specifically
in order to help cover this line of code as well.

Seen while working on T512-052

Change-Id: I7e9a09c5514b29c18cdf7d92f2c5d3eabf0fe82b
2020-06-15 11:32:45 -07:00
Joel Brobecker
febc78150e Add support for branch and tag custom namespaces
The idea is to introduce a new set of configuration options allowing
repositories to set alternate naming up for branches and tags.
And, in order to have the default to recognize all standard names
while at the same time give users an option to restrict the name
of the branches/tags that one can have in the standard naming,
we are introducing another option called...

    use-standard-{branch,tag}-ref-namespace

... whose default is True.

For repositories that want to add alternate naming schemes without
restrictions in the standard branch/tag namespaces, they just add
the alternate branch/tags names via (with "xxx" being a regular
expression):

    {branch,tag}-ref-namespace = xxx

For repositories that want to restrict the branch/tag naming within
the standard namespaces, they start by dropping the standard
ref naming, and then add the ref-naming that they want to allow:

    use-standard-{branch,tag}-ref-namespace = false
    {branch,tag}-ref-namespace = xxx
    {branch,tag}-ref-namespace = yyy

To support this feature, the engine for determining the type of
update we are facing has been made more dynamic. Because things
are more flexible, it can be harder to understand what is happening
when users are faced with an error. In that context, a reasonable
amount of effort is spent trying to provide helpful error messages
for the more common error cases. More far-fetched scenarios are
covered by testing, but no effort is made to provide detailed
diagnostic (at least not yet).

A fair amount of testing has been added, covering a matrix of scenarios.

Some existing tests also had to be adapted as follow:

  - check_update_utest: Adapt to the new (more precise) error message;

  - post_receive_one_utest: The scenario we were using prior to
    this change now triggers an exception, and so we no longer
    reach the code we wanted to cover with that scenario. So modify
    the repository data, and try to push a commit which is a tag
    instead, using a reference name that indicates a branch.

Change-Id: I0b2404c4c4b0d240e9ad29458fb75ddd1cd7dc7d
TN: T209-003
2020-06-15 11:32:45 -07:00
Joel Brobecker
199add7429 use refs/meta/config:project.config hooks configuration immediately
This commit enhances the hooks to read the repository's configuration
from the most recent version. In particular, if an update is updating
the refs/meta/config reference, then read the configuration from that
update, instead of reading from the existing refs/meta/config reference.
For updates of all other references, the behavior remains unchanged.

A testcase (T227-003__meta_config_is_immediate) is added to verify
that refs/meta/config reference creation works as expected.

Following that change, various testcases also needed to be adapted
as follow:

  - MC27-006__meta_config_branch_create: Creating the refs/meta/config
    reference now works;

  - QC13-022__checker_config_on_its_own: This testcase was pushing
    a local branch called "meta-config" to refs/meta/config. This
    update introduced a style-checker-config-file configuration. Since
    the configuration is now taken into account right away, the update
    is was rejected due to the file not existing.

    The branch "meta-config" is renamed to "meta-config-missing",
    and a new branch "meta-config" was created, containg the missing
    file in addition to the configuration changes above.

    We first try to push the "meta-config-missing" to verify
    that this is rejected. We then try to push the (new) "meta-config"
    branch, verifying that the presence of the config file allows
    the push to be accepted.

  - T209-001__update_hook_not_found: A similar situation to the above,
    but with the update hook. The added comments in the testcase
    should make the changes self-explanatory.

  - T209-001__update_hook_reject: Modify the update-hook, which is
    called during reference updates, to not reject the refs/meta/config
    update the testcase is doing as part of the preliminary setup phase.

Change-Id: I0bd7bc0801ba08cd281a751759bba8c48ba0c454
TN: T227-003
2020-06-15 11:32:45 -07:00
Joel Brobecker
907ae1d0d4 drop support for legacy config file (untracked file located in bare repo)
When initially created, these hooks were reading the repository's
configuration from an untracked file, installed in the repository.
In December 2013, this method of configuring the hooks became obsolete,
in favor of getting the information from a file which is checked in.
However, to ease the transition, support for the untracked config
file was kept as a fallback, with a large warning asking the user
to contact the repository's admin to perform the transition.

At this point, it is believed that all repositories have now
transitioned, and therefore keeping this fallback is no longer
necessary.

This commit therefore removes support for that functionality.
A couple of testcases are adjusted accordingly. As a side-effect,
this caused the testing of branch creations for branches whose name
does not follow the standard naming scheme to no longer be tested.
This commit therefore adds one using a reference name which is not
refs/meta/config, thus ensuring that testing coverage remains at 100%.

Change-Id: I3e9c176f46e831ea82cdc930d32f7f22913a4fbc
TN: T314-004
2020-06-15 11:32:45 -07:00
Joel Brobecker
632028320b Introduce a pre-receive hook
The main purpose of that pre-receive hook is to ensure that any push
updating the refs/meta/config reference only updates that one reference.
A large comment was added to the code to explain why (in short, this is
a pre-requisite for being able to use the git-hooks config at the same
time the config changes are being pushed).

While at it, to be consistent with the other hooks, support for
a repository-specific pre-receive hook is added. One side-effect
of this is that we end up trying to query the hooks configuration,
which triggers a check for the existence of the refs/meta/config
branch. As a result, an extra copy of the same warning gets generated
when the reference doesn't exist. This is not super elegant, but
isn't a problem in practice, since this is part of handling a deprecated
feature that we'll try to remove support for hopefully soon. In the
meantime, this isn't blocking to adding support for the pre-receive
option.

Since this commit increased the number of times `refs/meta/config`
was spelled out (aka "hardcoded"), this commit introduces a new
constant to avoid duplicating that special reference name.

Change-Id: Ib4fc0a32f639fe693e4d43269baf8c0838fc9214
TN: T227-003
2020-06-15 11:32:45 -07:00
Joel Brobecker
55be81f225 Add support for hooks.update-hook configuration option
This option allows users to specify a script to be run at update time,
for each reference being updated. This script can then be used to perform
additional checks on top of the standard checks already provided by
our git-hooks.

Change-Id: Iff527f1c9c0ba516ea5181c5f8c066c5175ef0ee
TN: T209-001
2020-06-15 11:32:45 -07:00
Joel Brobecker
24ebc361d6 Add support for hooks.style-checker-config-file config
For QC13-022.
2017-12-13 17:35:05 +04:00
Joel Brobecker
1e1e4ec080 Add support for hooks.no-style-checks config option
For Q608-030.
2017-08-04 16:06:50 -07:00
Joel Brobecker
acfb6e6349 Remove hooks.no-gitreview-check using hooks.no-precommit-check instead
The latter is really all-encompassing, and expected to disable all
precommit checks. And it would be used in the scenario that lead
to the creation of the hooks.no-gitreview-check config. So it should
be good enough for now to simply rely on hooks.no-precommit-check.

For Q802-008.
2017-08-02 06:09:53 -07:00
Joel Brobecker
6bd7529c2d Add support for hooks.no-gitreview-check configuration
For Q802-008.
2017-08-02 05:58:36 -07:00
Joel Brobecker
54bf80d9f7 Add support for users disallowing updates to specific references
This commit introduces a new hooks.frozen-ref (tuple) config which
allows a user, via an update of the refs/meta/config::project.config
file, to disallow changes to any reference.

Typically, this would be used when a given branch gets retired,
to prevent people from pushing updates to is, thinking that they
are updating an active branch, when in fact the branch is no longer
being used.

The same effect could be achieved using the "retired/*" namespace,
but this approach was deemed easier to manage for certain users
(and the latter approach was designed before users had access to
the hook's config file).

For Q314-009.
2017-07-05 09:11:08 -07:00
Joel Brobecker
229a66eb14 Support defining tuple configs via multiple entries of the same config
For instance, instead of defining hooks.no-emails as...

    no-emails = refs/heads/topic*,refs/heads/wip*

... one can now say:

    no-emails = refs/heads/topic*
    no-emails = refsheads/wip*

For Q314-009.
2017-07-05 09:11:06 -07:00
Joel Brobecker
9d2ee9ff3c add support for multiline values in git config files.
Prior to this patch, the git-hooks were assuming that all options
in the project.config file were entirely contained within a single
line. This patch lifts this limitation.

For Q119-043.
2017-07-05 09:11:04 -07:00
Joel Brobecker
168de73a97 transition default style checker to style_checker
For NA17-007.
2017-05-18 09:34:27 -07:00
Joel Brobecker
215b4035c7 ignore temporary references created by gerrit during web edition
This patch adds another entry to the list of references to be ignored
(in GERRIT_INTERNAL_REFS). These are the temporary references which
gerrit creates when editing a commit directly from the gerrit web
interface. These are not user-visible references, and therefore
should not influence the behavior of our hooks.

For P812-021.
2016-12-21 15:31:14 +04:00