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@drexel.edu>
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.args.extend([
61                 libbe.command.Argument(
62                     name='setting', metavar='SETTING', optional=True,
63                     completion_callback=complete_bugdir_settings),
64                 libbe.command.Argument(
65                     name='value', metavar='VALUE', optional=True)
66                 ])
67
68     def _run(self, **params):
69         bugdir = self._get_bugdir()
70         if params['setting'] == None:
71             keys = bugdir.settings_properties
72             keys.sort()
73             for key in keys:
74                 print >> self.stdout, \
75                     '%16s: %s' % (key, _value_string(bugdir, key))
76             return 0
77         if params['setting'] not in bugdir.settings_properties:
78             msg = 'Invalid setting %s\n' % params['setting']
79             msg += 'Allowed settings:\n  '
80             msg += '\n  '.join(bugdir.settings_properties)
81             raise libbe.command.UserError(msg)
82         if params['value'] == None:
83             print _value_string(bugdir, params['setting'])
84         else:
85             if params['value'] == 'none':
86                 params['value'] = EMPTY
87             old_setting = bugdir.settings.get(params['setting'])
88             attr = bugdir._setting_name_to_attr_name(params['setting'])
89             setattr(bugdir, attr, params['value'])
90         return 0
91
92     def _long_help(self):
93         return """
94 Show or change per-tree settings.
95
96 If name and value are supplied, the name is set to a new value.
97 If no value is specified, the current value is printed.
98 If no arguments are provided, all names and values are listed.
99
100 To unset a setting, set it to "none".
101
102 Allowed settings are:
103
104 %s
105
106 Note that this command does not provide a good interface for some of
107 these settings (yet!).  You may need to edit the bugdir settings file
108 (`.be/<bugdir>/settings`) manually.  Examples for each troublesome
109 setting are given below.
110
111 Add the following lines to override the default severities and use
112 your own:
113
114   severities:
115     - - target
116       - The issue is a target or milestone, not a bug.
117     - - wishlist
118       - A feature that could improve usefulness, but not a bug.
119
120 You may add as many name/description pairs as you wish to have; they
121 are sorted in order from least important at the top, to most important
122 at the bottom.  The target severity gets special handling by `be
123 target`.
124
125 Note that the values here _override_ the defaults. That means that if
126 you like the defaults, and wish to keep them, you will have to copy
127 them here before adding any of your own.  See `be severity --help` for
128 the current list.
129
130 Add the following lines to override the default statuses and use your
131 own:
132
133   active_status:
134     - - unconfirmed
135       - A possible bug which lacks independent existance confirmation.
136     - - open
137       - A working bug that has not been assigned to a developer.
138
139   inactive_status:
140     - - closed
141       - The bug is no longer relevant.
142     - - fixed
143       - The bug should no longer occur.
144
145 You may add as many name/description pairs as you wish to have; they
146 are sorted in order from most important at the top, to least important
147 at the bottom.
148
149 Note that the values here _override_ the defaults. That means that if
150 you like the defaults, and wish to keep them, you will have to copy
151 them here before adding any of your own.  See `be status --help` for
152 the current list.
153 """ % ('\n'.join(get_bugdir_settings()),)
154
155 def get_bugdir_settings():
156     settings = []
157     for s in libbe.bugdir.BugDir.settings_properties:
158         settings.append(s)
159     settings.sort()
160     documented_settings = []
161     for s in settings:
162         set = getattr(libbe.bugdir.BugDir, s)
163         dstr = set.__doc__.strip()
164         # per-setting comment adjustments
165         if s == 'vcs_name':
166             lines = dstr.split('\n')
167             while lines[0].startswith('This property defaults to') == False:
168                 lines.pop(0)
169             assert len(lines) != None, \
170                 'Unexpected vcs_name docstring:\n  "%s"' % dstr
171             lines.insert(
172                 0, 'The name of the revision control system to use.\n')
173             dstr = '\n'.join(lines)
174         doc = textwrap.wrap(dstr, width=70, initial_indent='  ',
175                             subsequent_indent='  ')
176         documented_settings.append('%s\n%s' % (s, '\n'.join(doc)))
177     return documented_settings
178
179 def _value_string(bugdir, setting):
180     val = bugdir.settings.get(setting, EMPTY)
181     if val == EMPTY:
182         default = getattr(bugdir, bugdir._setting_name_to_attr_name(setting))
183         if default not in [None, EMPTY]:
184             val = 'None (%s)' % default
185         else:
186             val = None
187     return str(val)
188
189 def complete_bugdir_settings(command, argument, fragment=None):
190     """
191     List possible command completions for fragment.
192
193     Neither the command nor argument arguments are used.
194     """
195     return libbe.bugdir.BugDir.settings_properties