#include <iostream>
#include <vector>
-#include "zypp/base/Logger.h"
+#include "zypp/base/LogTools.h"
#include "zypp/base/DefaultIntegral.h"
#include "zypp/parser/xml/XmlEscape.h"
#include "zypp/RepoInfo.h"
-#include "zypp/repo/RepoInfoBaseImpl.h"
+#include "zypp/TriBool.h"
+#include "zypp/Pathname.h"
#include "zypp/repo/RepoMirrorList.h"
#include "zypp/ExternalProgram.h"
#include "zypp/media/MediaAccess.h"
-using namespace std;
+#include "zypp/base/IOStream.h"
+#include "zypp/base/InputStream.h"
+#include "zypp/parser/xml/Reader.h"
+
+using std::endl;
using zypp::xml::escape;
///////////////////////////////////////////////////////////////////
// CLASS NAME : RepoInfo::Impl
//
/** RepoInfo implementation. */
- struct RepoInfo::Impl : public repo::RepoInfoBase::Impl
+ struct RepoInfo::Impl
{
Impl()
- : repo::RepoInfoBase::Impl()
- , gpgcheck(indeterminate)
+ : gpgcheck(indeterminate)
, keeppackages(indeterminate)
+ , _mirrorListForceMetalink(false)
, type(repo::RepoType::NONE_e)
, emptybaseurls(false)
{}
Pathname licenseTgz() const
{ return metadatapath.empty() ? Pathname() : metadatapath / path / "license.tar.gz"; }
- Url getmirrorListUrl() const
- { return replacer(mirrorlist_url); }
-
- Url &setmirrorListUrl()
- { return mirrorlist_url; }
-
- const std::set<Url> &baseUrls() const
+ const RepoVariablesReplacedUrlList & baseUrls() const
{
- if ( _baseUrls.empty() && ! (getmirrorListUrl().asString().empty()) )
+ const Url & mlurl( _mirrorListUrl.transformed() ); // Variables replaced!
+ if ( _baseUrls.empty() && ! mlurl.asString().empty() )
{
emptybaseurls = true;
- repo::RepoMirrorList *rmirrorlist = NULL;
-
DBG << "MetadataPath: " << metadatapath << endl;
- if( metadatapath.empty() )
- rmirrorlist = new repo::RepoMirrorList (getmirrorListUrl() );
- else
- rmirrorlist = new repo::RepoMirrorList (getmirrorListUrl(), metadatapath );
-
- std::vector<Url> rmurls = rmirrorlist->getUrls();
- delete rmirrorlist;
- rmirrorlist = NULL;
- _baseUrls.insert(rmurls.begin(), rmurls.end());
+ repo::RepoMirrorList rmurls( mlurl, metadatapath, _mirrorListForceMetalink );
+ _baseUrls.raw().insert( _baseUrls.raw().end(), rmurls.getUrls().begin(), rmurls.getUrls().end() );
}
return _baseUrls;
}
- std::set<Url> &baseUrls()
+ RepoVariablesReplacedUrlList & baseUrls()
{ return _baseUrls; }
bool baseurl2dump() const
{ return !emptybaseurls && !_baseUrls.empty(); }
+
+ void addContent( const std::string & keyword_r )
+ { _keywords.insert( keyword_r ); }
+
+ bool hasContent( const std::string & keyword_r ) const
+ {
+ if ( _keywords.empty() && ! metadatapath.empty() )
+ {
+ // HACK directly check master index file until RepoManager offers
+ // some content probing ans zypepr uses it.
+ /////////////////////////////////////////////////////////////////
+ MIL << "Empty keywords...." << metadatapath << endl;
+ Pathname master;
+ if ( PathInfo( (master=metadatapath/"/repodata/repomd.xml") ).isFile() )
+ {
+ //MIL << "GO repomd.." << endl;
+ xml::Reader reader( master );
+ while ( reader.seekToNode( 2, "content" ) )
+ {
+ _keywords.insert( reader.nodeText().asString() );
+ reader.seekToEndNode( 2, "content" );
+ }
+ _keywords.insert( "" ); // valid content in _keywords even if empty
+ }
+ else if ( PathInfo( (master=metadatapath/"/content") ).isFile() )
+ {
+ //MIL << "GO content.." << endl;
+ iostr::forEachLine( InputStream( master ),
+ [this]( int num_r, std::string line_r )->bool
+ {
+ if ( str::startsWith( line_r, "REPOKEYWORDS" ) )
+ {
+ std::vector<std::string> words;
+ if ( str::split( line_r, std::back_inserter(words) ) > 1
+ && words[0].length() == 12 /*"REPOKEYWORDS"*/ )
+ {
+ this->_keywords.insert( ++words.begin(), words.end() );
+ }
+ return true; // mult. occurrances are ok.
+ }
+ return( ! str::startsWith( line_r, "META " ) ); // no need to parse into META section.
+ } );
+ _keywords.insert( "" );
+ }
+ /////////////////////////////////////////////////////////////////
+ }
+ return( _keywords.find( keyword_r ) != _keywords.end() );
+ }
+
public:
TriBool gpgcheck;
TriBool keeppackages;
- Url gpgkey_url;
+ RepoVariablesReplacedUrl _gpgKeyUrl;
+ RepoVariablesReplacedUrl _mirrorListUrl;
+ bool _mirrorListForceMetalink;
repo::RepoType type;
Pathname path;
std::string service;
repo::RepoVariablesUrlReplacer replacer;
private:
- Url mirrorlist_url;
- mutable std::set<Url> _baseUrls;
+ mutable RepoVariablesReplacedUrlList _baseUrls;
+ mutable std::set<std::string> _keywords;
friend Impl * rwcowClone<Impl>( const Impl * rhs );
/** clone for RWCOW_pointer */
void RepoInfo::setGpgCheck( bool check )
{ _pimpl->gpgcheck = check; }
- void RepoInfo::setMirrorListUrl( const Url &url )
- { _pimpl->setmirrorListUrl() = url; }
+ void RepoInfo::setMirrorListUrl( const Url & url_r ) // Raw
+ { _pimpl->_mirrorListUrl.raw() = url_r; _pimpl->_mirrorListForceMetalink = false; }
- void RepoInfo::setGpgKeyUrl( const Url &url )
- { _pimpl->gpgkey_url = url; }
+ void RepoInfo::setMetalinkUrl( const Url & url_r ) // Raw
+ { _pimpl->_mirrorListUrl.raw() = url_r; _pimpl->_mirrorListForceMetalink = true; }
- void RepoInfo::addBaseUrl( const Url &url )
- { _pimpl->baseUrls().insert(url); }
+ void RepoInfo::setGpgKeyUrl( const Url & url_r )
+ { _pimpl->_gpgKeyUrl.raw() = url_r; }
- void RepoInfo::setBaseUrl( const Url &url )
+ void RepoInfo::addBaseUrl( const Url & url_r )
{
- _pimpl->baseUrls().clear();
- addBaseUrl(url);
+ for ( const auto & url : _pimpl->baseUrls().raw() ) // Raw unique!
+ if ( url == url_r )
+ return;
+ _pimpl->baseUrls().raw().push_back( url_r );
+ }
+
+ void RepoInfo::setBaseUrl( const Url & url_r )
+ {
+ _pimpl->baseUrls().raw().clear();
+ _pimpl->baseUrls().raw().push_back( url_r );
}
void RepoInfo::setPath( const Pathname &path )
repo::RepoType RepoInfo::type() const
{ return _pimpl->type; }
- Url RepoInfo::mirrorListUrl() const
- { return _pimpl->getmirrorListUrl(); }
+ Url RepoInfo::mirrorListUrl() const // Variables replaced!
+ { return _pimpl->_mirrorListUrl.transformed(); }
- Url RepoInfo::gpgKeyUrl() const
- { return _pimpl->gpgkey_url; }
+ Url RepoInfo::rawMirrorListUrl() const // Raw
+ { return _pimpl->_mirrorListUrl.raw(); }
- std::set<Url> RepoInfo::baseUrls() const
- {
- RepoInfo::url_set replaced_urls;
- for ( url_set::const_iterator it = _pimpl->baseUrls().begin();
- it != _pimpl->baseUrls().end();
- ++it )
- {
- replaced_urls.insert(_pimpl->replacer(*it));
- }
- return replaced_urls;
- }
+ Url RepoInfo::gpgKeyUrl() const // Variables replaced!
+ { return _pimpl->_gpgKeyUrl.transformed(); }
+
+ Url RepoInfo::rawGpgKeyUrl() const // Raw
+ { return _pimpl->_gpgKeyUrl.raw(); }
+
+ RepoInfo::url_set RepoInfo::baseUrls() const // Variables replaced!
+ { return _pimpl->baseUrls().transformed(); }
+
+ RepoInfo::url_set RepoInfo::rawBaseUrls() const // Raw
+ { return _pimpl->baseUrls().raw(); }
Pathname RepoInfo::path() const
{ return _pimpl->path; }
std::string RepoInfo::targetDistribution() const
{ return _pimpl->targetDistro; }
+ Url RepoInfo::rawUrl() const
+ { return( _pimpl->baseUrls().empty() ? Url() : *_pimpl->baseUrls().rawBegin() ); }
+
RepoInfo::urls_const_iterator RepoInfo::baseUrlsBegin() const
- {
- return make_transform_iterator( _pimpl->baseUrls().begin(),
- _pimpl->replacer );
- //return _pimpl->baseUrls.begin();
- }
+ { return _pimpl->baseUrls().transformedBegin(); }
RepoInfo::urls_const_iterator RepoInfo::baseUrlsEnd() const
- {
- //return _pimpl->baseUrls.end();
- return make_transform_iterator( _pimpl->baseUrls().end(),
- _pimpl->replacer );
- }
+ { return _pimpl->baseUrls().transformedEnd(); }
RepoInfo::urls_size_type RepoInfo::baseUrlsSize() const
{ return _pimpl->baseUrls().size(); }
bool RepoInfo::baseUrlSet() const
{ return _pimpl->baseurl2dump(); }
+
+ void RepoInfo::addContent( const std::string & keyword_r )
+ { _pimpl->addContent( keyword_r ); }
+
+ bool RepoInfo::hasContent( const std::string & keyword_r ) const
+ { return _pimpl->hasContent( keyword_r ); }
+
///////////////////////////////////////////////////////////////////
bool RepoInfo::hasLicense() const
{
Pathname licenseTgz( _pimpl->licenseTgz() );
- SEC << licenseTgz << endl;
- SEC << PathInfo(licenseTgz) << endl;
-
return ! licenseTgz.empty() && PathInfo(licenseTgz).isFile();
}
accept = false;
}
}
- MIL << "License for " << this->name() << " has to be accepted: " << (accept?"true":"false" ) << endl;
+ MIL << "License for " << name() << " has to be accepted: " << (accept?"true":"false" ) << endl;
return accept;
}
std::string RepoInfo::getLicense( const Locale & lang_r )
+ { return const_cast<const RepoInfo *>(this)->getLicense( lang_r ); }
+
+ std::string RepoInfo::getLicense( const Locale & lang_r ) const
{
LocaleSet avlocales( getLicenseLocales() );
if ( avlocales.empty() )
RepoInfoBase::dumpOn(str);
if ( _pimpl->baseurl2dump() )
{
- for ( urls_const_iterator it = baseUrlsBegin();
- it != baseUrlsEnd();
- ++it )
+ for ( const auto & url : _pimpl->baseUrls().raw() )
{
- str << "- url : " << *it << std::endl;
+ str << "- url : " << url << std::endl;
}
}
str << tag_r << value_r << std::endl;
});
- strif( "- mirrorlist : ", _pimpl->getmirrorListUrl().asString() );
+ strif( (_pimpl->_mirrorListForceMetalink ? "- metalink : " : "- mirrorlist : "), rawMirrorListUrl().asString() );
strif( "- path : ", path().asString() );
str << "- type : " << type() << std::endl;
str << "- priority : " << priority() << std::endl;
str << "- gpgcheck : " << gpgCheck() << std::endl;
- strif( "- gpgkey : ", gpgKeyUrl().asString() );
+ strif( "- gpgkey : ", rawGpgKeyUrl().asString() );
if ( ! indeterminate(_pimpl->keeppackages) )
str << "- keeppackages: " << keepPackages() << std::endl;
if ( _pimpl->baseurl2dump() )
{
str << "baseurl=";
- for ( url_set::const_iterator it = _pimpl->baseUrls().begin();
- it != _pimpl->baseUrls().end();
- ++it )
+ std::string indent;
+ for ( const auto & url : _pimpl->baseUrls().raw() )
{
- str << *it << endl;
+ str << indent << url << endl;
+ if ( indent.empty() ) indent = " "; // "baseurl="
}
}
if ( ! _pimpl->path.empty() )
str << "path="<< path() << endl;
- if ( ! (_pimpl->getmirrorListUrl().asString().empty()) )
- str << "mirrorlist=" << _pimpl->getmirrorListUrl() << endl;
+ if ( ! (rawMirrorListUrl().asString().empty()) )
+ str << (_pimpl->_mirrorListForceMetalink ? "metalink=" : "mirrorlist=") << rawMirrorListUrl() << endl;
str << "type=" << type().asString() << endl;
if (!indeterminate(_pimpl->gpgcheck))
str << "gpgcheck=" << (gpgCheck() ? "1" : "0") << endl;
- if ( ! (gpgKeyUrl().asString().empty()) )
- str << "gpgkey=" <<gpgKeyUrl() << endl;
+
+ if ( ! (rawGpgKeyUrl().asString().empty()) )
+ str << "gpgkey=" << rawGpgKeyUrl() << endl;
if (!indeterminate(_pimpl->keeppackages))
str << "keeppackages=" << keepPackages() << endl;
std::ostream & RepoInfo::dumpAsXmlOn( std::ostream & str, const std::string & content ) const
{
- string tmpstr;
+ std::string tmpstr;
str
<< "<repo"
<< " alias=\"" << escape(alias()) << "\""
if (!(tmpstr = gpgKeyUrl().asString()).empty())
str << " gpgkey=\"" << escape(tmpstr) << "\"";
if (!(tmpstr = mirrorListUrl().asString()).empty())
- str << " mirrorlist=\"" << escape(tmpstr) << "\"";
+ str << (_pimpl->_mirrorListForceMetalink ? " metalink=\"" : " mirrorlist=\"") << escape(tmpstr) << "\"";
str << ">" << endl;
if ( _pimpl->baseurl2dump() )
{
- for (RepoInfo::urls_const_iterator urlit = baseUrlsBegin();
- urlit != baseUrlsEnd(); ++urlit)
- str << "<url>" << escape(urlit->asString()) << "</url>" << endl;
+ for_( it, baseUrlsBegin(), baseUrlsEnd() ) // !transform iterator replaces variables
+ str << "<url>" << escape((*it).asString()) << "</url>" << endl;
}
str << "</repo>" << endl;