From c5ce2eb75326b6022ba0f02bff3a7832dd69bc32 Mon Sep 17 00:00:00 2001 From: piotrp Date: Mon, 11 Jan 2016 00:14:14 -0800 Subject: [PATCH] Fixes issue #781 makes CommandResolver comply with new implementation of --depsFile --- Documentation/specs/corehost.md | 2 ++ .../CommandResolver.cs | 6 ++-- src/corehost/cli/args.cpp | 32 ++++++++++++++++++- src/corehost/cli/args.h | 3 ++ src/corehost/cli/deps_resolver.cpp | 11 ++----- src/corehost/common/utils.cpp | 6 ++++ src/corehost/common/utils.h | 1 + 7 files changed, 49 insertions(+), 12 deletions(-) diff --git a/Documentation/specs/corehost.md b/Documentation/specs/corehost.md index 382723854..249c8c324 100644 --- a/Documentation/specs/corehost.md +++ b/Documentation/specs/corehost.md @@ -78,6 +78,8 @@ During host start-up, the host identifies if a `.deps` file is present and loads A `.deps` file is **not** required to successfully launch an application, but without it, all the dependent assemblies must be located within the same folder as the application. Also, since servicing is performed on the basis of packages, an application without a `.deps` file cannot use the servicing index to override the location of assemblies. +The host looks for the `.deps` file in the Application Base with the file name `[AssemblyName].deps`. The path to the deps file can be overriden by specifying `--corehost-depsfile:{path to deps file}` as the first parameter to the application. + Given the set of assembly names, the host performs the following resolution. In some steps, the Package ID/Version/Relative Path data is required. This is only available if the assembly was listed in the deps file. If the assembly comes from the app-local folder, these resolution steps are skipped. 1. If there is an entry in the servicing index for the Package ID/Version/Relative Path associated with the assembly, the Servicing Root is concatenated with the New Asset Path from the index and used as the Assembly Path. This occurs **even if the assembly is also located app-local**, as long as it is also in the `.deps` file. diff --git a/src/Microsoft.DotNet.Cli.Utils/CommandResolver.cs b/src/Microsoft.DotNet.Cli.Utils/CommandResolver.cs index b79477617..9d8072879 100644 --- a/src/Microsoft.DotNet.Cli.Utils/CommandResolver.cs +++ b/src/Microsoft.DotNet.Cli.Utils/CommandResolver.cs @@ -172,12 +172,14 @@ namespace Microsoft.DotNet.Cli.Utils fileName = CoreHost.Path; + var depsArg = string.Empty; + if (depsPath != null) { - args = $"--tpaFile:\"{depsPath}\" {args}"; + depsArg = $"\"--depsFile:{depsPath}\" "; } - args = $"\"{dllPath}\" {args}"; + args = $"\"{dllPath}\" {depsArg}{args}"; } else { diff --git a/src/corehost/cli/args.cpp b/src/corehost/cli/args.cpp index 49895e34c..706975515 100644 --- a/src/corehost/cli/args.cpp +++ b/src/corehost/cli/args.cpp @@ -10,7 +10,8 @@ arguments_t::arguments_t() : own_path(_X("")), app_dir(_X("")), app_argc(0), - app_argv(nullptr) + app_argv(nullptr), + deps_path(_X("")) { } @@ -72,6 +73,35 @@ bool parse_arguments(const int argc, const pal::char_t* argv[], arguments_t& arg args.app_argc = argc - 1; } + if(args.app_argc > 0) + { + auto depsfile_candidate = pal::string_t(args.app_argv[0]); + + if (starts_with(depsfile_candidate, s_depsArgPrefix)) + { + args.deps_path = depsfile_candidate.substr(s_depsArgPrefix.length()); + if (!pal::realpath(&args.deps_path)) + { + trace::error(_X("Failed to locate deps file: %s"), args.deps_path.c_str()); + return false; + } + args.app_argc = args.app_argc - 1; + args.app_argv = &args.app_argv[1]; + } + } + + if (args.deps_path.empty()) + { + const auto& app_base = args.app_dir; + auto app_name = get_filename(args.managed_application); + + args.deps_path.reserve(app_base.length() + 1 + app_name.length() + 5); + args.deps_path.append(app_base); + args.deps_path.push_back(DIR_SEPARATOR); + args.deps_path.append(app_name, 0, app_name.find_last_of(_X("."))); + args.deps_path.append(_X(".deps")); + } + pal::getenv(_X("DOTNET_PACKAGES"), &args.dotnet_packages); pal::getenv(_X("DOTNET_PACKAGES_CACHE"), &args.dotnet_packages_cache); pal::getenv(_X("DOTNET_SERVICING"), &args.dotnet_servicing); diff --git a/src/corehost/cli/args.h b/src/corehost/cli/args.h index c5a51ac81..67ef39581 100644 --- a/src/corehost/cli/args.h +++ b/src/corehost/cli/args.h @@ -8,10 +8,13 @@ #include "pal.h" #include "trace.h" +static const pal::string_t s_depsArgPrefix = _X("--corehost-depsfile:"); + struct arguments_t { pal::string_t own_path; pal::string_t app_dir; + pal::string_t deps_path; pal::string_t dotnet_servicing; pal::string_t dotnet_runtime_servicing; pal::string_t dotnet_home; diff --git a/src/corehost/cli/deps_resolver.cpp b/src/corehost/cli/deps_resolver.cpp index fd176e4eb..efbcdfdf2 100644 --- a/src/corehost/cli/deps_resolver.cpp +++ b/src/corehost/cli/deps_resolver.cpp @@ -340,7 +340,7 @@ bool deps_resolver_t::load() } // ----------------------------------------------------------------------------- -// Resolve path to the deps file from "args" and parse the deps file. +// Parse the deps file. // // Returns: // True if the file parse is successful or if file doesn't exist. False, @@ -348,14 +348,7 @@ bool deps_resolver_t::load() // bool deps_resolver_t::parse_deps_file(const arguments_t& args) { - const auto& app_base = args.app_dir; - auto app_name = get_filename(args.managed_application); - - m_deps_path.reserve(app_base.length() + 1 + app_name.length() + 5); - m_deps_path.append(app_base); - m_deps_path.push_back(DIR_SEPARATOR); - m_deps_path.append(app_name, 0, app_name.find_last_of(_X("."))); - m_deps_path.append(_X(".deps")); + m_deps_path = args.deps_path; return load(); } diff --git a/src/corehost/common/utils.cpp b/src/corehost/common/utils.cpp index bfb33ca1a..bff1afb2f 100644 --- a/src/corehost/common/utils.cpp +++ b/src/corehost/common/utils.cpp @@ -18,6 +18,12 @@ bool ends_with(const pal::string_t& value, const pal::string_t& suffix) (0 == value.compare(value.length() - suffix.length(), suffix.length(), suffix)); } +bool starts_with(const pal::string_t& value, const pal::string_t& prefix) +{ + return prefix.length() <= value.length() && + (0 == value.compare(0, prefix.length(), prefix)); +} + void append_path(pal::string_t* path1, const pal::char_t* path2) { if (pal::is_path_rooted(path2)) diff --git a/src/corehost/common/utils.h b/src/corehost/common/utils.h index 8a0740932..9275c25b4 100644 --- a/src/corehost/common/utils.h +++ b/src/corehost/common/utils.h @@ -7,6 +7,7 @@ #include "pal.h" bool ends_with(const pal::string_t& value, const pal::string_t& suffix); +bool starts_with(const pal::string_t& value, const pal::string_t& prefix); pal::string_t get_executable(const pal::string_t& filename); pal::string_t get_directory(const pal::string_t& path); pal::string_t get_filename(const pal::string_t& path);