paludis  Version 2.6.0
environment.hh
Go to the documentation of this file.
1 /* vim: set sw=4 sts=4 et foldmethod=syntax : */
2 
3 /*
4  * Copyright (c) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2014 Ciaran McCreesh
5  *
6  * This file is part of the Paludis package manager. Paludis is free software;
7  * you can redistribute it and/or modify it under the terms of the GNU General
8  * Public License version 2, as published by the Free Software Foundation.
9  *
10  * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
11  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13  * details.
14  *
15  * You should have received a copy of the GNU General Public License along with
16  * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
17  * Place, Suite 330, Boston, MA 02111-1307 USA
18  */
19 
20 #ifndef PALUDIS_GUARD_PALUDIS_ENVIRONMENT_HH
21 #define PALUDIS_GUARD_PALUDIS_ENVIRONMENT_HH 1
22 
24 
25 #include <paludis/output_manager-fwd.hh>
26 #include <paludis/name-fwd.hh>
27 #include <paludis/hook-fwd.hh>
29 #include <paludis/dep_spec.hh>
30 #include <paludis/spec_tree-fwd.hh>
32 #include <paludis/mask-fwd.hh>
33 #include <paludis/selection-fwd.hh>
34 #include <paludis/metadata_key_holder.hh>
35 #include <paludis/choice-fwd.hh>
36 #include <paludis/create_output_manager_info-fwd.hh>
37 #include <paludis/notifier_callback-fwd.hh>
38 #include <paludis/filter-fwd.hh>
39 
41 #include <paludis/util/tribool-fwd.hh>
42 #include <paludis/util/visitor.hh>
43 #include <paludis/util/pimp.hh>
45 
46 /** \file
47  * Declarations for the Environment class.
48  *
49  * \ingroup g_environment
50  *
51  * \section Examples
52  *
53  * - \ref example_environment.cc "example_environment.cc"
54  */
55 
56 namespace paludis
57 {
58  /**
59  * Thrown if a query results in more than one matching package.
60  *
61  * \ingroup g_exceptions
62  * \ingroup g_environment
63  */
65  public Exception
66  {
67  private:
68  struct NameData;
69  NameData * const _name_data;
70 
71  std::string _name;
72 
73  public:
74  ///\name Basic operations
75  ///\{
76 
77  AmbiguousPackageNameError(const std::string & name, const std::shared_ptr<const Sequence<std::string> > &) noexcept;
78 
80 
81  virtual ~AmbiguousPackageNameError();
82 
83  ///\}
84 
85  /**
86  * The name of the package.
87  */
88  const std::string & name() const PALUDIS_ATTRIBUTE((warn_unused_result));
89 
90  ///\name Iterate over possible matches
91  ///\{
92 
93  struct OptionsConstIteratorTag;
95 
96  OptionsConstIterator begin_options() const PALUDIS_ATTRIBUTE((warn_unused_result));
97  OptionsConstIterator end_options() const PALUDIS_ATTRIBUTE((warn_unused_result));
98 
99  ///\}
100  };
101 
102  /**
103  * Thrown if a Repository with the same name as an existing member is added
104  * to an Environment.
105  *
106  * \ingroup g_exceptions
107  * \ingroup g_environment
108  */
110  public Exception
111  {
112  public:
113  /**
114  * Constructor.
115  */
116  DuplicateRepositoryError(const std::string & name) noexcept;
117  };
118 
119  /**
120  * Thrown if there is no Package with the given name.
121  *
122  * \ingroup g_exceptions
123  * \ingroup g_environment
124  */
126  public Exception
127  {
128  private:
129  std::string _name;
130 
131  public:
132  ///\name Basic operations
133  ///\{
134 
135  NoSuchPackageError(const std::string & name) noexcept;
136 
137  virtual ~NoSuchPackageError()
138  {
139  }
140 
141  ///\}
142 
143  /**
144  * Name of the package.
145  */
146  const std::string & name() const
147  {
148  return _name;
149  }
150  };
151 
152  /**
153  * Thrown if there is no Repository in a RepositoryDatabase with the given
154  * name.
155  *
156  * \ingroup g_exceptions
157  * \ingroup g_environment
158  */
160  public Exception
161  {
162  private:
163  const RepositoryName _name;
164 
165  public:
166  ///\name Basic operations
167  ///\{
168 
169  NoSuchRepositoryError(const RepositoryName &) noexcept;
170 
172 
173  ///\}
174 
175  /**
176  * The name of our repository.
177  */
178  RepositoryName name() const;
179  };
180 
181  /**
182  * Represents a working environment, which contains an available packages
183  * database and provides various methods for querying package visibility
184  * and options.
185  *
186  * Holds a number of Repository instances.
187  *
188  * Environment itself is purely an interface class. Actual Environment
189  * implementations usually descend from EnvironmentImplementation, which
190  * provides much of the common implementation details. EnvironmentFactory is
191  * often used to create the appropriate Environment subclass for an
192  * application.
193  *
194  * \ingroup g_environment
195  * \see EnvironmentFactory
196  * \see EnvironmentImplementation
197  * \see Repository
198  * \nosubgrouping
199  */
201  public MetadataKeyHolder
202  {
203  protected:
204  static const Filter & all_filter() PALUDIS_ATTRIBUTE((warn_unused_result));
205 
206  public:
207  ///\name Basic operations
208  ///\{
209 
210  Environment() = default;
211  virtual ~Environment() = 0;
212 
213  Environment(const Environment &) = delete;
214  Environment & operator= (const Environment &) = delete;
215 
216  ///\}
217 
218  ///\name Choice-related queries
219  ///\{
220 
221  /**
222  * Do we want a choice enabled for a particular package?
223  *
224  * Only for use by Repository, to get defaults from the environment.
225  * Clients should query the metadata key directly.
226  *
227  * The third parameter is the name of the value, which might not
228  * have been created yet.
229  */
230  virtual const Tribool want_choice_enabled(
231  const std::shared_ptr<const PackageID> &,
232  const std::shared_ptr<const Choice> &,
233  const UnprefixedChoiceName &
234  ) const
235  PALUDIS_ATTRIBUTE((warn_unused_result)) = 0;
236 
237  /**
238  * What string value, if any, is set for the parameter for a particular
239  * choice for a particular package?
240  *
241  * There is no difference between "not set" and "set to an empty
242  * string".
243  *
244  * Only for use by Repository, to get defaults from the environment.
245  * Clients should query the metadata key directly.
246  *
247  * The third parameter is the name of the value, which might not
248  * have been created yet.
249  *
250  * \since 0.40
251  */
252  virtual const std::string value_for_choice_parameter(
253  const std::shared_ptr<const PackageID> &,
254  const std::shared_ptr<const Choice> &,
255  const UnprefixedChoiceName &
256  ) const
257  PALUDIS_ATTRIBUTE((warn_unused_result)) = 0;
258 
259  /**
260  * Return a collection of known value names for a particular
261  * choice.
262  *
263  * Only for use by Repository, to get defaults from the environment.
264  * Clients should query the metadata key directly.
265  *
266  * This is to deal with cases like USE_EXPAND values, where the
267  * repository doesn't know all possible values.
268  */
269  virtual std::shared_ptr<const Set<UnprefixedChoiceName> > known_choice_value_names(
270  const std::shared_ptr<const PackageID> &,
271  const std::shared_ptr<const Choice> &
272  ) const
273  PALUDIS_ATTRIBUTE((warn_unused_result)) = 0;
274 
275  ///\}
276 
277  ///\name Suggestion-related queries
278  ///\{
279 
280  /**
281  * Do we want to ignore or take a particular suggestion from a
282  * particular package?
283  *
284  * Command line things override this.
285  *
286  * \since 0.58
287  */
288  virtual Tribool interest_in_suggestion(
289  const std::shared_ptr<const PackageID> & from_id,
290  const PackageDepSpec & spec) const
291  PALUDIS_ATTRIBUTE((warn_unused_result)) = 0;
292 
293  ///\}
294 
295  ///\name Mask-related queries
296  ///\{
297 
298  /**
299  * Do we accept a particular license for a particular package?
300  *
301  * Used by PackageID implementations. Generally PackageID's masks methods
302  * should be used rather than calling this directly.
303  *
304  * \since 0.58 takes id by shared_ptr
305  */
306  virtual bool accept_license(
307  const std::string &,
308  const std::shared_ptr<const PackageID> &) const
309  PALUDIS_ATTRIBUTE((warn_unused_result)) = 0;
310 
311  /**
312  * Expand a licence group into its constituent licences, recursively (if any
313  * of our repositories thinks it is a group).
314  *
315  * The original group is included in the result.
316  *
317  * \since 0.68
318  */
319  virtual const std::shared_ptr<const Set<std::string> > expand_licence(
320  const std::string &) const
321  PALUDIS_ATTRIBUTE((warn_unused_result)) = 0;
322 
323  /**
324  * Do we accept any of the specified keywords for a particular package?
325  *
326  * If the collection includes "*", should return true.
327  *
328  * Used by PackageID implementations. Generally PackageID's masks methods
329  * should be used rather than calling this directly.
330  *
331  * \since 0.58 takes id by shared_ptr
332  */
333  virtual bool accept_keywords(
334  const std::shared_ptr<const KeywordNameSet> &,
335  const std::shared_ptr<const PackageID> &) const
336  PALUDIS_ATTRIBUTE((warn_unused_result)) = 0;
337 
338  /**
339  * Do we have a 'user' mask for a particular package?
340  *
341  * Returns a zero pointer if no.
342  *
343  * If the second parameter is true, return a Mask suitable for
344  * being added to an OverriddenMask.
345  *
346  * Used by PackageID implementations. Generally PackageID's masks methods
347  * should be used rather than calling this directly.
348  *
349  * \since 0.58 takes id by shared_ptr
350  */
351  virtual const std::shared_ptr<const Mask> mask_for_user(
352  const std::shared_ptr<const PackageID> &,
353  const bool will_be_used_for_overridden) const
354  PALUDIS_ATTRIBUTE((warn_unused_result)) = 0;
355 
356  /**
357  * Do we have a user unmask for a particular package?
358  *
359  * This is only applied to repository and profile style masks, not
360  * keywords, licences etc. If true, user_mask shouldn't be used.
361  *
362  * Used by PackageID implementations. Generally PackageID's masks methods
363  * should be used rather than calling this directly.
364  *
365  * \since 0.58 takes id by shared_ptr
366  * \since 0.60 takes optional extra reason string
367  */
368  virtual bool unmasked_by_user(
369  const std::shared_ptr<const PackageID> &,
370  const std::string &) const
371  PALUDIS_ATTRIBUTE((warn_unused_result)) = 0;
372 
373  ///\}
374 
375  /**
376  * Select some packages.
377  */
378  virtual std::shared_ptr<PackageIDSequence> operator[] (const Selection &) const
379  PALUDIS_ATTRIBUTE((warn_unused_result)) = 0;
380 
381  /**
382  * Create a repository from a particular file.
383  *
384  * Does not add the repository to the Environment.
385  *
386  * This allows RepositoryRepository to add a repo config file, then
387  * sync that repo. If you aren't RepositoryRepository you shouldn't
388  * be calling this.
389  *
390  * \since 0.48
391  */
392  virtual const std::shared_ptr<Repository> repository_from_new_config_file(
393  const FSPath &) PALUDIS_ATTRIBUTE((warn_unused_result)) = 0;
394 
395  ///\}
396 
397  ///\name System information
398  ///\{
399 
400  /**
401  * Return a collection of bashrc files to be used by the various components
402  * that are implemented in bash.
403  */
404  virtual std::shared_ptr<const FSPathSequence> bashrc_files() const
405  PALUDIS_ATTRIBUTE((warn_unused_result)) = 0;
406 
407  /**
408  * Return directories to search for syncer scripts.
409  */
410  virtual std::shared_ptr<const FSPathSequence> syncers_dirs() const
411  PALUDIS_ATTRIBUTE((warn_unused_result)) = 0;
412 
413  /**
414  * Return directories to search for fetcher scripts.
415  */
416  virtual std::shared_ptr<const FSPathSequence> fetchers_dirs() const
417  PALUDIS_ATTRIBUTE((warn_unused_result)) = 0;
418 
419  /**
420  * Return directories to search for hooks.
421  */
422  virtual std::shared_ptr<const FSPathSequence> hook_dirs() const
423  PALUDIS_ATTRIBUTE((warn_unused_result)) = 0;
424 
425  /**
426  * User id to use when reduced privs are permissible.
427  */
428  virtual uid_t reduced_uid() const = 0;
429 
430  /**
431  * Group id to use when reduced privs are permissible.
432  */
433  virtual gid_t reduced_gid() const = 0;
434 
435  /**
436  * Is the specified package Paludis?
437  *
438  * Used by InstallTask to decide whether to exec() after installing
439  * a package.
440  */
441  virtual bool is_paludis_package(const QualifiedPackageName &) const
442  PALUDIS_ATTRIBUTE((warn_unused_result)) = 0;
443 
444  ///\}
445 
446  ///\name Mirror information
447  ///\{
448 
449  /**
450  * Return the mirror URI prefixes for a named mirror.
451  */
452  virtual std::shared_ptr<const MirrorsSequence> mirrors(const std::string &) const
453  PALUDIS_ATTRIBUTE((warn_unused_result)) = 0;
454 
455  ///\}
456 
457  ///\name Package sets
458  ///\{
459 
460  /**
461  * Add a package set.
462  *
463  * Generally called by repositories, when Repository::populate_sets is called.
464  *
465  * \param base_name The basic name of the set, such as 'security'.
466  *
467  * \param combined_name The name to use for this set when combine is true, such
468  * as 'security.myrepo'. If combine is false, should be the same as base_name.
469  *
470  * \param func A function that returns the set.
471  *
472  * \param combine If true, rename the set from foo to foo.reponame, and make
473  * the foo set contain foo.reponame, along with any other repositories'
474  * sets named foo. If false, throw if the set already exists.
475  *
476  * \since 0.40
477  */
478  virtual void add_set(
479  const SetName & base_name,
480  const SetName & combined_name,
481  const std::function<std::shared_ptr<const SetSpecTree> ()> & func,
482  const bool combine) const = 0;
483 
484  /**
485  * Return all known named sets.
486  */
487  virtual std::shared_ptr<const SetNameSet> set_names() const
488  PALUDIS_ATTRIBUTE((warn_unused_result)) = 0;
489 
490  /**
491  * Return a named set.
492  *
493  * If the named set is not known, returns a zero pointer.
494  */
495  virtual const std::shared_ptr<const SetSpecTree> set(const SetName &) const
496  PALUDIS_ATTRIBUTE((warn_unused_result)) = 0;
497 
498  ///\}
499 
500  ///\name Hook methods
501  ///\{
502 
503  /**
504  * Perform a hook.
505  *
506  * \since 0.53 takes optional_output_manager
507  */
508  virtual HookResult perform_hook(
509  const Hook &,
510  const std::shared_ptr<OutputManager> & optional_output_manager) const
511  PALUDIS_ATTRIBUTE((warn_unused_result)) = 0;
512 
513  ///\}
514 
515  ///\name Distribution information
516  ///\{
517 
518  virtual std::string distribution() const
519  PALUDIS_ATTRIBUTE((warn_unused_result)) = 0;
520 
521  ///\}
522 
523  ///\name World and configuration functionality
524  ///\{
525 
526  /**
527  * Add this package to world.
528  *
529  * \return whether anything was added \since 0.49
530  */
531  virtual bool add_to_world(const QualifiedPackageName &) const = 0;
532 
533  /**
534  * Add this set to world.
535  *
536  * \return whether anything was added \since 0.49
537  */
538  virtual bool add_to_world(const SetName &) const = 0;
539 
540  /**
541  * Remove this package from world, if it is present.
542  *
543  * \return whether anything was removed \since 0.49
544  */
545  virtual bool remove_from_world(const QualifiedPackageName &) const = 0;
546 
547  /**
548  * Remove this set from world, if it is present.
549  *
550  * \return whether anything was removed \since 0.49
551  */
552  virtual bool remove_from_world(const SetName &) const = 0;
553 
554  /**
555  * Where possible, update configuration files with the first spec to use the second package name.
556  *
557  * Does not necessarily invalidate any in-memory configuration.
558  *
559  * \since 0.48
560  */
561  virtual void update_config_files_for_package_move(
562  const PackageDepSpec &, const QualifiedPackageName &) const = 0;
563 
564  ///\}
565 
566  ///\name Specific metadata keys
567  ///\{
568 
569  /**
570  * The preferred_root_key, which must not be null, specifies the
571  * preferred filesystem root for actions.
572  *
573  * \since 0.54
574  */
575  virtual const std::shared_ptr<const MetadataValueKey<FSPath> > preferred_root_key() const = 0;
576 
577  /**
578  * The system_root_key, which must not be null, specifies the
579  * filesystem root for dependencies etc. This is usually "/",
580  * unless something funky is going on.
581  *
582  * \since 0.55
583  */
584  virtual const std::shared_ptr<const MetadataValueKey<FSPath> > system_root_key() const = 0;
585 
586  /**
587  * The format_key, if non-zero, holds our environment's format. Environment
588  * implementations should not return zero here, but clients should still
589  * check.
590  */
591  virtual const std::shared_ptr<const MetadataValueKey<std::string> > format_key() const = 0;
592 
593  /**
594  * The config_location_key, if non-zero, specifies the location of the configuration file or directory,
595  * the contents of which depends on the format returned by format_key.
596  */
597  virtual const std::shared_ptr<const MetadataValueKey<FSPath> > config_location_key() const = 0;
598 
599  ///\}
600 
601  ///\name Output management
602  ///\{
603 
604  /**
605  * Create an output manager.
606  *
607  * \since 0.36
608  */
609  virtual const std::shared_ptr<OutputManager> create_output_manager(
610  const CreateOutputManagerInfo &) const = 0;
611 
612  /**
613  * Set a callback function to use when a particular event occurs.
614  *
615  * The return value can be passed to remove_notifier_callback.
616  *
617  * \since 0.40
618  */
619  virtual NotifierCallbackID add_notifier_callback(const NotifierCallbackFunction &) = 0;
620 
621  /**
622  * Remove a function added with add_notifier_callback.
623  *
624  * \since 0.40
625  */
626  virtual void remove_notifier_callback(const NotifierCallbackID) = 0;
627 
628  /**
629  * Trigger a notifier callback.
630  *
631  * \since 0.40
632  */
633  virtual void trigger_notifier_callback(const NotifierCallbackEvent &) const = 0;
634 
635  ///\}
636 
637  ///\name Repositories
638  ///\{
639 
640  /**
641  * Add a repository.
642  *
643  * \since 0.61 is in Environment rather than PackageDatabase
644  *
645  * \exception DuplicateRepositoryError if a Repository with the
646  * same name as the new Repository already exists in our
647  * collection.
648  */
649  virtual void add_repository(int importance, const std::shared_ptr<Repository> &) = 0;
650 
651  /**
652  * Fetch a named repository.
653  *
654  * \since 0.61 is in Environment rather than PackageDatabase
655  */
656  virtual const std::shared_ptr<const Repository> fetch_repository(const RepositoryName &) const
657  PALUDIS_ATTRIBUTE((warn_unused_result)) = 0;
658 
659  /**
660  * Fetch a named repository.
661  *
662  * \since 0.61 is in Environment rather than PackageDatabase
663  */
664  virtual const std::shared_ptr<Repository> fetch_repository(const RepositoryName &)
665  PALUDIS_ATTRIBUTE((warn_unused_result)) = 0;
666 
667  /**
668  * Do we have a named repository?
669  *
670  * \since 0.61 is in Environment rather than PackageDatabase
671  */
672  virtual bool has_repository_named(const RepositoryName &) const
673  PALUDIS_ATTRIBUTE((warn_unused_result)) = 0;
674 
675  /**
676  * Disambiguate a package name. If a filter is specified,
677  * limit the potential results to packages that match.
678  *
679  * \throw AmbiguousPackageNameError if there is no unambiguous
680  * disambiguation. If disambiguate is set to false, the
681  * exception will be always thrown in presence of ambiguity.
682  * \since 0.56 takes the disambiguate flag.
683  *
684  * \since 0.61 is in Environment rather than PackageDatabase
685  */
686  virtual QualifiedPackageName fetch_unique_qualified_package_name(
687  const PackageNamePart &, const Filter & = all_filter(), const bool disambiguate = true) const
688  PALUDIS_ATTRIBUTE((warn_unused_result)) = 0;
689 
690  /**
691  * Return true if the first repository is more important than the second.
692  *
693  * \since 0.61 is in Environment rather than PackageDatabase
694  */
695  virtual bool more_important_than(const RepositoryName &, const RepositoryName &) const
696  PALUDIS_ATTRIBUTE((warn_unused_result)) = 0;
697 
698  ///\}
699 
700  ///\name Iterate over our repositories
701  ///\{
702 
703  struct RepositoryConstIteratorTag;
705 
706  virtual RepositoryConstIterator begin_repositories() const
707  PALUDIS_ATTRIBUTE((warn_unused_result)) = 0;
708 
709  virtual RepositoryConstIterator end_repositories() const
710  PALUDIS_ATTRIBUTE((warn_unused_result)) = 0;
711 
712  ///\}
713  };
714 
719 }
720 
721 #endif
Definition: environment.hh:109
Definition: pimp.hh:51
Definition: about_metadata-fwd.hh:23
Definition: name.hh:110
Definition: filter.hh:57
Definition: environment.hh:125
Definition: exception.hh:74
Definition: hook.hh:61
Definition: dep_spec.hh:345
Definition: sequence-fwd.hh:32
Definition: environment.hh:200
Definition: notifier_callback.hh:33
Definition: environment.hh:64
Definition: hook.hh:74
Definition: wrapped_forward_iterator-fwd.hh:26
Definition: wrapped_value-fwd.hh:29
const std::string & name() const
Definition: environment.hh:146
Definition: fs_path.hh:33
Definition: tribool.hh:27
Definition: metadata_key_holder.hh:38
Definition: create_output_manager_info.hh:43
Definition: environment.hh:159
Definition: selection.hh:70
#define PALUDIS_ATTRIBUTE(x)
Definition: attributes.hh:53
#define PALUDIS_VISIBLE
Definition: attributes.hh:59