hghooks/mozhghooks/check/prevent_conduit_arcconfig.py (42 lines of code) (raw):
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
from __future__ import absolute_import
import json
from mercurial import error
from ..checks import (
PreTxnChangegroupCheck,
print_banner,
)
REJECT_MESSAGE = b"""
Push contains unwanted changes to `.arcconfig` files.
Please ensure `.arcconfig` points to the Phab dev or stage servers for
`conduit-testing` repos.
"""
ARCCONFIG_PATH = b".arcconfig"
DEV_PHAB_URL = "https://phabricator-dev.allizom.org/"
STAGE_PHAB_URL = "https://phabricator.allizom.org/"
HOOK_OVERRIDE_FLAG = b"ARCCONFIG_OVERRIDE"
class PreventConduitArcconfig(PreTxnChangegroupCheck):
"""Prevent `.arcconfig` updates for `conduit-testing` repos."""
@property
def name(self):
return b"prevent_conduit_arcconfig"
def relevant(self) -> bool:
return b"conduit-testing" in self.repo.root.split(b"/")
def pre(self, _node):
self.latest_arcconfig_contents = ""
self.hook_override = False
def check(self, ctx) -> bool:
if self.hook_override or HOOK_OVERRIDE_FLAG in ctx.description():
self.hook_override = True
return True
if ARCCONFIG_PATH in ctx.files():
fctx = ctx[ARCCONFIG_PATH]
self.latest_arcconfig_contents = fctx.data().decode("utf-8")
return True
def post_check(self) -> bool:
if self.hook_override:
# Hook should be skipped if the magic override flag was found.
return True
if not self.latest_arcconfig_contents:
# No updates to `.arcconfig`.
return True
try:
arcconfig = json.loads(self.latest_arcconfig_contents)
except json.JSONDecodeError as exc:
raise error.Abort(b"Could not decode `.arcconfig` to JSON.") from exc
if arcconfig["phabricator.uri"].startswith((DEV_PHAB_URL, STAGE_PHAB_URL)):
# Latest state of `.arcconfig` maintains dev/stage URL.
return True
# `.arcconfig` has been updated to point to the wrong server (prod).
print_banner(self.ui, b"error", REJECT_MESSAGE)
return False