00001 /* vim: set sw=4 sts=4 et foldmethod=syntax : */ 00002 00003 /* 00004 * Copyright (c) 2007, 2008, 2009 Ciaran McCreesh 00005 * 00006 * This file is part of the Paludis package manager. Paludis is free software; 00007 * you can redistribute it and/or modify it under the terms of the GNU General 00008 * Public License version 2, as published by the Free Software Foundation. 00009 * 00010 * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY 00011 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 00012 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 00013 * details. 00014 * 00015 * You should have received a copy of the GNU General Public License along with 00016 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple 00017 * Place, Suite 330, Boston, MA 02111-1307 USA 00018 */ 00019 00020 #ifndef PALUDIS_GUARD_PALUDIS_PACKAGE_ID_HH 00021 #define PALUDIS_GUARD_PALUDIS_PACKAGE_ID_HH 1 00022 00023 #include <paludis/package_id-fwd.hh> 00024 00025 #include <paludis/util/attributes.hh> 00026 #include <paludis/util/operators.hh> 00027 #include <paludis/util/private_implementation_pattern.hh> 00028 #include <paludis/util/wrapped_forward_iterator-fwd.hh> 00029 #include <paludis/util/fs_entry-fwd.hh> 00030 00031 #include <paludis/action-fwd.hh> 00032 #include <paludis/dep_spec-fwd.hh> 00033 #include <paludis/spec_tree-fwd.hh> 00034 #include <paludis/mask-fwd.hh> 00035 #include <paludis/metadata_key-fwd.hh> 00036 #include <paludis/metadata_key_holder.hh> 00037 #include <paludis/name-fwd.hh> 00038 #include <paludis/repository-fwd.hh> 00039 #include <paludis/contents-fwd.hh> 00040 #include <paludis/version_spec-fwd.hh> 00041 #include <paludis/choice-fwd.hh> 00042 00043 #include <tr1/memory> 00044 00045 /** \file 00046 * Declarations for PackageID classes. 00047 * 00048 * \ingroup g_package_id 00049 * 00050 * \section Examples 00051 * 00052 * - \ref example_package_id.cc "example_package_id.cc" (for package IDs) 00053 * - \ref example_action.cc "example_action.cc" (for actions) 00054 * - \ref example_metadata_key.cc "example_metadata_key.cc" (for metadata keys) 00055 * - \ref example_mask.cc "example_mask.cc" (for masks) 00056 */ 00057 00058 namespace paludis 00059 { 00060 class PackageDatabase; 00061 00062 /** 00063 * A PackageID represents a unique package version in a particular 00064 * Repository. 00065 * 00066 * All PackageID instances have some basic identification data: 00067 * 00068 * - A name 00069 * - A version 00070 * - An owning repository 00071 * 00072 * It should be noted that the above together are not sufficient to uniquely 00073 * identify a package. Some repositories support multiple slots per version 00074 * of a package, and some repositories support additional affixes that 00075 * prevent a package from being uniquely identifiable merely by the above. 00076 * 00077 * PackageID instances also have: 00078 * 00079 * - A collection of metadata keys. Some of these keys have a particular 00080 * specific role in certain places. These can be fetched via blah_key() 00081 * methods, all of which may return an empty pointer. Other keys have no 00082 * meaningful global role, and can only be fetched using the iteration 00083 * methods. 00084 * 00085 * - A collection (often empty) of masks. A masked package cannot be 00086 * installed. 00087 * 00088 * A PackageID instance may support certain actions, which are represented 00089 * via an Action subclass instance. 00090 */ 00091 class PALUDIS_VISIBLE PackageID : 00092 private PrivateImplementationPattern<PackageID>, 00093 public equality_operators::HasEqualityOperators, 00094 public MetadataKeyHolder 00095 { 00096 private: 00097 PrivateImplementationPattern<PackageID>::ImpPtr & _imp; 00098 00099 protected: 00100 /** 00101 * Add a new Mask. 00102 */ 00103 virtual void add_mask(const std::tr1::shared_ptr<const Mask> &) const; 00104 00105 /** 00106 * Add a new OverriddenMask. 00107 * 00108 * \since 0.34 00109 */ 00110 virtual void add_overridden_mask(const std::tr1::shared_ptr<const OverriddenMask> &) const; 00111 00112 /** 00113 * This method will be called before any of the mask iteration 00114 * methods does its work. It can be used by subclasses to implement 00115 * as-needed loading of masks. 00116 */ 00117 virtual void need_masks_added() const = 0; 00118 00119 public: 00120 ///\name Basic operations 00121 ///\{ 00122 00123 PackageID(); 00124 virtual ~PackageID() = 0; 00125 00126 std::size_t hash() const PALUDIS_ATTRIBUTE((warn_unused_result)); 00127 00128 ///\} 00129 00130 ///\name Name related operations 00131 ///\{ 00132 00133 /** 00134 * Return our canonical string representation. 00135 * 00136 * This method (which is called by paludis::stringify()) should be 00137 * used when outputting a PackageID or a PackageID's version. Some 00138 * repositories need to display additional information to identify a 00139 * package, so outputting merely the name and / or version may be 00140 * insufficient. 00141 */ 00142 virtual const std::string canonical_form(const PackageIDCanonicalForm) const = 0; 00143 00144 /** 00145 * What is our package name? 00146 * 00147 * Use canonical_form instead for outputting. 00148 */ 00149 virtual const QualifiedPackageName name() const = 0; 00150 00151 /** 00152 * What is our package version? 00153 * 00154 * Use canonical_form instead for outputting. 00155 */ 00156 virtual const VersionSpec version() const = 0; 00157 00158 /** 00159 * What is our owning repository? 00160 */ 00161 virtual const std::tr1::shared_ptr<const Repository> repository() const = 0; 00162 00163 /** 00164 * Return a PackageDepSpec that uniquely identifies us. 00165 * 00166 * When stringified, can be turned back into an equivalent unique 00167 * PackageDepSpec by using parse_user_package_dep_spec. 00168 * 00169 * \since 0.36 00170 */ 00171 virtual PackageDepSpec uniquely_identifying_spec() const = 0; 00172 00173 ///\} 00174 00175 ///\name Specific metadata keys 00176 ///\{ 00177 00178 /** 00179 * The slot, if specified, controls whether the package can be 00180 * installed in parallel with other versions of the same package. 00181 * 00182 * \since 0.36 00183 */ 00184 virtual const std::tr1::shared_ptr<const MetadataValueKey<SlotName> > slot_key() const = 0; 00185 00186 /** 00187 * The virtual_for_key, if non-zero, indicates that we are an 00188 * (old-style) virtual for another package. This affects dependency 00189 * resolution. 00190 */ 00191 virtual const std::tr1::shared_ptr<const MetadataValueKey<std::tr1::shared_ptr<const PackageID> > > virtual_for_key() const = 0; 00192 00193 /** 00194 * The keywords_key, if non-zero, is used by FindUnusedPackagesTask 00195 * to determine whether a package is unused. 00196 */ 00197 virtual const std::tr1::shared_ptr<const MetadataCollectionKey<KeywordNameSet> > keywords_key() const = 0; 00198 00199 /** 00200 * The provide_key, if non-zero, indicates that a package provides 00201 * certain old-style virtuals. This affects dependency resolution. 00202 */ 00203 virtual const std::tr1::shared_ptr<const MetadataSpecTreeKey<ProvideSpecTree> > provide_key() const = 0; 00204 00205 /** 00206 * The contains_key, if non-zero, indicates that a package contains 00207 * other packages. This affects dependency resolution. */ 00208 virtual const std::tr1::shared_ptr<const MetadataCollectionKey<PackageIDSequence> > contains_key() const = 0; 00209 00210 /** 00211 * The contained_in_key, if non-zero, indicates that a package is 00212 * contained in another package. This affects dependency resolution. 00213 */ 00214 virtual const std::tr1::shared_ptr<const MetadataValueKey<std::tr1::shared_ptr<const PackageID> > > contained_in_key() const = 0; 00215 00216 /** 00217 * The build_dependencies_key, if non-zero, indicates a package's 00218 * build-time dependencies. 00219 */ 00220 virtual const std::tr1::shared_ptr<const MetadataSpecTreeKey<DependencySpecTree> > build_dependencies_key() const = 0; 00221 00222 /** 00223 * The run_dependencies_key, if non-zero, indicates a package's 00224 * run-time dependencies. 00225 */ 00226 virtual const std::tr1::shared_ptr<const MetadataSpecTreeKey<DependencySpecTree> > run_dependencies_key() const = 0; 00227 00228 /** 00229 * The post_dependencies_key, if non-zero, indicates a package's 00230 * post-merge dependencies. 00231 */ 00232 virtual const std::tr1::shared_ptr<const MetadataSpecTreeKey<DependencySpecTree> > post_dependencies_key() const = 0; 00233 00234 /** 00235 * The suggested_dependencies_key, if non-zero, indicates a package's 00236 * suggested post-merge dependencies. 00237 */ 00238 virtual const std::tr1::shared_ptr<const MetadataSpecTreeKey<DependencySpecTree> > suggested_dependencies_key() const = 0; 00239 00240 /** 00241 * The fetches_key, if non-zero, indicates files that have to be fetched 00242 * in order to install a package. 00243 */ 00244 virtual const std::tr1::shared_ptr<const MetadataSpecTreeKey<FetchableURISpecTree> > fetches_key() const = 0; 00245 00246 /** 00247 * The homepage_key, if non-zero, describes a package's homepages. 00248 */ 00249 virtual const std::tr1::shared_ptr<const MetadataSpecTreeKey<SimpleURISpecTree> > homepage_key() const = 0; 00250 00251 /** 00252 * The short_description_key, if non-zero, provides a short (no more 00253 * than a few hundred characters) description of a package. 00254 */ 00255 virtual const std::tr1::shared_ptr<const MetadataValueKey<std::string> > short_description_key() const = 0; 00256 00257 /** 00258 * The long_description_key, if non-zero, provides a long 00259 * description of a package. 00260 */ 00261 virtual const std::tr1::shared_ptr<const MetadataValueKey<std::string> > long_description_key() const = 0; 00262 00263 /** 00264 * The contents_key, if non-zero, contains the contents of a 00265 * package. For installed packages, this means the files installed; 00266 * for installable packages, this means the files that will be 00267 * installed (if known, which it may be for some binary packages). 00268 */ 00269 virtual const std::tr1::shared_ptr<const MetadataValueKey<std::tr1::shared_ptr<const Contents> > > contents_key() const = 0; 00270 00271 /** 00272 * The installed_time_key, if non-zero, contains the time a package 00273 * was installed. It affects dependency resolution if DepList is 00274 * using dl_reinstall_scm_daily or dl_reinstall_scm_weekly. 00275 */ 00276 virtual const std::tr1::shared_ptr<const MetadataTimeKey> installed_time_key() const = 0; 00277 00278 /** 00279 * The from_repositories key, if non-zero, contains the set of repositories 00280 * that the ID is 'from'. An ID can be 'from' multiple repositories if, for 00281 * example, it was built via a binary package. 00282 */ 00283 virtual const std::tr1::shared_ptr<const MetadataCollectionKey<Set<std::string> > > from_repositories_key() const = 0; 00284 00285 /** 00286 * The fs_location_key, if non-zero, indicates the filesystem 00287 * location (for example, the ebuild file or VDB directory) that 00288 * best describes the location of a PackageID. 00289 */ 00290 virtual const std::tr1::shared_ptr<const MetadataValueKey<FSEntry> > fs_location_key() const = 0; 00291 00292 /** 00293 * The transient_key, if non-zero, indicates whether this 00294 * PackageID's originating repository is volatile. 00295 */ 00296 virtual const std::tr1::shared_ptr<const MetadataValueKey<bool> > transient_key() const = 0; 00297 00298 /** 00299 * The choices_key, if non-zero, contains zero or more 00300 * MetadataValueKey<std::tr1::shared_ptr<const Choice> > child 00301 * keys holding choice information for this ID. 00302 */ 00303 virtual const std::tr1::shared_ptr<const MetadataValueKey<std::tr1::shared_ptr<const Choices> > > choices_key() const = 0; 00304 00305 ///\} 00306 00307 ///\name Actions 00308 ///\{ 00309 00310 /** 00311 * Do we support a particular action? 00312 * 00313 * Attempting to call perform_action with an unsupported action type 00314 * will lead to an UnsupportedActionError. However, in performance 00315 * critical code and in situations where creating a full Action 00316 * subclass instance is non-trivial, supports_action is much 00317 * simpler. 00318 */ 00319 virtual bool supports_action(const SupportsActionTestBase &) const PALUDIS_ATTRIBUTE((warn_unused_result)) = 0; 00320 00321 /** 00322 * Perform the specified action. 00323 */ 00324 virtual void perform_action(Action &) const = 0; 00325 00326 ///\} 00327 00328 ///\name Masks 00329 ///\{ 00330 00331 struct MasksConstIteratorTag; 00332 typedef WrappedForwardIterator<MasksConstIteratorTag, const std::tr1::shared_ptr<const Mask> > MasksConstIterator; 00333 00334 MasksConstIterator begin_masks() const PALUDIS_ATTRIBUTE((warn_unused_result)); 00335 MasksConstIterator end_masks() const PALUDIS_ATTRIBUTE((warn_unused_result)); 00336 00337 /** 00338 * Do we have any effective masks? Equivalent to begin_masks() != end_masks(). 00339 */ 00340 bool masked() const PALUDIS_ATTRIBUTE((warn_unused_result)); 00341 00342 /** 00343 * Invalidate any masks. 00344 * 00345 * PackageID implementations may cache masks. This can cause 00346 * problems if the operating environment changes. Calling this 00347 * method will clear any masks held by the PackageID. 00348 */ 00349 virtual void invalidate_masks() const; 00350 00351 /** 00352 * Do we break Portage, and if so, why? 00353 * 00354 * This method may be used by Environment implementations to apply a "we don't 00355 * want packages that break Portage" mask. 00356 */ 00357 virtual std::tr1::shared_ptr<const Set<std::string> > breaks_portage() const PALUDIS_ATTRIBUTE((warn_unused_result)) = 0; 00358 00359 ///\} 00360 00361 ///\name Overridden masks 00362 ///\{ 00363 ///\since 0.34 00364 00365 struct OverriddenMasksConstIteratorTag; 00366 typedef WrappedForwardIterator<OverriddenMasksConstIteratorTag, const std::tr1::shared_ptr<const OverriddenMask> > OverriddenMasksConstIterator; 00367 00368 OverriddenMasksConstIterator begin_overridden_masks() const PALUDIS_ATTRIBUTE((warn_unused_result)); 00369 OverriddenMasksConstIterator end_overridden_masks() const PALUDIS_ATTRIBUTE((warn_unused_result)); 00370 00371 ///\} 00372 00373 ///\name Extra comparisons 00374 ///\{ 00375 00376 /** 00377 * Perform an arbitrary less than comparison on another PackageID. 00378 * 00379 * Used by PackageIDSetComparator and operator==. This function 00380 * should not be used by anything else. 00381 * 00382 * This function will only be called if the other PackageID has the 00383 * same name, version and repository as this. If this is not enough 00384 * to uniquely identify an ID (e.g. if there is an affix, or if multiple 00385 * slots per version are allowed), then this function's 00386 * implementation must differentiate appropriately. 00387 */ 00388 virtual bool arbitrary_less_than_comparison(const PackageID &) const 00389 PALUDIS_ATTRIBUTE((warn_unused_result)) = 0; 00390 00391 /** 00392 * Provide any additional hash information for a PackageID. 00393 * 00394 * The standard PackageID hash incorporates the repository name, the 00395 * package name and the version of the package. If this function is 00396 * defined, its value is also used when determining a hash. This can 00397 * provide increased performance if a repository uses affixes or 00398 * multiple slots per version. 00399 */ 00400 virtual std::size_t extra_hash_value() const 00401 PALUDIS_ATTRIBUTE((warn_unused_result)) = 0; 00402 00403 ///\} 00404 00405 /** 00406 * The dependencies_key, if non-zero, provides all of a package's 00407 * dependencies. 00408 * 00409 * If dependencies_key is used, the client should ignore 00410 * build_dependencies_key, run_dependencies_key, 00411 * post_dependencies_key and suggested_dependencies_key. 00412 * 00413 * Repositories that support this key must also provide the old 00414 * split out keys. 00415 * 00416 * \since 0.40.1 00417 */ 00418 virtual const std::tr1::shared_ptr<const MetadataSpecTreeKey<DependencySpecTree> > dependencies_key() const = 0; 00419 }; 00420 00421 /** 00422 * PackageID instances are equality-comparable. 00423 * 00424 * \ingroup g_package_id 00425 * \since 0.26 00426 */ 00427 bool operator== (const PackageID &, const PackageID &) PALUDIS_ATTRIBUTE((warn_unused_result)) PALUDIS_VISIBLE; 00428 00429 /** 00430 * A comparison functor that uses PackageID::arbitrary_less_than_comparison 00431 * to provide a meaningless but stable ordering for PackageIDSet. 00432 * 00433 * \ingroup g_package_id 00434 * \since 0.26 00435 * \nosubgrouping 00436 */ 00437 class PALUDIS_VISIBLE PackageIDSetComparator 00438 { 00439 public: 00440 /** 00441 * Perform an arbitrary less-than comparison. 00442 */ 00443 bool operator() (const std::tr1::shared_ptr<const PackageID> &, 00444 const std::tr1::shared_ptr<const PackageID> &) const; 00445 }; 00446 00447 /** 00448 * A comparison functor that provides a less-than comparison on PackageID 00449 * instances according to, in order, their name, their version, their 00450 * repository's importance according to the supplied PackageDatabase, 00451 * and PackageID::arbitrary_less_than_comparison. 00452 * 00453 * \ingroup g_package_id 00454 * \since 0.26 00455 * \nosubgrouping 00456 */ 00457 class PALUDIS_VISIBLE PackageIDComparator : 00458 private PrivateImplementationPattern<PackageIDComparator> 00459 { 00460 public: 00461 ///\name Standard library typedefs 00462 ///\{ 00463 00464 typedef bool result_type; 00465 00466 ///\} 00467 00468 ///\name Basic operations 00469 ///\{ 00470 00471 PackageIDComparator(const PackageDatabase * const); 00472 PackageIDComparator(const PackageIDComparator &); 00473 ~PackageIDComparator(); 00474 00475 ///\} 00476 00477 /** 00478 * Perform the less-than comparison. 00479 */ 00480 bool operator() (const std::tr1::shared_ptr<const PackageID> &, 00481 const std::tr1::shared_ptr<const PackageID> &) const; 00482 }; 00483 } 00484 00485 #endif