#include <iosfwd>
#include <list>
+#include <boost/iterator.hpp>
+
#include "zypp/base/PtrTypes.h"
#include "zypp/Pathname.h"
#include "zypp/ZConfig.h"
///////////////////////////////////////////////////////////////////
namespace zypp
{ /////////////////////////////////////////////////////////////////
+ class ServiceInfo; //predef
/**
* Parses \a repo_file and returns a list of \ref RepoInfo objects
*/
struct RepoManagerOptions
{
- RepoManagerOptions();
+ /** Default ctor following \ref ZConfig global settings.
+ * If an optional \c root_r directory is given, all paths will
+ * be prefixed accordingly.
+ * \code
+ * root_r\repoCachePath
+ * \repoRawCachePath
+ * \repoSolvCachePath
+ * \repoPackagesCachePath
+ * \knownReposPath
+ * \endcode
+ */
+ RepoManagerOptions( const Pathname & root_r = Pathname() );
+
+ /** Test setup adjusting all paths to be located below one \c root_r directory.
+ * \code
+ * root_r\ - repoCachePath
+ * \raw - repoRawCachePath
+ * \solv - repoSolvCachePath
+ * \packages - repoPackagesCachePath
+ * \repos.d - knownReposPath
+ * \endcode
+ */
+ static RepoManagerOptions makeTestSetup( const Pathname & root_r );
Pathname repoCachePath;
Pathname repoRawCachePath;
+ Pathname repoSolvCachePath;
Pathname repoPackagesCachePath;
Pathname knownReposPath;
+ Pathname knownServicesPath;
bool probe;
+ /**
+ * Target distro ID to be used when refreshing repo index services.
+ * Repositories not maching this ID will be skipped/removed.
+ *
+ * The value is initialized upon construction to
+ * \ref Target::targetDistribution() if the Target is already initialized,
+ * otherwise the value is initially empty.
+ *
+ * If empty, no repositories contained in the index will be skipped.
+ */
+ std::string servicesTargetDistro;
};
+
+
/**
* \short creates and provides information about known sources.
*
/** Implementation */
class Impl;
+ /** service typedefs */
+ typedef std::set<ServiceInfo> ServiceSet;
+ typedef ServiceSet::const_iterator ServiceConstIterator;
+ typedef ServiceSet::size_type ServiceSizeType;
+
+ /** RepoInfo typedefs */
+ typedef std::set<RepoInfo> RepoSet;
+ typedef RepoSet::const_iterator RepoConstIterator;
+ typedef RepoSet::size_type RepoSizeType;
+
public:
RepoManager( const RepoManagerOptions &options = RepoManagerOptions() );
/** Dtor */
enum RawMetadataRefreshPolicy
{
RefreshIfNeeded,
- RefreshForced
+ RefreshForced,
+ RefreshIfNeededIgnoreDelay
};
enum CacheBuildPolicy
*/
std::list<RepoInfo> knownRepositories() const;
+ bool repoEmpty() const;
+ RepoSizeType repoSize() const;
+ RepoConstIterator repoBegin() const;
+ RepoConstIterator repoEnd() const;
+
+
/**
* \short Status of local metadata
*/
RepoStatus metadataStatus( const RepoInfo &info ) const;
/**
+ * Possibly return state of checkIfRefreshMEtadata function
+ */
+ enum RefreshCheckStatus {
+ REFRESH_NEEDED, /**< refresh is needed */
+ REPO_UP_TO_DATE, /**< repository not changed */
+ REPO_CHECK_DELAYED /**< refresh is delayed due to settings */
+ };
+
+ /**
* Checks whether to refresh metadata for specified repository and url.
* <p>
* The need for refresh is evaluated according to the following conditions,
* {
* // check whether to refresh metadata
* // if the check fails for this url, it throws, so another url will be checked
- * if (!checkIfToRefreshMetadata(info, *it, policy))
+ * if (checkIfToRefreshMetadata(info, *it, policy)!=RepoInfo::REFRESH_NEEDED)
* return;
*
* // do the actual refresh
* \param info
* \param url
* \param policy
+ * \return state of repository
+ * \see RefreshCheckStatus
* \throws RepoUnknownTypeException
* \throws repo::RepoNoAliasException if can't figure an alias
* \throws Exception on unknown error
*
*/
- bool checkIfToRefreshMetadata( const RepoInfo &info,
+ RefreshCheckStatus checkIfToRefreshMetadata( const RepoInfo &info,
const Url &url,
RawMetadataRefreshPolicy policy = RefreshIfNeeded);
*/
Pathname metadataPath( const RepoInfo &info ) const;
+
+ /**
+ * \short Path where the rpm packages are downloaded and kept
+ *
+ * Given a repoinfo, tells where \ref RepoProvidePackage will download
+ * and keep the .rpm files.
+ *
+ * \param info Repository information
+ *
+ * \throws repo::RepoNoAliasException if can't figure an alias
+ */
+ Pathname packagesPath( const RepoInfo &info ) const;
+
+
/**
* \short Refresh local raw cache
*
const ProgressData::ReceiverFnc & progressrcv = ProgressData::ReceiverFnc() );
/**
- * Clean target system (rpm db) cache.
- */
- void cleanTargetCache(const ProgressData::ReceiverFnc & progressrcv = ProgressData::ReceiverFnc());
-
- /**
* \short Whether a repository exists in cache
*
* \param RepoInfo to be checked.
*
* \throws repo::RepoAlreadyExistsException If the repo clash some
* unique attribute like alias
- * \throws RepoUnknownType If repository type can't be determined
- * \throws RepoException If the access to the url fails (while probing).
+ * \throws RepoUnknownType
+ * If RepoManagerOptions::probe is true
+ * and repository type can't be determined.
+ * \throws RepoException
+ * If RepoManagerOptions::probe is true and access to the url fails.
* \throws Exception On other errors.
*/
void addRepository( const RepoInfo &info,
* \param url Url of the repo file
*
* \throws repo::RepoAlreadyExistsException If the repo clash some
- * unique attribute like alias
- *
- * \throws RepoAlreadyExistsException
+ * unique attribute like alias
* \throws MediaException If the access to the url fails
* \throws ParseException If the file parsing fails
* \throws RepoUnknownType If repository type can't be determined
const url::ViewOption & urlview = url::ViewOption::DEFAULTS,
const ProgressData::ReceiverFnc & progressrcv = ProgressData::ReceiverFnc() );
+ /**
+ * Adds new service by it's alias and url
+ *
+ * \param alias unique identifier of the service
+ * \param url url to service
+ *
+ * \throws FIXME RepoAlreadyExistException and as reponame is service name
+ */
+ void addService( const std::string & alias, const Url& url );
+
+ /**
+ * Adds new service
+ *
+ * \param service service info
+ *
+ * \throws FIXME RepoAlreadyExistException and as reponame is service name
+ */
+ void addService( const ServiceInfo & service );
+
+ /**
+ * Removes service specified by its name
+ *
+ * \param alias unique indientifier of the service to remove
+ *
+ * \throws RepoException if service is not found or file with ServiceInfo cannot be deleted
+ * \throws Exception if file contain more services and rewrite file failed
+ */
+ void removeService( const std::string & alias );
+
+ void removeService( const ServiceInfo & service );
+
+ /**
+ * Gets true if no service is in RepoManager (so no one in specified location)
+ *
+ * \return true if any ServiceInfo is in RepoManager
+ */
+ bool serviceEmpty() const;
+
+ /**
+ * Gets count of service in RepoManager (in specified location)
+ *
+ * \return count of service
+ */
+ ServiceSizeType serviceSize() const;
+
+ /**
+ * Iterator to first service in internal storage.
+ * \note Iterator is immutable, so you cannot change pointed ServiceInfo
+ * \return Iterator to first service
+ */
+ ServiceConstIterator serviceBegin() const;
+
+ /**
+ * Iterator to place behind last service in internal storage.
+ * \return iterator to end
+ */
+ ServiceConstIterator serviceEnd() const;
+
+ /**
+ * Finds ServiceInfo by alias or return noService
+ *
+ * \param alias unique identifier of service
+ * \return information about service
+ */
+ ServiceInfo getService( const std::string & alias ) const;
+
+ /**
+ * Refreshes all enabled services.
+ *
+ * \see refreshService(ServiceInfo)
+ */
+ void refreshServices();
+
+ /**
+ * Refresh specific service.
+ *
+ * \param name service structure
+ * \throws MediaException If there's a problem downloading the repo index file.
+ */
+ void refreshService( const ServiceInfo & service );
+
+ /**
+ * Modifies service file (rewrites it with new values) and underlying
+ * repositories if needed.
+ *
+ * Modifications of a service can lead to rewrite of all .repo files of
+ * contained repositories. Particularily, disabling a service (changing
+ * ServiceInfo::enabled() from true to false) will disable all contained
+ * repositories. Renaming of a service will modify the "service" key
+ * of all contained repositories.
+ *
+ * \param oldAlias Old alias of the service
+ * \param service ServiceInfo object containing new data
+ *
+ * \throws RepoException if sservice with oldAlias is not known
+ * \throws Exception if have problems with files
+ */
+ void modifyService(const std::string & oldAlias, const ServiceInfo & service);
+
+ private:
+ /**
+ * Functor thats filter RepoInfo by service which belongs to.
+ */
+ struct MatchServiceAlias
+ {
+ private:
+ std::string alias;
+ public:
+ MatchServiceAlias( const std::string & alias_ ) : alias(alias_) {}
+ bool match( const RepoInfo & info ) { return info.service() == alias; }
+ };
+
+ public:
+
+ /**
+ * fill to output iterator repositories in service name. This output iterator can perform
+ * any action on with Repo or service Container, because it is sets and it isn't dynamic recreate.
+ *
+ * \note Don't use this function with RepoManager::removeRepository(), it will lead to segfaults
+ * due to invalidated internal iterators. FIXME can this be solved (using STL) so that this
+ * warning would not be needed?
+ *
+ * \param alias service alias
+ * \param out output iterator which get all the repositories belonging to
+ * specified service
+ *
+ * example how set priority for each RepoInfo in this service:
+ * \code
+ * //functor
+ * class ChangePriority
+ * {
+ * private:
+ * int priority;
+ * public:
+ * ChangePriority(int prio) : priority(prio) {}
+ * // missing rewrite priority back via RepoManager::modifyRepo
+ * void doIt( RepoInfo info ) { info.setPriority(priority); }
+ * }
+ *
+ * //somewhere in code
+ * ChangePriority changer(10);
+ * getRepositoriesInService(name,
+ * boost::make_function_output_iterator(
+ * bind(&ChangePriority::doIt, &changer, _1)));
+ * \endcode
+ */
+ template<typename OutputIterator>
+ void getRepositoriesInService( const std::string & alias,
+ OutputIterator out ) const
+ {
+ MatchServiceAlias filter(alias);
+
+ std::copy(
+ boost::make_filter_iterator(
+ bind(&MatchServiceAlias::match, filter, _1), repoBegin(), repoEnd()),
+ boost::make_filter_iterator(
+ bind(&MatchServiceAlias::match, filter, _1), repoEnd(), repoEnd()),
+ out);
+ }
+
protected:
RepoStatus rawMetadataStatus( const RepoInfo &info );
- void setCacheStatus( const std::string &alias, const RepoStatus &status );
+ void setCacheStatus( const RepoInfo &info, const RepoStatus &status );
/**
* Update timestamp of repository index file for the specified repository \a info.