Author: mlandres Date: Wed Apr 18 14:56:52 2007 New Revision: 5404 URL: http://svn.opensuse.org/viewcvs/zypp?rev=5404&view=rev Log: Support filesystem dependencies to add needed filesystem RPMs automatically (Fate 301966). Added: trunk/libzypp/zypp/capability/FilesystemCap.cc trunk/libzypp/zypp/capability/FilesystemCap.h Modified: trunk/libzypp/zypp/CMakeLists.txt trunk/libzypp/zypp/CapFactory.cc trunk/libzypp/zypp/CapFactory.h trunk/libzypp/zypp/SystemResObject.cc trunk/libzypp/zypp/capability/CapTraits.cc trunk/libzypp/zypp/capability/CapTraits.h trunk/libzypp/zypp/capability/Capabilities.h trunk/libzypp/zypp/capability/CapabilityImpl.cc trunk/libzypp/zypp/capability/CapabilityImpl.h Modified: trunk/libzypp/zypp/CMakeLists.txt URL: http://svn.opensuse.org/viewcvs/zypp/trunk/libzypp/zypp/CMakeLists.txt?rev=5404&r1=5403&r2=5404&view=diff ============================================================================== --- trunk/libzypp/zypp/CMakeLists.txt (original) +++ trunk/libzypp/zypp/CMakeLists.txt Wed Apr 18 14:56:52 2007 @@ -235,6 +235,7 @@ base/Sysconfig.h base/UniqueString.h base/Unit.h + base/WatchFile.h ) INSTALL( FILES @@ -248,6 +249,7 @@ capability/FileCap.cc capability/HalCap.cc capability/ModaliasCap.cc + capability/FilesystemCap.cc capability/NamedCap.cc capability/NullCap.cc capability/SplitCap.cc @@ -262,6 +264,7 @@ capability/FileCap.h capability/HalCap.h capability/ModaliasCap.h + capability/FilesystemCap.h capability/NamedCap.h capability/NullCap.h capability/OrCap.h Modified: trunk/libzypp/zypp/CapFactory.cc URL: http://svn.opensuse.org/viewcvs/zypp/trunk/libzypp/zypp/CapFactory.cc?rev=5404&r1=5403&r2=5404&view=diff ============================================================================== --- trunk/libzypp/zypp/CapFactory.cc (original) +++ trunk/libzypp/zypp/CapFactory.cc Wed Apr 18 14:56:52 2007 @@ -148,7 +148,7 @@ */ struct CapFactory::Impl { - + }; /////////////////////////////////////////////////////////////////// @@ -191,7 +191,7 @@ ZYPP_RETHROW( excpt ); return Capability(); // not reached } - + /////////////////////////////////////////////////////////////////// // // METHOD NAME : CapFactory::parse @@ -281,6 +281,22 @@ /////////////////////////////////////////////////////////////////// // + // METHOD NAME : CapFactory::filesystemEvalCap + // METHOD TYPE : Capability + // + Capability CapFactory::filesystemEvalCap() const + try + { + return Capability( usetInsert( ::zypp::capability::buildFilesystem( Resolvable::Kind(), "filesystem()" ) ) ); + } + catch ( Exception & excpt ) + { + ZYPP_RETHROW( excpt ); + return Capability(); // not reached + } + + /////////////////////////////////////////////////////////////////// + // // METHOD NAME : CapFactory::encode // METHOD TYPE : std::string // Modified: trunk/libzypp/zypp/CapFactory.h URL: http://svn.opensuse.org/viewcvs/zypp/trunk/libzypp/zypp/CapFactory.h?rev=5404&r1=5403&r2=5404&view=diff ============================================================================== --- trunk/libzypp/zypp/CapFactory.h (original) +++ trunk/libzypp/zypp/CapFactory.h Wed Apr 18 14:56:52 2007 @@ -47,13 +47,13 @@ ~CapFactory(); public: - + /** Create capability from Implementation * \a impl is a valid \ref CapabilityImpl Ptr * \throw EXCEPTION on null capability */ Capability fromImpl( capability::CapabilityImpl::Ptr impl ) const; - + /** Parse Capability from string providing Resolvable::Kind. * \a strval_r is expected to define a valid Capability. * \throw EXCEPTION on parse error. @@ -78,6 +78,7 @@ Rel op_r, const Edition & edition_r ) const; + public: /** Special Capability, triggering evaluation of Hal * capabilities when matched. */ @@ -88,7 +89,12 @@ */ Capability modaliasEvalCap() const; - public: + /** Special Capability, triggering evaluation of filesystem + * capabilities when matched. + */ + Capability filesystemEvalCap() const; + + public: /** Provide a parsable string representation of \a cap_r. */ std::string encode( const Capability & cap_r ) const; Modified: trunk/libzypp/zypp/SystemResObject.cc URL: http://svn.opensuse.org/viewcvs/zypp/trunk/libzypp/zypp/SystemResObject.cc?rev=5404&r1=5403&r2=5404&view=diff ============================================================================== --- trunk/libzypp/zypp/SystemResObject.cc (original) +++ trunk/libzypp/zypp/SystemResObject.cc Wed Apr 18 14:56:52 2007 @@ -51,6 +51,7 @@ NVRAD dataCollect( "system" ); dataCollect[Dep::PROVIDES].insert( CapFactory().halEvalCap() ); dataCollect[Dep::PROVIDES].insert( CapFactory().modaliasEvalCap() ); + dataCollect[Dep::PROVIDES].insert( CapFactory().filesystemEvalCap() ); detail::ResImplTraitsdetail::SystemResObjectImplIf::Ptr sysImpl; _ptr = detail::makeResolvableAndImpl( dataCollect, sysImpl ); Modified: trunk/libzypp/zypp/capability/CapTraits.cc URL: http://svn.opensuse.org/viewcvs/zypp/trunk/libzypp/zypp/capability/CapTraits.cc?rev=5404&r1=5403&r2=5404&view=diff ============================================================================== --- trunk/libzypp/zypp/capability/CapTraits.cc (original) +++ trunk/libzypp/zypp/capability/CapTraits.cc Wed Apr 18 14:56:52 2007 @@ -34,6 +34,8 @@ template<> const CapabilityTraits::KindType CapTraits<ModaliasCap> ::kind( "ModaliasCap" ); template<> + const CapabilityTraits::KindType CapTraits<FilesystemCap> ::kind( "FilesystemCap" ); + template<> const CapabilityTraits::KindType CapTraits<OrCap> ::kind( "OrCap" ); template<> const CapabilityTraits::KindType CapTraits<ConditionalCap>::kind( "ConditionalCap" ); Modified: trunk/libzypp/zypp/capability/CapTraits.h URL: http://svn.opensuse.org/viewcvs/zypp/trunk/libzypp/zypp/capability/CapTraits.h?rev=5404&r1=5403&r2=5404&view=diff ============================================================================== --- trunk/libzypp/zypp/capability/CapTraits.h (original) +++ trunk/libzypp/zypp/capability/CapTraits.h Wed Apr 18 14:56:52 2007 @@ -38,6 +38,7 @@ class SplitCap; class HalCap; class ModaliasCap; + class FilesystemCap; class OrCap; class ConditionalCap; Modified: trunk/libzypp/zypp/capability/Capabilities.h URL: http://svn.opensuse.org/viewcvs/zypp/trunk/libzypp/zypp/capability/Capabilities.h?rev=5404&r1=5403&r2=5404&view=diff ============================================================================== --- trunk/libzypp/zypp/capability/Capabilities.h (original) +++ trunk/libzypp/zypp/capability/Capabilities.h Wed Apr 18 14:56:52 2007 @@ -21,6 +21,8 @@ #include "zypp/capability/SplitCap.h" #include "zypp/capability/HalCap.h" #include "zypp/capability/ModaliasCap.h" +#include "zypp/capability/FilesystemCap.h" + //#include "zypp/capability/OrCap.h" //#include "zypp/capability/ConditionalCap.h" Modified: trunk/libzypp/zypp/capability/CapabilityImpl.cc URL: http://svn.opensuse.org/viewcvs/zypp/trunk/libzypp/zypp/capability/CapabilityImpl.cc?rev=5404&r1=5403&r2=5404&view=diff ============================================================================== --- trunk/libzypp/zypp/capability/CapabilityImpl.cc (original) +++ trunk/libzypp/zypp/capability/CapabilityImpl.cc Wed Apr 18 14:56:52 2007 @@ -92,7 +92,7 @@ ZYPP_THROW( Exception("Unknow Operator NONE is not allowed in Capability") ); return false; // not reached } - + bool isFileSpec( const std::string & name_r ) { return *name_r.c_str() == '/'; @@ -113,6 +113,11 @@ return name_r.substr(0,9) == "modalias("; } + bool isFilesystemSpec( const std::string & name_r ) + { + return name_r.substr(0,11) == "filesystem("; + } + CapabilityImpl::Ptr buildFile( const Resolvable::Kind & refers_r, const std::string & name_r ) { @@ -145,6 +150,10 @@ { return new capability::FileCap( refers_r, name_r ); } + if ( isFilesystemSpec( name_r ) ) + { + return buildFilesystem( refers_r, name_r ); + } //split: name:/absolute/path static const str::regex rx( "([^/]*):(/.*)" ); @@ -224,9 +233,31 @@ return NULL; // make gcc happy } - CapabilityImpl::Ptr parse( const Resolvable::Kind & refers_r, - const std::string & strval_r ) + /****************************************************************** + ** + ** FUNCTION NAME : buildFilesystem + ** FUNCTION TYPE : CapabilityImpl::Ptr + */ + CapabilityImpl::Ptr buildFilesystem( const Resolvable::Kind & refers_r, + const std::string & name_r ) + { + //split: filesystem(name) [op string] + static const str::regex rx( "filesystem\\(([^)]*)\\)" ); + str::smatch what; + if( str::regex_match( name_r.begin(), name_r.end(), what, rx ) ) + { + // Filesystem always refers to 'System' kind of Resolvable + return new capability::FilesystemCap( ResTraits<SystemResObject>::kind, + what[1].str() ); + } + // otherwise + ZYPP_THROW( Exception("Unsupported kind of Filesystem Capability'" + name_r + "'") ); + return NULL; // make gcc happy + } + + CapabilityImpl::Ptr parse( const Resolvable::Kind & refers_r, + const std::string & strval_r ) try { if ( isHalSpec( strval_r ) ) @@ -237,6 +268,10 @@ { return buildModalias( refers_r, strval_r ); } + if ( isFilesystemSpec( strval_r ) ) + { + return buildFilesystem( refers_r, strval_r ); + } if ( isFileSpec( strval_r ) ) { return buildFile( refers_r, strval_r ); @@ -287,7 +322,7 @@ { if ( isHalSpec( name_r ) ) { - return buildHal( refers_r, name_r, Rel(op_r), edition_r ); + return buildHal( refers_r, name_r, Rel(op_r), edition_r ); } if ( isModaliasSpec( name_r ) ) { @@ -308,9 +343,9 @@ // METHOD TYPE : Capability // CapabilityImpl::Ptr parse( const Resolvable::Kind & refers_r, - const std::string & name_r, - Rel op_r, - const Edition & edition_r ) + const std::string & name_r, + Rel op_r, + const Edition & edition_r ) try { if ( isHalSpec( name_r ) ) @@ -328,7 +363,7 @@ ZYPP_RETHROW( excpt ); return NULL; // not reached } - + /////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////// Modified: trunk/libzypp/zypp/capability/CapabilityImpl.h URL: http://svn.opensuse.org/viewcvs/zypp/trunk/libzypp/zypp/capability/CapabilityImpl.h?rev=5404&r1=5403&r2=5404&view=diff ============================================================================== --- trunk/libzypp/zypp/capability/CapabilityImpl.h (original) +++ trunk/libzypp/zypp/capability/CapabilityImpl.h Wed Apr 18 14:56:52 2007 @@ -27,12 +27,41 @@ { ///////////////////////////////////////////////////////////////// DEFINE_PTR_TYPE(CapabilityImpl) - + /////////////////////////////////////////////////////////////////// // // CLASS NAME : CapabilityImpl // /** Abstract base for Capability implementations. + * + * Example: Adding a new kind of capability: FilesystemCap + * \code + * 1) Create the implementataion files + * zypp/capability/FilesystemCap.h + * zypp/capability/FilesystemCap.cc + * for + * class FilesystemCap : public CapabilityImpl + * + * 2) Add include in zypp/capability/Capabilities.h + * #include "zypp/capability/FilesystemCap.h" + * + * 3) Add forward declaration in zypp/capability/CapTraits.h + * class FilesystemCap; + * + * 4) Define the capabilities kind in zypp/capability/CapTraits.cc + * template<> + * const CapabilityTraits::KindType CapTraits<FilesystemCap> ::kind( "FilesystemCap" ); + * + * 5) If needed, define the EvalCap in zypp/CapFactory.h + * Capability filesystemEvalCap() const; + * What's this? + * Some capabilities are not evaluated by comparing 2 capabilities, but represent a query + * for some system property: 'filesystem(xfs)' -> 'xfs is listed in /etc/sysconfig/stoage'. + * The query is performed iff the capability is compared to a special EvalCap, which is usg. + * provided by a special SystemResolvable> + * <System> : provides : filesystem() // the filesystemEvalCap + * <Package>: supplements : filesystem(xfs) // a package that supplements xfs filesystem + * \endcode */ class CapabilityImpl : public base::ReferenceCounted, private base::NonCopyable { @@ -129,7 +158,7 @@ virtual bool capImplOrderLess( const constPtr & rhs ) const; }; /////////////////////////////////////////////////////////////////// - + /** Check whether \a op_r and \a edition_r make a valid edition spec. * * Rel::NONE is not usefull thus forbidden. Rel::ANY can be ignored, @@ -140,22 +169,31 @@ * is not Rel::ANY. */ bool isEditionSpec( Rel op_r, const Edition & edition_r ); - + /** Test for a FileCap. \a name_r starts with \c "/". */ bool isFileSpec( const std::string & name_r ); - + /** Test for a SplitCap. \a name_r constains \c ":/". */ bool isSplitSpec( const std::string & name_r ); - + /** Test for a HalCap. \a name_r starts with "hal(". */ bool isHalSpec( const std::string & name_r ); - - /** Test for a ModaliasCap. \a name_r starts with "modalias(". */ + + /** Test for a ModaliasCap. \a name_r starts with "modalias(". */ bool isModaliasSpec( const std::string & name_r ); - + + /** Test for a FilesystemCap. \a name_r starts with "filesystem(". */ + bool isFilesystemSpec( const std::string & name_r ); + + /** Try to build a file cap from \a name_r . + * + * The CapabilityImpl is built here and inserted into _uset. + * The final Capability must be created by CapFactory, as it + * is a friend of Capability. Here we can't access the ctor. + */ CapabilityImpl::Ptr buildFile( const Resolvable::Kind & refers_r, - const std::string & name_r ); - + const std::string & name_r ); + /** Try to build a non versioned cap from \a name_r . * * The CapabilityImpl is built here and inserted into _uset. @@ -163,8 +201,8 @@ * is a friend of Capability. Here we can't access the ctor. */ CapabilityImpl::Ptr buildNamed( const Resolvable::Kind & refers_r, - const std::string & name_r ); - + const std::string & name_r ); + /** Try to build a versioned cap from \a name_r . * * The CapabilityImpl is built here and inserted into _uset. @@ -174,10 +212,10 @@ * \todo Quick check for name not being filename or split. */ CapabilityImpl::Ptr buildVersioned( const Resolvable::Kind & refers_r, - const std::string & name_r, - Rel op_r, - const Edition & edition_r ); - + const std::string & name_r, + Rel op_r, + const Edition & edition_r ); + /** Try to build a hal cap from \a name_r . * * The CapabilityImpl is built here @@ -187,10 +225,10 @@ * \todo Fix incaccuracy. */ CapabilityImpl::Ptr buildHal( const Resolvable::Kind & refers_r, - const std::string & name_r, - Rel op_r = Rel::ANY, - const std::string & value_r = std::string() ); - + const std::string & name_r, + Rel op_r = Rel::ANY, + const std::string & value_r = std::string() ); + /** Try to build a modalias cap from \a name_r . * * The CapabilityImpl is built here @@ -200,22 +238,36 @@ * \todo Fix incaccuracy. */ CapabilityImpl::Ptr buildModalias( const Resolvable::Kind & refers_r, - const std::string & name_r, - Rel op_r = Rel::ANY, - const std::string & value_r = std::string() ); - - - CapabilityImpl::Ptr parse( const Resolvable::Kind & refers_r, - const std::string & strval_r ); - CapabilityImpl::Ptr parse( const Resolvable::Kind & refers_r, - const std::string & name_r, - const std::string & op_r, - const std::string & edition_r ); - CapabilityImpl::Ptr parse( const Resolvable::Kind & refers_r, - const std::string & name_r, - Rel op_r, - const Edition & edition_r ); - + const std::string & name_r, + Rel op_r = Rel::ANY, + const std::string & value_r = std::string() ); + + /** Try to build a filesystem cap from \a name_r . + * + * The CapabilityImpl is built here + * The final Capability must be created by CapFactory, as it + * is a friend of Capability. Here we can't access the ctor. + * + * \todo Fix incaccuracy. + */ + CapabilityImpl::Ptr buildFilesystem( const Resolvable::Kind & refers_r, + const std::string & name_r ); + + /////////////////////////////////////////////////////////////////// + + CapabilityImpl::Ptr parse( const Resolvable::Kind & refers_r, + const std::string & strval_r ); + + CapabilityImpl::Ptr parse( const Resolvable::Kind & refers_r, + const std::string & name_r, + const std::string & op_r, + const std::string & edition_r ); + + CapabilityImpl::Ptr parse( const Resolvable::Kind & refers_r, + const std::string & name_r, + Rel op_r, + const Edition & edition_r ); + /** Test whether a CapabilityImpl is of a certain Kind. * \code * isKind<FileCap>(cap); Added: trunk/libzypp/zypp/capability/FilesystemCap.cc URL: http://svn.opensuse.org/viewcvs/zypp/trunk/libzypp/zypp/capability/FilesystemCap.cc?rev=5404&view=auto ============================================================================== --- trunk/libzypp/zypp/capability/FilesystemCap.cc (added) +++ trunk/libzypp/zypp/capability/FilesystemCap.cc Wed Apr 18 14:56:52 2007 @@ -0,0 +1,89 @@ +/*---------------------------------------------------------------------\ +| ____ _ __ __ ___ | +| |__ / \ / / . \ . \ | +| / / \ V /| _/ _/ | +| / /__ | | | | | | | +| /_____||_| |_| |_| | +| | +\---------------------------------------------------------------------*/ +/** \file zypp/capability/FilesystemCap.cc + * +*/ +#include <iostream> + +#include "zypp/base/Logger.h" +#include "zypp/base/WatchFile.h" +#include "zypp/base/Sysconfig.h" + +#include "zypp/capability/FilesystemCap.h" + +using namespace std; + +/////////////////////////////////////////////////////////////////// +namespace zypp +{ ///////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////// + namespace capability + { ///////////////////////////////////////////////////////////////// + + /** Ctor */ + FilesystemCap::FilesystemCap( const Resolvable::Kind & refers_r, + const std::string & name_r ) + : CapabilityImpl( refers_r ) + , _name( name_r ) + {} + + const CapabilityImpl::Kind & FilesystemCap::kind() const + { return CapTraits<Self>::kind; } + + CapMatch FilesystemCap::matches( const constPtr & rhs ) const + { + if ( sameKindAndRefers( rhs ) ) + { + intrusive_ptr<const Self> filesystemrhs( asKind<Self>(rhs) ); + if ( isEvalCmd() == filesystemrhs->isEvalCmd() ) + return CapMatch::irrelevant; + + return( isEvalCmd() ? filesystemrhs->evaluate() : evaluate() ); + } + return false; + } + + std::string FilesystemCap::encode() const + { + std::string ret( "filesystem(" ); + ret += _name; + ret += ")"; + return ret; + } + + std::string FilesystemCap::index() const + { + return "filesystem()"; + } + + bool FilesystemCap::isEvalCmd() const + { return _name.empty(); } + + bool FilesystemCap::evaluate() const + { + static WatchFile sysconfigFile( "/etc/sysconfig/storage", WatchFile::NO_INIT ); + static std::setstd::string fs; + + if ( sysconfigFile.hasChanged() ) + { + std::setstd::string newfs; + str::split( base::sysconfig::read( sysconfigFile.path() )["USED_FS_LIST"], + std::inserter( newfs, newfs.end() ) ); + fs.swap( newfs ); + } + + return( fs.find( _name ) != fs.end() ); + } + + ///////////////////////////////////////////////////////////////// + } // namespace capability + /////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////// +} // namespace zypp +/////////////////////////////////////////////////////////////////// Added: trunk/libzypp/zypp/capability/FilesystemCap.h URL: http://svn.opensuse.org/viewcvs/zypp/trunk/libzypp/zypp/capability/FilesystemCap.h?rev=5404&view=auto ============================================================================== --- trunk/libzypp/zypp/capability/FilesystemCap.h (added) +++ trunk/libzypp/zypp/capability/FilesystemCap.h Wed Apr 18 14:56:52 2007 @@ -0,0 +1,86 @@ +/*---------------------------------------------------------------------\ +| ____ _ __ __ ___ | +| |__ / \ / / . \ . \ | +| / / \ V /| _/ _/ | +| / /__ | | | | | | | +| /_____||_| |_| |_| | +| | +\---------------------------------------------------------------------*/ +/** \file zypp/capability/FilesystemCap.h + * +*/ +#ifndef ZYPP_CAPABILITY_FILESYSTEMCAP_H +#define ZYPP_CAPABILITY_FILESYSTEMCAP_H + +#include "zypp/capability/CapabilityImpl.h" + +/////////////////////////////////////////////////////////////////// +namespace zypp +{ ///////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////// + namespace capability + { ///////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////////// + // + // CLASS NAME : FilesystemCap + // + /** A Capability resolved by a query to /etc/sysconfig/storage:USED_FS_LIST + * + * \note FilesystemCap is special as it is self evaluating, and does not + * comapre to the \a rhs (or \a lhs). This is currently solved by + * treating a FilesystemCap with an empty name as evaluate command. + * + * \ref matches returns \c CapMatch::irrelevant, if either both sides + * are evaluate commands, or both are not. + * + * Otherwise the result of the query /etc/sysconfig/storage:USED_FS_LIST + * is returned. Either from \a lhs or \a rhs, dependent on which one is the + * evaluate command. + */ + class FilesystemCap : public CapabilityImpl + { + public: + typedef FilesystemCap Self; + + public: + /** Ctor */ + FilesystemCap( const Resolvable::Kind & refers_r, const std::string & name_r ); + + public: + /** */ + virtual const Kind & kind() const; + + /** Query USED_FS_LIST. */ + virtual CapMatch matches( const constPtr & rhs ) const; + + /** <tt>filesystem(name)</tt> */ + virtual std::string encode() const; + + /** <tt>filesystem()</tt> */ + virtual std::string index() const; + + public: + const std::string & name() const + { return _name; } + + private: + /** Empty FilesystemCap <tt>filesystem()</tt> */ + bool isEvalCmd() const; + + /** Query USED_FS_LIST. */ + bool evaluate() const; + + private: + /** */ + std::string _name; + }; + /////////////////////////////////////////////////////////////////// + + ///////////////////////////////////////////////////////////////// + } // namespace capability + /////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////// +} // namespace zypp +/////////////////////////////////////////////////////////////////// +#endif // ZYPP_CAPABILITY_FILESYSTEMCAP_H -- To unsubscribe, e-mail: zypp-commit+unsubscribe@opensuse.org For additional commands, e-mail: zypp-commit+help@opensuse.org