Ran update-copyright.py.
[be.git] / libbe / command / set.py
1 # Copyright (C) 2005-2012 Aaron Bentley <abentley@panoramicfeedback.com>
2 #                         Chris Ball <cjb@laptop.org>
3 #                         Gianluca Montecchi <gian@grys.it>
4 #                         Marien Zwart <marien.zwart@gmail.com>
5 #                         Thomas Gerigk <tgerigk@gmx.de>
6 #                         W. Trevor King <wking@tremily.us>
7 #
8 # This file is part of Bugs Everywhere.
9 #
10 # Bugs Everywhere is free software: you can redistribute it and/or modify it
11 # under the terms of the GNU General Public License as published by the Free
12 # Software Foundation, either version 2 of the License, or (at your option) any
13 # later version.
14 #
15 # Bugs Everywhere is distributed in the hope that it will be useful, but
16 # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 # FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
18 # more details.
19 #
20 # You should have received a copy of the GNU General Public License along with
21 # Bugs Everywhere.  If not, see <http://www.gnu.org/licenses/>.
22
23
24 import textwrap
25
26 import libbe
27 import libbe.bugdir
28 import libbe.command
29 import libbe.command.util
30 from libbe.storage.util.settings_object import EMPTY
31
32
33 class Set (libbe.command.Command):
34     """Change bug directory settings
35
36     >>> import sys
37     >>> import libbe.bugdir
38     >>> bd = libbe.bugdir.SimpleBugDir(memory=False)
39     >>> io = libbe.command.StringInputOutput()
40     >>> io.stdout = sys.stdout
41     >>> ui = libbe.command.UserInterface(io=io)
42     >>> ui.storage_callbacks.set_storage(bd.storage)
43     >>> cmd = Set(ui=ui)
44
45     >>> ret = ui.run(cmd, args=['target'])
46     None
47     >>> ret = ui.run(cmd, args=['target', 'abcdefg'])
48     >>> ret = ui.run(cmd, args=['target'])
49     abcdefg
50     >>> ret = ui.run(cmd, args=['target', 'none'])
51     >>> ret = ui.run(cmd, args=['target'])
52     None
53     >>> ui.cleanup()
54     >>> bd.cleanup()
55     """
56     name = 'set'
57
58     def __init__(self, *args, **kwargs):
59         libbe.command.Command.__init__(self, *args, **kwargs)
60         self.options.extend([
61                 libbe.command.Option(name='bugdir', short_name='b',
62                     help='Short bugdir UUID to act on.  You '
63                     'only need to set this if you have multiple bugdirs in '
64                     'your repository.',
65                     arg=libbe.command.Argument(
66                         name='bugdir', metavar='ID', default=None,
67                         completion_callback=libbe.command.util.complete_bugdir_id)),
68                 ])
69         self.args.extend([
70                 libbe.command.Argument(
71                     name='setting', metavar='SETTING', optional=True,
72                     completion_callback=complete_bugdir_settings),
73                 libbe.command.Argument(
74                     name='value', metavar='VALUE', optional=True)
75                 ])
76
77     def _run(self, **params):
78         bugdirs = self._get_bugdirs()
79         if params['bugdir']:
80             bugdir = bugdirs[bugdir]
81         elif len(bugdirs) == 1:
82             bugdir = bugdirs.values()[0]
83         else:
84             raise libbe.command.UserError(
85                 'Ambiguous bugdir {}'.format(sorted(bugdirs.values())))
86         if params['setting'] == None:
87             keys = bugdir.settings_properties
88             keys.sort()
89             for key in keys:
90                 print >> self.stdout, \
91                     '%16s: %s' % (key, _value_string(bugdir, key))
92             return 0
93         if params['setting'] not in bugdir.settings_properties:
94             msg = 'Invalid setting %s\n' % params['setting']
95             msg += 'Allowed settings:\n  '
96             msg += '\n  '.join(bugdir.settings_properties)
97             raise libbe.command.UserError(msg)
98         if params['value'] == None:
99             print _value_string(bugdir, params['setting'])
100         else:
101             if params['value'] == 'none':
102                 params['value'] = EMPTY
103             old_setting = bugdir.settings.get(params['setting'])
104             attr = bugdir._setting_name_to_attr_name(params['setting'])
105             setattr(bugdir, attr, params['value'])
106         return 0
107
108     def _long_help(self):
109         return """
110 Show or change per-tree settings.
111
112 If name and value are supplied, the name is set to a new value.
113 If no value is specified, the current value is printed.
114 If no arguments are provided, all names and values are listed.
115
116 To unset a setting, set it to "none".
117
118 Allowed settings are:
119
120 %s
121
122 Note that this command does not provide a good interface for some of
123 these settings (yet!).  You may need to edit the bugdir settings file
124 (`.be/<bugdir>/settings`) manually.  Examples for each troublesome
125 setting are given below.
126
127 Add the following lines to override the default severities and use
128 your own:
129
130   severities:
131     - - target
132       - The issue is a target or milestone, not a bug.
133     - - wishlist
134       - A feature that could improve usefulness, but not a bug.
135
136 You may add as many name/description pairs as you wish to have; they
137 are sorted in order from least important at the top, to most important
138 at the bottom.  The target severity gets special handling by `be
139 target`.
140
141 Note that the values here _override_ the defaults. That means that if
142 you like the defaults, and wish to keep them, you will have to copy
143 them here before adding any of your own.  See `be severity --help` for
144 the current list.
145
146 Add the following lines to override the default statuses and use your
147 own:
148
149   active_status:
150     - - unconfirmed
151       - A possible bug which lacks independent existance confirmation.
152     - - open
153       - A working bug that has not been assigned to a developer.
154
155   inactive_status:
156     - - closed
157       - The bug is no longer relevant.
158     - - fixed
159       - The bug should no longer occur.
160
161 You may add as many name/description pairs as you wish to have; they
162 are sorted in order from most important at the top, to least important
163 at the bottom.
164
165 Note that the values here _override_ the defaults. That means that if
166 you like the defaults, and wish to keep them, you will have to copy
167 them here before adding any of your own.  See `be status --help` for
168 the current list.
169 """ % ('\n'.join(get_bugdir_settings()),)
170
171 def get_bugdir_settings():
172     settings = []
173     for s in libbe.bugdir.BugDir.settings_properties:
174         settings.append(s)
175     settings.sort()
176     documented_settings = []
177     for s in settings:
178         set = getattr(libbe.bugdir.BugDir, s)
179         dstr = set.__doc__.strip()
180         # per-setting comment adjustments
181         if s == 'vcs_name':
182             lines = dstr.split('\n')
183             while lines[0].startswith('This property defaults to') == False:
184                 lines.pop(0)
185             assert len(lines) != None, \
186                 'Unexpected vcs_name docstring:\n  "%s"' % dstr
187             lines.insert(
188                 0, 'The name of the revision control system to use.\n')
189             dstr = '\n'.join(lines)
190         doc = textwrap.wrap(dstr, width=70, initial_indent='  ',
191                             subsequent_indent='  ')
192         documented_settings.append('%s\n%s' % (s, '\n'.join(doc)))
193     return documented_settings
194
195 def _value_string(bugdir, setting):
196     val = bugdir.settings.get(setting, EMPTY)
197     if val == EMPTY:
198         default = getattr(bugdir, bugdir._setting_name_to_attr_name(setting))
199         if default not in [None, EMPTY]:
200             val = 'None (%s)' % default
201         else:
202             val = None
203     return str(val)
204
205 def complete_bugdir_settings(command, argument, fragment=None):
206     """
207     List possible command completions for fragment.
208
209     Neither the command nor argument arguments are used.
210     """
211     return libbe.bugdir.BugDir.settings_properties