aboutsummaryrefslogtreecommitdiffstats
path: root/libbe
diff options
context:
space:
mode:
Diffstat (limited to 'libbe')
-rw-r--r--libbe/command/assign.py31
-rw-r--r--libbe/command/base.py73
-rw-r--r--libbe/command/comment.py13
-rw-r--r--libbe/command/commit.py10
-rw-r--r--libbe/command/depend.py21
-rw-r--r--libbe/command/due.py15
-rw-r--r--libbe/command/help.py5
-rw-r--r--libbe/command/html.py7
-rw-r--r--libbe/command/import_xml.py12
-rw-r--r--libbe/command/init.py10
-rw-r--r--libbe/command/list.py10
-rw-r--r--libbe/command/merge.py9
-rw-r--r--libbe/command/new.py7
-rw-r--r--libbe/command/remove.py7
-rw-r--r--libbe/command/severity.py135
-rwxr-xr-xlibbe/ui/command_line.py23
-rw-r--r--libbe/ui/util/cmdutil.py14
17 files changed, 208 insertions, 194 deletions
diff --git a/libbe/command/assign.py b/libbe/command/assign.py
index 241c815..6cf74bc 100644
--- a/libbe/command/assign.py
+++ b/libbe/command/assign.py
@@ -30,24 +30,25 @@ class Assign (libbe.command.Command):
>>> import libbe.bugdir
>>> bd = libbe.bugdir.SimpleBugDir(memory=False)
>>> cmd = Assign()
+ >>> cmd._storage = bd.storage
>>> cmd._setup_io = lambda i_enc,o_enc : None
>>> cmd.stdout = sys.stdout
>>> bd.bug_from_uuid('a').assigned is None
True
- >>> ret = cmd.run(bd.storage, bd, {'user-id':u'Fran\xe7ois'}, ['-', '/a'])
+ >>> ret = cmd.run({'user-id':u'Fran\xe7ois'}, ['-', '/a'])
>>> bd.flush_reload()
>>> bd.bug_from_uuid('a').assigned
u'Fran\\xe7ois'
- >>> ret = cmd.run(bd.storage, bd, args=['someone', '/a', '/b'])
+ >>> ret = cmd.run(args=['someone', '/a', '/b'])
>>> bd.flush_reload()
>>> bd.bug_from_uuid('a').assigned
'someone'
>>> bd.bug_from_uuid('b').assigned
'someone'
- >>> ret = cmd.run(bd.storage, bd, args=['none', '/a'])
+ >>> ret = cmd.run(args=['none', '/a'])
>>> bd.flush_reload()
>>> bd.bug_from_uuid('a').assigned is None
True
@@ -57,10 +58,9 @@ class Assign (libbe.command.Command):
def __init__(self, *args, **kwargs):
libbe.command.Command.__init__(self, *args, **kwargs)
- self.requires_bugdir = True
self.args.extend([
libbe.command.Argument(
- name='assignee', metavar='ASSIGNEE', default=None,
+ name='assigned', metavar='ASSIGNED', default=None,
completion_callback=libbe.command.util.complete_assigned),
libbe.command.Argument(
name='bug-id', metavar='BUG-ID', default=None,
@@ -68,27 +68,28 @@ class Assign (libbe.command.Command):
completion_callback=libbe.command.util.complete_bug_id),
])
- def _run(self, storage, bugdir, **params):
- assignee = params['assignee']
- if assignee == 'none':
- assignee = None
- elif assignee == '-':
- assignee = params['user-id']
+ def _run(self, **params):
+ assigned = params['assigned']
+ if assigned == 'none':
+ assigned = None
+ elif assigned == '-':
+ assigned = self._get_user_id()
+ bugdir = self._get_bugdir()
for bug_id in params['bug-id']:
bug,dummy_comment = \
libbe.command.util.bug_comment_from_user_id(bugdir, bug_id)
- if bug.assigned != assignee:
- bug.assigned = assignee
+ if bug.assigned != assigned:
+ bug.assigned = assigned
return 0
def _long_help(self):
return """
Assign a person to fix a bug.
-Assignees should be the person's Bugs Everywhere identity, the same
+Assigneds should be the person's Bugs Everywhere identity, the same
string that appears in Creator fields.
-Special assignee strings:
+Special assigned strings:
"-" assign the bug to yourself
"none" un-assigns the bug
"""
diff --git a/libbe/command/base.py b/libbe/command/base.py
index 54463c8..2aaf51e 100644
--- a/libbe/command/base.py
+++ b/libbe/command/base.py
@@ -177,16 +177,15 @@ class Command (object):
name = 'command'
- def __init__(self, input_encoding=None, output_encoding=None):
+ def __init__(self, input_encoding=None, output_encoding=None,
+ get_unconnected_storage=None, ui=None):
+ self.input_encoding = input_encoding
+ self.output_encoding = output_encoding
+ self.get_unconnected_storage = get_unconnected_storage
+ self.ui = ui # calling user-interface, e.g. for Help()
self.status = None
self.result = None
- self.ui = None # calling user-interface, e.g. for Help()
- self.requires_bugdir = False
- self.requires_storage = False
- self.requires_unconnected_storage = False
self.restrict_file_access = True
- self.input_encoding = None
- self.output_encoding = None
self.options = [
Option(name='help', short_name='h',
help='Print a help message.',
@@ -197,7 +196,7 @@ class Command (object):
]
self.args = []
- def run(self, storage=None, bugdir=None, options=None, args=None):
+ def run(self, options=None, args=None):
if options == None:
options = {}
if args == None:
@@ -213,9 +212,7 @@ class Command (object):
params[option.name] = False
assert 'user-id' not in params, params['user-id']
if 'user-id' in options:
- params['user-id'] = options.pop('user-id')
- else:
- params['user-id'] = libbe.ui.util.user.get_user_id(storage)
+ self._user_id = options.pop('user-id')
if len(options) > 0:
raise UserError, 'Invalid option passed to command %s:\n %s' \
% (self.name, '\n '.join(['%s: %s' % (k,v)
@@ -253,11 +250,11 @@ class Command (object):
params.pop('complete')
self._setup_io(self.input_encoding, self.output_encoding)
- self.status = self._run(storage, bugdir, **params)
+ self.status = self._run(**params)
return self.status
- def _run(self, storage, bugdir, **kwargs):
- pass
+ def _run(self, **kwargs):
+ raise NotImplementedError
def _setup_io(self, input_encoding=None, output_encoding=None):
if input_encoding == None:
@@ -306,7 +303,7 @@ class Command (object):
return argument.completion_callback(self, argument, fragment)
return [] # the particular argument doesn't supply completion info
- def check_restricted_access(self, storage, path):
+ def _check_restricted_access(self, storage, path):
"""
Check that the file at path is inside bugdir.root. This is
important if you allow other users to execute becommands with
@@ -322,15 +319,15 @@ class Command (object):
>>> s.repo = os.path.expanduser('~/x/')
>>> c = Command()
>>> try:
- ... c.check_restricted_access(s, os.path.expanduser('~/.ssh/id_rsa'))
+ ... c._check_restricted_access(s, os.path.expanduser('~/.ssh/id_rsa'))
... except UserError, e:
... assert str(e).startswith('file access restricted!'), str(e)
... print 'we got the expected error'
we got the expected error
- >>> c.check_restricted_access(s, os.path.expanduser('~/x'))
- >>> c.check_restricted_access(s, os.path.expanduser('~/x/y'))
+ >>> c._check_restricted_access(s, os.path.expanduser('~/x'))
+ >>> c._check_restricted_access(s, os.path.expanduser('~/x/y'))
>>> c.restrict_file_access = False
- >>> c.check_restricted_access(s, os.path.expanduser('~/.ssh/id_rsa'))
+ >>> c._check_restricted_access(s, os.path.expanduser('~/.ssh/id_rsa'))
"""
if self.restrict_file_access == True:
path = os.path.abspath(path)
@@ -339,3 +336,41 @@ class Command (object):
return
raise UserError('file access restricted!\n %s not in %s'
% (path, repo))
+
+ def _get_unconnected_storage(self):
+ """Callback for use by commands that need it."""
+ if not hasattr(self, '_unconnected_storage'):
+ if self.get_unconnected_storage == None:
+ raise NotImplementedError
+ self._unconnected_storage = self.get_unconnected_storage()
+ return self._unconnected_storage
+
+ def _get_storage(self):
+ """
+ Callback for use by commands that need it.
+
+ Note that with the current implementation,
+ _get_unconnected_storage() will not work after this method
+ runs, but that shouldn't be an issue for any command I can
+ think of...
+ """
+ if not hasattr(self, '_storage'):
+ self._storage = self._get_unconnected_storage()
+ self._storage.connect()
+ return self._storage
+
+ def _get_bugdir(self):
+ """Callback for use by commands that need it."""
+ if not hasattr(self, '_bugdir'):
+ self._bugdir = libbe.bugdir.BugDir(self._get_storage(), from_storage=True)
+ return self._bugdir
+
+ def _get_user_id(self):
+ """Callback for use by commands that need it."""
+ if not hasattr(self, '_user_id'):
+ self._user_id = libbe.ui.util.user.get_user_id(self._get_storage())
+ return self._user_id
+
+ def cleanup(self):
+ if hasattr(self, '_storage'):
+ self._storage.disconnect()
diff --git a/libbe/command/comment.py b/libbe/command/comment.py
index 23def57..cb0dcbb 100644
--- a/libbe/command/comment.py
+++ b/libbe/command/comment.py
@@ -34,10 +34,11 @@ class Comment (libbe.command.Command):
>>> import libbe.bugdir
>>> bd = libbe.bugdir.SimpleBugDir(memory=False)
>>> cmd = Comment()
+ >>> cmd._storage = bd.storage
>>> cmd._setup_io = lambda i_enc,o_enc : None
>>> cmd.stdout = sys.stdout
- >>> ret = cmd.run(bd.storage, bd, {'user-id':u'Fran\\xe7ois'},
+ >>> ret = cmd.run({'user-id':u'Fran\\xe7ois'},
... ['/a', 'This is a comment about a'])
>>> bd.flush_reload()
>>> bug = bd.bug_from_uuid('a')
@@ -57,12 +58,12 @@ class Comment (libbe.command.Command):
>>> if 'EDITOR' in os.environ:
... del os.environ['EDITOR']
- >>> ret = cmd.run(bd.storage, bd, {'user-id':u'Frank'}, ['/b'])
+ >>> ret = cmd.run({'user-id':u'Frank'}, ['/b'])
Traceback (most recent call last):
UserError: No comment supplied, and EDITOR not specified.
>>> os.environ['EDITOR'] = "echo 'I like cheese' > "
- >>> ret = cmd.run(bd.storage, bd, {'user-id':u'Frank'}, ['/b'])
+ >>> ret = cmd.run({'user-id':u'Frank'}, ['/b'])
>>> bd.flush_reload()
>>> bug = bd.bug_from_uuid('b')
>>> bug.load_comments(load_full=False)
@@ -76,7 +77,6 @@ class Comment (libbe.command.Command):
def __init__(self, *args, **kwargs):
libbe.command.Command.__init__(self, *args, **kwargs)
- self.requires_bugdir = True
self.options.extend([
libbe.command.Option(name='author', short_name='a',
help='Set the comment author',
@@ -101,7 +101,8 @@ class Comment (libbe.command.Command):
completion_callback=libbe.command.util.complete_assigned),
])
- def _run(self, storage, bugdir, **params):
+ def _run(self, **params):
+ bugdir = self._get_bugdir()
bug,parent = \
libbe.command.util.bug_comment_from_user_id(bugdir, params['id'])
if params['comment'] == None:
@@ -133,7 +134,7 @@ class Comment (libbe.command.Command):
if not body.endswith('\n'):
body+='\n'
if params['author'] == None:
- params['author'] = params['user-id']
+ params['author'] = self._get_user_id()
new = parent.new_reply(body=body)
for key in ['alt-id', 'author', 'content-type']:
diff --git a/libbe/command/commit.py b/libbe/command/commit.py
index f795e80..4ef619c 100644
--- a/libbe/command/commit.py
+++ b/libbe/command/commit.py
@@ -40,11 +40,11 @@ class Commit (libbe.command.Command):
>>> vcs.repo = dir.path
>>> vcs.init()
>>> vcs.connect()
+ >>> cmd._storage = vcs
>>> if vcs.name in libbe.storage.vcs.base.VCS_ORDER:
... bd = libbe.bugdir.BugDir(vcs, from_storage=False)
... bd.extra_strings = ['hi there']
- ... cmd.run(vcs, None, {'user-id':'Joe'},
- ... ['Making a commit']) # doctest: +ELLIPSIS
+ ... cmd.run({'user-id':'Joe'}, ['Making a commit']) # doctest: +ELLIPSIS
... else:
... print 'Committed ...'
Committed ...
@@ -56,7 +56,6 @@ class Commit (libbe.command.Command):
def __init__(self, *args, **kwargs):
libbe.command.Command.__init__(self, *args, **kwargs)
- self.requires_storage = True
self.options.extend([
libbe.command.Option(name='body', short_name='b',
help='Provide the detailed body for the commit message. In the special case that FILE == "EDITOR", spawn an editor to enter the body text (in which case you cannot use stdin for the summary)',
@@ -70,20 +69,21 @@ class Commit (libbe.command.Command):
name='comment', metavar='COMMENT', default=None),
])
- def _run(self, storage, bugdir=None, **params):
+ def _run(self, **params):
if params['comment'] == '-': # read summary from stdin
assert params['body'] != 'EDITOR', \
'Cannot spawn and editor when the summary is using stdin.'
summary = sys.stdin.readline()
else:
summary = params['comment']
+ storage = self._get_storage()
if params['body'] == None:
body = None
elif params['body'] == 'EDITOR':
body = libbe.ui.util.editor.editor_string(
'Please enter your commit message above')
else:
- self.check_restricted_access(storage, params['body'])
+ self._check_restricted_access(storage, params['body'])
body = libbe.util.encoding.get_file_contents(
params['body'], decode=True)
try:
diff --git a/libbe/command/depend.py b/libbe/command/depend.py
index 471fd28..5e476fc 100644
--- a/libbe/command/depend.py
+++ b/libbe/command/depend.py
@@ -46,40 +46,40 @@ class Depend (libbe.command.Command):
>>> import libbe.bugdir
>>> bd = libbe.bugdir.SimpleBugDir(memory=False)
>>> cmd = Depend()
+ >>> cmd._storage = bd.storage
>>> cmd._setup_io = lambda i_enc,o_enc : None
>>> cmd.stdout = sys.stdout
- >>> ret = cmd.run(bd.storage, bd, {}, ['/a', '/b'])
+ >>> ret = cmd.run(args=['/a', '/b'])
a blocked by:
b
- >>> ret = cmd.run(bd.storage, bd, {}, ['/a'])
+ >>> ret = cmd.run(args=['/a'])
a blocked by:
b
- >>> ret = cmd.run(bd.storage, bd, {'show-status':True}, ['/a']) # doctest: +NORMALIZE_WHITESPACE
+ >>> ret = cmd.run({'show-status':True}, ['/a']) # doctest: +NORMALIZE_WHITESPACE
a blocked by:
b closed
- >>> ret = cmd.run(bd.storage, bd, {}, ['/b', '/a'])
+ >>> ret = cmd.run(args=['/b', '/a'])
b blocked by:
a
b blocks:
a
- >>> ret = cmd.run(bd.storage, bd, {'show-status':True}, ['/a']) # doctest: +NORMALIZE_WHITESPACE
+ >>> ret = cmd.run({'show-status':True}, ['/a']) # doctest: +NORMALIZE_WHITESPACE
a blocked by:
b closed
a blocks:
b closed
- >>> ret = cmd.run(bd.storage, bd, {'repair':True})
- >>> ret = cmd.run(bd.storage, bd, {'remove':True}, ['/b', '/a'])
+ >>> ret = cmd.run({'repair':True})
+ >>> ret = cmd.run({'remove':True}, ['/b', '/a'])
b blocks:
a
- >>> ret = cmd.run(bd.storage, bd, {'remove':True}, ['/a', '/b'])
+ >>> ret = cmd.run({'remove':True}, ['/a', '/b'])
>>> bd.cleanup()
"""
name = 'depend'
def __init__(self, *args, **kwargs):
libbe.command.Command.__init__(self, *args, **kwargs)
- self.requires_bugdir = True
self.options.extend([
libbe.command.Option(name='remove', short_name='r',
help='Remove dependency (instead of adding it)'),
@@ -114,7 +114,7 @@ class Depend (libbe.command.Command):
completion_callback=libbe.command.util.complete_bug_id),
])
- def _run(self, storage, bugdir, **params):
+ def _run(self, **params):
if params['repair'] == True and params['bug-id'] != None:
raise libbe.command.UsageError(
'No arguments with --repair calls.')
@@ -125,6 +125,7 @@ class Depend (libbe.command.Command):
and params['blocking-bug-id'] != None:
raise libbe.command.UsageError(
'Only one bug id used in tree mode.')
+ bugdir = self._get_bugdir()
if params['repair'] == True:
good,fixed,broken = check_dependencies(bugdir, repair_broken_links=True)
assert len(broken) == 0, broken
diff --git a/libbe/command/due.py b/libbe/command/due.py
index 372f10a..119115c 100644
--- a/libbe/command/due.py
+++ b/libbe/command/due.py
@@ -28,16 +28,17 @@ class Due (libbe.command.Command):
>>> import libbe.bugdir
>>> bd = libbe.bugdir.SimpleBugDir(memory=False)
>>> cmd = Due()
+ >>> cmd._storage = bd.storage
>>> cmd._setup_io = lambda i_enc,o_enc : None
>>> cmd.stdout = sys.stdout
- >>> ret = cmd.run(bd.storage, bd, {}, ['/a'])
+ >>> ret = cmd.run(args=['/a'])
No due date assigned.
- >>> ret = cmd.run(bd.storage, bd, {}, ['/a', 'Thu, 01 Jan 1970 00:00:00 +0000'])
- >>> ret = cmd.run(bd.storage, bd, {}, ['/a'])
+ >>> ret = cmd.run(args=['/a', 'Thu, 01 Jan 1970 00:00:00 +0000'])
+ >>> ret = cmd.run(args=['/a'])
Thu, 01 Jan 1970 00:00:00 +0000
- >>> ret = cmd.run(bd.storage, bd, {}, ['/a', 'none'])
- >>> ret = cmd.run(bd.storage, bd, {}, ['/a'])
+ >>> ret = cmd.run(args=['/a', 'none'])
+ >>> ret = cmd.run(args=['/a'])
No due date assigned.
>>> bd.cleanup()
"""
@@ -45,7 +46,6 @@ class Due (libbe.command.Command):
def __init__(self, *args, **kwargs):
libbe.command.Command.__init__(self, *args, **kwargs)
- self.requires_bugdir = True
self.args.extend([
libbe.command.Argument(
name='bug-id', metavar='BUG-ID',
@@ -54,7 +54,8 @@ class Due (libbe.command.Command):
name='due', metavar='DUE', optional=True),
])
- def _run(self, storage, bugdir, **params):
+ def _run(self, **params):
+ bugdir = self._get_bugdir()
bug,dummy_comment = libbe.command.util.bug_comment_from_user_id(
bugdir, params['bug-id'])
if params['due'] == None:
diff --git a/libbe/command/help.py b/libbe/command/help.py
index c8d700d..6e55598 100644
--- a/libbe/command/help.py
+++ b/libbe/command/help.py
@@ -54,14 +54,15 @@ class Help (libbe.command.Command):
completion_callback=self.complete_topic)
])
- def _run(self, storage, bugdir, **params):
+ def _run(self, **params):
if params['topic'] == None:
if hasattr(self.ui, 'help'):
self.ui.help()
elif params['topic'] in libbe.command.commands():
module = libbe.command.get_command(params['topic'])
Class = libbe.command.get_command_class(module,params['topic'])
- c = Class()
+ c = Class(get_unconnected_storage=self.get_unconnected_storage,
+ ui=self.ui)
print >> self.stdout, c.help().rstrip('\n')
elif params['topic'] in TOPICS:
print >> self.stdout, TOPICS[params['topic']].rstrip('\n')
diff --git a/libbe/command/html.py b/libbe/command/html.py
index 485753f..0f993ae 100644
--- a/libbe/command/html.py
+++ b/libbe/command/html.py
@@ -37,12 +37,13 @@ class HTML (libbe.command.Command):
>>> import libbe.bugdir
>>> bd = libbe.bugdir.SimpleBugDir(memory=False)
>>> cmd = HTML()
+ >>> cmd._storage = bd.storage
>>> cmd._setup_io = lambda i_enc,o_enc : None
>>> cmd.stdout = sys.stdout
>>> cwd = os.getcwd()
>>> os.chdir(bd.storage.repo)
- >>> ret = cmd.run(bd.storage, bd)
+ >>> ret = cmd.run()
>>> os.path.exists('./html_export')
True
>>> os.path.exists('./html_export/index.html')
@@ -62,7 +63,6 @@ class HTML (libbe.command.Command):
def __init__(self, *args, **kwargs):
libbe.command.Command.__init__(self, *args, **kwargs)
- self.requires_bugdir = True
self.options.extend([
libbe.command.Option(name='output', short_name='o',
help='Set the output path (%default)',
@@ -96,10 +96,11 @@ class HTML (libbe.command.Command):
help='Verbose output, default is %default'),
])
- def _run(self, storage, bugdir, **params):
+ def _run(self, **params):
if params['export-template'] == True:
html_gen.write_default_template(params['export-template-dir'])
return 0
+ bugdir = self._get_bugdir()
bugdir.load_all_bugs()
html_gen = HTMLGen(bugdir,
template=params['template-dir'],
diff --git a/libbe/command/import_xml.py b/libbe/command/import_xml.py
index f06c741..e73d90f 100644
--- a/libbe/command/import_xml.py
+++ b/libbe/command/import_xml.py
@@ -45,12 +45,13 @@ class Import_XML (libbe.command.Command):
>>> import libbe.bugdir
>>> bd = libbe.bugdir.SimpleBugDir(memory=False)
>>> cmd = Import_XML()
+ >>> cmd._storage = bd.storage
>>> cmd._setup_io = lambda i_enc,o_enc : None
>>> cmd.stdout = sys.stdout
>>> cmd.stdin = StringIO.StringIO('<be-xml><comment><uuid>c</uuid><body>This is a comment about a</body></comment></be-xml>')
>>> cmd.stdin.encoding = 'ascii'
- >>> ret = cmd.run(bd.storage, bd, {'comment-root':'/a'}, ['-'])
+ >>> ret = cmd.run({'comment-root':'/a'}, ['-'])
>>> bd.flush_reload()
>>> bug = bd.bug_from_uuid('a')
>>> bug.load_comments(load_full=False)
@@ -68,7 +69,6 @@ class Import_XML (libbe.command.Command):
def __init__(self, *args, **kwargs):
libbe.command.Command.__init__(self, *args, **kwargs)
- self.requires_bugdir = True
self.options.extend([
libbe.command.Option(name='ignore-missing-references', short_name='i',
help="If any comment's <in-reply-to> refers to a non-existent comment, ignore it (instead of raising an exception)."),
@@ -85,7 +85,8 @@ class Import_XML (libbe.command.Command):
name='xml-file', metavar='XML-FILE'),
])
- def _run(self, storage, bugdir, **params):
+ def _run(self, **params):
+ bugdir = self._get_bugdir()
writeable = bugdir.storage.writeable
bugdir.storage.writeable = False
if params['comment-root'] != None:
@@ -113,7 +114,7 @@ class Import_XML (libbe.command.Command):
if params['xml-file'] == '-':
xml = self.stdin.read().encode(self.stdin.encoding)
else:
- self.check_restricted_access(storage, params['xml-file'])
+ self._check_restricted_access(storage, params['xml-file'])
xml = libbe.util.encoding.get_file_contents(
params['xml-file'])
@@ -321,6 +322,7 @@ if libbe.TESTING == True:
def setUp(self):
self.bugdir = libbe.bugdir.SimpleBugDir(memory=False)
self.cmd = Import_XML()
+ self.cmd._storage = self.bugdir.storage
self.cmd._setup_io = lambda i_enc,o_enc : None
bugA = self.bugdir.bug_from_uuid('a')
self.bugdir.remove_bug(bugA)
@@ -364,7 +366,7 @@ if libbe.TESTING == True:
def tearDown(self):
self.bugdir.cleanup()
def _execute(self, params={}, args=[]):
- self.cmd.run(self.bugdir.storage, self.bugdir, params, args)
+ self.cmd.run(params, args)
self.bugdir.flush_reload()
def testCleanBugdir(self):
uuids = list(self.bugdir.uuids())
diff --git a/libbe/command/init.py b/libbe/command/init.py
index 017cdc3..b52d8e8 100644
--- a/libbe/command/init.py
+++ b/libbe/command/init.py
@@ -42,7 +42,8 @@ class Init (libbe.command.Command):
... except libbe.storage.ConnectionError:
... True
True
- >>> cmd.run(vcs)
+ >>> cmd._unconnected_storage = vcs
+ >>> cmd.run()
No revision control detected.
BE repository initialized.
>>> bd = libbe.bugdir.BugDir(vcs)
@@ -54,8 +55,9 @@ class Init (libbe.command.Command):
>>> vcs = libbe.storage.vcs.installed_vcs()
>>> vcs.repo = dir.path
>>> vcs._vcs_init(vcs.repo)
+ >>> cmd._unconnected_storage = vcs
>>> if vcs.name in libbe.storage.vcs.base.VCS_ORDER:
- ... cmd.run(vcs) # doctest: +ELLIPSIS
+ ... cmd.run() # doctest: +ELLIPSIS
... else:
... vcs.init()
... vcs.connect()
@@ -70,9 +72,9 @@ class Init (libbe.command.Command):
def __init__(self, *args, **kwargs):
libbe.command.Command.__init__(self, *args, **kwargs)
- self.requires_unconnected_storage = True
- def _run(self, storage, bugdir=None, **params):
+ def _run(self, **params):
+ storage = self._get_unconnected_storage()
if not os.path.isdir(storage.repo):
raise libbe.command.UserError(
'No such directory: %s' % storage.repo)
diff --git a/libbe/command/list.py b/libbe/command/list.py
index 7c3f5af..8bdeaae 100644
--- a/libbe/command/list.py
+++ b/libbe/command/list.py
@@ -60,11 +60,13 @@ class List (libbe.command.Command):
>>> import libbe.bugdir
>>> bd = libbe.bugdir.SimpleBugDir(memory=False)
>>> cmd = List()
+ >>> cmd._storage = bd.storage
>>> cmd._setup_io = lambda i_enc,o_enc : None
>>> cmd.stdout = sys.stdout
- >>> ret = cmd.run(bd.storage, bd)
+
+ >>> ret = cmd.run()
abc/a:om: Bug A
- >>> ret = cmd.run(bd.storage, bd, {'status':'closed'})
+ >>> ret = cmd.run({'status':'closed'})
abc/b:cm: Bug B
>>> bd.storage.writeable
True
@@ -75,7 +77,6 @@ class List (libbe.command.Command):
def __init__(self, *args, **kwargs):
libbe.command.Command.__init__(self, *args, **kwargs)
- self.requires_bugdir = True
self.options.extend([
libbe.command.Option(name='status',
help='Only show bugs matching the STATUS specifier',
@@ -131,7 +132,8 @@ class List (libbe.command.Command):
#
# ])
- def _run(self, storage, bugdir, **params):
+ def _run(self, **params):
+ bugdir = self._get_bugdir()
writeable = bugdir.storage.writeable
bugdir.storage.writeable = False
cmp_list, status, severity, assigned, extra_strings_regexps = \
diff --git a/libbe/command/merge.py b/libbe/command/merge.py
index 4624ab7..e3bf943 100644
--- a/libbe/command/merge.py
+++ b/libbe/command/merge.py
@@ -31,6 +31,7 @@ class Merge (libbe.command.Command):
>>> import libbe.comment
>>> bd = libbe.bugdir.SimpleBugDir(memory=False)
>>> cmd = Merge()
+ >>> cmd._storage = bd.storage
>>> cmd._setup_io = lambda i_enc,o_enc : None
>>> cmd.stdout = sys.stdout
@@ -48,7 +49,7 @@ class Merge (libbe.command.Command):
>>> dummy = dummy.new_reply('1 2 3 4')
>>> dummy.time = 2
- >>> ret = cmd.run(bd.storage, bd, {}, ['/a', '/b'])
+ >>> ret = cmd.run(args=['/a', '/b'])
Merged bugs #abc/a# and #abc/b#
>>> bd.flush_reload()
>>> a = bd.bug_from_uuid('a')
@@ -139,7 +140,6 @@ class Merge (libbe.command.Command):
def __init__(self, *args, **kwargs):
libbe.command.Command.__init__(self, *args, **kwargs)
- self.requires_bugdir = True
self.args.extend([
libbe.command.Argument(
name='bug-id', metavar='BUG-ID', default=None,
@@ -149,7 +149,8 @@ class Merge (libbe.command.Command):
completion_callback=libbe.command.util.complete_bug_id),
])
- def _run(self, storage, bugdir, **params):
+ def _run(self, **params):
+ bugdir = self._get_bugdir()
bugA,dummy_comment = \
libbe.command.util.bug_comment_from_user_id(
bugdir, params['bug-id'])
@@ -166,7 +167,7 @@ class Merge (libbe.command.Command):
if comment.alt_id == None:
comment.storage = None
comment.alt_id = comment.uuid
- comment.storage = storage
+ comment.storage = bugdir.storage
comment.uuid = libbe.util.id.uuid_gen()
comment.save() # force onto disk under bugA
diff --git a/libbe/command/new.py b/libbe/command/new.py
index d840503..de215fa 100644
--- a/libbe/command/new.py
+++ b/libbe/command/new.py
@@ -31,11 +31,12 @@ class New (libbe.command.Command):
>>> import libbe.util.id
>>> bd = libbe.bugdir.SimpleBugDir(memory=False)
>>> cmd = New()
+ >>> cmd._storage = bd.storage
>>> cmd._setup_io = lambda i_enc,o_enc : None
>>> cmd.stdout = sys.stdout
>>> libbe.util.id.uuid_gen = lambda: 'X'
- >>> ret = cmd.run(bd.storage, bd, args=['this is a test',])
+ >>> ret = cmd.run(args=['this is a test',])
Created bug with ID abc/X
>>> bd.flush_reload()
>>> bug = bd.bug_from_uuid('X')
@@ -53,7 +54,6 @@ class New (libbe.command.Command):
def __init__(self, *args, **kwargs):
libbe.command.Command.__init__(self, *args, **kwargs)
- self.requires_bugdir = True
self.options.extend([
libbe.command.Option(name='reporter', short_name='r',
help='The user who reported the bug',
@@ -69,11 +69,12 @@ class New (libbe.command.Command):
libbe.command.Argument(name='summary', metavar='SUMMARY')
])
- def _run(self, storage, bugdir, **params):
+ def _run(self, **params):
if params['summary'] == '-': # read summary from stdin
summary = self.stdin.readline()
else:
summary = params['summary']
+ bugdir = self._get_bugdir()
bug = bugdir.new_bug(summary=summary.strip())
if params['reporter'] != None:
bug.reporter = params['reporter']
diff --git a/libbe/command/remove.py b/libbe/command/remove.py
index e516443..3b9d3f3 100644
--- a/libbe/command/remove.py
+++ b/libbe/command/remove.py
@@ -27,12 +27,13 @@ class Remove (libbe.command.Command):
>>> import libbe.bugdir
>>> bd = libbe.bugdir.SimpleBugDir(memory=False)
>>> cmd = Remove()
+ >>> cmd._storage = bd.storage
>>> cmd._setup_io = lambda i_enc,o_enc : None
>>> cmd.stdout = sys.stdout
>>> print bd.bug_from_uuid('b').status
closed
- >>> ret = cmd.run(bd.storage, bd, args=['/b'])
+ >>> ret = cmd.run(args=['/b'])
Removed bug abc/b
>>> bd.flush_reload()
>>> try:
@@ -46,7 +47,6 @@ class Remove (libbe.command.Command):
def __init__(self, *args, **kwargs):
libbe.command.Command.__init__(self, *args, **kwargs)
- self.requires_bugdir = True
self.args.extend([
libbe.command.Argument(
name='bug-id', metavar='BUG-ID', default=None,
@@ -54,7 +54,8 @@ class Remove (libbe.command.Command):
completion_callback=libbe.command.util.complete_bug_id),
])
- def _run(self, storage, bugdir, **params):
+ def _run(self, **params):
+ bugdir = self._get_bugdir()
user_ids = []
for bug_id in params['bug-id']:
bug,dummy_comment = libbe.command.util.bug_comment_from_user_id(
diff --git a/libbe/command/severity.py b/libbe/command/severity.py
index 804dc4e..f6b586f 100644
--- a/libbe/command/severity.py
+++ b/libbe/command/severity.py
@@ -17,51 +17,65 @@
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-"""Show or change a bug's severity level"""
-from libbe import cmdutil, bugdir, bug
-__desc__ = __doc__
-def execute(args, manipulate_encodings=True, restrict_file_access=False,
- dir="."):
- """
- >>> import os
- >>> bd = bugdir.SimpleBugDir()
- >>> os.chdir(bd.root)
- >>> execute(["a"], manipulate_encodings=False)
- minor
- >>> execute(["a", "wishlist"], manipulate_encodings=False)
- >>> execute(["a"], manipulate_encodings=False)
- wishlist
- >>> execute(["a", "none"], manipulate_encodings=False)
+import libbe
+import libbe.bug
+import libbe.command
+import libbe.command.util
+
+class Severity (libbe.command.Command):
+ """Change a bug's severity level
+
+ >>> import sys
+ >>> import libbe.bugdir
+ >>> bd = libbe.bugdir.SimpleBugDir(memory=False)
+ >>> cmd = Severity()
+ >>> cmd._storage = bd.storage
+ >>> cmd._setup_io = lambda i_enc,o_enc : None
+ >>> cmd.stdout = sys.stdout
+
+ >>> bd.bug_from_uuid('a').severity
+ 'minor'
+ >>> ret = cmd.run(args=['wishlist', '/a'])
+ >>> bd.flush_reload()
+ >>> bd.bug_from_uuid('a').severity
+ 'wishlist'
+ >>> ret = cmd.run(args=['none', '/a'])
Traceback (most recent call last):
UserError: Invalid severity level: none
>>> bd.cleanup()
"""
- parser = get_parser()
- options, args = parser.parse_args(args)
- complete(options, args, parser)
- if len(args) not in (1,2):
- raise cmdutil.UsageError
- bd = bugdir.BugDir(from_disk=True,
- manipulate_encodings=manipulate_encodings,
- root=dir)
- bug = cmdutil.bug_from_id(bd, args[0])
- if len(args) == 1:
- print bug.severity
- elif len(args) == 2:
- try:
- bug.severity = args[1]
- except ValueError, e:
- if e.name != "severity":
- raise e
- raise cmdutil.UserError ("Invalid severity level: %s" % e.value)
+ name = 'severity'
-def get_parser():
- parser = cmdutil.CmdOptionParser("be severity BUG-ID [SEVERITY]")
- return parser
+ def __init__(self, *args, **kwargs):
+ libbe.command.Command.__init__(self, *args, **kwargs)
+ self.args.extend([
+ libbe.command.Argument(
+ name='severity', metavar='SEVERITY', default=None,
+ completion_callback=libbe.command.util.complete_severity),
+ libbe.command.Argument(
+ name='bug-id', metavar='BUG-ID', default=None,
+ repeatable=True,
+ completion_callback=libbe.command.util.complete_bug_id),
+ ])
+
+ def _run(self, **params):
+ bugdir = self._get_bugdir()
+ for bug_id in params['bug-id']:
+ bug,dummy_comment = \
+ libbe.command.util.bug_comment_from_user_id(bugdir, bug_id)
+ if bug.severity != params['severity']:
+ try:
+ bug.severity = params['severity']
+ except ValueError, e:
+ if e.name != 'severity':
+ raise e
+ raise libbe.command.UserError(
+ 'Invalid severity level: %s' % e.value)
+ return 0
-def help():
- longhelp=["""
+ def _long_help(self):
+ ret = ["""
Show or change a bug's severity level.
If no severity is specified, the current value is printed. If a severity level
@@ -69,38 +83,13 @@ is specified, it will be assigned to the bug.
Severity levels are:
"""]
- try: # See if there are any per-tree severity configurations
- bd = bugdir.BugDir(from_disk=True, manipulate_encodings=False)
- except bugdir.NoBugDir, e:
- pass # No tree, just show the defaults
- longest_severity_len = max([len(s) for s in bug.severity_values])
- for severity in bug.severity_values :
- description = bug.severity_description[severity]
- s = "%*s : %s\n" % (longest_severity_len, severity, description)
- longhelp.append(s)
- longhelp = ''.join(longhelp)
- return get_parser().help_str() + longhelp
-
-def complete(options, args, parser):
- for option,value in cmdutil.option_value_pairs(options, parser):
- if value == "--complete":
- # no argument-options at the moment, so this is future-proofing
- raise cmdutil.GetCompletions()
- for pos,value in enumerate(args):
- if value == "--complete":
- try: # See if there are any per-tree severity configurations
- bd = bugdir.BugDir(from_disk=True,
- manipulate_encodings=False)
- except bugdir.NoBugDir:
- bd = None
- if pos == 0: # fist positional argument is a bug id
- ids = []
- if bd != None:
- bd.load_all_bugs()
- filter = lambda bg : bg.active==True
- bugs = [bg for bg in bd if filter(bg)==True]
- ids = [bd.bug_shortname(bg) for bg in bugs]
- raise cmdutil.GetCompletions(ids)
- elif pos == 1: # second positional argument is a severity
- raise cmdutil.GetCompletions(bug.severity_values)
- raise cmdutil.GetCompletions()
+ try: # See if there are any per-tree severity configurations
+ bd = self._get_bugdir()
+ except NotImplementedError:
+ pass # No tree, just show the defaults
+ longest_severity_len = max([len(s) for s in libbe.bug.severity_values])
+ for severity in bug.severity_values :
+ description = bug.severity_description[severity]
+ ret.append('%*s : %s\n' \
+ % (longest_severity_len, severity, description))
+ return ''.join(ret)
diff --git a/libbe/ui/command_line.py b/libbe/ui/command_line.py
index 84f9450..0aa34f7 100755
--- a/libbe/ui/command_line.py
+++ b/libbe/ui/command_line.py
@@ -264,29 +264,18 @@ def main():
print e
return 1
Class = getattr(module, command_name.capitalize())
- command = Class()
- command.ui = self
+ def gucs():
+ return libbe.storage.get_storage(options['repo'])
+ command = Class(get_unconnected_storage=gucs, ui=ui)
parser = CmdOptionParser(command)
- storage = None
- bugdir = None
- if command.requires_bugdir == True:
- assert command.requires_unconnected_storage == False
- storage = libbe.storage.get_storage(options['repo'])
- storage.connect()
- bugdir = libbe.bugdir.BugDir(storage, from_storage=True)
- elif command.requires_storage == True \
- or command.requires_unconnected_storage == True:
- storage = libbe.storage.get_storage(options['repo'])
- if command.requires_unconnected_storage == False:
- storage.connect()
try:
options,args = parser.parse_args(args[1:])
- command.run(storage, bugdir, options, args)
+ command.run(options, args)
except CallbackExit:
- if storage != None: storage.disconnect()
+ command.cleanup()
return 0
except libbe.command.UserError, e:
- if storage != None: storage.disconnect()
+ command.cleanup()
print 'ERROR:\n', e
return 1
if storage != None: storage.disconnect()
diff --git a/libbe/ui/util/cmdutil.py b/libbe/ui/util/cmdutil.py
index 86ff9fc..f2eb5b9 100644
--- a/libbe/ui/util/cmdutil.py
+++ b/libbe/ui/util/cmdutil.py
@@ -59,20 +59,6 @@ def execute(cmd, args,
def restrict_file_access(bugdir, path):
- """
- Check that the file at path is inside bugdir.root. This is
- important if you allow other users to execute becommands with your
- username (e.g. if you're running be-handle-mail through your
- ~/.procmailrc). If this check wasn't made, a user could e.g.
- run
- be commit -b ~/.ssh/id_rsa "Hack to expose ssh key"
- which would expose your ssh key to anyone who could read the VCS
- log.
- """
- in_root = bugdir.vcs.path_in_root(path, bugdir.root)
- if in_root == False:
- raise UserError('file access restricted!\n %s not in %s'
- % (path, bugdir.root))
def parse_id(id):
"""