// file : bpkg/package-query.hxx -*- C++ -*- // license : MIT; see accompanying LICENSE file #ifndef BPKG_PACKAGE_QUERY_HXX #define BPKG_PACKAGE_QUERY_HXX #include #include #include #include #include #include namespace bpkg { // Query the available packages that optionally satisfy the specified // version constraint and return them in the version descending order, by // default. Note that a stub satisfies any constraint. // // By default if the revision is not explicitly specified for the version // constraint, then compare ignoring the revision. The idea is that when the // user runs 'bpkg build libfoo/1' and there is 1+1 available, it should // just work. The user shouldn't have to spell the revision // explicitly. Similarly, when we have 'depends: libfoo == 1', then it would // be strange if 1+1 did not satisfy this constraint. The same for libfoo <= // 1 -- 1+1 should satisfy. // // Note that by default we compare ignoring the iteration, as it can not be // specified in the manifest/command line. This way the latest iteration // will always be picked up. // // Pass true as the revision argument to query the exact available package // version, also comparing the version revision and iteration. // odb::result query_available (database&, const package_name&, const optional&, bool order = true, bool revision = false); // Only return packages that are in the specified repository fragments, their // complements or prerequisites (if prereq is true), recursively. While you // could maybe come up with a (barely comprehensible) view/query to achieve // this, doing it on the "client side" is definitely more straightforward. // vector> filter (const shared_ptr&, odb::result&&, bool prereq = true); pair, shared_ptr> filter_one (const shared_ptr&, odb::result&&, bool prereq = true); shared_ptr filter (const shared_ptr&, const shared_ptr&, bool prereq = true); vector, shared_ptr>> filter (const vector>&, odb::result&&, bool prereq = true); pair, shared_ptr> filter_one (const vector>&, odb::result&&, bool prereq = true); // Try to find packages that optionally satisfy the specified version // constraint in multiple databases, suppressing duplicates. Return the list // of packages and repository fragments in which each was found in the // package version descending order or empty list if none were found. Note // that a stub satisfies any constraint. // // Note that we return (loaded) lazy_shared_ptr in order to also convey // the database to which it belongs. // available_packages find_available (const linked_databases&, const package_name&, const optional&); // As above but only look for packages from the specified list of repository // fragments, their prerequisite repositories, and their complements, // recursively (note: recursivity applies to complements, not prerequisites). // using config_repo_fragments = database_map>>; available_packages find_available (const package_name&, const optional&, const config_repo_fragments&, bool prereq = true); // As above but only look for packages from a single repository fragment, // its prerequisite repositories, and its complements, recursively (note: // recursivity applies to complements, not prerequisites). Doesn't provide // the repository fragments the packages come from. // // It is assumed that the repository fragment lazy pointer contains the // database information. // vector> find_available (const package_name&, const optional&, const lazy_shared_ptr&, bool prereq = true); // As above but only look for a single package from the specified repository // fragment, its prerequisite repositories, and their complements, // recursively (note: recursivity applies to complements, not // prerequisites). Return the package and the repository fragment in which // it was found or NULL for both if not found. // // It is assumed that the repository fragment lazy pointer contains the // database information. // pair, lazy_shared_ptr> find_available_one (const package_name&, const optional&, const lazy_shared_ptr&, bool prereq = true, bool revision = false); // As above but look for a single package from a list of repository // fragments. // pair, shared_ptr> find_available_one (database&, const package_name&, const optional&, const vector>&, bool prereq = true, bool revision = false); // As above but look for a single package in multiple databases from their // respective root repository fragments. // pair, lazy_shared_ptr> find_available_one (const linked_databases&, const package_name&, const optional&, bool prereq = true, bool revision = false); // Try to find an available package corresponding to the specified selected // package and, if not found, return a transient one. The search is // performed in the ultimate dependent configurations of the selected // package (see dependent_repo_configs() for details). // // NOTE: repo_configs needs to be filled prior to the function call. // shared_ptr find_available (const common_options&, database&, const shared_ptr&); // As above but also pair the available package with the repository fragment // the available package comes from. Note that the package locations list is // left empty and that the returned repository fragment could be NULL if the // package is an orphan. // // NOTE: repo_configs needs to be filled prior to the function call. // pair, lazy_shared_ptr> find_available_fragment (const common_options&, database&, const shared_ptr&); // Try to find packages in multiple databases, traversing the explicitly and // implicitly linked databases recursively and suppressing duplicates and, // optionally, older package revisions. Return the list of packages and // repository fragments in which each was found in the package version // descending order or empty list if none were found. // // Note that we return (loaded) lazy_shared_ptr in order to also convey // the database to which it belongs. // available_packages find_available_all (const linked_databases&, const package_name&, bool suppress_older_revisions = true); // Create a transient (or fake, if you prefer) available_package object // corresponding to the specified selected object. Note that the package // locations list is left empty and that the returned repository fragment // could be NULL if the package is an orphan. // // Note that the repository fragment is searched in the ultimate dependent // configurations of the selected package (see dependent_repo_configs() for // details). // // Also note that in our model we assume that make_available_fragment() is // only called if there is no real available_package. This makes sure that // if the package moves (e.g., from testing to stable), then we will be // using stable to resolve its dependencies. // // NOTE: repo_configs needs to be filled prior to the function call. // pair, lazy_shared_ptr> make_available_fragment (const common_options&, database&, const shared_ptr&); // Try to find an available stub package in the imaginary system repository. // Such a repository contains stubs corresponding to the system packages // specified by the user on the command line with version information // (sys:libfoo/1.0, ?sys:libfoo/* but not ?sys:libfoo; the idea is that a // real stub won't add any extra information to such a specification so we // shouldn't insist on its presence). Semantically this imaginary repository // complements all real repositories. // extern vector> imaginary_stubs; shared_ptr find_imaginary_stub (const package_name&); // Try to find an available package in the existing packages registry. Such // a registry is configuration-specific and contains package versions // specified by the user on the command line as archives or directories for // specific configurations (see pkg-build for details on such packages). // // Note that semantically such a registry can be considered as an imaginary // repository which complements all the real repositories fetched in the // respective configuration. Also note that normally this repository is used // first (by calling this function) when trying to resolve a dependency // package, prior to searching in the real repositories. // extern vector, shared_ptr>> existing_packages; pair, lazy_shared_ptr> find_existing (database&, const package_name&, const optional&); inline pair, lazy_shared_ptr> find_existing (const package_name& n, const optional& c, const lazy_shared_ptr& rf) { return find_existing (rf.database (), n, c); } // Configurations to use as the repository information sources. // // The list normally contains the current configurations and configurations // of the specified on the command line build-to-hold packages (ultimate // dependents). // // For ultimate dependents we use configurations in which they are being // built as a source of the repository information. For dependency packages // we use configurations of their ultimate dependents. // extern linked_databases repo_configs; // Return the ultimate dependent configurations for packages in this // configuration. // // Specifically, this is an intersection of all the dependent configurations // for the specified configuration (see database::dependent_configs() for // details) and configurations which contain repository information // (repo_configs). // linked_databases dependent_repo_configs (database&); } #endif // BPKG_PACKAGE_QUERY_HXX