1# Code dedicated to adding various "safeguard" around evolution
2#
3# Some of these will be pollished and upstream when mature. Some other will be
4# replaced by better alternative later.
5#
6# Copyright 2017 Pierre-Yves David <pierre-yves.david@ens-lyon.org>
7#
8# This software may be used and distributed according to the terms of the
9# GNU General Public License version 2 or any later version.
10
11from mercurial.i18n import _
12
13from mercurial import (
14    configitems,
15    error,
16)
17
18from . import exthelper
19
20eh = exthelper.exthelper()
21
22# hg <= 4.8 (33d30fb1e4ae)
23if b'auto-publish' not in configitems.coreitems.get(b'experimental', {}):
24
25    eh.configitem(b'experimental', b'auto-publish', b'publish')
26
27    def _checkpublish(pushop):
28        repo = pushop.repo
29        ui = repo.ui
30        behavior = ui.config(b'experimental', b'auto-publish')
31        nocheck = behavior not in (b'warn', b'abort')
32        if nocheck or getattr(pushop, 'publish', False):
33            return
34        remotephases = pushop.remote.listkeys(b'phases')
35        publishing = remotephases.get(b'publishing', False)
36        if publishing:
37            if pushop.revs is None:
38                published = repo.filtered(b'served').revs(b"not public()")
39            else:
40                published = repo.revs(b"::%ln - public()", pushop.revs)
41                # we want to use pushop.revs in the revset even if they
42                # themselves are secret, but we don't want to have anything
43                # that the server won't see in the result of this expression
44                published &= repo.filtered(b'served')
45            if published:
46                if behavior == b'warn':
47                    ui.warn(_(b'%i changesets about to be published\n')
48                            % len(published))
49                elif behavior == b'abort':
50                    msg = _(b'push would publish 1 changesets')
51                    hint = _(b"behavior controlled by "
52                             b"'experimental.auto-publish' config")
53                    raise error.Abort(msg, hint=hint)
54
55    @eh.reposetup
56    def setuppublishprevention(ui, repo):
57
58        class noautopublishrepo(repo.__class__):
59
60            def checkpush(self, pushop):
61                super(noautopublishrepo, self).checkpush(pushop)
62                _checkpublish(pushop)
63
64        repo.__class__ = noautopublishrepo
65