aboutsummaryrefslogtreecommitdiffstats
path: root/libbe/cmdutil.py
blob: e6d5a8f4f2f4fc6f1f7dec3320457f948a550e1e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
import bugdir
import plugin
import os
import optparse

def unique_name(bug, bugs):
    chars = 1
    for some_bug in bugs:
        if bug.uuid == some_bug.uuid:
            continue
        while (bug.uuid[:chars] == some_bug.uuid[:chars]):
            chars+=1
    return bug.uuid[:chars]

class UserError(Exception):
    def __init__(self, msg):
        Exception.__init__(self, msg)

class UserErrorWrap(UserError):
    def __init__(self, exception):
        UserError.__init__(self, str(exception))
        self.exception = exception

def get_bug(spec, bug_dir=None):
    matches = []
    try:
        if bug_dir is None:
            bug_dir = bugdir.tree_root('.')
    except bugdir.NoBugDir, e:
        raise UserErrorWrap(e)
    bugs = list(bug_dir.list())
    for bug in bugs:
        if bug.uuid.startswith(spec):
            matches.append(bug)
    if len(matches) > 1:
        raise UserError("More than one bug matches %s.  Please be more"
                        " specific." % spec)
    if len(matches) == 1:
        return matches[0]
        
    matches = []
    if len(matches) == 0:
        raise UserError("No bug matches %s" % spec)
    return matches[0]

def bug_summary(bug, bugs, no_target=False):
    target = bug.target
    if target is None or no_target:
        target = ""
    else:
        target = "  Target: %s" % target
    if bug.assigned is None:
        assigned = ""
    else:
        assigned = "  Assigned: %s" % bug.assigned
    return "ID: %s  Severity: %s%s%s  Creator: %s \n%s\n" % \
            (unique_name(bug, bugs), bug.severity, assigned, target,
             bug.creator, bug.summary)

def iter_commands():
    for name, module in plugin.iter_plugins("becommands"):
        yield name.replace("_", "-"), module

def get_command(command_name):
    """Retrieves the module for a user command

    >>> get_command("asdf")
    Traceback (most recent call last):
    File "<stdin>", line 1, in ?
    File "/home/abentley/be/libbe/cmdutil.py", line 60, in get_command
      raise UserError("Unknown command %s" % command_name)
    UserError: Unknown command asdf
    >>> repr(get_command("list")).startswith("<module 'becommands.list' from ")
    True
    """
    cmd = plugin.get_plugin("becommands", command_name.replace("-", "_"))
    if cmd is None:
        raise UserError("Unknown command %s" % command_name)
    return cmd

def execute(cmd, args):
    return get_command(cmd).execute(args)

def help(cmd):
    return get_command(cmd).help()


class GetHelp(Exception):
    pass


class UsageError(Exception):
    pass


def raise_get_help(option, opt, value, parser):
    raise GetHelp


class CmdOptionParser(optparse.OptionParser):
    def __init__(self, usage):
        optparse.OptionParser.__init__(self, usage)
        self.remove_option("-h")
        self.add_option("-h", "--help", action="callback", 
                        callback=raise_get_help, help="Print a help message")

    def error(self, message):
        raise UsageError(message)

    def iter_options(self):
        return iter_combine([self._short_opt.iterkeys(), 
                            self._long_opt.iterkeys()])


def underlined(instring):
    """Produces a version of a string that is underlined with '='

    >>> underlined("Underlined String")
    'Underlined String\\n================='
    """
    
    return "%s\n%s" % (instring, "="*len(instring))


def bug_tree(dir=None):
    """Retrieve the bug tree specified by the user.  If no directory is
    specified, the current working directory is used.

    :param dir: The directory to search for the bug tree in.

    >>> bug_tree() is not None
    True
    >>> bug_tree("/")
    Traceback (most recent call last):
    UserErrorWrap: The directory "/" has no bug directory.
    """
    if dir is None:
        dir = os.getcwd()
    try:
        return bugdir.tree_root(dir)
    except bugdir.NoBugDir, e:
        raise UserErrorWrap(e)


def _test():
    import doctest
    import sys
    doctest.testmod()

if __name__ == "__main__":
    _test()