libzypp 17.37.17
RepoFileReader.cc
Go to the documentation of this file.
1/*---------------------------------------------------------------------\
2| ____ _ __ __ ___ |
3| |__ / \ / / . \ . \ |
4| / / \ V /| _/ _/ |
5| / /__ | | | | | | |
6| /_____||_| |_| |_| |
7| |
8\---------------------------------------------------------------------*/
12#include <iostream>
13#include <zypp/base/LogTools.h>
14#include <zypp/base/String.h>
15#include <zypp/base/StringV.h>
16#include <utility>
17#include <zypp-core/base/InputStream>
18#include <zypp-core/base/UserRequestException>
19
20#include <zypp-core/parser/IniDict>
22
23using std::endl;
24
26namespace zypp
27{
29 namespace parser
30 {
32 namespace {
33
38 class RepoFileParser : public IniDict
39 {
40 public:
41 RepoFileParser( const InputStream & is_r )
42 { read( is_r ); }
43
44 using IniDict::consume; // don't hide overloads we don't redefine here
45
46 void consume( const std::string & section_r, const std::string & key_r, const std::string & value_r ) override
47 {
48 if ( key_r == "baseurl" )
49 {
50 _inMultiline = MultiLine::baseurl;
51 storeUrl( _baseurls[section_r], value_r );
52 }
53 else if ( key_r == "gpgkey" )
54 {
55 _inMultiline = MultiLine::gpgkey;
56 storeUrl( _gpgkeys[section_r], value_r );
57 }
58 else if ( key_r == "mirrorlist" )
59 {
60 _inMultiline = MultiLine::mirrorlist;
61 storeUrl( _mirrorlist[section_r], value_r );
62 }
63 else if ( key_r == "metalink" )
64 {
65 _inMultiline = MultiLine::metalink;
66 storeUrl( _metalink[section_r], value_r );
67 }
68 else
69 {
70 _inMultiline = MultiLine::none;
71 IniDict::consume( section_r, key_r, value_r );
72 }
73 }
74
75 void garbageLine( const std::string & section_r, const std::string & line_r ) override
76 {
77 switch ( _inMultiline )
78 {
79 case MultiLine::baseurl:
80 storeUrl( _baseurls[section_r], line_r );
81 break;
82
83 case MultiLine::gpgkey:
84 storeUrl( _gpgkeys[section_r], line_r );
85 break;
86
87 case MultiLine::mirrorlist:
88 storeUrl( _mirrorlist[section_r], line_r );
89 break;
90
91 case MultiLine::metalink:
92 storeUrl( _metalink[section_r], line_r );
93 break;
94
95 case MultiLine::none:
96 IniDict::garbageLine( section_r, line_r ); // throw
97 break;
98 }
99 }
100
101 std::list<Url> & baseurls( const std::string & section_r )
102 { return _baseurls[section_r]; }
103
104 std::list<Url> & gpgkeys( const std::string & section_r )
105 { return _gpgkeys[section_r]; }
106
107 std::list<Url> & mirrorlist( const std::string & section_r )
108 { return _mirrorlist[section_r]; }
109
110 std::list<Url> & metalink( const std::string & section_r )
111 { return _metalink[section_r]; }
112
113 private:
114 void storeUrl( std::list<Url> & store_r, const std::string & line_r )
115 {
116 // #285: Fedora/dnf allows WS separated urls (and an optional comma)
117 strv::splitRx( line_r, "[,[:blank:]]*[[:blank:]][,[:blank:]]*", [&store_r]( std::string_view w ) {
118 if ( ! w.empty() )
119 store_r.push_back( Url(std::string(w)) );
120 });
121 }
122
123 enum class MultiLine { none, baseurl, gpgkey, mirrorlist, metalink };
124 MultiLine _inMultiline = MultiLine::none;
125
126 std::map<std::string,std::list<Url>> _baseurls;
127 std::map<std::string,std::list<Url>> _gpgkeys;
128 std::map<std::string,std::list<Url>> _mirrorlist;
129 std::map<std::string,std::list<Url>> _metalink;
130 };
131
132 } //namespace
134
139 static void repositories_in_stream( const InputStream &is,
141 const ProgressData::ReceiverFnc &progress )
142 try {
143 RepoFileParser dict(is);
144 for_( its, dict.sectionsBegin(), dict.sectionsEnd() )
145 {
146 RepoInfo info;
147 info.setAlias(*its);
148 std::string proxy;
149 std::string proxyport;
150
151 for_( it, dict.entriesBegin(*its), dict.entriesEnd(*its) )
152 {
153 //MIL << (*it).first << endl;
154 if (it->first == "name" )
155 info.setName(it-> second);
156 else if ( it->first == "enabled" )
157 info.setEnabled( str::strToTrue( it->second ) );
158 else if ( it->first == "priority" )
159 info.setPriority( str::strtonum<unsigned>( it->second ) );
160 else if ( it->first == "path" )
161 info.setPath( Pathname(it->second) );
162 else if ( it->first == "type" )
163 ; // bsc#1177427 et.al.: type in a .repo file is legacy - ignore it and let RepoManager probe
164 else if ( it->first == "autorefresh" )
165 info.setAutorefresh( str::strToTrue( it->second ) );
166 else if ( it->first == "gpgcheck" )
167 info.setGpgCheck( str::strToTriBool( it->second ) );
168 else if ( it->first == "repo_gpgcheck" )
169 info.setRepoGpgCheck( str::strToTrue( it->second ) );
170 else if ( it->first == "pkg_gpgcheck" )
171 info.setPkgGpgCheck( str::strToTrue( it->second ) );
172 else if ( it->first == "keeppackages" )
173 info.setKeepPackages( str::strToTrue( it->second ) );
174 else if ( it->first == "service" )
175 info.setService( it->second );
176 else if ( it->first == "proxy" )
177 {
178 // Translate it into baseurl queryparams
179 // NOTE: The hack here does not add proxy to mirrorlist urls but the
180 // original code worked without complains, so keep it for now.
181 static const str::regex ex( ":[0-9]+$" ); // portspec
182 str::smatch what;
183 if ( str::regex_match( it->second, what, ex ) )
184 {
185 proxy = it->second.substr( 0, it->second.size() - what[0].size() );
186 proxyport = what[0].substr( 1 );
187 }
188 else
189 {
190 proxy = it->second;
191 }
192 }
193 else
194 ERR << "Unknown attribute in [" << *its << "]: " << it->first << "=" << it->second << " ignored" << endl;
195 }
196
197 for ( auto & url : dict.baseurls( *its ) )
198 {
199 if ( ! proxy.empty() && url.getQueryParam( "proxy" ).empty() )
200 {
201 url.setQueryParam( "proxy", proxy );
202 url.setQueryParam( "proxyport", proxyport );
203 }
204 info.addBaseUrl( url );
205 }
206
207 if ( ! dict.gpgkeys( *its ).empty() )
208 info.setGpgKeyUrls( std::move(dict.gpgkeys( *its )) );
209
210 if ( ! dict.mirrorlist( *its ).empty() ) // parser tolerates multiple definitions, but 1st one wins
211 info.setMirrorlistUrl( dict.mirrorlist( *its ).front() );
212
213 if ( ! dict.metalink( *its ).empty() ) // parser tolerates multiple definitions, but 1st one wins
214 info.setMetalinkUrl( dict.metalink( *its ).front() );
215
216 info.setFilepath(is.path());
217 MIL << info << endl;
218 // add it to the list.
219 callback(info);
220 //if (!progress.tick())
221 // ZYPP_THROW(AbortRequestException());
222 }
223 }
224 catch ( Exception & ex ) {
225 ex.addHistory( "Parsing .repo file "+is.name() );
226 ZYPP_RETHROW( ex );
227 }
228
230 //
231 // CLASS NAME : RepoFileReader
232 //
234
237 const ProgressData::ReceiverFnc &progress )
238 : _callback(std::move(callback))
239 {
240 repositories_in_stream(InputStream(repo_file), _callback, progress);
241 }
242
245 const ProgressData::ReceiverFnc &progress )
246 : _callback(std::move(callback))
247 {
248 repositories_in_stream(is, _callback, progress);
249 }
250
253
254
255 std::ostream & operator<<( std::ostream & str, const RepoFileReader & obj )
256 {
257 return str;
258 }
259
260 } // namespace parser
262} // namespace zypp
Base class for Exception.
Definition Exception.h:153
void addHistory(const std::string &msg_r)
Add some message text to the history.
Definition Exception.cc:189
Helper to create and pass std::istream.
Definition inputstream.h:57
const Pathname & path() const
Path to the input file or empty if no file.
function< bool(const ProgressData &)> ReceiverFnc
Most simple version of progress reporting The percentage in most cases.
What is known about a repository.
Definition RepoInfo.h:72
void setPkgGpgCheck(TriBool value_r)
Set the value for pkgGpgCheck (or indeterminate to use the default).
Definition RepoInfo.cc:561
void setGpgKeyUrls(url_set urls)
Set a list of gpgkey URLs defined for this repo.
Definition RepoInfo.cc:662
void setMetalinkUrl(const Url &url)
Set the raw metalink url.
Definition RepoInfo.cc:644
void setMirrorlistUrl(const Url &url)
Set the raw mirrorlist url.
Definition RepoInfo.cc:641
void setKeepPackages(bool keep)
Set if packaqes downloaded from this repository will be kept in local cache.
Definition RepoInfo.cc:726
void setService(const std::string &name)
sets service which added this repository
Definition RepoInfo.cc:729
void setGpgCheck(TriBool value_r)
Set the value for gpgCheck (or indeterminate to use the default).
Definition RepoInfo.cc:533
void addBaseUrl(Url url)
Add a base url.
Definition RepoInfo.cc:674
void setPath(const Pathname &path)
set the product path.
Definition RepoInfo.cc:707
void setPriority(unsigned newval_r)
Set repository priority for solver.
Definition RepoInfo.cc:526
void setRepoGpgCheck(TriBool value_r)
Set the value for repoGpgCheck (or indeterminate to use the default).
Definition RepoInfo.cc:551
Parses a INI file and offers its structure as a dictionary.
Definition inidict.h:42
void consume(const std::string &section) override
Called when a section is found.
Definition inidict.cc:64
virtual void garbageLine(const std::string &section, const std::string &line)
Called whenever a garbage line is found.
Definition iniparser.cc:72
function< bool(const RepoInfo &)> ProcessRepo
Callback definition.
RepoFileReader(const Pathname &repo_file, ProcessRepo callback, const ProgressData::ReceiverFnc &progress=ProgressData::ReceiverFnc())
Constructor.
void setAutorefresh(bool autorefresh)
enable or disable autorefresh
void setFilepath(const Pathname &filename)
set the path to the .repo file
void setAlias(const std::string &alias)
set the repository alias
void setName(const std::string &name)
set the repository name
void setEnabled(bool enabled)
enable or disable the repository
Regular expression.
Definition Regex.h:95
Regular expression match result.
Definition Regex.h:168
unsigned size() const
Definition Regex.cc:106
Definition Arch.h:364
String related utilities and Regular expression matching.
@ none
Definition Table.h:92
std::map< std::string, std::string > read(const Pathname &_path)
Read sysconfig file path_r and return (key,valye) pairs.
Definition sysconfig.cc:34
Callbacks light.
Definition Callback.h:146
std::ostream & operator<<(std::ostream &str, const ProductFileData &obj)
static void repositories_in_stream(const InputStream &is, const RepoFileReader::ProcessRepo &callback, const ProgressData::ReceiverFnc &progress)
List of RepoInfo's from a file.
bool strToTrue(const C_Str &str)
Parsing boolean from string.
Definition String.cc:66
TriBool strToTriBool(const C_Str &str)
Parse str into a bool if it's a legal true or false string; else indeterminate.
Definition String.cc:96
bool regex_match(const std::string &s, smatch &matches, const regex &regex)
\relates regex \ingroup ZYPP_STR_REGEX \relates regex \ingroup ZYPP_STR_REGEX
Definition Regex.h:70
TInt strtonum(const C_Str &str)
Parsing numbers from string.
Url details namespace.
Definition UrlBase.cc:58
Easy-to use interface to the ZYPP dependency resolver.
zypp::Url Url
Definition url.h:15
#define for_(IT, BEG, END)
Convenient for-loops using iterator.
Definition Easy.h:27
#define ZYPP_RETHROW(EXCPT)
Drops a logline and rethrows, updating the CodeLocation.
Definition Exception.h:479
#define MIL
Definition Logger.h:100
#define ERR
Definition Logger.h:102
c++17: std::string_view tools