Merge branch 'rel/1.0.0' of https://github.com/dotnet/cli into cli-sdk-stages

This commit is contained in:
Sridhar Periyasamy 2016-03-17 11:16:43 -07:00
commit de8b326872
12 changed files with 179 additions and 63 deletions

View file

@ -29,7 +29,7 @@ Installers
|---------|:------:|:------:|:------:|:------:|:------:|:------:|
|**Version**|![](https://dotnetcli.blob.core.windows.net/dotnet/beta/Binaries/Latest/Ubuntu_x64_Release_version_badge.svg)|![](https://dotnetcli.blob.core.windows.net/dotnet/beta/Binaries/Latest/Windows_x64_Release_version_badge.svg)|![](https://dotnetcli.blob.core.windows.net/dotnet/beta/Binaries/Latest/Windows_x86_Release_version_badge.svg)|![](https://dotnetcli.blob.core.windows.net/dotnet/beta/Binaries/Latest/OSX_x64_Release_version_badge.svg)|![](https://dotnetcli.blob.core.windows.net/dotnet/beta/Binaries/Latest/CentOS_x64_Release_version_badge.svg)|![](https://dotnetcli.blob.core.windows.net/dotnet/beta/Binaries/Latest/RHEL_x64_Release_version_badge.svg)|
|**Installers**|[Download Debian Package](https://dotnetcli.blob.core.windows.net/dotnet/beta/Installers/Latest/dotnet-ubuntu-x64.latest.deb)|[Download Installer](https://dotnetcli.blob.core.windows.net/dotnet/beta/Installers/Latest/dotnet-win-x64.latest.exe)|[Download Installer](https://dotnetcli.blob.core.windows.net/dotnet/beta/Installers/Latest/dotnet-win-x86.latest.exe)|[Download Pkg](https://dotnetcli.blob.core.windows.net/dotnet/beta/Installers/Latest/dotnet-osx-x64.latest.pkg) |N/A |N/A |
|**Binaries**|[Download tar file](https://dotnetcli.blob.core.windows.net/dotnet/beta/Binaries/Latest/dotnet-ubuntu-x64.latest.tar.gz)|[Download zip file](https://dotnetcli.blob.core.windows.net/dotnet/beta/Binaries/Latest/dotnet-win-x64.latest.zip)|[Download zip file](https://dotnetcli.blob.core.windows.net/dotnet/beta/Binaries/Latest/dotnet-win-x86.latest.zip)|[Download tar file](https://dotnetcli.blob.core.windows.net/dotnet/beta/Binaries/Latest/dotnet-osx-x64.latest.tar.gz) |[Download tar file](https://dotnetcli.blob.core.windows.net/dotnet/beta/Binaries/Latest/dotnet-centos-x64.latest.tar.gz)|[Download tar file](https://dotnetcli.blob.core.windows.net/dotnet/beta/Binaries/Latest/dotnet-rhel-x64.latest.tar.gz) |
|**Binaries**|[Download tar file](https://dotnetcli.blob.core.windows.net/dotnet/beta/Binaries/Latest/dotnet-combined-framework-sdk-host-ubuntu-x64.latest.tar.gz)|[Download zip file](https://dotnetcli.blob.core.windows.net/dotnet/beta/Binaries/Latest/dotnet-combined-framework-sdk-host-win-x64.latest.zip)|[Download zip file](https://dotnetcli.blob.core.windows.net/dotnet/beta/Binaries/Latest/dotnet-combined-framework-sdk-host-win-x86.latest.zip)|[Download tar file](https://dotnetcli.blob.core.windows.net/dotnet/beta/Binaries/Latest/dotnet-combined-framework-sdk-host-osx-x64.latest.tar.gz) |[Download tar file](https://dotnetcli.blob.core.windows.net/dotnet/beta/Binaries/Latest/dotnet-combined-framework-sdk-host-centos-x64.latest.tar.gz)|[Download tar file](https://dotnetcli.blob.core.windows.net/dotnet/beta/Binaries/Latest/dotnet-combined-framework-sdk-host-rhel-x64.latest.tar.gz) |
Interested in .NET Core + ASP.NET Core 1.0 RC1 bits?
----------------------------------------------------

View file

@ -1,5 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace Microsoft.DotNet.Cli.Build.Framework
{
@ -13,7 +13,11 @@ namespace Microsoft.DotNet.Cli.Build.Framework
{
if (string.IsNullOrEmpty(envVar))
{
throw new ArgumentNullException("envVar");
throw new ArgumentNullException(nameof(envVar));
}
if (expectedVals == null)
{
throw new ArgumentNullException(nameof(expectedVals));
}
_envVar = envVar;
@ -24,15 +28,14 @@ namespace Microsoft.DotNet.Cli.Build.Framework
{
var actualVal = Environment.GetEnvironmentVariable(_envVar);
foreach (var expectedVal in _expectedVals)
if (_expectedVals.Any())
{
if (string.Equals(actualVal, expectedVal, StringComparison.Ordinal))
return _expectedVals.Any(ev => string.Equals(actualVal, ev, StringComparison.Ordinal));
}
else
{
return true;
}
}
return false;
return !string.IsNullOrEmpty(actualVal);
}
}
}
}

View file

@ -1,12 +1,9 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using System.Net.Http;
using System.Text;
using Microsoft.DotNet.Cli.Build.Framework;
using Microsoft.Extensions.PlatformAbstractions;
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Auth;
using Microsoft.WindowsAzure.Storage.Blob;
using static Microsoft.DotNet.Cli.Build.Framework.BuildHelpers;
@ -36,7 +33,8 @@ namespace Microsoft.DotNet.Cli.Build
[Target(nameof(PrepareTargets.Init),
nameof(PublishTargets.InitPublish),
nameof(PublishTargets.PublishArtifacts))]
nameof(PublishTargets.PublishArtifacts),
nameof(PublishTargets.TriggerDockerHubBuilds))]
[Environment("PUBLISH_TO_AZURE_BLOB", "1", "true")] // This is set by CI systems
public static BuildTargetResult Publish(BuildTargetContext c)
{
@ -107,6 +105,45 @@ namespace Microsoft.DotNet.Cli.Build
return c.Success();
}
[Target]
[Environment("DOCKER_HUB_REPO")]
[Environment("DOCKER_HUB_TRIGGER_TOKEN")]
public static BuildTargetResult TriggerDockerHubBuilds(BuildTargetContext c)
{
string dockerHubRepo = Environment.GetEnvironmentVariable("DOCKER_HUB_REPO");
string dockerHubTriggerToken = Environment.GetEnvironmentVariable("DOCKER_HUB_TRIGGER_TOKEN");
Uri baseDockerHubUri = new Uri("https://registry.hub.docker.com/u/");
Uri dockerHubTriggerUri;
if (!Uri.TryCreate(baseDockerHubUri, $"{dockerHubRepo}/trigger/{dockerHubTriggerToken}/", out dockerHubTriggerUri))
{
return c.Failed("Invalid DOCKER_HUB_REPO and/or DOCKER_HUB_TRIGGER_TOKEN");
}
c.Info($"Triggering automated DockerHub builds for {dockerHubRepo}");
using (HttpClient client = new HttpClient())
{
StringContent requestContent = new StringContent("{\"build\": true}", Encoding.UTF8, "application/json");
try
{
HttpResponseMessage response = client.PostAsync(dockerHubTriggerUri, requestContent).Result;
if (!response.IsSuccessStatusCode)
{
StringBuilder sb = new StringBuilder();
sb.AppendLine($"HTTP request to {dockerHubTriggerUri.ToString()} was unsuccessful.");
sb.AppendLine($"Response status code: {response.StatusCode}. Reason phrase: {response.ReasonPhrase}.");
sb.Append($"Respone content: {response.Content.ReadAsStringAsync().Result}");
return c.Failed(sb.ToString());
}
}
catch (AggregateException e)
{
return c.Failed($"HTTP request to {dockerHubTriggerUri.ToString()} failed. {e.ToString()}");
}
}
return c.Success();
}
private static string GenerateUploadJsonFile(string packageName, string version, string uploadUrl)
{
var repoID = Environment.GetEnvironmentVariable("REPO_ID");

View file

@ -129,18 +129,22 @@ bool deps_json_t::perform_rid_fallback(rid_specific_assets_t* portable_assets, c
auto iter = std::find_if(fallback_rids.begin(), fallback_rids.end(), [&package](const pal::string_t& rid) {
return package.second.count(rid);
});
if (iter == fallback_rids.end() || (*iter).empty())
if (iter != fallback_rids.end())
{
trace::error(_X("Did not find a matching fallback rid for package %s for the host rid %s"), package.first.c_str(), host_rid.c_str());
return false;
}
matched_rid = *iter;
}
assert(!matched_rid.empty());
}
if (matched_rid.empty())
{
package.second.clear();
}
for (auto iter = package.second.begin(); iter != package.second.end(); /* */)
{
if (iter->first != matched_rid)
{
trace::verbose(_X("Chose %s, so removing rid (%s) specific assets for package %s"), matched_rid.c_str(), iter->first.c_str(), package.first.c_str());
iter = package.second.erase(iter);
}
else
@ -194,7 +198,6 @@ bool deps_json_t::process_targets(const json_value& json, const pal::string_t& t
for (const auto& package : json.at(_X("targets")).at(target_name).as_object())
{
// if (package.second.at(_X("type")).as_string() != _X("package")) continue;
const auto& asset_types = package.second.as_object();
for (int i = 0; i < s_known_asset_types.size(); ++i)
{
@ -226,27 +229,31 @@ bool deps_json_t::load_portable(const json_value& json, const pal::string_t& tar
return false;
}
std::vector<pal::string_t> merged;
auto package_exists = [&rid_assets, &non_rid_assets](const pal::string_t& package) -> bool {
return rid_assets.count(package) || non_rid_assets.count(package);
};
auto get_relpaths = [&rid_assets, &non_rid_assets, &merged](const pal::string_t& package, int type_index) -> const std::vector<pal::string_t>& {
if (rid_assets.count(package) && non_rid_assets.count(package))
std::vector<pal::string_t> empty;
auto get_relpaths = [&rid_assets, &non_rid_assets, &empty](const pal::string_t& package, int type_index) -> const std::vector<pal::string_t>& {
// Is there any rid specific assets for this type ("native" or "runtime" or "resources")
if (rid_assets.count(package) && !rid_assets[package].empty())
{
const std::vector<pal::string_t>& rel1 = rid_assets[package].begin()->second[type_index];
const std::vector<pal::string_t>& rel2 = non_rid_assets[package][type_index];
merged.clear();
merged.reserve(rel1.size() + rel2.size());
merged.insert(merged.end(), rel1.begin(), rel1.end());
merged.insert(merged.end(), rel2.begin(), rel2.end());
return merged;
}
else
const auto& assets_by_type = rid_assets[package].begin()->second[type_index];
if (!assets_by_type.empty())
{
return rid_assets.count(package)
? rid_assets[package].begin()->second[type_index]
: non_rid_assets[package][type_index];
return assets_by_type;
}
trace::verbose(_X("There were no rid specific %s asset for %s"), deps_json_t::s_known_asset_types[type_index], package.c_str());
}
if (non_rid_assets.count(package))
{
return non_rid_assets[package][type_index];
}
return empty;
};
reconcile_libraries_with_targets(json, package_exists, get_relpaths);

View file

@ -16,8 +16,9 @@
typedef web::json::value json_value;
pal::string_t fx_muxer_t::resolve_fx_dir(const pal::string_t& muxer_dir, runtime_config_t* runtime, const pal::string_t& app_path)
pal::string_t fx_muxer_t::resolve_fx_dir(const pal::string_t& muxer_dir, runtime_config_t* runtime)
{
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_ver = runtime->get_fx_version();
const auto roll_fwd = runtime->get_fx_roll_fwd();
@ -25,25 +26,31 @@ pal::string_t fx_muxer_t::resolve_fx_dir(const pal::string_t& muxer_dir, runtime
fx_ver_t specified(-1, -1, -1);
if (!fx_ver_t::parse(fx_ver, &specified, false))
{
trace::error(_X("The specified runtimeconfig.json version [%s] could not be parsed"), fx_ver.c_str());
return pal::string_t();
}
auto fx_dir = muxer_dir;
append_path(&fx_dir, _X("Shared"));
append_path(&fx_dir, _X("shared"));
append_path(&fx_dir, fx_name.c_str());
// If not roll forward or if pre-release, just return.
if (!roll_fwd || specified.is_prerelease())
{
trace::verbose(_X("Did not roll forward because rollfwd=%d and [%s] is prerelease=%d"),
roll_fwd, fx_ver.c_str(), specified.is_prerelease());
append_path(&fx_dir, fx_ver.c_str());
}
else
{
trace::verbose(_X("Attempting production FX roll forward starting from [%s]"), fx_ver.c_str());
std::vector<pal::string_t> list;
pal::readdir(fx_dir, &list);
fx_ver_t max_specified = specified;
for (const auto& version : list)
{
trace::verbose(_X("Inspecting version... [%s]"), version.c_str());
fx_ver_t ver(-1, -1, -1);
if (fx_ver_t::parse(version, &ver, true) &&
ver.get_major() == max_specified.get_major() &&
@ -55,21 +62,26 @@ pal::string_t fx_muxer_t::resolve_fx_dir(const pal::string_t& muxer_dir, runtime
pal::string_t max_specified_str = max_specified.as_str();
append_path(&fx_dir, max_specified_str.c_str());
}
trace::verbose(_X("Found fx in: %s"), fx_dir.c_str());
trace::verbose(_X("Chose FX version [%s]"), fx_dir.c_str());
return pal::directory_exists(fx_dir) ? fx_dir : pal::string_t();
}
pal::string_t fx_muxer_t::resolve_cli_version(const pal::string_t& global_json)
{
trace::verbose(_X("--- Resolving CLI version from global json [%s]"), global_json.c_str());
pal::string_t retval;
if (!pal::file_exists(global_json))
{
trace::verbose(_X("[%s] does not exist"), global_json.c_str());
return retval;
}
pal::ifstream_t file(global_json);
if (!file.good())
{
trace::verbose(_X("[%s] could not be opened"), global_json.c_str());
return retval;
}
@ -80,6 +92,7 @@ pal::string_t fx_muxer_t::resolve_cli_version(const pal::string_t& global_json)
const auto sdk_iter = json.find(_X("sdk"));
if (sdk_iter == json.end() || sdk_iter->second.is_null())
{
trace::verbose(_X("CLI '/sdk/version' field not present/null in [%s]"), global_json.c_str());
return retval;
}
@ -87,19 +100,23 @@ pal::string_t fx_muxer_t::resolve_cli_version(const pal::string_t& global_json)
const auto ver_iter = sdk_obj.find(_X("version"));
if (ver_iter == sdk_obj.end() || ver_iter->second.is_null())
{
trace::verbose(_X("CLI 'sdk/version' field not present/null in [%s]"), global_json.c_str());
return retval;
}
retval = ver_iter->second.as_string();
}
catch (...)
{
trace::verbose(_X("A JSON parsing exception occurred"));
}
trace::verbose(_X("Found cli in: %s"), retval.c_str());
trace::verbose(_X("CLI version is [%s] in global json file [%s]"), retval.c_str(), global_json.c_str());
return retval;
}
pal::string_t resolve_sdk_version(pal::string_t sdk_path)
{
trace::verbose(_X("--- Resolving SDK version from SDK dir [%s]"), sdk_path.c_str());
pal::string_t retval;
std::vector<pal::string_t> versions;
@ -108,6 +125,8 @@ pal::string_t resolve_sdk_version(pal::string_t sdk_path)
fx_ver_t max_pre(-1, -1, -1);
for (const auto& version : versions)
{
trace::verbose(_X("Considering version... [%s]"), version.c_str());
fx_ver_t ver(-1, -1, -1);
if (fx_ver_t::parse(version, &ver, true))
{
@ -122,20 +141,26 @@ pal::string_t resolve_sdk_version(pal::string_t sdk_path)
// No production, use the max pre-release.
if (max_ver == fx_ver_t(-1, -1, -1))
{
trace::verbose(_X("No production version found, so using latest prerelease"));
max_ver = max_pre;
}
pal::string_t max_ver_str = max_ver.as_str();
append_path(&sdk_path, max_ver_str.c_str());
trace::verbose(_X("Checking if resolved SDK dir [%s] exists"), sdk_path.c_str());
if (pal::directory_exists(sdk_path))
{
retval = sdk_path;
}
trace::verbose(_X("Resolved SDK dir is [%s]"), retval.c_str());
return retval;
}
bool fx_muxer_t::resolve_sdk_dotnet_path(const pal::string_t& own_dir, pal::string_t* cli_sdk)
{
trace::verbose(_X("--- Resolving dotnet from working dir"));
pal::string_t cwd;
pal::string_t global;
if (pal::getcwd(&cwd))
@ -144,18 +169,27 @@ bool fx_muxer_t::resolve_sdk_dotnet_path(const pal::string_t& own_dir, pal::stri
{
pal::string_t file = cur_dir;
append_path(&file, _X("global.json"));
trace::verbose(_X("Probing path [%s] for global.json"), file.c_str());
if (pal::file_exists(file))
{
global = file;
trace::verbose(_X("Found global.json [%s]"), global.c_str());
break;
}
parent_dir = get_directory(cur_dir);
if (parent_dir.empty() || parent_dir.size() == cur_dir.size())
{
trace::verbose(_X("Terminating global.json search at [%s]"), parent_dir.c_str());
break;
}
}
}
else
{
trace::verbose(_X("Failed to obtain current working dir"));
}
pal::string_t retval;
if (!global.empty())
{
@ -165,10 +199,16 @@ bool fx_muxer_t::resolve_sdk_dotnet_path(const pal::string_t& own_dir, pal::stri
pal::string_t sdk_path = own_dir;
append_path(&sdk_path, _X("sdk"));
append_path(&sdk_path, cli_version.c_str());
if (pal::directory_exists(sdk_path))
{
trace::verbose(_X("CLI directory [%s] from global.json exists"), sdk_path.c_str());
retval = sdk_path;
}
else
{
trace::verbose(_X("CLI directory [%s] from global.json doesn't exist"), sdk_path.c_str());
}
}
}
if (retval.empty())
@ -178,13 +218,15 @@ bool fx_muxer_t::resolve_sdk_dotnet_path(const pal::string_t& own_dir, pal::stri
retval = resolve_sdk_version(sdk_path);
}
cli_sdk->assign(retval);
trace::verbose(_X("Found cli sdk in: %s"), cli_sdk->c_str());
trace::verbose(_X("Found CLI SDK in: %s"), cli_sdk->c_str());
return !retval.empty();
}
/* static */
int fx_muxer_t::execute(const int argc, const pal::char_t* argv[])
{
trace::verbose(_X("--- Executing in muxer mode..."));
pal::string_t own_path;
// Get the full name of the application
@ -198,6 +240,7 @@ int fx_muxer_t::execute(const int argc, const pal::char_t* argv[])
if (argc <= 1)
{
trace::error(_X("Usage: dotnet [--help | app.dll]"));
return StatusCode::InvalidArgFailure;
}
if (ends_with(argv[1], _X(".dll"), false))
@ -206,10 +249,12 @@ int fx_muxer_t::execute(const int argc, const pal::char_t* argv[])
if (!pal::realpath(&app_path))
{
trace::error(_X("Could not resolve app's full path [%s]"), app_path.c_str());
return StatusCode::LibHostExecModeFailure;
}
runtime_config_t config(get_runtime_config_json(app_path));
auto config_file = get_runtime_config_from_file(app_path);
runtime_config_t config(config_file);
if (!config.is_valid())
{
trace::error(_X("Invalid runtimeconfig.json [%s]"), config.get_path().c_str());
@ -217,12 +262,14 @@ int fx_muxer_t::execute(const int argc, const pal::char_t* argv[])
}
if (config.get_portable())
{
pal::string_t fx_dir = resolve_fx_dir(own_dir, &config, app_path);
trace::verbose(_X("Executing as a portable app as per config file [%s]"), config_file.c_str());
pal::string_t fx_dir = resolve_fx_dir(own_dir, &config);
corehost_init_t init(_X(""), _X(""), fx_dir, host_mode_t::muxer, &config);
return policy_load_t::execute_app(fx_dir, &init, argc, argv);
}
else
{
trace::verbose(_X("Executing as a standlone app as per config file [%s]"), config_file.c_str());
corehost_init_t init(_X(""), _X(""), _X(""), host_mode_t::muxer, &config);
return policy_load_t::execute_app(get_directory(app_path), &init, argc, argv);
}
@ -237,11 +284,13 @@ int fx_muxer_t::execute(const int argc, const pal::char_t* argv[])
std::unordered_map<pal::string_t, pal::string_t> opts;
if (!parse_known_args(argc - 2, &argv[2], known_opts, &opts, &num_args))
{
trace::error(_X("Failed to parse known arguments."));
return InvalidArgFailure;
}
int cur_i = 2 + num_args;
if (cur_i >= argc)
{
trace::error(_X("Parsed known args, but need more arguments."));
return InvalidArgFailure;
}
@ -256,23 +305,31 @@ int fx_muxer_t::execute(const int argc, const pal::char_t* argv[])
pal::string_t deps_file = opts.count(opts_deps_file) ? opts[opts_deps_file] : _X("");
pal::string_t probe_path = opts.count(opts_probe_path) ? opts[opts_probe_path] : _X("");
pal::string_t app_path = argv[cur_i];
runtime_config_t config(get_runtime_config_json(app_path));
pal::string_t app_or_deps = deps_file.empty() ? argv[cur_i] : deps_file;
auto config_file = get_runtime_config_from_file(app_or_deps);
runtime_config_t config(config_file);
if (!config.is_valid())
{
trace::error(_X("Invalid runtimeconfig.json [%s]"), config.get_path().c_str());
return StatusCode::InvalidConfigFile;
}
if (!deps_file.empty() && !pal::file_exists(deps_file))
{
trace::error(_X("Deps file [%s] specified but doesn't exist"), deps_file.c_str());
return StatusCode::InvalidArgFailure;
}
if (config.get_portable())
{
pal::string_t fx_dir = resolve_fx_dir(own_dir, &config, app_path);
trace::verbose(_X("Executing as a portable app as per config file [%s]"), config_file.c_str());
pal::string_t fx_dir = resolve_fx_dir(own_dir, &config);
corehost_init_t init(deps_file, probe_path, fx_dir, host_mode_t::muxer, &config);
return policy_load_t::execute_app(fx_dir, &init, new_argv.size(), new_argv.data());
}
else
{
trace::verbose(_X("Executing as a standalone app as per config file [%s]"), config_file.c_str());
corehost_init_t init(deps_file, probe_path, _X(""), host_mode_t::muxer, &config);
pal::string_t impl_dir = get_directory(deps_file.empty() ? app_path : deps_file);
pal::string_t impl_dir = get_directory(app_or_deps);
return policy_load_t::execute_app(impl_dir, &init, new_argv.size(), new_argv.data());
}
}
@ -281,9 +338,17 @@ int fx_muxer_t::execute(const int argc, const pal::char_t* argv[])
pal::string_t sdk_dotnet;
if (!resolve_sdk_dotnet_path(own_dir, &sdk_dotnet))
{
trace::error(_X("Could not resolve SDK directory from [%s]"), own_dir.c_str());
return StatusCode::LibHostSdkFindFailure;
}
append_path(&sdk_dotnet, _X("dotnet.dll"));
if (!pal::file_exists(sdk_dotnet))
{
trace::error(_X("Could not find dotnet.dll at [%s]"), sdk_dotnet.c_str());
return StatusCode::LibHostSdkFindFailure;
}
// Transform dotnet [command] [args] -> dotnet [dotnet.dll] [command] [args]
std::vector<const pal::char_t*> new_argv(argc + 1);
@ -291,20 +356,21 @@ int fx_muxer_t::execute(const int argc, const pal::char_t* argv[])
new_argv[0] = argv[0];
new_argv[1] = sdk_dotnet.c_str();
trace::verbose(_X("Using SDK dll=[%s]"), sdk_dotnet.c_str());
trace::verbose(_X("Using dotnet SDK dll=[%s]"), sdk_dotnet.c_str());
assert(ends_with(sdk_dotnet, _X(".dll"), false));
runtime_config_t config(get_runtime_config_json(sdk_dotnet));
auto config_file = get_runtime_config_from_file(sdk_dotnet);
runtime_config_t config(config_file);
if (config.get_portable())
{
pal::string_t fx_dir = resolve_fx_dir(own_dir, &config, sdk_dotnet);
trace::verbose(_X("Executing dotnet.dll as a portable app as per config file [%s]"), config_file.c_str());
pal::string_t fx_dir = resolve_fx_dir(own_dir, &config);
corehost_init_t init(_X(""), _X(""), fx_dir, host_mode_t::muxer, &config);
return policy_load_t::execute_app(fx_dir, &init, new_argv.size(), new_argv.data());
}
else
{
trace::verbose(_X("Executing dotnet.dll as a standalone app as per config file [%s]"), config_file.c_str());
corehost_init_t init(_X(""), _X(""), _X(""), host_mode_t::muxer, &config);
return policy_load_t::execute_app(get_directory(sdk_dotnet), &init, new_argv.size(), new_argv.data());
}

View file

@ -9,7 +9,7 @@ class fx_muxer_t
public:
static int execute(const int argc, const pal::char_t* argv[]);
private:
static pal::string_t resolve_fx_dir(const pal::string_t& muxer_path, runtime_config_t* runtime, const pal::string_t& app_path);
static pal::string_t resolve_fx_dir(const pal::string_t& muxer_path, runtime_config_t* runtime);
static pal::string_t resolve_cli_version(const pal::string_t& global);
static bool resolve_sdk_dotnet_path(const pal::string_t& own_dir, pal::string_t* cli_sdk);
};

View file

@ -215,7 +215,8 @@ SHARED_API int corehost_main(const int argc, const pal::char_t* argv[])
}
else
{
runtime_config_t config(get_runtime_config_json(args.managed_application));
auto config_path = get_runtime_config_from_file(args.managed_application);
runtime_config_t config(config_path);
if (!config.is_valid())
{
trace::error(_X("Invalid runtimeconfig.json [%s]"), config.get_path().c_str());

View file

@ -6,11 +6,12 @@
#include "trace.h"
#include "libhost.h"
pal::string_t get_runtime_config_json(const pal::string_t& app_path)
pal::string_t get_runtime_config_from_file(const pal::string_t& file)
{
auto name = get_filename_without_ext(app_path);
auto name = get_filename_without_ext(file);
name = name.substr(0, name.find(_X('.')));
auto json_name = name + _X(".runtimeconfig.json");
auto json_path = get_directory(app_path);
auto json_path = get_directory(file);
append_path(&json_path, json_name.c_str());
if (pal::file_exists(json_path))

View file

@ -64,7 +64,7 @@ public:
}
};
pal::string_t get_runtime_config_json(const pal::string_t& app_path);
pal::string_t get_runtime_config_from_file(const pal::string_t& file);
host_mode_t detect_operating_mode(const int argc, const pal::char_t* argv[], pal::string_t* own_dir = nullptr);
#endif // __LIBHOST_H__

View file

@ -202,6 +202,7 @@ void pal::readdir(const pal::string_t& path, std::vector<pal::string_t>* list)
// We are interested in files only
switch (entry->d_type)
{
case DT_DIR:
case DT_REG:
break;

View file

@ -74,7 +74,7 @@ pal::string_t get_filename_without_ext(const pal::string_t& path)
size_t name_pos = path.find_last_of(_X("/\\"));
size_t dot_pos = path.rfind(_X('.'));
size_t start_pos = (name_pos == pal::string_t::npos) ? 0 : (name_pos + 1);
size_t count = (dot_pos == pal::string_t::npos) ? pal::string_t::npos : (dot_pos - start_pos);
size_t count = (dot_pos == pal::string_t::npos || dot_pos < start_pos) ? pal::string_t::npos : (dot_pos - start_pos);
return path.substr(start_pos, count);
}

View file

@ -114,7 +114,7 @@ namespace Microsoft.DotNet.Tools.Compiler
var dependencyContext = new DependencyContextBuilder().Build(compilationOptions,
allExports,
allExports,
true, // For now, just assume portable mode in the legacy deps file (this is going away soon anyway)
false, // For now, just assume non-portable mode in the legacy deps file (this is going away soon anyway)
context.TargetFramework,
context.RuntimeIdentifier ?? string.Empty);