Imported Upstream version 16.3.2
[platform/upstream/libzypp.git] / zypp / solver / detail / SystemCheck.cc
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file       zypp/solver/detail/SystemCheck.cc
10  *
11 */
12 #include <iostream>
13 #include <fstream>
14 #include <vector>
15
16 #define ZYPP_USE_RESOLVER_INTERNALS
17
18 #include "zypp/base/LogTools.h"
19 #include "zypp/base/IOStream.h"
20 #include "zypp/base/String.h"
21
22 #include "zypp/ZYppFactory.h"
23 #include "zypp/ZConfig.h"
24 #include "zypp/Pathname.h"
25 #include "zypp/PathInfo.h"
26 #include "zypp/solver/detail/SystemCheck.h"
27
28 using namespace std;
29
30 ///////////////////////////////////////////////////////////////////
31 namespace zypp
32 { /////////////////////////////////////////////////////////////////
33
34     Pathname            _file = "";
35     Pathname            _dir = "";
36     CapabilitySet       _require;
37     CapabilitySet       _conflict;
38
39     typedef vector<string> CapList;
40
41     const SystemCheck & SystemCheck::instance()
42     {
43         static SystemCheck _val;
44         return _val;
45     }
46
47
48   SystemCheck::SystemCheck() {
49         if (_file.empty()) {
50             _file = ZConfig::instance().solver_checkSystemFile();
51             loadFile(_file);
52         }
53         if (_dir.empty()) {
54           _dir = ZConfig::instance().solver_checkSystemFileDir();
55           loadFiles();
56         }
57     }
58
59     bool SystemCheck::setFile(const Pathname & file) const{
60         MIL << "Setting checkFile to : " << file << endl;
61         _file = file;
62         loadFile(_file);
63         return true;
64     }
65
66     bool SystemCheck::setDir(const Pathname & dir) const {
67       MIL << "Setting checkFile directory to : " << dir << endl;
68       loadFile(_file);
69       _dir = dir;
70       loadFiles();
71       return true;
72     }
73
74     const Pathname & SystemCheck::file() {
75         return _file;
76     }
77
78     const Pathname & SystemCheck::dir() {
79         return _dir;
80     }
81
82     const CapabilitySet & SystemCheck::requiredSystemCap() const{
83         return _require;
84     }
85
86     const CapabilitySet & SystemCheck::conflictSystemCap() const{
87         return _conflict;
88     }
89
90     bool SystemCheck::loadFile(Pathname & file, bool reset_caps) const{
91         Target_Ptr trg( getZYpp()->getTarget() );
92         if ( trg )
93           file = trg->assertRootPrefix( file );
94
95         PathInfo pi( file );
96         if ( ! pi.isFile() ) {
97             WAR << "Can't read " << file << " " << pi << endl;
98             return false;
99         }
100
101         if (reset_caps) {
102           _require.clear();
103           _conflict.clear();
104         }
105
106         std::ifstream infile( file.c_str() );
107         for( iostr::EachLine in( infile ); in; in.next() ) {
108             std::string l( str::trim(*in) );
109             if ( ! l.empty() && l[0] != '#' )
110             {
111                 CapList capList;
112                 str::split( l, back_inserter(capList), ":" );
113                 if (capList.size() == 2 ) {
114                     CapList::iterator it = capList.begin();
115                     if (*it == "requires") {
116                         _require.insert(Capability(*(it+1)));
117                     } else if (*it == "conflicts") {
118                         _conflict.insert(Capability(*(it+1)));
119                     } else {
120                         ERR << "Wrong parameter: " << l << endl;
121                     }
122                 } else {
123                     ERR << "Wrong line: " << l << endl;
124                 }
125             }
126         }
127         MIL << "Read " << pi << endl;
128         return true;
129     }
130
131   bool SystemCheck::loadFiles() const {
132
133     filesystem::dirForEach(_dir,
134                            [this](const Pathname & dir_r, const char *const & name_r)->bool
135                            {
136                              const std::string wanted = ".check";
137                              Pathname pth = dir_r/name_r;
138                              if (pth.extension() != wanted) {
139                                MIL << "Skipping " << pth << " (not a *.check file)" << endl;
140                                return true;
141                              }
142                              else {
143                                MIL << "Reading " << pth << endl;
144                                return loadFile(pth, false /* do not reset caps */);
145                              }
146                            });
147     return true;
148   }
149
150
151     /******************************************************************
152     **
153     **  FUNCTION NAME : operator<<
154     **  FUNCTION TYPE : std::ostream &
155     */
156     std::ostream & operator<<( std::ostream & str, const SystemCheck & obj )
157     {
158       str << _file << endl;
159       str << "requires" << endl;
160       for (CapabilitySet::const_iterator it = _require.begin(); it != _require.end(); ++it)
161           str << "  " << *it << endl;
162
163       str << "conflicts" << endl;
164       for (CapabilitySet::const_iterator it = _conflict.begin(); it != _conflict.end(); ++it)
165           str << "  " << *it << endl;
166
167       return str;
168     }
169
170   /////////////////////////////////////////////////////////////////
171 } // namespace zypp
172 ///////////////////////////////////////////////////////////////////