Sharg 1.1.2-rc.1
The argument parser for bio-c++ tools.
Loading...
Searching...
No Matches
format_tdl.hpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2006-2024, Knut Reinert & Freie Universität Berlin
2// SPDX-FileCopyrightText: 2016-2024, Knut Reinert & MPI für molekulare Genetik
3// SPDX-License-Identifier: BSD-3-Clause
4
10#pragma once
11
12#if !SHARG_HAS_TDL
13
15
16namespace sharg::detail
17{
18// A dummy class that is used when TDL is not available.
19// This reduces the number of '#if's in the code.
20// It will always throw when parse is called.
21// For the user, the behavior of the parser will be the same as if `parser::init()` would check for TDL availability.
22class format_tdl : public format_help
23{
24public:
25 enum class FileFormat
26 {
27 CTD,
28 CWL
29 };
30
31 format_tdl(format_tdl const &) = default;
32 format_tdl & operator=(format_tdl const &) = default;
33 format_tdl(format_tdl &&) = default;
34 format_tdl & operator=(format_tdl &&) = default;
35 ~format_tdl() = default;
36
38 {}
39
40 void parse(parser_meta_data &, std::vector<std::string> const &)
41 {
42 throw validation_error{"Validation failed for option --export-help: "
43 "Value must be one of "
44 + detail::supported_exports + "."};
45 }
46
48};
49
50} // namespace sharg::detail
51
52#else
53# include <concepts>
54# include <numeric>
55
57# include <sharg/validators.hpp>
58
59# include <tdl/tdl.h>
60
61namespace sharg::detail
62{
63
68inline auto to_tdl(bool v)
69{
70 return tdl::BoolValue(v);
71}
72
75{
76 return tdl::IntValue(v);
77}
78
81{
82 return tdl::DoubleValue(v);
83}
84
86inline auto to_tdl(std::string const & v)
87{
88 return tdl::StringValue(v);
89}
90
92auto to_tdl(auto SHARG_DOXYGEN_ONLY(v))
93{
94 return tdl::BoolValue(false);
95}
96
106{
107public:
109 enum class FileFormat
110 {
111 CTD,
112 CWL,
113 };
114
118 std::vector<std::function<void(std::string_view)>> positional_option_calls; // singled out to be printed on top
121
123 tdl::ToolInfo info;
124
126 tdl::Node::Children parameters;
127
130
146
147public:
156
157 format_tdl(format_tdl const &) = default;
158 format_tdl & operator=(format_tdl const &) = default;
159 format_tdl(format_tdl &&) = default;
161 ~format_tdl() = default;
162
166 template <typename option_type, typename validator_t>
167 void add_option(option_type & value, config<validator_t> const & config)
168 {
169 auto description = config.description;
170
172 description += ((config.required) ? std::string{} : get_default_message(value, value));
173 else
174 description += get_default_message(value, config.default_message);
175
176 if (auto const & validator_message = config.validator.get_help_page_message(); !validator_message.empty())
177 description += ". " + validator_message;
178
179 auto tags = std::set<std::string>{};
180 if (config.required)
181 {
182 tags.insert("required");
183 }
184 if (config.advanced)
185 {
186 tags.insert("advanced");
187 }
189 {
190 auto valueAsStr = to_string(value);
192 [this, config, description, valueAsStr, _tags = tags](std::string_view)
193 {
194 auto tags = _tags;
195
196 // Check if validator is a file,directory,input and/or output paremeter
197 using Validator = std::decay_t<decltype(config.validator)>;
199 {
200 tags.insert("file");
201 }
203 {
204 tags.insert("directory");
205 }
207 {
208 tags.insert("file");
209 tags.insert("output");
210 }
212 {
213 tags.insert("directory");
214 tags.insert("output");
215 }
216
217 parameters.push_back(tdl::Node{
218 .name = config.long_id,
219 .description = description,
220 .tags = std::move(tags),
221 .value = tdl::StringValue{valueAsStr},
222 });
223 info.cliMapping.emplace_back("--" + config.long_id, config.long_id);
224 },
225 config);
226 }
227 else
228 {
230 [this, config, value, description, tags](std::string_view)
231 {
232 parameters.push_back(tdl::Node{
233 .name = config.long_id,
234 .description = description,
235 .tags = std::move(tags),
236 .value = to_tdl(value),
237 });
238 info.cliMapping.emplace_back("--" + config.long_id, config.long_id);
239 },
240 config);
241 }
242 }
243
247 template <typename validator_t>
248 void add_flag(bool & value, config<validator_t> const & config)
249 {
251 [this, config, value](std::string_view)
252 {
253 parameters.push_back(tdl::Node{
254 .name = config.long_id,
255 .description = config.description,
256 .tags = {},
257 .value = to_tdl(value),
258 });
259 },
260 config);
261 }
262
266 template <typename option_type, typename validator_t>
267 void add_positional_option(option_type & value, config<validator_t> const & config)
268 {
269 // a list at the end may be empty and thus have a default value
270 auto positional_default_message = [&value]() -> std::string
271 {
273 {
274 return get_default_message(value, value);
275 }
276 else
277 {
278 (void)value; // Silence unused variable warning.
279 return {};
280 }
281 };
282
283 auto positional_validator_message = [&config]() -> std::string
284 {
285 if (auto const & validator_message = config.validator.get_help_page_message(); !validator_message.empty())
286 return ". " + validator_message;
287 else
288 return {};
289 };
290
292 [this,
293 config,
294 default_message = positional_default_message(),
295 validator_message = positional_validator_message()](std::string_view)
296 {
297 auto id = "positional_" + std::to_string(positional_option_count);
299 auto description = config.description + default_message + validator_message;
300
301 parameters.push_back(tdl::Node{.name = id, .description = description});
302
303 auto & node = parameters.back();
304
306 {
307 node.value = tdl::StringValueList{};
308 }
309 else
310 {
311 node.value = tdl::StringValue{};
312 node.tags.insert("required");
313 }
314 });
315 }
316
322 void parse(parser_meta_data & parser_meta, std::vector<std::string> const & executable_name)
323 {
324 meta = parser_meta;
325
326 // each call will evaluate the function print_list_item()
327 for (auto f : positional_option_calls)
328 f(meta.app_name);
329
330 // each call will evaluate the function print_list_item()
331 for (auto f : parser_set_up_calls)
332 f(meta.app_name);
333
334 info.metaInfo = tdl::MetaInfo{
336 .name = meta.app_name,
337 .docurl = meta.url,
338 .category = "",
339 .description = std::accumulate(begin(meta.description),
340 end(meta.description),
341 std::string{},
342 [](auto a, auto v)
343 {
344 return a + v + '\n';
345 }),
346 // .citations = {meta.citation},
347 };
348 if (!executable_name.empty())
349 {
350 info.metaInfo.executableName = executable_name[0];
351 }
352 for (size_t i{1}; i < executable_name.size(); ++i)
353 {
354 parameters = {tdl::Node{
355 .name = executable_name[executable_name.size() - i],
356 .tags = {"basecommand"},
357 .value = parameters,
358 }};
359 }
360 info.params = std::move(parameters);
361
363 {
364 std::cout << tdl::convertToCTD(info);
365 }
366 else if (fileFormat == FileFormat::CWL)
367 {
368 std::cout << tdl::convertToCWL(info) << "\n";
369 }
370 else
371 {
372 throw std::runtime_error("unsupported file format (this is a bug)");
373 }
374 std::exit(EXIT_SUCCESS); // program should not continue from here
375 }
376
380 void add_section(std::string const & SHARG_DOXYGEN_ONLY(title), bool const SHARG_DOXYGEN_ONLY(advanced_only))
381 {}
382
386 void add_subsection(std::string const & SHARG_DOXYGEN_ONLY(title), bool const SHARG_DOXYGEN_ONLY(advanced_only))
387 {}
388
392 void add_line(std::string const & SHARG_DOXYGEN_ONLY(text),
393 bool SHARG_DOXYGEN_ONLY(is_paragraph),
394 bool const SHARG_DOXYGEN_ONLY(advanced_only))
395 {}
396
400 void add_list_item(std::string const & SHARG_DOXYGEN_ONLY(key),
401 std::string const & SHARG_DOXYGEN_ONLY(desc),
402 bool const SHARG_DOXYGEN_ONLY(advanced_only))
403 {}
404
405private:
414 template <typename validator_t>
416 {
417 if (config.hidden)
418 return;
419 parser_set_up_calls.push_back(std::move(printer));
420 }
421};
422
423} // namespace sharg::detail
424
425#endif
T accumulate(T... args)
The format that contains all helper functions needed in all formats.
Definition format_base.hpp:31
static std::string get_default_message(option_type const &option, default_type const &value)
Returns the default message for the help page.
Definition format_base.hpp:197
A generalized format to create different tool description files.
Definition format_tdl.hpp:106
std::vector< std::function< void(std::string_view)> > positional_option_calls
Vector of functions that stores add_positional_option calls.
Definition format_tdl.hpp:118
FileFormat fileFormat
Targeted tool description format.
Definition format_tdl.hpp:129
unsigned positional_option_count
Keeps track of the number of positional options.
Definition format_tdl.hpp:120
void add_section(std::string const &title, bool const advanced_only)
Adds a print_section call to parser_set_up_calls.
Definition format_tdl.hpp:380
format_tdl & operator=(format_tdl const &)=default
Defaulted.
void add_subsection(std::string const &title, bool const advanced_only)
Adds a print_subsection call to parser_set_up_calls.
Definition format_tdl.hpp:386
std::vector< std::function< void(std::string_view)> > parser_set_up_calls
Vector of functions that stores all calls except add_positional_option.
Definition format_tdl.hpp:116
void add_flag(bool &value, config< validator_t > const &config)
Adds a sharg::print_list_item call to be evaluated later on.
Definition format_tdl.hpp:248
void add_option(option_type &value, config< validator_t > const &config)
Adds a sharg::print_list_item call to be evaluated later on.
Definition format_tdl.hpp:167
void add_line(std::string const &text, bool is_paragraph, bool const advanced_only)
Adds a print_line call to parser_set_up_calls.
Definition format_tdl.hpp:392
format_tdl & operator=(format_tdl &&)=default
Defaulted.
void parse(parser_meta_data &parser_meta, std::vector< std::string > const &executable_name)
Initiates the printing of the help page to std::cout.
Definition format_tdl.hpp:322
tdl::Node::Children parameters
all collected parameters
Definition format_tdl.hpp:126
tdl::ToolInfo info
TDL DS filled with tool meta information.
Definition format_tdl.hpp:123
void add_positional_option(option_type &value, config< validator_t > const &config)
Adds a sharg::print_list_item call to be evaluated later on.
Definition format_tdl.hpp:267
format_tdl(format_tdl &&)=default
Defaulted.
format_tdl(format_tdl const &)=default
Defaulted.
format_tdl(FileFormat fileFormat)
Construct from a file format.
Definition format_tdl.hpp:154
void add_list_item(std::string const &key, std::string const &desc, bool const advanced_only)
Adds a sharg::print_list_item call to parser_set_up_calls.
Definition format_tdl.hpp:400
void store_help_page_element(std::function< void(std::string_view)> printer, config< validator_t > const &config)
Adds a function object to parser_set_up_calls if the annotation in spec does not prevent it.
Definition format_tdl.hpp:415
~format_tdl()=default
Defaulted.
FileFormat
Supported tool description file formats.
Definition format_tdl.hpp:110
@ CTD
Support for CTD format.
@ CWL
Support for CWL format.
parser_meta_data meta
Stores all meta information about the application.
Definition format_tdl.hpp:145
Whether the option type is considered to be a container.
Definition detail/concept.hpp:38
T empty(T... args)
T exit(T... args)
Provides the format_base struct containing all helper functions that are needed in all formats.
Provides the format_help struct that print the help page to the command line and the two child format...
auto to_tdl(bool v)
converts a value into the corresponding tdl value type
Definition format_tdl.hpp:68
std::string to_string(value_types &&... values)
Streams all parameters via std::ostringstream and returns a concatenated string.
Definition to_string.hpp:40
T insert(T... args)
T is_same_v
T push_back(T... args)
T size(T... args)
Option struct that is passed to the sharg::parser::add_option() function.
Definition config.hpp:43
std::string description
The description to be shown on any (exported) help page.
Definition config.hpp:68
std::string long_id
The long identifier for the option (e.g. "age", making the option callable via --age).
Definition config.hpp:62
bool hidden
Whether the option should be hidden.
Definition config.hpp:117
bool advanced
Whether the option should only be displayed on the advanced help page.
Definition config.hpp:105
bool required
Whether the option is required.
Definition config.hpp:129
validator_t validator
A sharg::validator that verifies the value after parsing (callable).
Definition config.hpp:135
std::string default_message
The default message to be shown on any (exported) help page.
Definition config.hpp:87
Stores all parser related meta information of the sharg::parser.
Definition auxiliary.hpp:45
std::vector< std::string > description
A more detailed description that is displayed on the help page in the section "DESCRIPTION"....
Definition auxiliary.hpp:97
std::string app_name
The application name that will be displayed on the help page.
Definition auxiliary.hpp:51
std::string version
The version information MAJOR.MINOR.PATH (e.g. 3.1.3)
Definition auxiliary.hpp:54
std::string url
A link to your github/gitlab project with the newest release.
Definition auxiliary.hpp:71
T to_string(T... args)
Provides some standard validators for (positional) options.
Hide me