--- a/review/api.py Sun Oct 11 11:38:15 2009 -0400
+++ b/review/api.py Sun Oct 11 17:28:23 2009 -0400
@@ -4,7 +4,7 @@
import datetime, operator, os
import messages, templates
-from mercurial import cmdutil, hg, patch, util
+from mercurial import cmdutil, error, hg, patch, util
from mercurial.node import hex
@@ -17,6 +17,28 @@
self.committed = committed
+class UninitializedDatastore(Exception):
+ """Raised when trying to access a datastore that does not exist.
+
+ The committed attribute will be True if someone else has already
+ initialized code review for the target (i.e. the .hgreview file is present
+ in the target repository), or False otherwise.
+
+ """
+ def __init__(self, committed):
+ super(UninitializedDatastore, self).__init__()
+ self.committed = committed
+
+
+class DatastoreRequiresRemotePath(Exception):
+ """Raised when initializing a fresh datastore without a remote path."""
+ pass
+
+class RelativeRemotePath(Exception):
+ """Raised when trying to use a relative remote path (for now)."""
+ pass
+
+
class SignoffExists(Exception):
"""Raised when trying to signoff twice without forcing."""
pass
@@ -157,29 +179,54 @@
"""
self.ui = ui
+ self.target = repo
if not create:
+ if not '.hgreview' in repo['tip']:
+ raise UninitializedDatastore(False)
+
data = _parse_hgrf(repo)
self.lpath = data['lpath']
self.rpath = data['rpath']
- else:
- if '.hgreview' in repo['tip']:
+
+ datastore_root = os.path.join(self.target.root, self.lpath)
+ try:
+ self.repo = hg.repository(ui, datastore_root)
+ except error.RepoError:
+ raise UninitializedDatastore(True)
+ elif '.hgreview' in repo['tip']:
+ data = _parse_hgrf(self.target)
+ self.lpath = data['lpath']
+ self.rpath = data['rpath']
+
+ if self.rpath.startswith('.'):
+ raise RelativeRemotePath
+
+ try:
+ hg.repository(ui, self.lpath)
+ except error.RepoError:
+ hg.clone(cmdutil.remoteui(self.ui, {}), self.rpath, self.lpath)
+ else:
raise PreexistingDatastore(True)
- if os.path.exists(os.path.join(repo.root, '.hgreview')):
- raise PreexistingDatastore(False)
+ elif os.path.exists(os.path.join(self.target.root, '.hgreview')):
+ raise PreexistingDatastore(False)
+ else:
+ if not rpath:
+ raise DatastoreRequiresRemotePath
+ elif rpath.startswith('.'):
+ raise RelativeRemotePath
+ else:
+ self.rpath = rpath
+
self.lpath = lpath or DEFAULT_DATASTORE_DIRNAME
- self.rpath = rpath or ('../%s-review' % os.path.basename(repo.root))
-
- root = os.path.join(repo.root, self.lpath)
- self.target = repo
- self.repo = hg.repository(ui, root, create)
-
- if create:
- hgrpath = os.path.join(repo.root, '.hgreview')
- with open(hgrpath, 'w') as hgrf:
+
+ with open(os.path.join(self.target.root, '.hgreview'), 'w') as hgrf:
hgrf.write('local = %s\n' % self.lpath)
hgrf.write('remote = %s\n' % self.rpath)
- repo.add(['.hgreview'])
+ self.target.add(['.hgreview'])
+
+ self.repo = hg.repository(ui,
+ os.path.join(self.target.root, self.lpath), create)
def __getitem__(self, rev):
"""Return a ReviewChangeset for the given revision."""
--- a/review/extension_ui.py Sun Oct 11 11:38:15 2009 -0400
+++ b/review/extension_ui.py Sun Oct 11 17:28:23 2009 -0400
@@ -13,18 +13,22 @@
def _init_command(ui, repo, **opts):
- if not opts['remote_path']:
- raise util.Abort(messages.INIT_REQUIRES_REMOTE_PATH)
+ ui.note(messages.INIT_START)
- ui.note(messages.INIT_START)
try:
ReviewDatastore(ui, repo, lpath=opts.pop('local_path'),
rpath=opts.pop('remote_path'), create=True)
- ui.status(messages.INIT_SUCCESS)
- return
+ if '.hgreview' not in repo['tip'].files():
+ ui.status(messages.INIT_SUCCESS_UNCOMMITTED)
+ else:
+ ui.status(messages.INIT_SUCCESS_CLONED)
+ except RelativeRemotePath:
+ raise util.Abort(messages.INIT_UNSUPPORTED_RELATIVE_RPATH)
+ except DatastoreRequiresRemotePath:
+ raise util.Abort(messages.INIT_REQUIRES_REMOTE_PATH)
except PreexistingDatastore, e:
if e.committed:
- ui.note(messages.INIT_EXISTS_COMMITTED)
+ ui.note(messages.INIT_EXISTS)
else:
raise util.Abort(messages.INIT_EXISTS_UNCOMMITTED)
@@ -264,6 +268,7 @@
* Create a new Mercurial repository called "code-review" in the root
of the current repository. This name can be changed with the
--local-path option.
+
* Create and 'hg add' a .hgreview file in the current repository. You
will need to commit this file yourself with:
hg commmit .hgreview -m 'Initialize code review data.'
--- a/review/messages.py Sun Oct 11 11:38:15 2009 -0400
+++ b/review/messages.py Sun Oct 11 17:28:23 2009 -0400
@@ -10,22 +10,30 @@
initializing the code review data store and config
"""
-INIT_SUCCESS = """\
+INIT_SUCCESS_UNCOMMITTED = """\
the review data has been initialized
-run "hg commit .hgreview -m'initialize code review'" to record it permanently
+run "hg commit .hgreview -m 'initialize code review'" to record it permanently
+"""
+
+INIT_SUCCESS_CLONED = """\
+the review data has been initialized
"""
INIT_REQUIRES_REMOTE_PATH ="""\
you must provide a remote path (see 'hg help review-init')!
"""
-INIT_EXISTS_COMMITTED = """\
-the review data was already initialized by someone else
+INIT_EXISTS = """\
+the review data has already been initialized!
"""
INIT_EXISTS_UNCOMMITTED = """\
the review data has already been initialized, but is not recorded!
-run "hg commit .hgreview -m'initialize code review'" to record it permanently
+run "hg commit .hgreview -m 'initialize code review'" to record it permanently
+"""
+
+INIT_UNSUPPORTED_RELATIVE_RPATH = """\
+relative remote paths are not supported (yet)!
"""
COMMENT_REQUIRES_MESSAGE = """\
--- a/review/tests/test_init.py Sun Oct 11 11:38:15 2009 -0400
+++ b/review/tests/test_init.py Sun Oct 11 17:28:23 2009 -0400
@@ -11,8 +11,8 @@
def test_init():
sandbox = get_sandbox_repo()
- output = review(init=True, remote_path='../sandbox-review')
- assert messages.INIT_SUCCESS in output
+ output = review(init=True, remote_path='/sandbox-review')
+ assert messages.INIT_SUCCESS_UNCOMMITTED in output
assert '.hgreview' not in sandbox['tip']
assert os.path.exists('.hgreview')
@@ -22,15 +22,15 @@
with open('.hgreview', 'r') as hgrf:
hgr = hgrf.read()
assert 'local = %s' % api.DEFAULT_DATASTORE_DIRNAME in hgr
- assert 'remote = ../sandbox-review' in hgr
+ assert 'remote = /sandbox-review' in hgr
@with_setup(setup_sandbox, teardown_sandbox)
def test_init_with_local_path():
sandbox = get_sandbox_repo()
- output = review(init=True, local_path='NEW', remote_path='../sandbox-review')
- assert messages.INIT_SUCCESS in output
+ output = review(init=True, local_path='NEW', remote_path='/sandbox-review')
+ assert messages.INIT_SUCCESS_UNCOMMITTED in output
assert '.hgreview' not in sandbox['tip']
assert os.path.exists('.hgreview')
@@ -39,8 +39,9 @@
with open('.hgreview', 'r') as hgrf:
hgr = hgrf.read()
+ print hgr
assert 'local = NEW' in hgr
- assert 'remote = ../sandbox-review' in hgr
+ assert 'remote = /sandbox-review' in hgr
@with_setup(setup_sandbox, teardown_sandbox)
@@ -60,10 +61,10 @@
def test_init_twice():
sandbox = get_sandbox_repo()
- review(init=True, remote_path='../sandbox-review')
+ review(init=True, remote_path='/sandbox-review')
try:
- review(init=True, remote_path='../sandbox-review')
+ review(init=True, remote_path='/sandbox-review')
except hgutil.Abort, e:
error = str(e)
assert messages.INIT_EXISTS_UNCOMMITTED in error
--- a/review/tests/util.py Sun Oct 11 11:38:15 2009 -0400
+++ b/review/tests/util.py Sun Oct 11 17:28:23 2009 -0400
@@ -3,7 +3,7 @@
import os, shutil
import sample_data
from mercurial import commands, hg, ui
-from .. import extension_ui
+from .. import api, extension_ui
_ui = ui.ui()
@@ -57,7 +57,8 @@
setup_sandbox()
sandbox = get_sandbox_repo()
- review(init=True, remote_path='../sandbox-review')
+ rpath = os.path.join(sandbox.root, api.DEFAULT_DATASTORE_DIRNAME)
+ review(init=True, remote_path=rpath)
opts = { 'addremove': True, 'date': None, 'user': 'Review Tester',
'logfile': None, 'message': "Add the code review.", }