From 12a08e0a47a41c1452bf482502cb4cc1236fad2d Mon Sep 17 00:00:00 2001 From: Wez Furlong Date: Wed, 27 Apr 2016 09:27:56 -0700 Subject: [PATCH] add arcconfig accessors Summary: This is here to support other arcanist/phabrication integration modules. Note: this adds a new package. I'm not sure what the packaging ramifications are exactly, but surely there are some as other extensions start to depend on this. Test Plan: integration test is provided: ``` $ ../../hg-crew/tests/run-tests.py -j8 .................................................... # Ran 52 tests, 0 skipped, 0 warned, 0 failed. ``` Reviewers: #sourcecontrol, ttung Subscribers: mjpieters Differential Revision: https://phabricator.fb.com/D3215615 --- phabricator/__init__.py | 0 phabricator/arcconfig.py | 58 ++++++++++++++++++++++++++++++++++++++++ setup.py | 1 + tests/test-arcconfig.t | 26 ++++++++++++++++++ 4 files changed, 85 insertions(+) create mode 100644 phabricator/__init__.py create mode 100644 phabricator/arcconfig.py create mode 100644 tests/test-arcconfig.t diff --git a/phabricator/__init__.py b/phabricator/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/phabricator/arcconfig.py b/phabricator/arcconfig.py new file mode 100644 index 0000000000..3270668714 --- /dev/null +++ b/phabricator/arcconfig.py @@ -0,0 +1,58 @@ +# Copyright 2016 Facebook Inc. +# +# Locate and load arcanist configuration for a project + +import errno +import json +import os +from mercurial import ( + cmdutil, + error +) + +cmdtable = {} +command = cmdutil.command(cmdtable) + +class ArcConfigError(Exception): + pass + +def _load_file(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 + +def load_for_path(path): + homedir = os.getenv('HOME') + if not homedir: + raise ArcConfigError('$HOME environment variable not found') + + # Use their own file as a basis + userconfig = _load_file(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 = _load_file(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 = load_for_path(repo.root) + ui.write(json.dumps(config, sort_keys=True), '\n') + except ArcConfigError as ex: + raise error.Abort(str(ex)) diff --git a/setup.py b/setup.py index 0ac0c4747d..5d10ff858e 100644 --- a/setup.py +++ b/setup.py @@ -14,6 +14,7 @@ setup( long_description="", keywords='fb hg mercurial', license='', + packages=['phabricator'], py_modules=[ 'arcdiff', 'backups', diff --git a/tests/test-arcconfig.t b/tests/test-arcconfig.t new file mode 100644 index 0000000000..eae3dc8bd7 --- /dev/null +++ b/tests/test-arcconfig.t @@ -0,0 +1,26 @@ + $ cat >> $HGRCPATH << EOF + > [extensions] + > arcconfig=$TESTDIR/../phabricator/arcconfig.py + > EOF + +Sanity check expectations when there is no arcconfig + + $ hg init repo + $ cd repo + $ hg debugarcconfig + abort: no .arcconfig found + [255] + +Show that we can locate and reflect the contents of the .arcconfig from +the repo dir + + $ echo '{"hello": "world"}' > .arcconfig + $ hg debugarcconfig + {"_arcconfig_path": "$TESTTMP/repo", "hello": "world"} + +We expect to see the combination of the user arcrc and the repo rc + + $ echo '{"user": true}' > $HOME/.arcrc + $ hg debugarcconfig + {"_arcconfig_path": "$TESTTMP/repo", "hello": "world", "user": true} +