/**
 * Probe helper for a deps entry. Lookup all probe configurations and then
 * lookup in the directory where the deps file is present. For app dirs,
 *     1. RID specific entries are present in the package relative structure.
 *     2. Non-RID entries are present in the directory path.
 */
bool deps_resolver_t::probe_deps_entry(const deps_entry_t& entry, const pal::string_t& deps_dir, pal::string_t* candidate)
{
    if (probe_entry_in_configs(entry, candidate))
    {
        return true;
    }
    if (entry.is_rid_specific && entry.to_rel_path(deps_dir, candidate))
    {
        return true;
    }
    if (!entry.is_rid_specific && entry.to_dir_path(deps_dir, candidate))
    {
        return true;
    }
    return false;
}
bool deps_resolver_t::probe_entry_in_configs(const deps_entry_t& entry, pal::string_t* candidate)
{
    candidate->clear();
    for (const auto& config : m_probes)
    {
        trace::verbose(_X("  Considering entry [%s/%s/%s] and probe dir [%s]"), entry.library_name.c_str(), entry.library_version.c_str(), entry.relative_path.c_str(), config.probe_dir.c_str());

        if (config.only_serviceable_assets && !entry.is_serviceable)
        {
            trace::verbose(_X("    Skipping... not serviceable asset"));
            continue;
        }
        if (config.only_runtime_assets && entry.asset_type != deps_entry_t::asset_types::runtime)
        {
            trace::verbose(_X("    Skipping... not runtime asset"));
            continue;
        }
        pal::string_t probe_dir = config.probe_dir;
        if (config.match_hash)
        {
            if (entry.to_hash_matched_path(probe_dir, candidate))
            {
                assert(!config.is_roll_fwd_set());
                trace::verbose(_X("    Matched hash for [%s]"), candidate->c_str());
                return true;
            }
            trace::verbose(_X("    Skipping... match hash failed"));
        }
        else if (config.probe_deps_json)
        {
            // If the deps json has it then someone has already done rid selection and put the right stuff in the dir.
            // So checking just package name and version would suffice. No need to check further for the exact asset relative path.
            if (config.probe_deps_json->has_package(entry.library_name, entry.library_version) && entry.to_dir_path(probe_dir, candidate))
            {
                trace::verbose(_X("    Probed deps json and matched [%s]"), candidate->c_str());
                return true;
            }
            trace::verbose(_X("    Skipping... probe in deps json failed"));
        }
        else if (!config.is_roll_fwd_set())
        {
            if (entry.to_full_path(probe_dir, candidate))
            {
                trace::verbose(_X("    Specified no roll forward; matched [%s]"), candidate->c_str());
                return true;
            }
            trace::verbose(_X("    Skipping... not found in probe dir"));
        }
        else if (config.is_roll_fwd_set())
        {
            if (try_roll_forward(entry, probe_dir, config.patch_roll_fwd, config.prerelease_roll_fwd, candidate))
            {
                trace::verbose(_X("    Specified roll forward; matched [%s]"), candidate->c_str());
                return true;
            }
            trace::verbose(_X("    Skipping... could not roll forward and match in probe dir"));
        }

        // continue to try next probe config
    }
    return false;
}
Exemple #3
0
/**
 * Given a deps entry, do a probe (lookup) for the file, based on the probe config.
 *   -- When crossgen-ed folders are looked up, look up only "runtime" (managed) assets.
 *   -- When servicing directories are looked up, look up only if the deps file marks the entry as serviceable.
 *   -- When a deps json based probe is performed, the deps entry's package name and version must match.
 *   -- When looking into a published dir, for rid specific assets lookup rid split folders; for non-rid assets lookup the layout dir.
 */
bool deps_resolver_t::probe_deps_entry(const deps_entry_t& entry, const pal::string_t& deps_dir, int fx_level, pal::string_t* candidate)
{
    candidate->clear();

    for (const auto& config : m_probes)
    {
        trace::verbose(_X("  Considering entry [%s/%s/%s], probe dir [%s], probe fx level:%d, entry fx level:%d"),
            entry.library_name.c_str(), entry.library_version.c_str(), entry.asset.relative_path.c_str(), config.probe_dir.c_str(), config.fx_level, fx_level);

        if (config.only_serviceable_assets && !entry.is_serviceable)
        {
            trace::verbose(_X("    Skipping... not serviceable asset"));
            continue;
        }
        if (config.only_runtime_assets && entry.asset_type != deps_entry_t::asset_types::runtime)
        {
            trace::verbose(_X("    Skipping... not runtime asset"));
            continue;
        }
        pal::string_t probe_dir = config.probe_dir;

        if (config.is_fx())
        {
            assert(config.fx_level > 0);

            // Only probe frameworks that are the same level or lower than the current entry because
            // a lower-level fx should not have a dependency on a higher-level fx and because starting
            // with fx_level allows it to override a higher-level fx location if the entry is newer.
            // Note that fx_level 0 is the highest level (the app)
            if (fx_level <= config.fx_level)
            {
                // If the deps json has the package name and version, then someone has already done rid selection and
                // put the right asset in the dir. So checking just package name and version would suffice.
                // No need to check further for the exact asset relative sub path.
                if (config.probe_deps_json->has_package(entry.library_name, entry.library_version) && entry.to_dir_path(probe_dir, candidate))
                {
                    trace::verbose(_X("    Probed deps json and matched '%s'"), candidate->c_str());
                    return true;
                }
            }

            trace::verbose(_X("    Skipping... not found in deps json."));
        }
        else if (config.is_app())
        {
            // This is a published dir probe, so look up rid specific assets in the rid folders.
            assert(config.fx_level == 0);

            if (fx_level <= config.fx_level)
            {
                if (entry.is_rid_specific)
                {
                    if (entry.to_rel_path(deps_dir, candidate))
                    {
                        trace::verbose(_X("    Probed deps dir and matched '%s'"), candidate->c_str());
                        return true;
                    }
                }
                else
                {
                    // Non-rid assets, lookup in the published dir.
                    if (entry.to_dir_path(deps_dir, candidate))
                    {
                        trace::verbose(_X("    Probed deps dir and matched '%s'"), candidate->c_str());
                        return true;
                    }
                }
            }

            trace::verbose(_X("    Skipping... not found in deps dir '%s'"), deps_dir.c_str());
        }
        else if (entry.to_full_path(probe_dir, candidate))
        {
            trace::verbose(_X("    Probed package dir and matched '%s'"), candidate->c_str());
            return true;
        }

        trace::verbose(_X("    Skipping... not found in probe dir '%s'"), probe_dir.c_str());
        // continue to try next probe config
    }
    return false;
}