monotone

monotone Mtn Source Tree

Root/cmd.hh

1#ifndef __CMD_HH__
2#define __CMD_HH__
3
4// Copyright (C) 2002 Graydon Hoare <graydon@pobox.com>
5//
6// This program is made available under the GNU GPL version 2.0 or
7// greater. See the accompanying file COPYING for details.
8//
9// This program is distributed WITHOUT ANY WARRANTY; without even the
10// implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
11// PURPOSE.
12
13#include <map>
14#include <set>
15
16#include "commands.hh"
17#include "selectors.hh"
18#include "options.hh"
19#include "sanity.hh"
20
21class app_state;
22class database;
23class project_t;
24struct workspace;
25
26namespace commands
27{
28 class command
29 {
30 public:
31 typedef std::set< utf8 > names_set;
32 typedef std::set< command * > children_set;
33
34 private:
35 // NB: these strings are stored _un_translated, because we cannot
36 // translate them until after main starts, by which time the
37 // command objects have all been constructed.
38 utf8 m_primary_name;
39 names_set m_names;
40 command * m_parent;
41 bool m_is_group;
42 bool m_hidden;
43 utf8 m_params;
44 utf8 m_abstract;
45 utf8 m_desc;
46 bool m_use_workspace_options;
47 options::options_type m_opts;
48 children_set m_children;
49 bool m_allow_completion;
50
51 std::map< command_id, command * >
52 find_completions(utf8 const & prefix, command_id const & completed,
53 bool completion_ok = true) const;
54 command * find_child_by_name(utf8 const & name) const;
55
56 bool allow_completion() const;
57 public:
58 command(std::string const & primary_name,
59 std::string const & other_names,
60 command * parent,
61 bool is_group,
62 bool hidden,
63 std::string const & params,
64 std::string const & abstract,
65 std::string const & desc,
66 bool use_workspace_options,
67 options::options_type const & opts,
68 bool allow_completion);
69
70 virtual ~command(void);
71
72 command_id ident(void) const;
73
74 utf8 const & primary_name(void) const;
75 names_set const & names(void) const;
76 void add_alias(const utf8 &new_name);
77 command * parent(void) const;
78 bool is_group(void) const;
79 bool hidden(void) const;
80 virtual std::string params(void) const;
81 virtual std::string abstract(void) const;
82 virtual std::string desc(void) const;
83 virtual names_set subcommands(void) const;
84 options::options_type const & opts(void) const;
85 bool use_workspace_options(void) const;
86 children_set & children(void);
87 children_set const & children(void) const;
88 bool is_leaf(void) const;
89
90 bool operator<(command const & cmd) const;
91
92 virtual void exec(app_state & app,
93 command_id const & execid,
94 args_vector const & args) const = 0;
95
96 bool has_name(utf8 const & name) const;
97 command const * find_command(command_id const & id) const;
98 command * find_command(command_id const & id);
99 std::set< command_id >
100 complete_command(command_id const & id,
101 command_id completed = command_id(),
102 bool completion_ok = true) const;
103 };
104
105 class automate : public command
106 {
107 // This function is supposed to be called only after the requirements
108 // for "automate" commands have been fulfilled. This is done by the
109 // "exec" function defined below, which implements code shared among
110 // all automation commands. Also, this is also needed by the "stdio"
111 // automation, as it executes multiple of these commands sharing the
112 // same initialization, hence the friend declaration.
113 virtual void exec_from_automate(app_state & app,
114 command_id const & execid,
115 args_vector const & args,
116 std::ostream & output) const = 0;
117 friend class automate_stdio;
118
119 public:
120 automate(std::string const & name,
121 std::string const & params,
122 std::string const & abstract,
123 std::string const & desc,
124 options::options_type const & opts);
125
126 void exec(app_state & app,
127 command_id const & execid,
128 args_vector const & args,
129 std::ostream & output) const;
130
131 void exec(app_state & app,
132 command_id const & execid,
133 args_vector const & args) const;
134 };
135};
136
137inline std::vector<file_path>
138args_to_paths(args_vector const & args)
139{
140 std::vector<file_path> paths;
141 for (args_vector::const_iterator i = args.begin(); i != args.end(); ++i)
142 {
143 if (bookkeeping_path::external_string_is_bookkeeping_path(*i))
144 W(F("ignored bookkeeping path '%s'") % *i);
145 else
146 paths.push_back(file_path_external(*i));
147 }
148 // "it should not be the case that args were passed, but our paths set
149 // ended up empty". This test is because some commands have default
150 // behavior for empty path sets -- in particular, it is the same as having
151 // no restriction at all. "mtn revert _MTN" turning into "mtn revert"
152 // would be bad. (Or substitute diff, etc.)
153 N(!(!args.empty() && paths.empty()),
154 F("all arguments given were bookkeeping paths; aborting"));
155 return paths;
156}
157
158std::string
159describe_revision(project_t & project, revision_id const & id);
160
161void
162notify_if_multiple_heads(project_t & project, branch_name const & branchname,
163 bool ignore_suspend_certs);
164
165void
166process_commit_message_args(options const & opts,
167 bool & given,
168 utf8 & log_message,
169 utf8 const & message_prefix = utf8());
170
171#define CMD_FWD_DECL(C) \
172namespace commands { \
173 class cmd_ ## C; \
174 extern cmd_ ## C C ## _cmd; \
175}
176
177#define CMD_REF(C) ((commands::command *)&(commands::C ## _cmd))
178
179#define _CMD2(C, name, aliases, parent, hidden, params, abstract, desc, opts) \
180namespace commands { \
181 class cmd_ ## C : public command \
182 { \
183 public: \
184 cmd_ ## C() : command(name, aliases, parent, false, hidden, \
185 params, abstract, desc, true, \
186 options::options_type() | opts, true) \
187 {} \
188 virtual void exec(app_state & app, \
189 command_id const & execid, \
190 args_vector const & args) const; \
191 }; \
192 cmd_ ## C C ## _cmd; \
193} \
194void commands::cmd_ ## C::exec(app_state & app, \
195 command_id const & execid, \
196 args_vector const & args) const
197
198#define CMD(C, name, aliases, parent, params, abstract, desc, opts) \
199 _CMD2(C, name, aliases, parent, false, params, abstract, desc, opts)
200
201#define CMD_HIDDEN(C, name, aliases, parent, params, abstract, desc, opts) \
202 _CMD2(C, name, aliases, parent, true, params, abstract, desc, opts)
203
204#define _CMD_GROUP2(C, name, aliases, parent, abstract, desc, cmpl) \
205 namespace commands { \
206 class cmd_ ## C : public command \
207 { \
208 public: \
209 cmd_ ## C() : command(name, aliases, parent, true, false, "", \
210 abstract, desc, true, \
211 options::options_type(), cmpl) \
212 {} \
213 virtual void exec(app_state & app, \
214 command_id const & execid, \
215 args_vector const & args) const; \
216 }; \
217 cmd_ ## C C ## _cmd; \
218} \
219void commands::cmd_ ## C::exec(app_state & app, \
220 command_id const & execid, \
221 args_vector const & args) const \
222{ \
223 I(false); \
224}
225
226#define CMD_GROUP(C, name, aliases, parent, abstract, desc) \
227 _CMD_GROUP2(C, name, aliases, parent, abstract, desc, true)
228
229#define CMD_GROUP_NO_COMPLETE(C, name, aliases, parent, abstract, desc) \
230 _CMD_GROUP2(C, name, aliases, parent, abstract, desc, false)
231
232// Use this for commands that should specifically _not_ look for an
233// _MTN dir and load options from it.
234
235#define CMD_NO_WORKSPACE(C, name, aliases, parent, params, abstract, \
236 desc, opts) \
237namespace commands { \
238 class cmd_ ## C : public command \
239 { \
240 public: \
241 cmd_ ## C() : command(name, aliases, parent, false, false, \
242 params, abstract, desc, false, \
243 options::options_type() | opts, true) \
244 {} \
245 virtual void exec(app_state & app, \
246 command_id const & execid, \
247 args_vector const & args) const; \
248 }; \
249 cmd_ ## C C ## _cmd; \
250} \
251void commands::cmd_ ## C::exec(app_state & app, \
252 command_id const & execid, \
253 args_vector const & args) const
254
255// TODO: 'abstract' and 'desc' should be refactored so that the
256// command definition allows the description of input/output format,
257// error conditions, version when added, etc. 'desc' can later be
258// automatically built from these.
259#define CMD_AUTOMATE(C, params, abstract, desc, opts) \
260namespace commands { \
261 class automate_ ## C : public automate \
262 { \
263 void exec_from_automate(app_state & app, \
264 command_id const & execid, \
265 args_vector const & args, \
266 std::ostream & output) const; \
267 public: \
268 automate_ ## C() : automate(#C, params, abstract, desc, \
269 options::options_type() | opts) \
270 {} \
271 }; \
272 automate_ ## C C ## _automate; \
273} \
274void commands::automate_ ## C :: exec_from_automate \
275 (app_state & app, \
276 command_id const & execid, \
277 args_vector const & args, \
278 std::ostream & output) const
279
280CMD_FWD_DECL(__root__);
281CMD_FWD_DECL(automation);
282CMD_FWD_DECL(database);
283CMD_FWD_DECL(debug);
284CMD_FWD_DECL(informative);
285CMD_FWD_DECL(key_and_cert);
286CMD_FWD_DECL(network);
287CMD_FWD_DECL(packet_io);
288CMD_FWD_DECL(rcs);
289CMD_FWD_DECL(review);
290CMD_FWD_DECL(tree);
291CMD_FWD_DECL(variables);
292CMD_FWD_DECL(workspace);
293CMD_FWD_DECL(user);
294
295// Local Variables:
296// mode: C++
297// fill-column: 76
298// c-file-style: "gnu"
299// indent-tabs-mode: nil
300// End:
301// vim: et:sw=2:sts=2:ts=2:cino=>2s,{s,\:s,+s,t0,g0,^-2,e-2,n-2,p2s,(0,=s:
302
303#endif

Archive Download this file

Branches

Tags

Quick Links:     www.monotone.ca    -     Downloads    -     Documentation    -     Wiki    -     Code Forge    -     Build Status