libzypp  17.24.2
VendorAttr.cc
Go to the documentation of this file.
1 /*---------------------------------------------------------------------\
2 | ____ _ __ __ ___ |
3 | |__ / \ / / . \ . \ |
4 | / / \ V /| _/ _/ |
5 | / /__ | | | | | | |
6 | /_____||_| |_| |_| |
7 | |
8 \---------------------------------------------------------------------*/
11 #include <iostream>
12 #include <fstream>
13 #include <set>
14 #include <map>
15 #include <vector>
16 
17 #include <zypp/base/LogTools.h>
18 #include <zypp/base/IOStream.h>
19 #include <zypp/base/StringV.h>
20 
21 #include <zypp/PathInfo.h>
22 #include <zypp/VendorAttr.h>
23 #include <zypp/ZYppFactory.h>
24 
25 #include <zypp/ZConfig.h>
26 #include <zypp/PathInfo.h>
27 #include <zypp/parser/IniDict.h>
28 
29 #undef ZYPP_BASE_LOGGER_LOGGROUP
30 #define ZYPP_BASE_LOGGER_LOGGROUP "zypp::VendorAttr"
31 
33 namespace zypp
34 {
35 
40  class VendorAttr::Impl // : private base::NonCopyable
41  {
42  friend std::ostream & operator<<( std::ostream & str, const Impl & obj );
43  public:
48  void legacySetup()
49  {
50  if ( _vendorMap.find("suse") == _vendorMap.end() )
51  _vendorMap["suse"] = ++vendorGroupCounter;
52 
53  if ( _vendorMap.find("opensuse") == _vendorMap.end() )
54  _vendorMap["opensuse"] = ++vendorGroupCounter;
55  }
56 
57  public:
59  void addVendorList( VendorList && vendorList_r );
60 
62  bool equivalent( IdString lVendor, IdString rVendor ) const
63  { return lVendor == rVendor || vendorMatchId( lVendor ) == vendorMatchId( rVendor ); }
64 
65  private:
66  using VendorMap = std::map<std::string,unsigned>;
68  unsigned vendorGroupCounter = 1;
69 
70  private:
72  typedef std::unordered_map<IdString, VendorMatchEntry> VendorMatch;
73  mutable int _nextId = -1;
75 
78  {
79  _nextId = -1;
80  _vendorMatch.clear();
81  }
82 
91  unsigned vendorMatchId( IdString vendor ) const;
92 
93  private:
94  friend Impl * rwcowClone<Impl>( const Impl * rhs );
96  Impl * clone() const
97  { return new Impl( *this ); }
98  };
99 
100  unsigned VendorAttr::Impl::vendorMatchId( IdString vendor ) const
101  {
102  VendorMatchEntry & ent( _vendorMatch[vendor] );
103  if ( ! ent )
104  {
105  IdString lcvendor( str::toLower( vendor.asString() ) );
106  VendorMatchEntry & lcent( _vendorMatch[lcvendor] );
107  if ( ! lcent )
108  {
109  unsigned myid = 0;
110  // bnc#812608: no pefix compare in opensuse namespace
111  static const IdString openSUSE( "opensuse" );
112  if ( lcvendor == openSUSE || ! str::hasPrefix( lcvendor.c_str(), openSUSE.c_str() ) )
113  {
114  // Compare this entry with the global vendor map.
115  // Reversed to get the longest prefix.
116  for ( VendorMap::reverse_iterator it = _vendorMap.rbegin(); it != _vendorMap.rend(); ++it )
117  {
118  if ( str::hasPrefix( lcvendor.c_str(), it->first ) )
119  {
120  myid = it->second;
121  break; // found
122  }
123  }
124  }
125  if ( ! myid )
126  {
127  myid = --_nextId; // get a new class ID
128  }
129  ent = lcent = myid; // remember the new DI
130  }
131  else
132  {
133  ent = lcent; // take the ID from the lowercased vendor string
134  }
135  }
136  return ent;
137  }
138 
140  {
141 #warning REIMPLEMENT
142  std::vector<std::string> vendorList_r;
143  for ( const auto & el : vendorList_rr ) {
144  vendorList_r.push_back( el.asString() );
145  }
146 
147  unsigned int nextId = vendorGroupCounter + 1;
148  // convert to lowercase and check if a vendor is already defined
149  // in an existing group.
150 
151  for_( it, vendorList_r.begin(), vendorList_r.end() )
152  {
153  *it = str::toLower( *it );
154  if (_vendorMap.find(*it) != _vendorMap.end())
155  {
156  if (nextId != vendorGroupCounter + 1 &&
157  nextId != _vendorMap[*it])
158  {
159  // We have at least 3 groups which has to be mixed --> mix the third group to the first
160  unsigned int moveID = _vendorMap[*it];
161  for_( itMap, _vendorMap.begin(), _vendorMap.end() )
162  {
163  if (itMap->second == moveID)
164  itMap->second = nextId;
165  }
166  }
167  else
168  {
169  nextId = _vendorMap[*it];
170  WAR << "Vendor " << *it << " is already used in another vendor group. --> mixing these groups" << endl;
171  }
172  }
173  }
174  // add new entries
175  for_( it, vendorList_r.begin(), vendorList_r.end() )
176  {
177  _vendorMap[*it] = nextId;
178  }
179 
180  if (nextId == vendorGroupCounter + 1)
181  ++vendorGroupCounter;
182 
183  // invalidate any match cache
184  vendorMatchIdReset();
185  }
186 
188  inline std::ostream & operator<<( std::ostream & str, const VendorAttr::Impl & obj )
189  {
190  str << "Equivalent vendors:";
191  for( const auto & p : obj._vendorMap ) {
192  str << endl << " [" << p.second << "] " << p.first;
193  }
194  return str;
195  }
196 
198  //
199  // CLASS NAME : VendorAttr
200  //
202 
204  {
205  Target_Ptr trg { getZYpp()->getTarget() };
206  return trg ? trg->vendorAttr() : noTargetInstance();
207  }
208 
210  {
211  static VendorAttr _val { ZConfig::instance().vendorPath() };
212  return _val;
213  }
214 
216  : _pimpl( new Impl )
217  {
218  _pimpl->legacySetup();
219  MIL << "Initial: " << *this << endl;
220  }
221 
222  VendorAttr::VendorAttr( const Pathname & initial_r )
223  : _pimpl( new Impl )
224  {
225  addVendorDirectory( initial_r );
226  _pimpl->legacySetup();
227  MIL << "Initial " << initial_r << ": " << *this << endl;
228  }
229 
231  {}
232 
233  bool VendorAttr::addVendorDirectory( const Pathname & dirname_r )
234  {
235  if ( PathInfo pi { dirname_r }; ! pi.isDir() ) {
236  MIL << "Not a directory " << pi << endl;
237  return false;
238  }
239 
241  [this]( const Pathname & dir_r, const std::string & str_r )->bool
242  {
243  this->addVendorFile( dir_r/str_r );
244  return true;
245  }
246  );
247  return true;
248  }
249 
250  bool VendorAttr::addVendorFile( const Pathname & filename_r )
251  {
252  if ( PathInfo pi { filename_r }; ! pi.isFile() ) {
253  MIL << "Not a file " << pi << endl;
254  return false;
255  }
256 
257  parser::IniDict dict { InputStream(filename_r) };
258  for ( const auto & el : dict.entries("main") )
259  {
260  if ( el.first == "vendors" )
261  {
262  VendorList tmp;
263  strv::split( el.second, ",", strv::Trim::trim,
264  [&tmp]( std::string_view word ) {
265  if ( ! word.empty() )
266  tmp.push_back( IdString( word ) );
267  } );
268  _addVendorList( std::move(tmp) );
269  break;
270  }
271  }
272  return true;
273  }
274 
275  void VendorAttr::_addVendorList( VendorList && vendorList_r )
276  { _pimpl->addVendorList( std::move(vendorList_r) ); }
277 
278 #if LEGACY(1722)
279  bool VendorAttr::addVendorDirectory( const Pathname & dirname ) const
280  { return const_cast<VendorAttr*>(this)->addVendorDirectory( dirname ); }
281 
282  bool VendorAttr::addVendorFile( const Pathname & filename ) const
283  { return const_cast<VendorAttr*>(this)->addVendorFile( filename ); }
284 
285  void VendorAttr::_addVendorList( std::vector<std::string> & vendorList_r ) const
286  { return const_cast<VendorAttr*>(this)->_addVendorList( VendorList( vendorList_r.begin(), vendorList_r.end() ) ); }
287 #endif
288  // vendor equivalence:
291 
292  bool VendorAttr::equivalent( IdString lVendor, IdString rVendor ) const
293  { return _pimpl->equivalent( lVendor, rVendor );}
294 
295  bool VendorAttr::equivalent( const Vendor & lVendor, const Vendor & rVendor ) const
296  { return _pimpl->equivalent( IdString( lVendor ), IdString( rVendor ) ); }
297 
298  bool VendorAttr::equivalent( sat::Solvable lVendor, sat::Solvable rVendor ) const
299  { return _pimpl->equivalent( lVendor.vendor(), rVendor.vendor() ); }
300 
301  bool VendorAttr::equivalent( const PoolItem & lVendor, const PoolItem & rVendor ) const
302  { return _pimpl->equivalent( lVendor.satSolvable().vendor(), rVendor.satSolvable().vendor() ); }
303 
305 
306  std::ostream & operator<<( std::ostream & str, const VendorAttr & obj )
307  { return str << *obj._pimpl; }
308 
310 } // namespace zypp
312 
zypp::VendorAttr::_pimpl
RWCOW_pointer< Impl > _pimpl
Pointer to implementation.
Definition: VendorAttr.h:118
zypp::VendorAttr::Impl::vendorGroupCounter
unsigned vendorGroupCounter
Definition: VendorAttr.cc:68
zypp::PoolItem
Combining sat::Solvable and ResStatus.
Definition: PoolItem.h:51
zypp::Vendor
std::string Vendor
Definition: Vendor.h:22
zypp::filesystem::matchNoDots
const StrMatcher & matchNoDots()
Convenience returning StrMatcher( "[^.]*", Match::GLOB )
Definition: PathInfo.cc:536
PathInfo.h
zypp::sat::Solvable
A Solvable object within the sat Pool.
Definition: Solvable.h:54
zypp::VendorAttr::VendorList
std::vector< IdString > VendorList
Implementation class.
Definition: VendorAttr.h:115
ZYppFactory.h
zypp::VendorAttr::equivalent
bool equivalent(const Vendor &lVendor, const Vendor &rVendor) const
Return whether two vendor strings should be treated as the same vendor.
Definition: VendorAttr.cc:295
zypp::VendorAttr::Impl::vendorMatchId
unsigned vendorMatchId(IdString vendor) const
Helper mapping vendor string to eqivalence class ID.
Definition: VendorAttr.cc:100
zypp::VendorAttr::Impl::_vendorMatch
VendorMatch _vendorMatch
Definition: VendorAttr.cc:74
zypp::sat::SolvableType::satSolvable
Solvable satSolvable() const
Return the corresponding sat::Solvable.
Definition: SolvableType.h:57
zypp::IdString::c_str
const char * c_str() const
Conversion to const char *
Definition: IdString.cc:50
zypp::VendorAttr::Impl::operator<<
std::ostream & operator<<(std::ostream &str, const VendorAttr::Impl &obj)
Definition: VendorAttr.cc:188
zypp::VendorAttr::Impl::legacySetup
void legacySetup()
bsc#1030686: The legacy default equivalence of 'suse' and 'opensuse' has been removed.
Definition: VendorAttr.cc:48
zypp::VendorAttr::addVendorDirectory
bool addVendorDirectory(const Pathname &dirname_r)
Adding new equivalent vendors described in a directory.
Definition: VendorAttr.cc:233
ZConfig.h
MIL
#define MIL
Definition: Logger.h:79
zypp::ZConfig::vendorPath
Pathname vendorPath() const
Directory for equivalent vendor definitions (configPath()/vendors.d)
Definition: ZConfig.cc:996
zypp::VendorAttr::Impl::_vendorMap
VendorMap _vendorMap
Definition: VendorAttr.cc:67
zypp::VendorAttr
Definition of vendor equivalence.
Definition: VendorAttr.h:47
IOStream.h
zypp::parser::IniDict
Parses a INI file and offers its structure as a dictionary.
Definition: IniDict.h:42
zypp::IdString
Access to the sat-pools string space.
Definition: IdString.h:43
zypp::VendorAttr::Impl::clone
Impl * clone() const
clone for RWCOW_pointer
Definition: VendorAttr.cc:96
LogTools.h
zypp::filesystem::PathInfo
Wrapper class for ::stat/::lstat.
Definition: PathInfo.h:221
zypp::strv::split
unsigned split(std::string_view line_r, std::string_view sep_r, Trim trim_r, std::function< void(std::string_view)> fnc_r)
Definition: StringV.cc:20
zypp::VendorAttr::Impl::equivalent
bool equivalent(IdString lVendor, IdString rVendor) const
Return whether two vendor strings should be treated as equivalent.
Definition: VendorAttr.cc:62
WAR
#define WAR
Definition: Logger.h:80
zypp::VendorAttr::addVendorFile
bool addVendorFile(const Pathname &filename_r)
Adding new equivalent vendors described in a file.
Definition: VendorAttr.cc:250
zypp::ZConfig::instance
static ZConfig & instance()
Singleton ctor.
Definition: Resolver.cc:126
zypp::InputStream
Helper to create and pass std::istream.
Definition: InputStream.h:57
zypp
Easy-to use interface to the ZYPP dependency resolver.
Definition: CodePitfalls.doc:2
zypp::str::toLower
std::string toLower(const std::string &s)
Return lowercase version of s.
Definition: String.cc:177
zypp::VendorAttr::Impl::VendorMap
std::map< std::string, unsigned > VendorMap
Definition: VendorAttr.cc:66
zypp::VendorAttr::Impl::vendorMatchIdReset
void vendorMatchIdReset()
Reset match cache if global VendorMap was changed.
Definition: VendorAttr.cc:77
zypp::VendorAttr::_addVendorList
void _addVendorList(VendorList &&list_r)
Definition: VendorAttr.cc:275
zypp::VendorAttr::Impl::operator<<
friend std::ostream & operator<<(std::ostream &str, const Impl &obj)
zypp::DefaultIntegral< int, 0 >
zypp::VendorAttr::Impl::VendorMatch
std::unordered_map< IdString, VendorMatchEntry > VendorMatch
Definition: VendorAttr.cc:72
zypp::operator<<
std::ostream & operator<<(std::ostream &str, const Exception &obj)
Definition: Exception.cc:147
for_
#define for_(IT, BEG, END)
Convenient for-loops using iterator.
Definition: Easy.h:28
IniDict.h
Target_Ptr
zypp::filesystem::Pathname
Pathname.
Definition: Pathname.h:45
VendorAttr.h
zypp::VendorAttr::instance
static const VendorAttr & instance()
(Pseudo)Singleton, mapped to the current Target::vendorAttr settings or to noTargetInstance.
Definition: VendorAttr.cc:203
zypp::VendorAttr::Impl
VendorAttr implementation.
Definition: VendorAttr.cc:41
zypp::VendorAttr::~VendorAttr
~VendorAttr()
Dtor.
Definition: VendorAttr.cc:230
str
String related utilities and Regular expression matching.
zypp::str::hasPrefix
bool hasPrefix(const C_Str &str_r, const C_Str &prefix_r)
Return whether str_r has prefix prefix_r.
Definition: String.h:1023
zypp::str::trim
std::string trim(const std::string &s, const Trim trim_r)
Definition: String.cc:223
zypp::VendorAttr::Impl::addVendorList
void addVendorList(VendorList &&vendorList_r)
Add a new equivalent vendor set.
Definition: VendorAttr.cc:139
zypp::filesystem::dirForEach
int dirForEach(const Pathname &dir_r, function< bool(const Pathname &, const char *const)> fnc_r)
Invoke callback function fnc_r for each entry in directory dir_r.
Definition: PathInfo.cc:542
zypp::VendorAttr::Impl::VendorMatchEntry
DefaultIntegral< int, 0 > VendorMatchEntry
Definition: VendorAttr.cc:71
zypp::VendorAttr::noTargetInstance
static VendorAttr & noTargetInstance()
Singleton, settings used if no Target is active.
Definition: VendorAttr.cc:209
StringV.h
zypp::VendorAttr::Impl::_nextId
int _nextId
Definition: VendorAttr.cc:73
zypp::sat::Solvable::vendor
IdString vendor() const
The vendor.
Definition: Solvable.cc:356
zypp::VendorAttr::VendorAttr
VendorAttr()
Ctor providing the default set.
Definition: VendorAttr.cc:215