GCC Code Coverage Report


Directory: cvmfs/
File: cvmfs/publish/command.h
Date: 2025-06-22 02:36:02
Exec Total Coverage
Lines: 0 53 0.0%
Branches: 0 44 0.0%

Line Branch Exec Source
1 /**
2 * This file is part of the CernVM File System.
3 */
4
5 #ifndef CVMFS_PUBLISH_COMMAND_H_
6 #define CVMFS_PUBLISH_COMMAND_H_
7
8 #include <stdint.h>
9
10 #include <cassert>
11 #include <map>
12 #include <string>
13 #include <vector>
14
15 #include "util/single_copy.h"
16 #include "util/string.h"
17
18 namespace publish {
19
20 class Command {
21 friend class CmdHelp; // to set the progname_
22
23 public:
24 /**
25 * A parameter is information that can be passed by -$short_key or --$key to
26 * a command. Parameters can be boolean switches (they have no arguments).
27 * If they have an argument, parameters can be required for the command or
28 * optional.
29 */
30 struct Parameter {
31 /**
32 * This constructor should only be used for objects that are meant for
33 * comparison with / search of existing parameters.
34 */
35 explicit Parameter(const std::string &key)
36 : key(key)
37 , short_key('?')
38 , arg_name("")
39 , description("")
40 , is_switch(false)
41 , is_optional(false) { }
42
43 Parameter(const std::string &key,
44 char short_key,
45 const std::string &arg_name,
46 const std::string &desc,
47 bool is_switch,
48 bool is_optional)
49 : key(key)
50 , short_key(short_key)
51 , arg_name(arg_name)
52 , description(desc)
53 , is_switch(is_switch)
54 , is_optional(is_optional) {
55 assert(!key.empty());
56 assert(!is_switch || is_optional); // switches are always optional
57 assert(is_optional || !arg_name.empty());
58 }
59
60 bool operator==(const Parameter &other) const { return key == other.key; }
61 bool operator!=(const Parameter &other) const { return key != other.key; }
62 bool operator<(const Parameter &other) const { return key < other.key; }
63
64 static Parameter Mandatory(const std::string &key, char short_key,
65 const std::string &arg_name,
66 const std::string &desc) {
67 return Parameter(key, short_key, arg_name, desc, false, false);
68 }
69 static Parameter Optional(const std::string &key, char short_key,
70 const std::string &arg_name,
71 const std::string &desc) {
72 return Parameter(key, short_key, arg_name, desc, false, true);
73 }
74 static Parameter Switch(const std::string &key, char short_key,
75 const std::string &desc) {
76 return Parameter(key, short_key, "", desc, true, true);
77 }
78
79 std::string key;
80 char short_key;
81 std::string arg_name;
82 std::string description;
83 bool is_switch;
84 bool is_optional;
85 };
86 typedef std::vector<Parameter> ParameterList;
87
88 /**
89 * Encapsulates the value of parameters that are not switches. The conversion
90 * to an int is done unconditionally, which doesn't hurt even for string
91 * arguments.
92 */
93 struct Argument {
94 Argument() : value_int(0) { }
95 explicit Argument(const std::string &v)
96 : value_str(v), value_int(String2Int64(v)) { }
97 std::string value_str;
98 int64_t value_int;
99 };
100
101 /**
102 * Encapsulates parameter-argument pairs
103 */
104 class Options {
105 public:
106 void AppendPlain(const Argument &a) { plain_args_.push_back(a); }
107 void Set(const Parameter &p, const Argument &a) { map_[p] = a; }
108 bool Has(const std::string &key) const {
109 return map_.count(Parameter(key)) > 0;
110 }
111 bool HasNot(const std::string &key) const { return !Has(key); }
112 Argument Get(const std::string &key) const {
113 return map_.find(Parameter(key))->second;
114 }
115 std::string GetString(const std::string &key) const {
116 return map_.find(Parameter(key))->second.value_str;
117 }
118 std::string GetStringDefault(const std::string &key,
119 const std::string &default_value) const {
120 if (Has(key))
121 return map_.find(Parameter(key))->second.value_str;
122 return default_value;
123 }
124 int GetInt(const std::string &key) const {
125 return map_.find(Parameter(key))->second.value_int;
126 }
127 unsigned GetSize() const { return map_.size(); }
128 const std::vector<Argument> &plain_args() const { return plain_args_; }
129
130 private:
131 std::map<Parameter, Argument> map_;
132 std::vector<Argument> plain_args_;
133 };
134
135 virtual ~Command() { }
136
137 /**
138 * Used to call the command as `cvmfs_server $GetName() ...`
139 */
140 virtual std::string GetName() const = 0;
141 /**
142 * A one-line explanation of what the command does
143 */
144 virtual std::string GetBrief() const = 0;
145 /**
146 * An extended description of the functionality
147 */
148 virtual std::string GetDescription() const { return GetBrief(); }
149 /**
150 * Returns the ordered array of possible parameters to this command
151 */
152 virtual ParameterList GetParams() const = 0;
153 virtual std::string GetUsage() const { return "[options]"; }
154 std::string GetExamples() const;
155 /**
156 * The command needs at least so many non-parameter arguments (e.g. fqrn)
157 */
158 virtual unsigned GetMinPlainArgs() const { return 0; }
159 /**
160 * Internal commands can be added that will be omitted from the printed list
161 * of available commands. By default, commands are visible though.
162 */
163 virtual bool IsHidden() const { return false; }
164
165 Options ParseOptions(int argc, char **argv);
166
167 /**
168 * The dictionary of passed arguments can be obtained by a call to
169 * ParseOptions()
170 */
171 virtual int Main(const Options &options) = 0;
172
173 std::string progname() const { return progname_; }
174
175 protected:
176 /**
177 * Example one-liners which get prepended by the command invocation
178 */
179 virtual std::vector<std::string> DoGetExamples() const {
180 return std::vector<std::string>();
181 }
182
183 private:
184 std::string progname_;
185 };
186
187
188 class CommandList : SingleCopy {
189 public:
190 ~CommandList();
191 void TakeCommand(Command *command);
192 Command *Find(const std::string &name);
193
194 const std::vector<Command *> &commands() const { return commands_; }
195
196 private:
197 std::vector<Command *> commands_;
198 };
199
200 } // namespace publish
201
202 #endif // CVMFS_PUBLISH_COMMAND_H_
203