Merge pull request #2316 from schellap/rollfwd

Perform prerelease roll forward for FX and servicing
This commit is contained in:
Senthil 2016-04-06 20:21:15 -07:00
commit 76610c4cd4
11 changed files with 191 additions and 71 deletions

View file

@ -14,7 +14,8 @@ struct probe_config_t
{ {
pal::string_t probe_dir; pal::string_t probe_dir;
bool match_hash; bool match_hash;
bool roll_forward; bool patch_roll_fwd;
bool prerelease_roll_fwd;
const deps_json_t* probe_deps_json; const deps_json_t* probe_deps_json;
bool only_runtime_assets; bool only_runtime_assets;
@ -22,60 +23,66 @@ struct probe_config_t
void print() const void print() const
{ {
trace::verbose(_X("probe_config_t: probe=[%s] match-hash=[%d] roll-forward=[%d] deps-json=[%p]"), trace::verbose(_X("probe_config_t: probe=[%s] match-hash=[%d] patch-roll-forward=[%d] prerelease-roll-forward=[%d] deps-json=[%p]"),
probe_dir.c_str(), match_hash, roll_forward, probe_deps_json); probe_dir.c_str(), match_hash, patch_roll_fwd, prerelease_roll_fwd, probe_deps_json);
}
bool is_roll_fwd_set() const
{
return patch_roll_fwd || prerelease_roll_fwd;
} }
probe_config_t( probe_config_t(
const pal::string_t& probe_dir, const pal::string_t& probe_dir,
bool match_hash, bool match_hash,
bool roll_forward, bool patch_roll_fwd,
bool prerelease_roll_fwd,
const deps_json_t* probe_deps_json, const deps_json_t* probe_deps_json,
bool only_serviceable_assets, bool only_serviceable_assets,
bool only_runtime_assets) bool only_runtime_assets)
: probe_dir(probe_dir) : probe_dir(probe_dir)
, match_hash(match_hash) , match_hash(match_hash)
, roll_forward(roll_forward) , patch_roll_fwd(patch_roll_fwd)
, prerelease_roll_fwd(prerelease_roll_fwd)
, probe_deps_json(probe_deps_json) , probe_deps_json(probe_deps_json)
, only_serviceable_assets(only_serviceable_assets) , only_serviceable_assets(only_serviceable_assets)
, only_runtime_assets(only_runtime_assets) , only_runtime_assets(only_runtime_assets)
{ {
// Cannot roll forward and also match hash. // Cannot roll forward and also match hash.
assert(!roll_forward || !match_hash); assert(!is_roll_fwd_set() || !match_hash);
// Will not roll forward within a deps json. // Will not roll forward within a deps json.
assert(!roll_forward || probe_deps_json == nullptr); assert(!is_roll_fwd_set() || probe_deps_json == nullptr);
// Will not do hash match when probing a deps json. // Will not do hash match when probing a deps json.
assert(!match_hash || probe_deps_json == nullptr); assert(!match_hash || probe_deps_json == nullptr);
} }
static probe_config_t svc_ni(const pal::string_t dir, bool roll_fwd) static probe_config_t svc_ni(const pal::string_t dir, bool patch_roll_fwd, bool prerelease_roll_fwd)
{ {
return probe_config_t(dir, false, roll_fwd, nullptr, true, true); return probe_config_t(dir, false, patch_roll_fwd, prerelease_roll_fwd, nullptr, true, true);
} }
static probe_config_t svc(const pal::string_t dir, bool roll_fwd) static probe_config_t svc(const pal::string_t dir, bool patch_roll_fwd, bool prerelease_roll_fwd)
{ {
return probe_config_t(dir, false, roll_fwd, nullptr, true, false); return probe_config_t(dir, false, patch_roll_fwd, prerelease_roll_fwd, nullptr, true, false);
} }
static probe_config_t cache_ni(const pal::string_t dir) static probe_config_t cache_ni(const pal::string_t dir)
{ {
return probe_config_t(dir, true, false, nullptr, false, true); return probe_config_t(dir, true, false, false, nullptr, false, true);
} }
static probe_config_t cache(const pal::string_t dir) static probe_config_t cache(const pal::string_t dir)
{ {
return probe_config_t(dir, true, false, nullptr, false, false); return probe_config_t(dir, true, false, false, nullptr, false, false);
} }
static probe_config_t fx(const pal::string_t dir, const deps_json_t* deps) static probe_config_t fx(const pal::string_t dir, const deps_json_t* deps)
{ {
return probe_config_t(dir, false, false, deps, false, false); return probe_config_t(dir, false, false, false, deps, false, false);
} }
static probe_config_t additional(const pal::string_t dir, bool roll_fwd) static probe_config_t additional(const pal::string_t dir, bool patch_roll_fwd, bool prerelease_roll_fwd)
{ {
return probe_config_t(dir, false, roll_fwd, nullptr, false, false); return probe_config_t(dir, false, patch_roll_fwd, prerelease_roll_fwd, nullptr, false, false);
} }
}; };

View file

@ -124,6 +124,8 @@ void deps_resolver_t::get_dir_assemblies(
bool deps_resolver_t::try_roll_forward(const deps_entry_t& entry, bool deps_resolver_t::try_roll_forward(const deps_entry_t& entry,
const pal::string_t& probe_dir, const pal::string_t& probe_dir,
bool patch_roll_fwd,
bool prerelease_roll_fwd,
pal::string_t* candidate) pal::string_t* candidate)
{ {
trace::verbose(_X("Attempting a roll forward for [%s/%s/%s] in [%s]"), entry.library_name.c_str(), entry.library_version.c_str(), entry.relative_path.c_str(), probe_dir.c_str()); trace::verbose(_X("Attempting a roll forward for [%s/%s/%s] in [%s]"), entry.library_name.c_str(), entry.library_version.c_str(), entry.relative_path.c_str(), probe_dir.c_str());
@ -136,29 +138,46 @@ bool deps_resolver_t::try_roll_forward(const deps_entry_t& entry,
trace::verbose(_X("No roll forward as specified version [%s] could not be parsed"), lib_ver.c_str()); trace::verbose(_X("No roll forward as specified version [%s] could not be parsed"), lib_ver.c_str());
return false; return false;
} }
// Extract glob string of the form: 1.0.* from the version 1.0.0-prerelease-00001.
size_t pat_start = lib_ver.find(_X('.'), lib_ver.find(_X('.')) + 1);
pal::string_t maj_min_star = lib_ver.substr(0, pat_start + 1) + _X('*');
pal::string_t path = probe_dir; pal::string_t path = probe_dir;
append_path(&path, entry.library_name.c_str()); append_path(&path, entry.library_name.c_str());
pal::string_t max_str = lib_ver;
pal::string_t cache_key = path; if (cur_ver.is_prerelease() && prerelease_roll_fwd)
append_path(&cache_key, maj_min_star.c_str());
pal::string_t max_str;
if (m_roll_forward_cache.count(cache_key))
{ {
max_str = m_roll_forward_cache[cache_key]; pal::string_t maj_min_pat_star = cur_ver.prerelease_glob();
trace::verbose(_X("Found cached roll forward version [%s] -> [%s]"), lib_ver.c_str(), max_str.c_str());
}
else
{
try_patch_roll_forward_in_dir(path, cur_ver, &max_str, true);
m_roll_forward_cache[cache_key] = max_str;
}
pal::string_t cache_key = path;
append_path(&cache_key, maj_min_pat_star.c_str());
if (m_prerelease_roll_forward_cache.count(cache_key))
{
max_str = m_prerelease_roll_forward_cache[cache_key];
trace::verbose(_X("Found cached roll forward version [%s] -> [%s]"), lib_ver.c_str(), max_str.c_str());
}
else
{
try_prerelease_roll_forward_in_dir(path, cur_ver, &max_str);
m_prerelease_roll_forward_cache[cache_key] = max_str;
}
}
if (!cur_ver.is_prerelease() && patch_roll_fwd)
{
// Extract glob string of the form: 1.0.* from the version 1.0.0-prerelease-00001.
pal::string_t maj_min_star = cur_ver.patch_glob();
pal::string_t cache_key = path;
append_path(&cache_key, maj_min_star.c_str());
if (m_patch_roll_forward_cache.count(cache_key))
{
max_str = m_patch_roll_forward_cache[cache_key];
trace::verbose(_X("Found cached roll forward version [%s] -> [%s]"), lib_ver.c_str(), max_str.c_str());
}
else
{
try_patch_roll_forward_in_dir(path, cur_ver, &max_str);
m_patch_roll_forward_cache[cache_key] = max_str;
}
}
append_path(&path, max_str.c_str()); append_path(&path, max_str.c_str());
return entry.to_rel_path(path, candidate); return entry.to_rel_path(path, candidate);
@ -176,11 +195,11 @@ void deps_resolver_t::setup_probe_config(
if (pal::directory_exists(ext_ni)) if (pal::directory_exists(ext_ni))
{ {
// Servicing NI probe. // Servicing NI probe.
m_probes.push_back(probe_config_t::svc_ni(ext_ni, config.get_fx_roll_fwd())); m_probes.push_back(probe_config_t::svc_ni(ext_ni, config.get_patch_roll_fwd(), config.get_prerelease_roll_fwd()));
} }
// Servicing normal probe. // Servicing normal probe.
m_probes.push_back(probe_config_t::svc(args.dotnet_extensions, config.get_fx_roll_fwd())); m_probes.push_back(probe_config_t::svc(args.dotnet_extensions, config.get_patch_roll_fwd(), config.get_prerelease_roll_fwd()));
} }
if (pal::directory_exists(args.dotnet_packages_cache)) if (pal::directory_exists(args.dotnet_packages_cache))
@ -206,8 +225,9 @@ void deps_resolver_t::setup_probe_config(
for (const auto& probe : m_additional_probes) for (const auto& probe : m_additional_probes)
{ {
// Additional paths // Additional paths
bool roll_fwd = config.get_fx_roll_fwd(); bool patch_roll_fwd = config.get_patch_roll_fwd();
m_probes.push_back(probe_config_t::additional(probe, roll_fwd)); bool prerelease_roll_fwd = config.get_prerelease_roll_fwd();
m_probes.push_back(probe_config_t::additional(probe, patch_roll_fwd, prerelease_roll_fwd));
} }
if (trace::is_enabled()) if (trace::is_enabled())
@ -259,7 +279,7 @@ bool deps_resolver_t::probe_entry_in_configs(const deps_entry_t& entry, pal::str
{ {
if (entry.to_hash_matched_path(probe_dir, candidate)) if (entry.to_hash_matched_path(probe_dir, candidate))
{ {
assert(!config.roll_forward); assert(!config.is_roll_fwd_set());
trace::verbose(_X(" Matched hash for [%s]"), candidate->c_str()); trace::verbose(_X(" Matched hash for [%s]"), candidate->c_str());
return true; return true;
} }
@ -276,7 +296,7 @@ bool deps_resolver_t::probe_entry_in_configs(const deps_entry_t& entry, pal::str
} }
trace::verbose(_X(" Skipping... probe in deps json failed")); trace::verbose(_X(" Skipping... probe in deps json failed"));
} }
else if (!config.roll_forward) else if (!config.is_roll_fwd_set())
{ {
if (entry.to_full_path(probe_dir, candidate)) if (entry.to_full_path(probe_dir, candidate))
{ {
@ -285,9 +305,9 @@ bool deps_resolver_t::probe_entry_in_configs(const deps_entry_t& entry, pal::str
} }
trace::verbose(_X(" Skipping... not found in probe dir")); trace::verbose(_X(" Skipping... not found in probe dir"));
} }
else if (config.roll_forward) else if (config.is_roll_fwd_set())
{ {
if (try_roll_forward(entry, probe_dir, candidate)) 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()); trace::verbose(_X(" Specified roll forward; matched [%s]"), candidate->c_str());
return true; return true;

View file

@ -117,6 +117,8 @@ private:
bool try_roll_forward( bool try_roll_forward(
const deps_entry_t& entry, const deps_entry_t& entry,
const pal::string_t& probe_dir, const pal::string_t& probe_dir,
bool patch_roll_fwd,
bool prerelease_roll_fwd,
pal::string_t* candidate); pal::string_t* candidate);
// Framework deps file. // Framework deps file.
@ -130,7 +132,8 @@ private:
dir_assemblies_t m_local_assemblies; dir_assemblies_t m_local_assemblies;
dir_assemblies_t m_fx_assemblies; dir_assemblies_t m_fx_assemblies;
std::unordered_map<pal::string_t, pal::string_t> m_roll_forward_cache; std::unordered_map<pal::string_t, pal::string_t> m_patch_roll_forward_cache;
std::unordered_map<pal::string_t, pal::string_t> m_prerelease_roll_forward_cache;
pal::string_t m_package_cache; pal::string_t m_package_cache;

View file

@ -19,7 +19,7 @@ pal::string_t fx_muxer_t::resolve_fx_dir(const pal::string_t& muxer_dir, runtime
trace::verbose(_X("--- Resolving FX directory from muxer dir [%s]"), muxer_dir.c_str()); trace::verbose(_X("--- Resolving FX directory from muxer dir [%s]"), muxer_dir.c_str());
const auto fx_name = runtime->get_fx_name(); const auto fx_name = runtime->get_fx_name();
const auto fx_ver = runtime->get_fx_version(); const auto fx_ver = runtime->get_fx_version();
const auto roll_fwd = runtime->get_fx_roll_fwd(); const auto patch_roll_fwd = runtime->get_patch_roll_fwd();
fx_ver_t specified(-1, -1, -1); fx_ver_t specified(-1, -1, -1);
if (!fx_ver_t::parse(fx_ver, &specified, false)) if (!fx_ver_t::parse(fx_ver, &specified, false))
@ -32,16 +32,16 @@ pal::string_t fx_muxer_t::resolve_fx_dir(const pal::string_t& muxer_dir, runtime
append_path(&fx_dir, _X("shared")); append_path(&fx_dir, _X("shared"));
append_path(&fx_dir, fx_name.c_str()); append_path(&fx_dir, fx_name.c_str());
// If not roll forward or if pre-release, just return. // If production and no roll forward use given version.
if (!roll_fwd || specified.is_prerelease()) // For prerelease, we will always roll forward.
if (!specified.is_prerelease() && !patch_roll_fwd)
{ {
trace::verbose(_X("Did not roll forward because rollfwd=%d and [%s] is prerelease=%d"), trace::verbose(_X("Did not roll forward because patch_roll_fwd=%d, chose [%s]"), patch_roll_fwd, fx_ver.c_str());
roll_fwd, fx_ver.c_str(), specified.is_prerelease());
append_path(&fx_dir, fx_ver.c_str()); append_path(&fx_dir, fx_ver.c_str());
} }
else else
{ {
trace::verbose(_X("Attempting production FX roll forward starting from [%s]"), fx_ver.c_str()); trace::verbose(_X("Attempting FX roll forward starting from [%s]"), fx_ver.c_str());
std::vector<pal::string_t> list; std::vector<pal::string_t> list;
pal::readdir(fx_dir, &list); pal::readdir(fx_dir, &list);
@ -50,11 +50,19 @@ pal::string_t fx_muxer_t::resolve_fx_dir(const pal::string_t& muxer_dir, runtime
{ {
trace::verbose(_X("Inspecting version... [%s]"), version.c_str()); trace::verbose(_X("Inspecting version... [%s]"), version.c_str());
fx_ver_t ver(-1, -1, -1); fx_ver_t ver(-1, -1, -1);
if (fx_ver_t::parse(version, &ver, true) && if (!specified.is_prerelease() && fx_ver_t::parse(version, &ver, true) && // true -- only prod. prevents roll forward to prerelease.
ver.get_major() == max_specified.get_major() && ver.get_major() == max_specified.get_major() &&
ver.get_minor() == max_specified.get_minor()) ver.get_minor() == max_specified.get_minor())
{ {
max_specified.set_patch(std::max(ver.get_patch(), max_specified.get_patch())); max_specified = std::max(ver, max_specified);
}
if (specified.is_prerelease() && fx_ver_t::parse(version, &ver, false) && // false -- implies both production and prerelease.
ver.is_prerelease() && // prevent roll forward to production.
ver.get_major() == max_specified.get_major() &&
ver.get_minor() == max_specified.get_minor() &&
ver.get_patch() == max_specified.get_patch())
{
max_specified = std::max(ver, max_specified);
} }
} }
pal::string_t max_specified_str = max_specified.as_str(); pal::string_t max_specified_str = max_specified.as_str();

View file

@ -59,6 +59,20 @@ pal::string_t fx_ver_t::as_str() const
return stream.str(); return stream.str();
} }
pal::string_t fx_ver_t::prerelease_glob() const
{
pal::stringstream_t stream;
stream << m_major << _X(".") << m_minor << _X(".") << m_patch << _X("-*");
return stream.str();
}
pal::string_t fx_ver_t::patch_glob() const
{
pal::stringstream_t stream;
stream << m_major << _X(".") << m_minor << _X(".*");
return stream.str();
}
/* static */ /* static */
int fx_ver_t::compare(const fx_ver_t&a, const fx_ver_t& b) int fx_ver_t::compare(const fx_ver_t&a, const fx_ver_t& b)
{ {

View file

@ -25,6 +25,8 @@ struct fx_ver_t
bool is_prerelease() const { return !m_pre.empty(); } bool is_prerelease() const { return !m_pre.empty(); }
pal::string_t as_str() const; pal::string_t as_str() const;
pal::string_t prerelease_glob() const;
pal::string_t patch_glob() const;
bool operator ==(const fx_ver_t& b) const; bool operator ==(const fx_ver_t& b) const;
bool operator !=(const fx_ver_t& b) const; bool operator !=(const fx_ver_t& b) const;

View file

@ -105,7 +105,15 @@ bool hostpolicy_exists_in_svc(pal::string_t* resolved_dir)
append_path(&path, _STRINGIFY(HOST_POLICY_PKG_NAME)); append_path(&path, _STRINGIFY(HOST_POLICY_PKG_NAME));
pal::string_t max_ver; pal::string_t max_ver;
try_patch_roll_forward_in_dir(path, lib_ver, &max_ver, false); if (lib_ver.is_prerelease())
{
try_prerelease_roll_forward_in_dir(path, lib_ver, &max_ver);
}
else
{
try_patch_roll_forward_in_dir(path, lib_ver, &max_ver);
}
append_path(&path, max_ver.c_str()); append_path(&path, max_ver.c_str());
append_path(&path, rel_dir.c_str()); append_path(&path, rel_dir.c_str());

View file

@ -61,17 +61,17 @@ host_mode_t detect_operating_mode(const int argc, const pal::char_t* argv[], pal
} }
} }
void try_patch_roll_forward_in_dir(const pal::string_t& cur_dir, const fx_ver_t& start_ver, pal::string_t* max_str, bool only_production) void try_patch_roll_forward_in_dir(const pal::string_t& cur_dir, const fx_ver_t& start_ver, pal::string_t* max_str)
{ {
pal::string_t path = cur_dir; pal::string_t path = cur_dir;
if (trace::is_enabled()) if (trace::is_enabled())
{ {
pal::string_t start_str = start_ver.as_str(); pal::string_t start_str = start_ver.as_str();
trace::verbose(_X("Reading roll forward candidates in dir [%s] for version [%s]"), path.c_str(), start_str.c_str()); trace::verbose(_X("Reading patch roll forward candidates in dir [%s] for version [%s]"), path.c_str(), start_str.c_str());
} }
pal::string_t maj_min_star = pal::to_string(start_ver.get_major()) + _X(".") + pal::to_string(start_ver.get_minor()) + _X("*"); pal::string_t maj_min_star = start_ver.patch_glob();
std::vector<pal::string_t> list; std::vector<pal::string_t> list;
pal::readdir(path, maj_min_star, &list); pal::readdir(path, maj_min_star, &list);
@ -80,8 +80,8 @@ void try_patch_roll_forward_in_dir(const pal::string_t& cur_dir, const fx_ver_t&
fx_ver_t ver(-1, -1, -1); fx_ver_t ver(-1, -1, -1);
for (const auto& str : list) for (const auto& str : list)
{ {
trace::verbose(_X("Considering roll forward candidate version [%s]"), str.c_str()); trace::verbose(_X("Considering patch roll forward candidate version [%s]"), str.c_str());
if (fx_ver_t::parse(str, &ver, only_production)) if (fx_ver_t::parse(str, &ver, true))
{ {
max_ver = std::max(ver, max_ver); max_ver = std::max(ver, max_ver);
} }
@ -91,6 +91,42 @@ void try_patch_roll_forward_in_dir(const pal::string_t& cur_dir, const fx_ver_t&
if (trace::is_enabled()) if (trace::is_enabled())
{ {
pal::string_t start_str = start_ver.as_str(); pal::string_t start_str = start_ver.as_str();
trace::verbose(_X("Roll forwarded [%s] -> [%s] in [%s]"), start_str.c_str(), max_str->c_str(), path.c_str()); trace::verbose(_X("Patch roll forwarded [%s] -> [%s] in [%s]"), start_str.c_str(), max_str->c_str(), path.c_str());
}
}
void try_prerelease_roll_forward_in_dir(const pal::string_t& cur_dir, const fx_ver_t& start_ver, pal::string_t* max_str)
{
pal::string_t path = cur_dir;
if (trace::is_enabled())
{
pal::string_t start_str = start_ver.as_str();
trace::verbose(_X("Reading prerelease roll forward candidates in dir [%s] for version [%s]"), path.c_str(), start_str.c_str());
}
pal::string_t maj_min_pat_star = start_ver.prerelease_glob();
std::vector<pal::string_t> list;
pal::readdir(path, maj_min_pat_star, &list);
fx_ver_t max_ver = start_ver;
fx_ver_t ver(-1, -1, -1);
for (const auto& str : list)
{
trace::verbose(_X("Considering prerelease roll forward candidate version [%s]"), str.c_str());
if (fx_ver_t::parse(str, &ver, false)
&& ver.is_prerelease()) // Pre-release can roll forward to only pre-release
{
max_ver = std::max(ver, max_ver);
}
}
max_str->assign(max_ver.as_str());
if (trace::is_enabled())
{
pal::string_t start_str = start_ver.as_str();
trace::verbose(_X("Prerelease roll forwarded [%s] -> [%s] in [%s]"), start_str.c_str(), max_str->c_str(), path.c_str());
} }
} }

View file

@ -25,7 +25,7 @@ class corehost_init_t
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
public: public:
static const int s_version = 0x8002; static const int s_version = 0x8003;
private: private:
int m_version; int m_version;
std::vector<pal::string_t> m_probe_paths; std::vector<pal::string_t> m_probe_paths;
@ -83,6 +83,7 @@ public:
pal::string_t get_runtime_config_from_file(const pal::string_t& file, pal::string_t* dev_config_file); pal::string_t get_runtime_config_from_file(const pal::string_t& file, pal::string_t* dev_config_file);
host_mode_t detect_operating_mode(const int argc, const pal::char_t* argv[], pal::string_t* own_dir = nullptr); host_mode_t detect_operating_mode(const int argc, const pal::char_t* argv[], pal::string_t* own_dir = nullptr);
void try_patch_roll_forward_in_dir(const pal::string_t& cur_dir, const fx_ver_t& start_ver, pal::string_t* max_str, bool only_production); void try_patch_roll_forward_in_dir(const pal::string_t& cur_dir, const fx_ver_t& start_ver, pal::string_t* max_str);
void try_prerelease_roll_forward_in_dir(const pal::string_t& cur_dir, const fx_ver_t& start_ver, pal::string_t* max_str);
#endif // __LIBHOST_H__ #endif // __LIBHOST_H__

View file

@ -9,7 +9,8 @@
#include <cassert> #include <cassert>
runtime_config_t::runtime_config_t(const pal::string_t& path, const pal::string_t& dev_path) runtime_config_t::runtime_config_t(const pal::string_t& path, const pal::string_t& dev_path)
: m_fx_roll_fwd(true) : m_patch_roll_fwd(true)
, m_prerelease_roll_fwd(false)
, m_path(path) , m_path(path)
, m_dev_path(dev_path) , m_dev_path(dev_path)
, m_portable(false) , m_portable(false)
@ -58,10 +59,16 @@ bool runtime_config_t::parse_opts(const json_value& opts)
} }
} }
auto roll_fwd = opts_obj.find(_X("applyPatches")); auto patch_roll_fwd = opts_obj.find(_X("applyPatches"));
if (roll_fwd != opts_obj.end()) if (patch_roll_fwd != opts_obj.end())
{ {
m_fx_roll_fwd = roll_fwd->second.as_bool(); m_patch_roll_fwd = patch_roll_fwd->second.as_bool();
}
auto prerelease_roll_fwd = opts_obj.find(_X("preReleaseRollForward"));
if (prerelease_roll_fwd != opts_obj.end())
{
m_prerelease_roll_fwd = prerelease_roll_fwd->second.as_bool();
} }
auto framework = opts_obj.find(_X("framework")); auto framework = opts_obj.find(_X("framework"));
@ -90,7 +97,7 @@ bool runtime_config_t::ensure_dev_config_parsed()
} }
// Set dev mode default values, if the file exists. // Set dev mode default values, if the file exists.
m_fx_roll_fwd = false; m_patch_roll_fwd = false;
pal::ifstream_t file(m_dev_path); pal::ifstream_t file(m_dev_path);
if (!file.good()) if (!file.good())
@ -120,6 +127,7 @@ bool runtime_config_t::ensure_dev_config_parsed()
trace::error(_X("A JSON parsing exception occurred in [%s]: %s"), m_dev_path.c_str(), jes.c_str()); trace::error(_X("A JSON parsing exception occurred in [%s]: %s"), m_dev_path.c_str(), jes.c_str());
return false; return false;
} }
return true; return true;
} }
@ -181,10 +189,16 @@ const pal::string_t& runtime_config_t::get_fx_version() const
return m_fx_ver; return m_fx_ver;
} }
bool runtime_config_t::get_fx_roll_fwd() const bool runtime_config_t::get_patch_roll_fwd() const
{ {
assert(m_valid); assert(m_valid);
return m_fx_roll_fwd; return m_patch_roll_fwd;
}
bool runtime_config_t::get_prerelease_roll_fwd() const
{
assert(m_valid);
return m_prerelease_roll_fwd;
} }
bool runtime_config_t::get_portable() const bool runtime_config_t::get_portable() const

View file

@ -10,6 +10,11 @@ typedef web::json::value json_value;
class runtime_config_t class runtime_config_t
{ {
// // WARNING // WARNING // WARNING // WARNING // WARNING // WARNING //
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// !! If you change this class layout increment the !!
// !! corehost_init_t::s_version field; !!
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
public: public:
runtime_config_t(const pal::string_t& path, const pal::string_t& dev_path); runtime_config_t(const pal::string_t& path, const pal::string_t& dev_path);
bool is_valid() { return m_valid; } bool is_valid() { return m_valid; }
@ -19,7 +24,8 @@ public:
const pal::string_t& get_fx_version() const; const pal::string_t& get_fx_version() const;
const pal::string_t& get_fx_name() const; const pal::string_t& get_fx_name() const;
const std::list<pal::string_t>& get_probe_paths() const; const std::list<pal::string_t>& get_probe_paths() const;
bool get_fx_roll_fwd() const; bool get_patch_roll_fwd() const;
bool get_prerelease_roll_fwd() const;
bool get_portable() const; bool get_portable() const;
bool parse_opts(const json_value& opts); bool parse_opts(const json_value& opts);
void config_kv(std::vector<std::string>*, std::vector<std::string>*) const; void config_kv(std::vector<std::string>*, std::vector<std::string>*) const;
@ -34,7 +40,8 @@ private:
std::list<pal::string_t> m_probe_paths; std::list<pal::string_t> m_probe_paths;
pal::string_t m_fx_name; pal::string_t m_fx_name;
pal::string_t m_fx_ver; pal::string_t m_fx_ver;
bool m_fx_roll_fwd; bool m_patch_roll_fwd;
bool m_prerelease_roll_fwd;
pal::string_t m_dev_path; pal::string_t m_dev_path;
pal::string_t m_path; pal::string_t m_path;