Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 52 additions & 9 deletions src/corehost/cli/args.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,58 @@ arguments_t::arguments_t() :
app_dir(_X("")),
app_argc(0),
app_argv(nullptr),
dotnet_packages_cache(_X("")),
core_servicing(_X("")),
deps_path(_X(""))
{
}

/**
*
* Setup the shared package directories.
*
* o %DOTNET_SHARED_PACKAGES% -- multiple delimited paths
* o $HOME/.dotnet/{x86|x64}/ or %USERPROFILE%\.dotnet\{x86|x64}
* o dotnet.exe relative shared packages
* o Global location
* Windows: C:\Program Files (x86) or
* Unix: directory of dotnet on the path.
*/
void setup_shared_package_paths(const hostpolicy_init_t& init, const pal::string_t& own_dir, arguments_t* args)
{
if (init.tfm.empty())
{
// Old (MNA < 1.1.*) "runtimeconfig.json" files do not contain TFM property.
return;
}

// Environment variable DOTNET_SHARED_PACKAGES
(void) get_env_shared_package_dirs(&args->env_shared_packages, get_arch(), init.tfm);

// User profile based packages
pal::string_t local_shared_packages;
if (get_local_shared_package_dir(&local_shared_packages))
{
append_path(&local_shared_packages, init.tfm.c_str());
args->local_shared_packages = local_shared_packages;
}

// "dotnet.exe" relative shared packages folder
if (init.host_mode == host_mode_t::muxer)
{
args->dotnet_shared_packages = own_dir;
append_path(&args->dotnet_shared_packages, _X("packages"));
append_path(&args->dotnet_shared_packages, init.tfm.c_str());
}

// Global shared package dir
if (get_global_shared_package_dir(&args->global_shared_packages))
{
append_path(&args->global_shared_packages, init.tfm.c_str());
}
}

bool parse_arguments(
const pal::string_t& deps_path,
const std::vector<pal::string_t>& probe_paths,
host_mode_t mode,
const hostpolicy_init_t& init,
const int argc, const pal::char_t* argv[], arguments_t* arg_out)
{
arguments_t& args = *arg_out;
Expand All @@ -35,7 +77,7 @@ bool parse_arguments(
auto own_name = get_filename(args.own_path);
auto own_dir = get_directory(args.own_path);

if (mode != host_mode_t::standalone)
if (init.host_mode != host_mode_t::standalone)
{
// corerun mode. First argument is managed app
if (argc < 2)
Expand Down Expand Up @@ -70,13 +112,13 @@ bool parse_arguments(
args.app_argc = argc - 1;
}

if (!deps_path.empty())
if (!init.deps_file.empty())
{
args.deps_path = deps_path;
args.deps_path = init.deps_file;
args.app_dir = get_directory(args.deps_path);
}

for (const auto& probe : probe_paths)
for (const auto& probe : init.probe_paths)
{
args.probe_paths.push_back(probe);
}
Expand All @@ -93,8 +135,9 @@ bool parse_arguments(
args.deps_path.append(_X(".deps.json"));
}

pal::getenv(_X("DOTNET_HOSTING_OPTIMIZATION_CACHE"), &args.dotnet_packages_cache);
pal::get_default_servicing_directory(&args.core_servicing);

setup_shared_package_paths(init, own_dir, &args);

return true;
}
75 changes: 34 additions & 41 deletions src/corehost/cli/args.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,76 +13,58 @@
struct probe_config_t
{
pal::string_t probe_dir;
bool match_hash;
bool patch_roll_fwd;
bool prerelease_roll_fwd;
const deps_json_t* probe_deps_json;

bool only_runtime_assets;
bool only_serviceable_assets;

bool probe_publish_dir;

void print() const
{
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, patch_roll_fwd, prerelease_roll_fwd, probe_deps_json);
}
bool is_roll_fwd_set() const
{
return patch_roll_fwd || prerelease_roll_fwd;
trace::verbose(_X("probe_config_t: probe=[%s] deps-json=[%p] deps-dir-probe=[%d]"),
probe_dir.c_str(), probe_deps_json, probe_publish_dir);
}

probe_config_t(
const pal::string_t& probe_dir,
bool match_hash,
bool patch_roll_fwd,
bool prerelease_roll_fwd,
const deps_json_t* probe_deps_json,
bool only_serviceable_assets,
bool only_runtime_assets)
bool only_runtime_assets,
bool probe_publish_dir)
: probe_dir(probe_dir)
, match_hash(match_hash)
, patch_roll_fwd(patch_roll_fwd)
, prerelease_roll_fwd(prerelease_roll_fwd)
, probe_deps_json(probe_deps_json)
, only_serviceable_assets(only_serviceable_assets)
, only_runtime_assets(only_runtime_assets)
, probe_publish_dir(probe_publish_dir)
{
// Cannot roll forward and also match hash.
assert(!is_roll_fwd_set() || !match_hash);
// Will not roll forward within a deps json.
assert(!is_roll_fwd_set() || probe_deps_json == nullptr);
// Will not do hash match when probing a deps json.
assert(!match_hash || probe_deps_json == nullptr);
}

static probe_config_t svc_ni(const pal::string_t& dir, bool patch_roll_fwd, bool prerelease_roll_fwd)
static probe_config_t svc_ni(const pal::string_t& dir)
{
return probe_config_t(dir, false, patch_roll_fwd, prerelease_roll_fwd, nullptr, true, true);
return probe_config_t(dir, nullptr, true, true, false);
}

static probe_config_t svc(const pal::string_t& dir, bool patch_roll_fwd, bool prerelease_roll_fwd)
static probe_config_t svc(const pal::string_t& dir)
{
return probe_config_t(dir, false, patch_roll_fwd, prerelease_roll_fwd, nullptr, true, false);
return probe_config_t(dir, nullptr, true, false, false);
}

static probe_config_t cache_ni(const pal::string_t& dir)
{
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 fx(const pal::string_t& dir, const deps_json_t* deps)
{
return probe_config_t(dir, true, false, false, nullptr, false, false);
return probe_config_t(dir, deps, false, false, false);
}

static probe_config_t fx(const pal::string_t& dir, const deps_json_t* deps)
static probe_config_t lookup(const pal::string_t& dir)
{
return probe_config_t(dir, false, false, false, deps, false, false);
return probe_config_t(dir, nullptr, false, false, false);
}

static probe_config_t additional(const pal::string_t& dir)
static probe_config_t published_deps_dir()
{
return probe_config_t(dir, false, false, false, nullptr, false, false);
return probe_config_t(_X(""), nullptr, false, false, true);
}
};

Expand All @@ -93,9 +75,11 @@ struct arguments_t
pal::string_t deps_path;
pal::string_t core_servicing;
std::vector<pal::string_t> probe_paths;
pal::string_t dotnet_packages_cache;
pal::string_t managed_application;

pal::string_t local_shared_packages;
pal::string_t global_shared_packages;
pal::string_t dotnet_shared_packages;
std::vector<pal::string_t> env_shared_packages;
int app_argc;
const pal::char_t** app_argv;

Expand All @@ -105,16 +89,25 @@ struct arguments_t
{
if (trace::is_enabled())
{
trace::verbose(_X("-- arguments_t: own_path=%s app_dir=%s deps=%s core_svc=%s packages_cache=%s mgd_app=%s"),
own_path.c_str(), app_dir.c_str(), deps_path.c_str(), core_servicing.c_str(), dotnet_packages_cache.c_str(), managed_application.c_str());
trace::verbose(_X("-- arguments_t: own_path='%s' app_dir='%s' deps='%s' core_svc='%s' mgd_app='%s'"),
own_path.c_str(), app_dir.c_str(), deps_path.c_str(), core_servicing.c_str(), managed_application.c_str());
for (const auto& probe : probe_paths)
{
trace::verbose(_X("-- arguments_t: probe dir: [%s]"), probe.c_str());
trace::verbose(_X("-- arguments_t: probe dir: '%s'"), probe.c_str());
}
for (const auto& shared : env_shared_packages)
{
trace::verbose(_X("-- arguments_t: env shared packages: '%s'"), shared.c_str());
}
trace::verbose(_X("-- arguments_t: local shared packages: '%s'"), local_shared_packages.c_str());
trace::verbose(_X("-- arguments_t: dotnet shared packages: '%s'"), dotnet_shared_packages.c_str());
trace::verbose(_X("-- arguments_t: global shared packages: '%s'"), global_shared_packages.c_str());
}
}
};

bool parse_arguments(const pal::string_t& deps_path, const std::vector<pal::string_t>& probe_paths, host_mode_t mode, const int argc, const pal::char_t* argv[], arguments_t* args);
bool parse_arguments(
const hostpolicy_init_t& init,
const int argc, const pal::char_t* argv[], arguments_t* arg_out);

#endif // ARGS_H
116 changes: 1 addition & 115 deletions src/corehost/cli/deps_entry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,118 +130,4 @@ bool deps_entry_t::to_full_path(const pal::string_t& base, pal::string_t* str) c
}

return to_rel_path(new_base, str);
}

// -----------------------------------------------------------------------------
// Given a "base" directory, yield the relative path of this file in the package
// layout if the entry hash matches the hash file in the "base" directory
//
// Parameters:
// base - The base directory to look for the relative path of this entry and
// the hash file.
// str - If the method returns true, contains the file path for this deps
// entry relative to the "base" directory
//
// Description:
// Looks for a file named "{PackageName}.{PackageVersion}.nupkg.{HashAlgorithm}"
// If the deps entry's {HashAlgorithm}-{HashValue} matches the contents then
// yields the relative path of this entry in the "base" dir.
//
// Returns:
// If the file exists in the path relative to the "base" directory and there
// was hash file match with this deps entry.
//
// See: to_full_path(base, str)
//
bool deps_entry_t::to_hash_matched_path(const pal::string_t& base, pal::string_t* str) const
{
pal::string_t& candidate = *str;

candidate.clear();

// Base directory must be present to perform hash lookup.
if (base.empty())
{
return false;
}

// First detect position of hyphen in [Algorithm]-[Hash] in the string.
size_t pos = library_hash.find(_X("-"));
if (pos == 0 || pos == pal::string_t::npos)
{
trace::verbose(_X("Invalid hash %s value for deps file entry: %s"), library_hash.c_str(), library_name.c_str());
return false;
}

// Build the relative hash path (what is added to the package directory path).
pal::string_t relative_hash_path;
if (library_hash_path.empty())
{
// Reserve approx 8 char_t's for the algorithm name.
relative_hash_path.reserve(library_name.length() + 1 + library_version.length() + 16);
relative_hash_path.append(library_name);
relative_hash_path.append(_X("."));
relative_hash_path.append(library_version);
relative_hash_path.append(_X(".nupkg."));
relative_hash_path.append(library_hash.substr(0, pos));
}
else
{
relative_hash_path.assign(library_hash_path);
}

// Build the directory that contains the hash file.
pal::string_t hash_file;
if (library_path.empty())
{
hash_file.reserve(base.length() + 1 +
library_name.length() + 1 + library_version.length() + 1 +
relative_hash_path.length());
hash_file.assign(base);

append_path(&hash_file, library_name.c_str());
append_path(&hash_file, library_version.c_str());
}
else
{
hash_file.reserve(base.length() + 1 +
library_path.length() + 1 +
relative_hash_path.length());
hash_file.assign(base);

append_path(&hash_file, library_path.c_str());
}

// Append the relative path to the hash file.
append_path(&hash_file, relative_hash_path.c_str());

// Read the contents of the hash file.
pal::ifstream_t fstream(hash_file);
if (!fstream.good())
{
trace::verbose(_X("The hash file is invalid [%s]"), hash_file.c_str());
return false;
}

// Obtain the hash from the file.
std::string hash;
hash.assign(pal::istreambuf_iterator_t(fstream),
pal::istreambuf_iterator_t());
pal::string_t pal_hash;
if (!pal::utf8_palstring(hash.c_str(), &pal_hash))
{
return false;
}

// Check if contents match deps entry.
pal::string_t entry_hash = library_hash.substr(pos + 1);
if (entry_hash != pal_hash)
{
trace::verbose(_X("The file hash [%s][%d] did not match entry hash [%s][%d]"),
pal_hash.c_str(), pal_hash.length(), entry_hash.c_str(), entry_hash.length());
return false;
}

// All good, just append the relative dir to base.
return to_full_path(base, &candidate);
}
}
3 changes: 0 additions & 3 deletions src/corehost/cli/deps_entry.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,6 @@ struct deps_entry_t
// Given a "base" dir, yield the relative path with package name, version in the package layout.
bool to_full_path(const pal::string_t& root, pal::string_t* str) const;

// Given a "base" dir, yield the relative path with package name, version in the package layout only if
// the hash matches contents of the hash file.
bool to_hash_matched_path(const pal::string_t& root, pal::string_t* str) const;
};

#endif // __DEPS_ENTRY_H_
Loading