Line data Source code
1 : /**
2 : * @file
3 : *
4 : * @brief
5 : *
6 : * @copyright BSD License (see LICENSE.md or https://www.libelektra.org)
7 : */
8 :
9 : #include <gen.hpp>
10 :
11 : #include "gen/template.hpp"
12 : #include <cmdline.hpp>
13 : #include <kdb.hpp>
14 :
15 : #include <fstream>
16 : #include <kdbplugin.h>
17 : #include <modules.hpp>
18 :
19 : using namespace kdb;
20 : using namespace kdb::tools;
21 : using namespace std;
22 :
23 9 : int GenCommand::execute (Cmdline const & cl)
24 : {
25 18 : if (cl.arguments.size () < 3)
26 : {
27 0 : throw invalid_argument ("need at least 3 arguments");
28 : }
29 :
30 27 : auto templateName = cl.arguments[0];
31 27 : auto parentKey = cl.arguments[1];
32 27 : auto outputName = cl.arguments[2];
33 :
34 18 : std::unordered_map<std::string, std::string> parameters;
35 18 : if (cl.arguments.size () > 3)
36 : {
37 8 : std::transform (cl.arguments.begin () + 3, cl.arguments.end (), std::inserter (parameters, parameters.end ()),
38 4 : [](const std::string & param) {
39 4 : auto search = param.find ('=');
40 4 : if (search == std::string::npos)
41 : {
42 0 : throw invalid_argument ("parameters have to be of format name=value");
43 : }
44 :
45 32 : return std::make_pair (std::string (param.begin (), param.begin () + search),
46 40 : std::string (param.begin () + search + 1, param.end ()));
47 16 : });
48 : }
49 :
50 9 : const auto & templates = GenTemplateList::getInstance ();
51 9 : const auto tmpl = templates.getTemplate (templateName, parameters);
52 :
53 9 : if (tmpl->isEmpty ())
54 : {
55 : // empty template -> correct one not found
56 0 : throw invalid_argument ("couldn't find template '" + templateName + "'");
57 : }
58 :
59 9 : if (parentKey == "-")
60 : {
61 0 : for (const auto & part : tmpl->getParts ())
62 : {
63 0 : std::cout << outputName + part << std::endl;
64 : }
65 : return 0;
66 : }
67 :
68 10 : KeySet ks;
69 :
70 18 : if (cl.inputFile.empty ())
71 : {
72 27 : Key getKey (parentKey, KEY_END);
73 :
74 18 : KDB kdb;
75 9 : kdb.get (ks, getKey);
76 :
77 9 : printWarnings (cerr, getKey, cl.verbose, cl.debug);
78 9 : printError (cerr, getKey, cl.verbose, cl.debug);
79 :
80 36 : if (getKey.hasMeta ("error"))
81 : {
82 0 : throw CommandAbortException ("Error loading from KDB");
83 : }
84 : }
85 : else
86 : {
87 0 : auto pos = cl.inputFile.find ('=');
88 0 : if (pos == std::string::npos)
89 : {
90 0 : throw invalid_argument ("-F/--input-file argument must be given as <plugin>=<file>");
91 : }
92 :
93 0 : std::string pluginName (cl.inputFile.begin (), cl.inputFile.begin () + pos);
94 0 : std::string file (cl.inputFile.begin () + pos + 1, cl.inputFile.end ());
95 :
96 0 : Modules modules;
97 0 : PluginPtr plugin = modules.load (pluginName, cl.getPluginsConfig ());
98 :
99 0 : if (plugin == nullptr)
100 : {
101 0 : throw invalid_argument ("plugin '" + pluginName + "' given to -F/--input-file could not be loaded");
102 : }
103 :
104 0 : Key getKey (parentKey, KEY_VALUE, file.c_str (), KEY_END);
105 0 : if (plugin->get (ks, getKey) == ELEKTRA_PLUGIN_STATUS_ERROR)
106 : {
107 0 : printWarnings (cerr, getKey, cl.verbose, cl.debug);
108 0 : printError (cerr, getKey, cl.verbose, cl.debug);
109 0 : throw invalid_argument ("file '" + file + "' given to -F/--input-file could not be loaded with plugin '" +
110 0 : pluginName + "'");
111 : }
112 : }
113 :
114 45 : auto inputKs = ks.cut (Key (parentKey, KEY_END));
115 :
116 62 : for (const auto & part : tmpl->getParts ())
117 : {
118 80 : std::ofstream output (outputName + part);
119 27 : tmpl->render (output, outputName, part, inputKs, parentKey);
120 : }
121 :
122 8 : return 0;
123 7164 : }
|