Merge branch 'rel/1.0.0' of https://github.com/dotnet/cli into cli-sdk-stages
This commit is contained in:
commit
de8b326872
12 changed files with 179 additions and 63 deletions
|
@ -29,7 +29,7 @@ Installers
|
|||
|---------|:------:|:------:|:------:|:------:|:------:|:------:|
|
||||
|**Version**|||||||
|
||||
|**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?
|
||||
----------------------------------------------------
|
||||
|
|
|
@ -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 true;
|
||||
}
|
||||
return _expectedVals.Any(ev => string.Equals(actualVal, ev, StringComparison.Ordinal));
|
||||
}
|
||||
else
|
||||
{
|
||||
return !string.IsNullOrEmpty(actualVal);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -129,23 +129,27 @@ 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;
|
||||
}
|
||||
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)
|
||||
{
|
||||
iter = package.second.erase(iter);
|
||||
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
|
||||
{
|
||||
++iter;
|
||||
++iter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
const auto& assets_by_type = rid_assets[package].begin()->second[type_index];
|
||||
if (!assets_by_type.empty())
|
||||
{
|
||||
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());
|
||||
}
|
||||
else
|
||||
|
||||
if (non_rid_assets.count(package))
|
||||
{
|
||||
return rid_assets.count(package)
|
||||
? rid_assets[package].begin()->second[type_index]
|
||||
: non_rid_assets[package][type_index];
|
||||
return non_rid_assets[package][type_index];
|
||||
}
|
||||
|
||||
return empty;
|
||||
};
|
||||
|
||||
reconcile_libraries_with_targets(json, package_exists, get_relpaths);
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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__
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue