Updated copyright information
[be.git] / libbe / command / tag.py
1 # Copyright (C) 2009-2010 Gianluca Montecchi <gian@grys.it>
2 #                         W. Trevor King <wking@drexel.edu>
3 #
4 # This program is free software; you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License as published by
6 # the Free Software Foundation; either version 2 of the License, or
7 # (at your option) any later version.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public License along
15 # with this program; if not, write to the Free Software Foundation, Inc.,
16 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17
18 import libbe
19 import libbe.command
20 import libbe.command.util
21
22
23 TAG_TAG = 'TAG:'
24
25
26 class Tag (libbe.command.Command):
27     __doc__ = """Tag a bug, or search bugs for tags
28
29     >>> import sys
30     >>> import libbe.bugdir
31     >>> bd = libbe.bugdir.SimpleBugDir(memory=False)
32     >>> io = libbe.command.StringInputOutput()
33     >>> io.stdout = sys.stdout
34     >>> ui = libbe.command.UserInterface(io=io)
35     >>> ui.storage_callbacks.set_bugdir(bd)
36     >>> cmd = Tag(ui=ui)
37
38     >>> a = bd.bug_from_uuid('a')
39     >>> print a.extra_strings
40     []
41     >>> ret = ui.run(cmd, args=['/a', 'GUI'])
42     Tags for abc/a:
43     GUI
44     >>> bd.flush_reload()
45     >>> a = bd.bug_from_uuid('a')
46     >>> print a.extra_strings
47     ['%(tag_tag)sGUI']
48     >>> ret = ui.run(cmd, args=['/a', 'later'])
49     Tags for abc/a:
50     GUI
51     later
52     >>> ret = ui.run(cmd, args=['/a'])
53     Tags for abc/a:
54     GUI
55     later
56     >>> ret = ui.run(cmd, {'list':True})
57     GUI
58     later
59     >>> ret = ui.run(cmd, args=['/a', 'Alphabetically first'])
60     Tags for abc/a:
61     Alphabetically first
62     GUI
63     later
64     >>> bd.flush_reload()
65     >>> a = bd.bug_from_uuid('a')
66     >>> print a.extra_strings
67     ['%(tag_tag)sAlphabetically first', '%(tag_tag)sGUI', '%(tag_tag)slater']
68     >>> a.extra_strings = []
69     >>> print a.extra_strings
70     []
71     >>> ret = ui.run(cmd, args=['/a'])
72     >>> bd.flush_reload()
73     >>> a = bd.bug_from_uuid('a')
74     >>> print a.extra_strings
75     []
76     >>> ret = ui.run(cmd, args=['/a', 'Alphabetically first'])
77     Tags for abc/a:
78     Alphabetically first
79     >>> ret = ui.run(cmd, {'remove':True}, ['/a', 'Alphabetically first'])
80     >>> ui.cleanup()
81     >>> bd.cleanup()
82     """ % {'tag_tag':TAG_TAG}
83     name = 'tag'
84
85     def __init__(self, *args, **kwargs):
86         libbe.command.Command.__init__(self, *args, **kwargs)
87         self.options.extend([
88                 libbe.command.Option(name='remove', short_name='r',
89                     help='Remove TAG (instead of adding it)'),
90                 libbe.command.Option(name='list', short_name='l',
91                     help='List all available tags and exit'),
92                 ])
93         self.args.extend([
94                 libbe.command.Argument(
95                     name='id', metavar='BUG-ID', optional=True,
96                     completion_callback=libbe.command.util.complete_bug_id),
97                 libbe.command.Argument(
98                     name='tag', metavar='TAG', default=tuple(),
99                     optional=True, repeatable=True),
100                 ])
101
102     def _run(self, **params):
103         if params['id'] == None and params['list'] == False:
104             raise libbe.command.UserError('Please specify a bug id.')
105         if params['id'] != None and params['list'] == True:
106             raise libbe.command.UserError(
107                 'Do not specify a bug id with the --list option.')
108         bugdir = self._get_bugdir()
109         if params['list'] == True:
110             bugdir.load_all_bugs()
111             tags = []
112             for bug in bugdir:
113                 for estr in bug.extra_strings:
114                     if estr.startswith(TAG_TAG):
115                         tag = estr[len(TAG_TAG):]
116                         if tag not in tags:
117                             tags.append(tag)
118             tags.sort()
119             if len(tags) > 0:
120                 print >> self.stdout, '\n'.join(tags)
121             return 0
122
123         bug,dummy_comment = libbe.command.util.bug_comment_from_user_id(
124             bugdir, params['id'])
125         if len(params['tag']) > 0:
126             estrs = bug.extra_strings
127             for tag in params['tag']:
128                 tag_string = '%s%s' % (TAG_TAG, tag)
129                 if params['remove'] == True:
130                     estrs.remove(tag_string)
131                 else: # add the tag
132                     estrs.append(tag_string)
133             bug.extra_strings = estrs # reassign to notice change
134
135         tags = []
136         for estr in bug.extra_strings:
137             if estr.startswith(TAG_TAG):
138                 tags.append(estr[len(TAG_TAG):])
139
140         if len(tags) > 0:
141             print "Tags for %s:" % bug.id.user()
142             print '\n'.join(tags)
143         return 0
144
145     def _long_help(self):
146         return """
147 If TAG is given, add TAG to BUG-ID.  If it is not specified, just
148 print the tags for BUG-ID.
149
150 To search for bugs with a particular tag, try
151   $ be list --extra-strings %s<your-tag>
152 """ % TAG_TAG