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 <import.hpp>
10 :
11 : #include <cmdline.hpp>
12 : #include <kdb.hpp>
13 : #include <keysetio.hpp>
14 : #include <modules.hpp>
15 : #include <toolexcept.hpp>
16 :
17 : #include <iostream>
18 :
19 : #include <mergehelper.hpp>
20 : #include <merging/metamergestrategy.hpp>
21 : #include <merging/threewaymerge.hpp>
22 :
23 : using namespace std;
24 : using namespace kdb;
25 : using namespace kdb::tools;
26 : using namespace kdb::tools::merging;
27 :
28 165 : ImportCommand::ImportCommand ()
29 : {
30 165 : }
31 :
32 87 : int ImportCommand::execute (Cmdline const & cl)
33 : {
34 174 : size_t argc = cl.arguments.size ();
35 87 : if (argc != 1 && argc != 2 && argc != 3)
36 : {
37 0 : throw invalid_argument ("need 1 to 3 arguments");
38 : }
39 :
40 167 : Key root = cl.createKey (0);
41 80 : if (!root.isValid ())
42 : {
43 0 : throw invalid_argument ("root key \"" + cl.arguments[0] + "\" is not a valid key name");
44 : }
45 :
46 160 : KeySet originalKeys;
47 80 : kdb.get (originalKeys, root);
48 80 : printWarnings (cerr, root, cl.verbose, cl.debug);
49 :
50 240 : string format = cl.format;
51 159 : if (argc > 1) format = cl.arguments[1];
52 :
53 320 : string file = "/dev/stdin";
54 80 : if (argc > 2 && cl.arguments[2] != "-") file = cl.arguments[2];
55 :
56 160 : Modules modules;
57 480 : PluginPtr plugin = modules.load (format, cl.getPluginsConfig ());
58 :
59 160 : Key errorKey (root);
60 240 : errorKey.setString (file);
61 :
62 160 : KeySet importedKeys;
63 80 : plugin->get (importedKeys, errorKey);
64 :
65 80 : printWarnings (cerr, errorKey, cl.verbose, cl.debug);
66 80 : printError (cerr, errorKey, cl.verbose, cl.debug);
67 :
68 160 : if (cl.strategy == "validate")
69 : {
70 0 : KeySet toset = prependNamespace (importedKeys, cl.ns);
71 0 : originalKeys.cut (prependNamespace (root, cl.ns));
72 0 : originalKeys.append (toset);
73 :
74 0 : PluginPtr specPlugin = modules.load ("spec", cl.getPluginsConfig ());
75 0 : if (specPlugin->get (originalKeys, root) == -1)
76 : {
77 0 : printWarnings (cerr, root, cl.verbose, cl.debug);
78 0 : printError (cerr, errorKey, cl.verbose, cl.debug);
79 : return -1;
80 : }
81 :
82 0 : if (cl.verbose)
83 : {
84 0 : cout.setf (std::ios_base::showbase);
85 0 : std::cout << originalKeys << std::endl;
86 : }
87 :
88 0 : kdb.set (originalKeys, root);
89 0 : printWarnings (cerr, root, cl.verbose, cl.debug);
90 : return 0;
91 : }
92 :
93 240 : KeySet base = originalKeys.cut (root);
94 400 : importedKeys = importedKeys.cut (root);
95 80 : if (cl.withoutElektra)
96 : {
97 0 : KeySet baseCopy = base.dup ();
98 0 : Key systemElektra ("system/elektra", KEY_END);
99 0 : KeySet systemKeySet = baseCopy.cut (systemElektra);
100 0 : importedKeys.append (systemKeySet);
101 : }
102 :
103 160 : ThreeWayMerge merger;
104 160 : MergeHelper helper;
105 :
106 80 : helper.configureMerger (cl, merger);
107 : MergeResult result = merger.mergeKeySet (
108 560 : MergeTask (BaseMergeKeys (base, root), OurMergeKeys (base, root), TheirMergeKeys (importedKeys, root), root));
109 :
110 80 : helper.reportResult (cl, result, cout, cerr);
111 :
112 80 : int ret = -1;
113 80 : if (!result.hasConflicts ())
114 : {
115 80 : if (cl.verbose)
116 : {
117 0 : cout << "The merged keyset with strategy " << cl.strategy << " is:" << endl;
118 0 : cout << result.getMergedKeys ();
119 : }
120 :
121 160 : KeySet resultKeys = result.getMergedKeys ();
122 80 : originalKeys.append (resultKeys);
123 80 : kdb.set (originalKeys, root);
124 80 : ret = 0;
125 :
126 80 : printWarnings (cerr, root, cl.verbose, cl.debug);
127 80 : printError (cerr, root, cl.verbose, cl.debug);
128 : }
129 :
130 80 : return ret;
131 : }
132 :
133 330 : ImportCommand::~ImportCommand ()
134 : {
135 7329 : }
|