diff --git a/heptapod/hooks/perm.py b/heptapod/hooks/perm.py index d325833962a6d9d9460d6cb4ddb9ddff69b190c7_aGVwdGFwb2QvaG9va3MvcGVybS5weQ==..cac20dfe000d1c5af3221a9e83b3db8c7adf3150_aGVwdGFwb2QvaG9va3MvcGVybS5weQ== 100644 --- a/heptapod/hooks/perm.py +++ b/heptapod/hooks/perm.py @@ -7,6 +7,7 @@ from mercurial import ( configitems, error, + pycompat, scmutil, phases, ) @@ -115,6 +116,29 @@ return 1 +def extract_published_revs(tr): + """Extract revision numbers of revision published by given transaction. + + :returns: iterable of revision numbers, without duplicates. + """ + phaseschanges = tr.changes.get("phases", ()) + try: + # phases changes is a dict in hg < 5.4 + phaseschanges = pycompat.iteritems(phaseschanges) + revs_range = False + except AttributeError: + # phaseschanges is a list of pairs in hg >= 5.4 + revs_range = True + + publishing = set(rev for rev, (old, new) in phaseschanges + if new == phases.public and old != phases.public) + + # TODO drop this once we are on hg >= 5.4 only + if revs_range: + publishing = set(rev for rev_range in publishing for rev in rev_range) + return publishing + + def check_publish(repo, *args, **kwargs): validate_hook_type('pretxnclose', **kwargs) remoteuser = get_remote_user(repo) @@ -129,9 +153,7 @@ tr = repo.currenttransaction() assert tr is not None and tr.running() - phaseschanges = tr.changes.get("phases", {}) - publishing = set(rev for rev, (old, new) in phaseschanges.iteritems() - if new == phases.public and old != phases.public) + publishing = extract_published_revs(tr) if publishing: node = repo.changelog.node nodes = [node(r) for r in sorted(publishing)] diff --git a/heptapod/hooks/tests/test_check_publish.py b/heptapod/hooks/tests/test_check_publish.py index d325833962a6d9d9460d6cb4ddb9ddff69b190c7_aGVwdGFwb2QvaG9va3MvdGVzdHMvdGVzdF9jaGVja19wdWJsaXNoLnB5..cac20dfe000d1c5af3221a9e83b3db8c7adf3150_aGVwdGFwb2QvaG9va3MvdGVzdHMvdGVzdF9jaGVja19wdWJsaXNoLnB5 100644 --- a/heptapod/hooks/tests/test_check_publish.py +++ b/heptapod/hooks/tests/test_check_publish.py @@ -9,9 +9,10 @@ from mercurial import ( error, phases, + pycompat, ) from heptapod.testhelpers import ( LocalRepoWrapper, ) from .utils import switch_user @@ -12,9 +13,10 @@ ) from heptapod.testhelpers import ( LocalRepoWrapper, ) from .utils import switch_user +from ..perm import extract_published_revs def init_repo(basedir): @@ -60,3 +62,25 @@ wrapper.write_commit('foo') assert 'precommit' in exc_info.value.args[0] + + +class FakeTransaction(object): + def __init__(self, phases): + self.changes = dict(phases=phases) + + +def test_extract_published_revs_hg_5_3(): + txn = FakeTransaction({3: (phases.draft, phases.public), + 19: (phases.secret, phases.public), + 7: (phases.secret, phases.draft), + }) + assert set(extract_published_revs(txn)) == {3, 19} + + +def test_extract_published_revs_hg_5_4(): + txn = FakeTransaction([ + (pycompat.xrange(3, 5), (phases.draft, phases.public)), + (pycompat.xrange(2), (phases.secret, phases.public)), + (pycompat.xrange(7, 8), (phases.secret, phases.draft)), + ]) + assert set(extract_published_revs(txn)) == {0, 1, 3, 4}