From: Steve Harter Date: Thu, 1 Mar 2018 00:01:42 +0000 (-0600) Subject: Sort output from --list-sdks and --list-runtimes (dotnet/core-setup#3744) X-Git-Tag: submit/tizen/20210909.063632~11032^2~852 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=0f355a8a31e03b8ac9f6c3c8d55caf2a54a6f1f0;p=platform%2Fupstream%2Fdotnet%2Fruntime.git Sort output from --list-sdks and --list-runtimes (dotnet/core-setup#3744) Commit migrated from https://github.com/dotnet/core-setup/commit/993292d06f646276d541f22a15c7256c7928756e --- diff --git a/src/installer/corehost/cli/fxr/CMakeLists.txt b/src/installer/corehost/cli/fxr/CMakeLists.txt index 1e8ac30..ec666f8 100644 --- a/src/installer/corehost/cli/fxr/CMakeLists.txt +++ b/src/installer/corehost/cli/fxr/CMakeLists.txt @@ -41,6 +41,8 @@ set(SOURCES ./hostfxr.cpp ./fx_ver.cpp ./fx_muxer.cpp + ./framework_info.cpp + ./sdk_info.cpp ) if(WIN32) diff --git a/src/installer/corehost/cli/fxr/framework_info.cpp b/src/installer/corehost/cli/fxr/framework_info.cpp new file mode 100644 index 0000000..1afafc2 --- /dev/null +++ b/src/installer/corehost/cli/fxr/framework_info.cpp @@ -0,0 +1,126 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +#include +#include "framework_info.h" +#include "pal.h" +#include "trace.h" +#include "utils.h" + +bool compare_by_name_and_version(const framework_info &a, const framework_info &b) +{ + if (a.name < b.name) + { + return true; + } + + if (a.name > b.name) + { + return false; + } + + return a.version < b.version; +} + +/*static*/ void framework_info::get_all_framework_infos( + host_mode_t mode, + const pal::string_t& own_dir, + const pal::string_t& fx_name, + std::vector* framework_infos) +{ + // No FX resolution for standalone apps + if (mode == host_mode_t::standalone) + { + trace::verbose(_X("Standalone mode detected. Not gathering shared FX locations")); + return; + } + + // No FX resolution for mixed apps + if (mode == host_mode_t::split_fx) + { + trace::verbose(_X("Split/FX mode detected. Not gathering shared FX locations")); + return; + } + + std::vector global_dirs; + bool multilevel_lookup = multilevel_lookup_enabled(); + + // own_dir contains DIR_SEPARATOR appended that we need to remove. + pal::string_t own_dir_temp = own_dir; + remove_trailing_dir_seperator(&own_dir_temp); + + std::vector hive_dir; + hive_dir.push_back(own_dir_temp); + + if (multilevel_lookup && pal::get_global_dotnet_dirs(&global_dirs)) + { + for (pal::string_t dir : global_dirs) + { + if (dir != own_dir_temp) + { + hive_dir.push_back(dir); + } + } + } + + for (pal::string_t dir : hive_dir) + { + auto fx_shared_dir = dir; + append_path(&fx_shared_dir, _X("shared")); + + if (pal::directory_exists(fx_shared_dir)) + { + std::vector fx_names; + if (fx_name.length()) + { + // Use the provided framework name + fx_names.push_back(fx_name); + } + else + { + // Read all frameworks, including "Microsoft.NETCore.App" + pal::readdir_onlydirectories(fx_shared_dir, &fx_names); + } + + for (pal::string_t fx_name : fx_names) + { + auto fx_dir = fx_shared_dir; + append_path(&fx_dir, fx_name.c_str()); + + if (pal::directory_exists(fx_dir)) + { + trace::verbose(_X("Gathering FX locations in [%s]"), fx_dir.c_str()); + + std::vector versions; + pal::readdir_onlydirectories(fx_dir, &versions); + for (const auto& ver : versions) + { + // Make sure we filter out any non-version folders. + fx_ver_t parsed(-1, -1, -1); + if (fx_ver_t::parse(ver, &parsed, false)) + { + trace::verbose(_X("Found FX version [%s]"), ver.c_str()); + + framework_info info(fx_name, fx_dir, parsed); + framework_infos->push_back(info); + } + } + } + } + } + } + + std::sort(framework_infos->begin(), framework_infos->end(), compare_by_name_and_version); +} + +/*static*/ bool framework_info::print_all_frameworks(const pal::string_t& own_dir, const pal::string_t& leading_whitespace) +{ + std::vector framework_infos; + get_all_framework_infos(host_mode_t::muxer, own_dir, _X(""), &framework_infos); + for (framework_info info : framework_infos) + { + trace::println(_X("%s%s %s [%s]"), leading_whitespace.c_str(), info.name.c_str(), info.version.as_str().c_str(), info.path.c_str()); + } + + return framework_infos.size() > 0; +} diff --git a/src/installer/corehost/cli/fxr/framework_info.h b/src/installer/corehost/cli/fxr/framework_info.h new file mode 100644 index 0000000..9aaea39 --- /dev/null +++ b/src/installer/corehost/cli/fxr/framework_info.h @@ -0,0 +1,29 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +#ifndef __FRAMEWORK_INFO_H_ +#define __FRAMEWORK_INFO_H_ + +#include "libhost.h" + +struct framework_info +{ + framework_info(pal::string_t name, pal::string_t path, fx_ver_t version) + : name(name) + , path(path) + , version(version) { } + + static void get_all_framework_infos( + host_mode_t mode, + const pal::string_t& own_dir, + const pal::string_t& fx_name, + std::vector* framework_infos); + + static bool print_all_frameworks(const pal::string_t& own_dir, const pal::string_t& leading_whitespace); + + pal::string_t name; + pal::string_t path; + fx_ver_t version; +}; + +#endif // __FRAMEWORK_INFO_H_ diff --git a/src/installer/corehost/cli/fxr/fx_muxer.cpp b/src/installer/corehost/cli/fxr/fx_muxer.cpp index 43a9e32..0002d7e 100644 --- a/src/installer/corehost/cli/fxr/fx_muxer.cpp +++ b/src/installer/corehost/cli/fxr/fx_muxer.cpp @@ -2,161 +2,20 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. #include -#include "pal.h" -#include "utils.h" -#include "libhost.h" #include "args.h" +#include "cpprest/json.h" +#include "deps_format.h" +#include "error_codes.h" +#include "framework_info.h" #include "fx_definition.h" -#include "fx_ver.h" #include "fx_muxer.h" -#include "trace.h" +#include "fx_ver.h" +#include "libhost.h" +#include "pal.h" #include "runtime_config.h" -#include "cpprest/json.h" -#include "error_codes.h" -#include "deps_format.h" - -void get_all_fx_versions( - host_mode_t mode, - const pal::string_t& own_dir, - const pal::string_t& fx_name, - std::vector* fx_framework_names, - std::vector* fx_versions, - std::vector* fx_locations) -{ - // No FX resolution for standalone apps - if (mode == host_mode_t::standalone) - { - trace::verbose(_X("Standalone mode detected. Not gathering shared FX locations")); - return; - } - - // No FX resolution for mixed apps - if (mode == host_mode_t::split_fx) - { - trace::verbose(_X("Split/FX mode detected. Not gathering shared FX locations")); - return; - } - - std::vector global_dirs; - bool multilevel_lookup = multilevel_lookup_enabled(); - - // own_dir contains DIR_SEPARATOR appended that we need to remove. - pal::string_t own_dir_temp = own_dir; - remove_trailing_dir_seperator(&own_dir_temp); - - std::vector hive_dir; - hive_dir.push_back(own_dir_temp); - - if (multilevel_lookup && pal::get_global_dotnet_dirs(&global_dirs)) - { - for (pal::string_t dir : global_dirs) - { - if (dir != own_dir_temp) - { - hive_dir.push_back(dir); - } - } - } - - for (pal::string_t dir : hive_dir) - { - auto fx_shared_dir = dir; - append_path(&fx_shared_dir, _X("shared")); - - if (pal::directory_exists(fx_shared_dir)) - { - std::vector fx_names; - if (fx_name.length()) - { - // Use the provided framework name - fx_names.push_back(fx_name); - } - else - { - // Read all frameworks, including "Microsoft.NETCore.App" - pal::readdir_onlydirectories(fx_shared_dir, &fx_names); - } - - for (pal::string_t fx_name : fx_names) - { - auto fx_dir = fx_shared_dir; - append_path(&fx_dir, fx_name.c_str()); - - if (pal::directory_exists(fx_dir)) - { - trace::verbose(_X("Gathering FX locations in [%s]"), fx_dir.c_str()); - - std::vector versions; - pal::readdir_onlydirectories(fx_dir, &versions); - for (const auto& ver : versions) - { - // Make sure we filter out any non-version folders. - fx_ver_t parsed(-1, -1, -1); - if (fx_ver_t::parse(ver, &parsed, false)) - { - trace::verbose(_X("Found FX version [%s]"), ver.c_str()); - fx_framework_names->push_back(fx_name); - fx_versions->push_back(ver); - fx_locations->push_back(fx_shared_dir); - } - } - } - } - } - } -} - -void get_all_sdk_versions( - const pal::string_t& own_dir, - std::vector* sdk_versions, - std::vector* sdk_locations) -{ - std::vector global_dirs; - bool multilevel_lookup = multilevel_lookup_enabled(); - - // own_dir contains DIR_SEPARATOR appended that we need to remove. - pal::string_t own_dir_temp = own_dir; - remove_trailing_dir_seperator(&own_dir_temp); - - std::vector hive_dir; - hive_dir.push_back(own_dir_temp); - - if (multilevel_lookup && pal::get_global_dotnet_dirs(&global_dirs)) - { - for (pal::string_t dir : global_dirs) - { - if (dir != own_dir_temp) - { - hive_dir.push_back(dir); - } - } - } - - for (pal::string_t dir : hive_dir) - { - auto sdk_dir = dir; - trace::verbose(_X("Gathering SDK locations in [%s]"), sdk_dir.c_str()); - - append_path(&sdk_dir, _X("sdk")); - - if (pal::directory_exists(sdk_dir)) - { - std::vector versions; - pal::readdir_onlydirectories(sdk_dir, &versions); - for (const auto& ver : versions) - { - // Make sure we filter out any non-version folders. - fx_ver_t parsed(-1, -1, -1); - if (fx_ver_t::parse(ver, &parsed, false)) - { - trace::verbose(_X("Found SDK version [%s]"), ver.c_str()); - sdk_versions->push_back(ver.c_str()); - sdk_locations->push_back(sdk_dir.c_str()); - } - } - } - } -} +#include "sdk_info.h" +#include "trace.h" +#include "utils.h" /** * When the framework is not found, display detailed error message @@ -169,23 +28,19 @@ void handle_missing_framework_error( const pal::string_t& fx_dir, const pal::string_t& own_dir) { - std::vector fx_framework_names; - std::vector fx_versions; - std::vector fx_locations; + std::vector framework_infos; pal::string_t fx_ver_dirs; if (fx_dir.length()) { fx_ver_dirs = fx_dir; - get_all_fx_versions(mode, get_directory(fx_dir), fx_name, &fx_framework_names, &fx_versions, &fx_locations); + framework_info::get_all_framework_infos(mode, get_directory(fx_dir), fx_name, &framework_infos); } else { fx_ver_dirs = own_dir; } - get_all_fx_versions(mode, own_dir, fx_name, &fx_framework_names, &fx_versions, &fx_locations); - assert(fx_framework_names.size() == fx_versions.size()); - assert(fx_framework_names.size() == fx_locations.size()); + framework_info::get_all_framework_infos(mode, own_dir, fx_name, &framework_infos); // Display the error message about missing FX. if (fx_version.length()) @@ -207,7 +62,7 @@ void handle_missing_framework_error( // Gather the list of versions installed at the shared FX location. bool is_print_header = true; - for (int i = 0; i < fx_versions.size(); i++) + for (framework_info info : framework_infos) { // Print banner only once before printing the versions if (is_print_header) @@ -216,7 +71,7 @@ void handle_missing_framework_error( is_print_header = false; } - trace::error(_X(" %s at [%s]"), fx_versions[i].c_str(), fx_locations[i].c_str()); + trace::error(_X(" %s at [%s]"), info.version.as_str().c_str(), info.path.c_str()); } } @@ -1010,36 +865,6 @@ bool is_sdk_dir_present(const pal::string_t& own_dir) return pal::directory_exists(sdk_path); } -bool versions_sdk_info(pal::string_t own_dir, pal::string_t leading_whitespace) -{ - std::vector sdk_versions; - std::vector sdk_locations; - get_all_sdk_versions(own_dir, &sdk_versions, &sdk_locations); - assert(sdk_versions.size() == sdk_locations.size()); - for (int i = 0; i < sdk_versions.size(); i++) - { - trace::println(_X("%s%s [%s]"), leading_whitespace.c_str(), sdk_versions[i].c_str(), sdk_locations[i].c_str()); - } - - return sdk_versions.size() > 0; -} - -bool versions_runtime_info(pal::string_t own_dir, pal::string_t leading_whitespace) -{ - std::vector fx_framework_names; - std::vector fx_versions; - std::vector fx_locations; - get_all_fx_versions(host_mode_t::muxer, own_dir, _X(""), &fx_framework_names, &fx_versions, &fx_locations); - assert(fx_framework_names.size() == fx_versions.size()); - assert(fx_framework_names.size() == fx_locations.size()); - for (int i = 0; i < fx_versions.size(); i++) - { - trace::println(_X("%s%s %s [%s]"), leading_whitespace.c_str(), fx_framework_names[i].c_str(), fx_versions[i].c_str(), fx_locations[i].c_str()); - } - - return fx_versions.size() > 0; -} - void muxer_info(pal::string_t own_dir) { trace::println(); @@ -1051,14 +876,14 @@ void muxer_info(pal::string_t own_dir) trace::println(); trace::println(_X(".NET Core SDKs installed:")); - if (!versions_sdk_info(own_dir, _X(" "))) + if (!sdk_info::print_all_sdks(own_dir, _X(" "))) { trace::println(_X(" No SDKs were found.")); } trace::println(); trace::println(_X("The.NET Core runtimes installed:")); - if (!versions_runtime_info(own_dir, _X(" "))) + if (!framework_info::print_all_frameworks(own_dir, _X(" "))) { trace::println(_X(" No runtimes were found.")); } @@ -1594,12 +1419,12 @@ int fx_muxer_t::handle_cli( // Check for commands that don't depend on the CLI SDK to be loaded if (pal::strcasecmp(_X("--list-sdks"), argv[1]) == 0) { - versions_sdk_info(own_dir, _X("")); + sdk_info::print_all_sdks(own_dir, _X("")); return StatusCode::Success; } else if (pal::strcasecmp(_X("--list-runtimes"), argv[1]) == 0) { - versions_runtime_info(own_dir, _X("")); + framework_info::print_all_frameworks(own_dir, _X("")); return StatusCode::Success; } diff --git a/src/installer/corehost/cli/fxr/sdk_info.cpp b/src/installer/corehost/cli/fxr/sdk_info.cpp new file mode 100644 index 0000000..4732b2a --- /dev/null +++ b/src/installer/corehost/cli/fxr/sdk_info.cpp @@ -0,0 +1,80 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +#include +#include "pal.h" +#include "sdk_info.h" +#include "trace.h" +#include "utils.h" + +bool compare_by_version(const sdk_info &a, const sdk_info &b) +{ + return a.version < b.version; +} + +void sdk_info::get_all_sdk_infos( + const pal::string_t& own_dir, + std::vector* sdk_infos) +{ + std::vector global_dirs; + bool multilevel_lookup = multilevel_lookup_enabled(); + + // own_dir contains DIR_SEPARATOR appended that we need to remove. + pal::string_t own_dir_temp = own_dir; + remove_trailing_dir_seperator(&own_dir_temp); + + std::vector hive_dir; + hive_dir.push_back(own_dir_temp); + + if (multilevel_lookup && pal::get_global_dotnet_dirs(&global_dirs)) + { + for (pal::string_t dir : global_dirs) + { + if (dir != own_dir_temp) + { + hive_dir.push_back(dir); + } + } + } + + for (pal::string_t dir : hive_dir) + { + auto sdk_dir = dir; + trace::verbose(_X("Gathering SDK locations in [%s]"), sdk_dir.c_str()); + + append_path(&sdk_dir, _X("sdk")); + + if (pal::directory_exists(sdk_dir)) + { + std::vector versions; + pal::readdir_onlydirectories(sdk_dir, &versions); + for (const auto& ver : versions) + { + // Make sure we filter out any non-version folders. + fx_ver_t parsed(-1, -1, -1); + if (fx_ver_t::parse(ver, &parsed, false)) + { + trace::verbose(_X("Found SDK version [%s]"), ver.c_str()); + + sdk_info info(sdk_dir, parsed); + + sdk_infos->push_back(info); + } + } + } + } + + std::sort(sdk_infos->begin(), sdk_infos->end(), compare_by_version); +} + +/*static*/ bool sdk_info::print_all_sdks(const pal::string_t& own_dir, const pal::string_t& leading_whitespace) +{ + std::vector sdk_infos; + get_all_sdk_infos(own_dir, &sdk_infos); + for (sdk_info info : sdk_infos) + { + trace::println(_X("%s%s [%s]"), leading_whitespace.c_str(), info.version.as_str().c_str(), info.path.c_str()); + } + + return sdk_infos.size() > 0; +} diff --git a/src/installer/corehost/cli/fxr/sdk_info.h b/src/installer/corehost/cli/fxr/sdk_info.h new file mode 100644 index 0000000..1a43ccb --- /dev/null +++ b/src/installer/corehost/cli/fxr/sdk_info.h @@ -0,0 +1,25 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +#ifndef __SDK_INFO_H_ +#define __SDK_INFO_H_ + +#include "libhost.h" + +struct sdk_info +{ + sdk_info(pal::string_t path, fx_ver_t version) + : path(path) + , version(version) { } + + static void get_all_sdk_infos( + const pal::string_t& own_dir, + std::vector* sdk_infos); + + static bool print_all_sdks(const pal::string_t& own_dir, const pal::string_t& leading_whitespace); + + pal::string_t path; + fx_ver_t version; +}; + +#endif // __SDK_INFO_H_