libzypp  17.25.1
HelixHelpers.h
Go to the documentation of this file.
1 /*---------------------------------------------------------------------\
2 | ____ _ __ __ ___ |
3 | |__ / \ / / . \ . \ |
4 | / / \ V /| _/ _/ |
5 | / /__ | | | | | | |
6 | /_____||_| |_| |_| |
7 | |
8 \---------------------------------------------------------------------*/
12 #ifndef ZYPP_MISC_HELIXHELPERS_H
13 #define ZYPP_MISC_HELIXHELPERS_H
14 
15 #include <zypp/AutoDispose.h>
16 #include <zypp/base/LogControl.h>
17 #include <zypp/misc/LoadTestcase.h>
18 
19 #include <libxml/parser.h>
20 #include <libxml/xmlmemory.h>
21 
22 #include <string>
23 #include <map>
24 #include <string_view>
25 #include <optional>
26 
27 
28 namespace helix::detail {
29 
30  template <typename Tp>
31  struct AutoXmlFree : public zypp::AutoDispose<Tp*>
32  {
33  AutoXmlFree( Tp* ptr_r = nullptr ) : zypp::AutoDispose<Tp*>( ptr_r, [] ( Tp* ptr_r ) { if ( ptr_r ) ::xmlFree( ptr_r ); } ) {}
34  };
35 
36  class XmlNode
37  {
38 
39  private:
40  xmlNodePtr _node;
41 
42  public:
43  XmlNode (const xmlNodePtr node) : _node(node){};
44  virtual ~XmlNode (){};
45 
46  // ---------------------------------- accessors
47 
48  std::string_view name() const { return (std::string_view((const char *)_node->name)); }
49  xmlElementType type() const { return (_node->type); }
50 
51  xmlNodePtr node() const { return (_node); }
52  std::optional<XmlNode> next() const { return (_node->next == NULL ? std::optional<XmlNode>() : XmlNode (_node->next)); }
53  std::optional<XmlNode> children() const { return (_node->xmlChildrenNode == NULL ? std::optional<XmlNode>() : XmlNode (_node->xmlChildrenNode)); }
54 
55  // ---------------------------------- methods
56 
57  bool equals (const std::string_view & n) const { return (strncasecmp ( name().data(), n.data(), n.length() ) == 0); }
58  bool isElement (void) const { return (type() == XML_ELEMENT_NODE); }
59 
60  std::map<std::string, std::string> getAllProps () const {
61  std::map<std::string, std::string> res;
62  for( xmlAttrPtr attr = _node->properties; NULL != attr; attr = attr->next ) {
63  if ( !attr->children )
64  continue;
65  AutoXmlFree<xmlChar> value( xmlNodeListGetString( _node->doc, attr->children, 1 ) );
66  res.insert( std::make_pair( std::string((char *)attr->name), std::string( (char *)value.value() ) ) );
67  }
68  return res;
69  }
70 
71  std::string getContent (void) const {
73  std::string ret;
74 
75  *buf = xmlNodeGetContent (_node);
76 
77  ret = std::string ((const char *)buf.value());
78 
79  return (ret);
80  }
81 
82  std::string getProp (const std::string & name, const std::string & deflt = "") const {
84  std::string gs;
85 
86  *ret = xmlGetProp (_node, (const xmlChar *)name.c_str());
87 
88  if (ret) {
89  gs = std::string ((const char *)ret.value());
90  return gs;
91  }
92  return deflt;
93  }
94 
95 
96  template<typename T>
97  T getValue ( const std::string & name, const T& deflt ) const;
98 
99  template<typename T>
100  bool getValue ( const std::string & name, T& target ) const;
101  };
102 
103  template<>
104  bool XmlNode::getValue ( const std::string & name, std::string& target ) const {
105  AutoXmlFree<xmlChar> xml_s;
106  xmlNode *child;
107 
108  *xml_s = xmlGetProp(_node, (const xmlChar *)name.c_str());
109  if (xml_s) {
110  target = std::string ((const char *)xml_s.value());
111  return true;
112  }
113 
114  child = _node->xmlChildrenNode;
115 
116  while (child) {
117  if (strcasecmp((const char *)(child->name), name.c_str()) == 0) {
118  xml_s = xmlNodeGetContent(child);
119  if (xml_s) {
120  target = std::string ((const char *)xml_s.value());
121  return true;
122  }
123  }
124  child = child->next;
125  }
126  return false;
127  }
128 
129  template<>
130  std::string XmlNode::getValue ( const std::string & name, const std::string& deflt ) const {
131  std::string res;
132  if ( !getValue( name, res ) )
133  return deflt;
134  return res;
135  }
136 
137  bool parseSetup ( const XmlNode &setup, zypp::misc::testcase::TestcaseSetup &target, std::string *err )
138  {
139  auto architecture = setup.getProp( "arch" );
140  if ( !architecture.empty() )
141  {
142  try {
143  target.architecture = ( zypp::Arch(architecture) );
144  }
145  catch( const zypp::Exception & excpt_r ) {
146  ZYPP_CAUGHT( excpt_r );
147  if ( err ) *err = zypp::str::Str() << "Bad architecture '" << architecture << "' in <setup...>";
148  return false;
149  }
150  }
151 
152  auto node = setup.children();
153  while ( node )
154  {
155  if ( !node->isElement() ) {
156  node = node->next();
157  continue;
158  }
159 
160 #define if_SolverFlag( N ) if ( node->equals( #N ) ) { target.N = true; }
161  if_SolverFlag( ignorealreadyrecommended ) else if ( node->equals( "ignorealready" ) ) { target.ignorealreadyrecommended = true; }
162  else if_SolverFlag( onlyRequires ) else if ( node->equals( "ignorerecommended" ) ) { target.onlyRequires = true; }
163  else if_SolverFlag( forceResolve )
164 
165  else if_SolverFlag( cleandepsOnRemove )
166 
167  else if_SolverFlag( allowDowngrade )
168  else if_SolverFlag( allowNameChange )
169  else if_SolverFlag( allowArchChange )
171 
176 #undef if_SolverFlag
177  else if ( node->equals("focus") ) {
178  target.resolverFocus = zypp::resolverFocusFromString( node->getProp("value") );
179  }
180  else if ( node->equals("system") ) {
183  "@System",
184  99,
185  node->getProp("file")
186  };
187  }
188  else if ( node->equals("hardwareInfo") ) {
189  target.hardwareInfoFile = target.globalPath / node->getProp("path");
190  }
191  else if ( node->equals("modalias") ) {
192  target.modaliasList.push_back( node->getProp("name") );
193  }
194  else if ( node->equals("multiversion") ) {
195  target.multiversionSpec.insert( node->getProp("name") );
196  }
197  else if (node->equals ("channel")) {
198  std::string name = node->getProp("name");
199  std::string file = node->getProp("file");
200  std::string type = node->getProp("type");
201 
202  unsigned prio = 99;
203  std::string priority = node->getProp("priority");
204  if ( !priority.empty() ) {
205  prio = zypp::str::strtonum<unsigned>( priority );
206  }
207 
208  target.repos.push_back( zypp::misc::testcase::RepoData{
210  name,
211  prio,
212  file
213  });
214  }
215  else if ( node->equals("source") )
216  {
217  std::string url = node->getProp("url");
218  std::string alias = node->getProp("name");
219  target.repos.push_back( zypp::misc::testcase::RepoData{
221  alias,
222  99,
223  url
224  });
225  }
226  else if ( node->equals("force-install") )
227  {
229  node->getProp("channel"),
230  node->getProp("package"),
231  node->getProp("kind")
232  });
233  }
234  else if ( node->equals("mediaid") )
235  {
236  target.show_mediaid = true;
237  }
238  else if ( node->equals("arch") ) {
239  MIL << "<arch...> deprecated, use <setup arch=\"...\"> instead" << std::endl;
240  std::string architecture = node->getProp("name");
241  if ( architecture.empty() ) {
242  ERR << "Property 'name=' in <arch.../> missing or empty" << std::endl;
243  }
244  else {
245  MIL << "Setting architecture to '" << architecture << "'" << std::endl;
246  target.architecture = zypp::Arch( architecture );
247  }
248  }
249  else if ( node->equals("locale") )
250  {
251  zypp::Locale loc( node->getProp("name") );
252  std::string fate = node->getProp("fate");
253  if ( !loc ) {
254  ERR << "Bad or missing name in <locale...>" << std::endl;
255  }
256  else if ( fate == "added" ) {
257  target.localesTracker.added().insert( loc );
258  }
259  else if ( fate == "removed" ) {
260  target.localesTracker.removed().insert( loc );
261  }
262  else {
263  target.localesTracker.current().insert( loc );
264  }
265  }
266  else if ( node->equals("autoinst") ) {
267  target.autoinstalled.push( zypp::IdString( node->getProp("name") ).id() );
268  }
269  else if ( node->equals("systemCheck") ) {
270  target.systemCheck = target.globalPath / node->getProp("path");
271  }
272  else if ( node->equals("setlicencebit") ) {
273  target.set_licence = true;
274  }
275  else {
276  ERR << "Unrecognized tag '" << node->name() << "' in setup" << std::endl;
277  }
278  node = node->next();
279  }
280  return true;
281  }
282 
284  {
285  testcaseNode.name = node.name();
286  const auto & content = node.getContent();
287  if ( !content.empty() ) {
288  testcaseNode.value = content;
289  }
290  testcaseNode.properties = node.getAllProps();
291 
292  for ( auto childNode = node.children(); childNode; childNode = childNode->next() ) {
293  auto testNode = std::make_shared<zypp::misc::testcase::TestcaseTrial::Node>();
294  if ( !parseTrialNode( *childNode, *testNode ) )
295  return false;
296  testcaseNode.children.push_back( testNode );
297  }
298  return true;
299  }
300 
301  bool parseTrial ( const XmlNode &trial, zypp::misc::testcase::TestcaseTrial &target, std::string * )
302  {
303  auto node = trial.children();
304  while (node) {
305  if (!node->isElement()) {
306  node = node->next();
307  continue;
308  }
309 
311  parseTrialNode( *node, testcaseNode );
312  target.nodes.push_back( testcaseNode );
313  node = node->next();
314  }
315  return true;
316  }
317 }
318 
319 #endif
bool parseTrialNode(const XmlNode &node, zypp::misc::testcase::TestcaseTrial::Node &testcaseNode)
Definition: HelixHelpers.h:283
std::string_view name() const
Definition: HelixHelpers.h:48
std::ostream & node(std::ostream &out_r, const std::string &name_r, Node::Attr attr_r)
Definition: Xml.h:203
#define MIL
Definition: Logger.h:79
bool parseTrial(const XmlNode &trial, zypp::misc::testcase::TestcaseTrial &target, std::string *)
Definition: HelixHelpers.h:301
std::map< std::string, std::string > properties
Definition: LoadTestcase.h:105
AutoXmlFree(Tp *ptr_r=nullptr)
Definition: HelixHelpers.h:33
std::optional< XmlNode > next() const
Definition: HelixHelpers.h:52
Architecture.
Definition: Arch.h:36
sat::SolvAttr attr
Definition: PoolQuery.cc:311
xmlElementType type() const
Definition: HelixHelpers.h:49
std::vector< RepoData > repos
Definition: LoadTestcase.h:59
Access to the sat-pools string space.
Definition: IdString.h:42
Url url
Definition: MediaCurl.cc:66
std::set< std::string > multiversionSpec
Definition: LoadTestcase.h:71
#define ERR
Definition: Logger.h:81
std::optional< RepoData > systemRepo
Definition: LoadTestcase.h:58
const set_type & removed() const
Return the set of removed items.
Definition: SetTracker.h:145
void push(value_type val_r)
Push a value to the end off the Queue.
Definition: Queue.cc:103
Convenient building of std::string via std::ostringstream Basically a std::ostringstream autoconverti...
Definition: String.h:208
std::vector< ForceInstall > forceInstallTasks
Definition: LoadTestcase.h:72
#define if_SolverFlag(N)
const set_type & current() const
Return the current set.
Definition: SetTracker.h:139
bool parseSetup(const XmlNode &setup, zypp::misc::testcase::TestcaseSetup &target, std::string *err)
Definition: HelixHelpers.h:137
xmlNodePtr node() const
Definition: HelixHelpers.h:51
std::vector< std::shared_ptr< Node > > children
Definition: LoadTestcase.h:106
const set_type & added() const
Return the set of added items.
Definition: SetTracker.h:142
std::string getProp(const std::string &name, const std::string &deflt="") const
Definition: HelixHelpers.h:82
AutoDispose()
Default Ctor using default constructed value and no dispose function.
Definition: AutoDispose.h:107
base::SetTracker< LocaleSet > localesTracker
Definition: LoadTestcase.h:69
&#39;Language[_Country]&#39; codes.
Definition: Locale.h:49
#define ZYPP_CAUGHT(EXCPT)
Drops a logline telling the Exception was caught (in order to handle it).
Definition: Exception.h:396
Base class for Exception.
Definition: Exception.h:145
reference value() const
Reference to the Tp object.
Definition: AutoDispose.h:133
std::optional< XmlNode > children() const
Definition: HelixHelpers.h:53
bool equals(const std::string_view &n) const
Definition: HelixHelpers.h:57
std::map< std::string, std::string > getAllProps() const
Definition: HelixHelpers.h:60
Reference counted access to a Tp object calling a custom Dispose function when the last AutoDispose h...
Definition: AutoDispose.h:92
T getValue(const std::string &name, const T &deflt) const
target::Modalias::ModaliasList modaliasList
Definition: LoadTestcase.h:68
bool isElement(void) const
Definition: HelixHelpers.h:58
Easy-to use interface to the ZYPP dependency resolver.
Definition: CodePitfalls.doc:1
std::string getContent(void) const
Definition: HelixHelpers.h:71
XmlNode(const xmlNodePtr node)
Definition: HelixHelpers.h:43