sapling/edenscm/hgext/extlib/phabricator/arcconfig.py
Jun Wu 9dc21f8d0b codemod: import from the edenscm package
Summary:
D13853115 adds `edenscm/` to `sys.path` and code still uses `import mercurial`.
That has nasty problems if both `import mercurial` and
`import edenscm.mercurial` are used, because Python would think `mercurial.foo`
and `edenscm.mercurial.foo` are different modules so code like
`try: ... except mercurial.error.Foo: ...`, or `isinstance(x, mercurial.foo.Bar)`
would fail to handle the `edenscm.mercurial` version. There are also some
module-level states (ex. `extensions._extensions`) that would cause trouble if
they have multiple versions in a single process.

Change imports to use the `edenscm` so ideally the `mercurial` is no longer
imported at all. Add checks in extensions.py to catch unexpected extensions
importing modules from the old (wrong) locations when running tests.

Reviewed By: phillco

Differential Revision: D13868981

fbshipit-source-id: f4e2513766957fd81d85407994f7521a08e4de48
2019-01-29 17:25:32 -08:00

76 lines
2.1 KiB
Python

# Copyright 2016 Facebook Inc.
#
# Locate and load arcanist configuration for a project
from __future__ import absolute_import
import errno
import json
import os
from edenscm.mercurial import encoding, error, pycompat, registrar
cmdtable = {}
command = registrar.command(cmdtable)
class ArcConfigError(Exception):
pass
def _loadfile(filename):
try:
with open(filename, "r") as f:
return json.loads(f.read())
except IOError as ex:
if ex.errno == errno.ENOENT:
return None
raise
except ValueError as ex:
# if the json file is badly formatted
if "Expecting property name" in str(ex):
raise ArcConfigError(
"Configuration file %s " "is not a proper JSON file." % filename
)
raise
def loadforpath(path):
# location where `arc install-certificate` writes .arcrc
if pycompat.iswindows:
envvar = "APPDATA"
else:
envvar = "HOME"
homedir = encoding.environ.get(envvar)
if not homedir:
raise ArcConfigError("$%s environment variable not found" % envvar)
# Use their own file as a basis
userconfig = _loadfile(os.path.join(homedir, ".arcrc")) or {}
# Walk up the path and augment with an .arcconfig if we find it,
# terminating the search at that point.
path = os.path.abspath(path)
while len(path) > 1:
config = _loadfile(os.path.join(path, ".arcconfig"))
if config is not None:
userconfig.update(config)
# Return the located path too, as we need this for figuring
# out where we are relative to the fbsource root.
userconfig["_arcconfig_path"] = path
return userconfig
path = os.path.dirname(path)
raise ArcConfigError("no .arcconfig found")
@command("debugarcconfig")
def debugarcconfig(ui, repo, *args, **opts):
""" exists purely for testing and diagnostic purposes """
try:
config = loadforpath(repo.root)
ui.write(json.dumps(config, sort_keys=True), "\n")
except ArcConfigError as ex:
raise error.Abort(str(ex))