diff options
| author | ras0219 <533828+ras0219@users.noreply.github.com> | 2020-08-13 18:36:33 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-08-13 18:36:33 -0700 |
| commit | 0b5bbe30d940c597242cefa899dc93168054e466 (patch) | |
| tree | a02a36758c8d4f794194dd37b48a7649fc143ee3 | |
| parent | 5bb91a9452c2155e8ccd69c88629af24507249d4 (diff) | |
| download | vcpkg-0b5bbe30d940c597242cefa899dc93168054e466.tar.gz vcpkg-0b5bbe30d940c597242cefa899dc93168054e466.zip | |
[vcpkg] Lift `--x-json` to a global option, implement experimental `x-package-info` command (#12845)
* [vcpkg] Improve error reporting in vcpkg::Json
* [vcpkg] Lift --x-json to a common option
* [vcpkg] Address warnings-as-errors in VS2015
* [vcpkg] Remove unused local
* [vcpkg] Extract vcpkg::Install::get_cmake_usage
* [vcpkg] Implement vcpkg::serialize_ipv(ipv, paths)
* [vcpkg] Implement x-package-info to enable tooling
* [vcpkg] Fixup tests to respect new cli mode
Co-authored-by: Robert Schumacher <roschuma@microsoft.com>
| -rw-r--r-- | toolsrc/include/vcpkg/base/json.h | 4 | ||||
| -rw-r--r-- | toolsrc/include/vcpkg/binaryparagraph.h | 2 | ||||
| -rw-r--r-- | toolsrc/include/vcpkg/commands.info.h | 13 | ||||
| -rw-r--r-- | toolsrc/include/vcpkg/install.h | 11 | ||||
| -rw-r--r-- | toolsrc/include/vcpkg/statusparagraph.h | 2 | ||||
| -rw-r--r-- | toolsrc/include/vcpkg/vcpkgcmdarguments.h | 4 | ||||
| -rw-r--r-- | toolsrc/src/vcpkg-test/commands.cpp | 3 | ||||
| -rw-r--r-- | toolsrc/src/vcpkg-test/manifests.cpp | 6 | ||||
| -rw-r--r-- | toolsrc/src/vcpkg-test/strings.cpp | 4 | ||||
| -rw-r--r-- | toolsrc/src/vcpkg-test/system.cpp | 4 | ||||
| -rw-r--r-- | toolsrc/src/vcpkg.cpp | 4 | ||||
| -rw-r--r-- | toolsrc/src/vcpkg/base/json.cpp | 10 | ||||
| -rw-r--r-- | toolsrc/src/vcpkg/commands.cpp | 3 | ||||
| -rw-r--r-- | toolsrc/src/vcpkg/commands.info.cpp | 146 | ||||
| -rw-r--r-- | toolsrc/src/vcpkg/commands.list.cpp | 8 | ||||
| -rw-r--r-- | toolsrc/src/vcpkg/install.cpp | 46 | ||||
| -rw-r--r-- | toolsrc/src/vcpkg/statusparagraphs.cpp | 40 | ||||
| -rw-r--r-- | toolsrc/src/vcpkg/vcpkgcmdarguments.cpp | 4 | ||||
| -rw-r--r-- | toolsrc/src/vcpkg/vcpkglib.cpp | 1 | ||||
| -rw-r--r-- | toolsrc/src/vcpkg/vcpkgpaths.cpp | 2 | ||||
| -rw-r--r-- | toolsrc/windows-bootstrap/vcpkglib/vcpkglib.vcxproj | 2 |
21 files changed, 287 insertions, 32 deletions
diff --git a/toolsrc/include/vcpkg/base/json.h b/toolsrc/include/vcpkg/base/json.h index b7adde38f..a4ad44ebd 100644 --- a/toolsrc/include/vcpkg/base/json.h +++ b/toolsrc/include/vcpkg/base/json.h @@ -227,13 +227,13 @@ namespace vcpkg::Json Value& operator[](StringView key) noexcept { auto res = this->get(key); - vcpkg::Checks::check_exit(VCPKG_LINE_INFO, res); + vcpkg::Checks::check_exit(VCPKG_LINE_INFO, res, "missing key: \"%s\"", key); return *res; } const Value& operator[](StringView key) const noexcept { auto res = this->get(key); - vcpkg::Checks::check_exit(VCPKG_LINE_INFO, res); + vcpkg::Checks::check_exit(VCPKG_LINE_INFO, res, "missing key: \"%s\"", key); return *res; } diff --git a/toolsrc/include/vcpkg/binaryparagraph.h b/toolsrc/include/vcpkg/binaryparagraph.h index 2d2e4cf20..f10c41af0 100644 --- a/toolsrc/include/vcpkg/binaryparagraph.h +++ b/toolsrc/include/vcpkg/binaryparagraph.h @@ -39,7 +39,7 @@ namespace vcpkg std::vector<std::string> default_features; std::vector<std::string> dependencies; std::string abi; - Type type; + Type type = {Type::UNKNOWN}; }; bool operator==(const BinaryParagraph&, const BinaryParagraph&); diff --git a/toolsrc/include/vcpkg/commands.info.h b/toolsrc/include/vcpkg/commands.info.h new file mode 100644 index 000000000..556d1eb01 --- /dev/null +++ b/toolsrc/include/vcpkg/commands.info.h @@ -0,0 +1,13 @@ +#pragma once + +#include <vcpkg/commands.interface.h> + +namespace vcpkg::Commands::Info +{ + extern const CommandStructure COMMAND_STRUCTURE; + + struct InfoCommand : PathsCommand + { + virtual void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) const override; + }; +} diff --git a/toolsrc/include/vcpkg/install.h b/toolsrc/include/vcpkg/install.h index 0ba0932e0..f85d48d8d 100644 --- a/toolsrc/include/vcpkg/install.h +++ b/toolsrc/include/vcpkg/install.h @@ -2,6 +2,7 @@ #include <vcpkg/base/chrono.h> +#include <vcpkg/binaryparagraph.h> #include <vcpkg/build.h> #include <vcpkg/dependencies.h> #include <vcpkg/vcpkgcmdarguments.h> @@ -90,6 +91,16 @@ namespace vcpkg::Install const Build::IBuildLogsRecorder& build_logs_recorder, const CMakeVars::CMakeVarProvider& var_provider); + struct CMakeUsageInfo + { + std::string message; + bool usage_file = false; + Optional<bool> header_only; + std::map<std::string, std::vector<std::string>> cmake_targets_map; + }; + + CMakeUsageInfo get_cmake_usage(const BinaryParagraph& bpgh, const VcpkgPaths& paths); + extern const CommandStructure COMMAND_STRUCTURE; void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, Triplet default_triplet); diff --git a/toolsrc/include/vcpkg/statusparagraph.h b/toolsrc/include/vcpkg/statusparagraph.h index dde4ecb19..cf4c3c046 100644 --- a/toolsrc/include/vcpkg/statusparagraph.h +++ b/toolsrc/include/vcpkg/statusparagraph.h @@ -61,4 +61,6 @@ namespace vcpkg const StatusParagraph* core; std::vector<const StatusParagraph*> features; }; + + Json::Value serialize_ipv(const InstalledPackageView& ipv, const struct VcpkgPaths& paths); } diff --git a/toolsrc/include/vcpkg/vcpkgcmdarguments.h b/toolsrc/include/vcpkg/vcpkgcmdarguments.h index 82c4f6dc2..84cd7c599 100644 --- a/toolsrc/include/vcpkg/vcpkgcmdarguments.h +++ b/toolsrc/include/vcpkg/vcpkgcmdarguments.h @@ -153,6 +153,9 @@ namespace vcpkg constexpr static StringLiteral WAIT_FOR_LOCK_SWITCH = "x-wait-for-lock"; Optional<bool> wait_for_lock = nullopt; + constexpr static StringLiteral JSON_SWITCH = "x-json"; + Optional<bool> json = nullopt; + // feature flags constexpr static StringLiteral FEATURE_FLAGS_ENV = "VCPKG_FEATURE_FLAGS"; constexpr static StringLiteral FEATURE_FLAGS_ARG = "feature-flags"; @@ -169,6 +172,7 @@ namespace vcpkg bool binary_caching_enabled() const { return binary_caching.value_or(true); } bool compiler_tracking_enabled() const { return compiler_tracking.value_or(true); } + bool output_json() const { return json.value_or(false); } std::string command; std::vector<std::string> command_arguments; diff --git a/toolsrc/src/vcpkg-test/commands.cpp b/toolsrc/src/vcpkg-test/commands.cpp index eeefa3098..2c3779877 100644 --- a/toolsrc/src/vcpkg-test/commands.cpp +++ b/toolsrc/src/vcpkg-test/commands.cpp @@ -24,7 +24,7 @@ TEST_CASE ("get_available_basic_commands works", "[commands]") TEST_CASE ("get_available_paths_commands works", "[commands]") { auto commands_list = Commands::get_available_paths_commands(); - CHECK(commands_list.size() == 18); + CHECK(commands_list.size() == 19); CHECK(Commands::find("/?", commands_list) != nullptr); CHECK(Commands::find("help", commands_list) != nullptr); @@ -42,6 +42,7 @@ TEST_CASE ("get_available_paths_commands works", "[commands]") CHECK(Commands::find("fetch", commands_list) != nullptr); CHECK(Commands::find("x-ci-clean", commands_list) != nullptr); CHECK(Commands::find("x-history", commands_list) != nullptr); + CHECK(Commands::find("x-package-info", commands_list) != nullptr); CHECK(Commands::find("x-vsinstances", commands_list) != nullptr); CHECK(Commands::find("x-format-manifest", commands_list) != nullptr); diff --git a/toolsrc/src/vcpkg-test/manifests.cpp b/toolsrc/src/vcpkg-test/manifests.cpp index 9fc041a19..4b450b7be 100644 --- a/toolsrc/src/vcpkg-test/manifests.cpp +++ b/toolsrc/src/vcpkg-test/manifests.cpp @@ -8,6 +8,10 @@ #include <vcpkg-test/util.h> +#if defined(_MSC_VER) +#pragma warning(disable : 6237) +#endif + using namespace vcpkg; using namespace vcpkg::Paragraphs; using namespace vcpkg::Test; @@ -248,7 +252,7 @@ TEST_CASE ("Serialize all the ports", "[manifests]") std::vector<std::string> args_list = {"x-format-manifest"}; auto& fs = Files::get_real_filesystem(); auto args = VcpkgCmdArguments::create_from_arg_sequence(args_list.data(), args_list.data() + args_list.size()); - auto paths = VcpkgPaths{fs, args}; + VcpkgPaths paths{fs, args}; std::vector<SourceControlFile> scfs; diff --git a/toolsrc/src/vcpkg-test/strings.cpp b/toolsrc/src/vcpkg-test/strings.cpp index 95a6de2af..cc45365e6 100644 --- a/toolsrc/src/vcpkg-test/strings.cpp +++ b/toolsrc/src/vcpkg-test/strings.cpp @@ -8,6 +8,10 @@ #include <utility> #include <vector> +#if defined(_MSC_VER) +#pragma warning(disable : 6237) +#endif + TEST_CASE ("b32 encoding", "[strings]") { using u64 = uint64_t; diff --git a/toolsrc/src/vcpkg-test/system.cpp b/toolsrc/src/vcpkg-test/system.cpp index 015406358..dec7b5769 100644 --- a/toolsrc/src/vcpkg-test/system.cpp +++ b/toolsrc/src/vcpkg-test/system.cpp @@ -11,6 +11,10 @@ #include <string> +#if defined(_MSC_VER) +#pragma warning(disable : 6237) +#endif + using vcpkg::nullopt; using vcpkg::Optional; using vcpkg::StringView; diff --git a/toolsrc/src/vcpkg.cpp b/toolsrc/src/vcpkg.cpp index 0158b3755..d0df8749f 100644 --- a/toolsrc/src/vcpkg.cpp +++ b/toolsrc/src/vcpkg.cpp @@ -77,7 +77,9 @@ static void inner(vcpkg::Files::Filesystem& fs, const VcpkgCmdArguments& args) paths.track_feature_flag_metrics(); fs.current_path(paths.root, VCPKG_LINE_INFO); - if (args.command == "install" || args.command == "remove" || args.command == "export" || args.command == "update") + if ((args.command == "install" || args.command == "remove" || args.command == "export" || + args.command == "update") && + !args.output_json()) { Commands::Version::warn_if_vcpkg_version_mismatch(paths); std::string surveydate = *GlobalState::g_surveydate.lock(); diff --git a/toolsrc/src/vcpkg/base/json.cpp b/toolsrc/src/vcpkg/base/json.cpp index 7536e09df..0a9422d66 100644 --- a/toolsrc/src/vcpkg/base/json.cpp +++ b/toolsrc/src/vcpkg/base/json.cpp @@ -141,30 +141,30 @@ namespace vcpkg::Json } StringView Value::string() const noexcept { - vcpkg::Checks::check_exit(VCPKG_LINE_INFO, is_string()); + vcpkg::Checks::check_exit(VCPKG_LINE_INFO, is_string(), "json value is not string"); return underlying_->string; } const Array& Value::array() const& noexcept { - vcpkg::Checks::check_exit(VCPKG_LINE_INFO, is_array()); + vcpkg::Checks::check_exit(VCPKG_LINE_INFO, is_array(), "json value is not array"); return underlying_->array; } Array& Value::array() & noexcept { - vcpkg::Checks::check_exit(VCPKG_LINE_INFO, is_array()); + vcpkg::Checks::check_exit(VCPKG_LINE_INFO, is_array(), "json value is not array"); return underlying_->array; } Array&& Value::array() && noexcept { return std::move(this->array()); } const Object& Value::object() const& noexcept { - vcpkg::Checks::check_exit(VCPKG_LINE_INFO, is_object()); + vcpkg::Checks::check_exit(VCPKG_LINE_INFO, is_object(), "json value is not object"); return underlying_->object; } Object& Value::object() & noexcept { - vcpkg::Checks::check_exit(VCPKG_LINE_INFO, is_object()); + vcpkg::Checks::check_exit(VCPKG_LINE_INFO, is_object(), "json value is not object"); return underlying_->object; } Object&& Value::object() && noexcept { return std::move(this->object()); } diff --git a/toolsrc/src/vcpkg/commands.cpp b/toolsrc/src/vcpkg/commands.cpp index a455867ed..466cc11c0 100644 --- a/toolsrc/src/vcpkg/commands.cpp +++ b/toolsrc/src/vcpkg/commands.cpp @@ -15,6 +15,7 @@ #include <vcpkg/commands.format-manifest.h> #include <vcpkg/commands.h> #include <vcpkg/commands.hash.h> +#include <vcpkg/commands.info.h> #include <vcpkg/commands.integrate.h> #include <vcpkg/commands.list.h> #include <vcpkg/commands.owns.h> @@ -49,6 +50,7 @@ namespace vcpkg::Commands static const Help::HelpCommand help{}; static const Search::SearchCommand search{}; static const List::ListCommand list{}; + static const Info::InfoCommand info{}; static const Integrate::IntegrateCommand integrate{}; static const Owns::OwnsCommand owns{}; static const Update::UpdateCommand update{}; @@ -80,6 +82,7 @@ namespace vcpkg::Commands {"hash", &hash}, {"fetch", &fetch}, {"x-ci-clean", &ciclean}, + {"x-package-info", &info}, {"x-history", &porthistory}, {"x-vsinstances", &vsinstances}, {"x-format-manifest", &format_manifest}, diff --git a/toolsrc/src/vcpkg/commands.info.cpp b/toolsrc/src/vcpkg/commands.info.cpp new file mode 100644 index 000000000..afb2642c6 --- /dev/null +++ b/toolsrc/src/vcpkg/commands.info.cpp @@ -0,0 +1,146 @@ +#include "pch.h" + +#include <vcpkg/base/json.h> +#include <vcpkg/base/parse.h> +#include <vcpkg/base/stringliteral.h> + +#include <vcpkg/commands.info.h> +#include <vcpkg/input.h> +#include <vcpkg/install.h> +#include <vcpkg/portfileprovider.h> +#include <vcpkg/statusparagraphs.h> +#include <vcpkg/vcpkglib.h> +#include <vcpkg/versiont.h> + +namespace vcpkg::Commands::Info +{ + static constexpr StringLiteral OPTION_TRANSITIVE = "x-transitive"; + static constexpr StringLiteral OPTION_INSTALLED = "x-installed"; + + static constexpr CommandSwitch INFO_SWITCHES[] = { + {OPTION_INSTALLED, "(experimental) Report on installed packages instead of available"}, + {OPTION_TRANSITIVE, "(experimental) Also report on dependencies of installed packages"}, + }; + + const CommandStructure COMMAND_STRUCTURE = { + Strings::format("Display detailed information on packages.\n%s", + create_example_string("x-package-info zlib openssl:x64-windows")), + 1, + SIZE_MAX, + {INFO_SWITCHES, {}}, + nullptr, + }; + + void InfoCommand::perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) const + { + const ParsedArguments options = args.parse_arguments(COMMAND_STRUCTURE); + if (!args.output_json()) + { + Checks::exit_with_message( + VCPKG_LINE_INFO, "This command currently requires --%s", VcpkgCmdArguments::JSON_SWITCH); + } + + const bool installed = Util::Sets::contains(options.switches, OPTION_INSTALLED); + const bool transitive = Util::Sets::contains(options.switches, OPTION_TRANSITIVE); + + if (transitive && !installed) + { + Checks::exit_with_message(VCPKG_LINE_INFO, "--%s requires --%s", OPTION_TRANSITIVE, OPTION_INSTALLED); + } + + if (installed) + { + const StatusParagraphs status_paragraphs = database_load_check(paths); + std::set<PackageSpec> specs_written; + std::vector<PackageSpec> specs_to_write; + for (auto&& arg : args.command_arguments) + { + Parse::ParserBase parser(arg, "<command>"); + auto maybe_qpkg = parse_qualified_specifier(parser); + if (!parser.at_eof() || !maybe_qpkg) + { + parser.add_error("expected a package specifier"); + } + else if (!maybe_qpkg.get()->triplet) + { + parser.add_error("expected an explicit triplet"); + } + else if (maybe_qpkg.get()->features) + { + parser.add_error("unexpected list of features"); + } + else if (maybe_qpkg.get()->platform) + { + parser.add_error("unexpected qualifier"); + } + if (auto err = parser.get_error()) + { + System::print2(err->format(), "\n"); + Checks::exit_fail(VCPKG_LINE_INFO); + } + + auto& qpkg = *maybe_qpkg.get(); + auto t = Triplet::from_canonical_name(std::string(*qpkg.triplet.get())); + Input::check_triplet(t, paths); + specs_to_write.emplace_back(qpkg.name, t); + } + Json::Object response; + Json::Object results; + while (!specs_to_write.empty()) + { + auto spec = std::move(specs_to_write.back()); + specs_to_write.pop_back(); + if (!specs_written.insert(spec).second) continue; + auto maybe_ipv = status_paragraphs.get_installed_package_view(spec); + if (auto ipv = maybe_ipv.get()) + { + results.insert(spec.to_string(), serialize_ipv(*ipv, paths)); + if (transitive) + { + auto deps = ipv->dependencies(); + specs_to_write.insert(specs_to_write.end(), + std::make_move_iterator(deps.begin()), + std::make_move_iterator(deps.end())); + } + } + } + response.insert("results", std::move(results)); + System::print2(Json::stringify(response, {})); + } + else + { + Json::Object response; + Json::Object results; + PortFileProvider::PathsPortFileProvider provider(paths, args.overlay_ports); + + for (auto&& arg : args.command_arguments) + { + Parse::ParserBase parser(arg, "<command>"); + auto maybe_pkg = parse_package_name(parser); + if (!parser.at_eof() || !maybe_pkg) + { + parser.add_error("expected only a package identifier"); + } + if (auto err = parser.get_error()) + { + System::print2(err->format(), "\n"); + Checks::exit_fail(VCPKG_LINE_INFO); + } + + auto& pkg = *maybe_pkg.get(); + + if (results.contains(pkg)) continue; + + auto maybe_scfl = provider.get_control_file(pkg); + + Json::Object obj; + if (auto pscfl = maybe_scfl.get()) + { + results.insert(pkg, serialize_manifest(*pscfl->source_control_file)); + } + } + response.insert("results", std::move(results)); + System::print2(Json::stringify(response, {})); + } + } +} diff --git a/toolsrc/src/vcpkg/commands.list.cpp b/toolsrc/src/vcpkg/commands.list.cpp index 9385e4423..fcd2919ff 100644 --- a/toolsrc/src/vcpkg/commands.list.cpp +++ b/toolsrc/src/vcpkg/commands.list.cpp @@ -9,8 +9,6 @@ namespace vcpkg::Commands::List { static constexpr StringLiteral OPTION_FULLDESC = "x-full-desc"; // TODO: This should find a better home, eventually - static constexpr StringLiteral OPTION_JSON = "--x-json"; - static void do_print_json(std::vector<const vcpkg::StatusParagraph*> installed_packages) { Json::Object obj; @@ -73,9 +71,8 @@ namespace vcpkg::Commands::List } } - static constexpr std::array<CommandSwitch, 2> LIST_SWITCHES = {{ + static constexpr std::array<CommandSwitch, 1> LIST_SWITCHES = {{ {OPTION_FULLDESC, "Do not truncate long text"}, - {OPTION_JSON, "List libraries in JSON format"}, }}; const CommandStructure COMMAND_STRUCTURE = { @@ -113,7 +110,6 @@ namespace vcpkg::Commands::List }); const auto enable_fulldesc = Util::Sets::contains(options.switches, OPTION_FULLDESC.to_string()); - const auto enable_json = Util::Sets::contains(options.switches, OPTION_JSON.to_string()); if (!args.command_arguments.empty()) { @@ -124,7 +120,7 @@ namespace vcpkg::Commands::List installed_packages = pghs; } - if (enable_json) + if (args.output_json()) { do_print_json(installed_packages); } diff --git a/toolsrc/src/vcpkg/install.cpp b/toolsrc/src/vcpkg/install.cpp index e381b90a3..03ae77d98 100644 --- a/toolsrc/src/vcpkg/install.cpp +++ b/toolsrc/src/vcpkg/install.cpp @@ -574,20 +574,34 @@ namespace vcpkg::Install static void print_cmake_information(const BinaryParagraph& bpgh, const VcpkgPaths& paths) { + auto usage = get_cmake_usage(bpgh, paths); + + if (!usage.message.empty()) + { + System::print2(usage.message); + } + } + + CMakeUsageInfo get_cmake_usage(const BinaryParagraph& bpgh, const VcpkgPaths& paths) + { static const std::regex cmake_library_regex(R"(\badd_library\(([^\$\s\)]+)\s)", std::regex_constants::ECMAScript); + CMakeUsageInfo ret; + auto& fs = paths.get_filesystem(); auto usage_file = paths.installed / bpgh.spec.triplet().canonical_name() / "share" / bpgh.spec.name() / "usage"; if (fs.exists(usage_file)) { + ret.usage_file = true; auto maybe_contents = fs.read_contents(usage_file); if (auto p_contents = maybe_contents.get()) { - System::print2(*p_contents, '\n'); + ret.message = std::move(*p_contents); + ret.message.push_back('\n'); } - return; + return ret; } auto files = fs.read_lines(paths.listfile_path(bpgh)); @@ -652,6 +666,8 @@ namespace vcpkg::Install } } + ret.header_only = is_header_only; + if (library_targets.empty()) { if (is_header_only && !header_path.empty()) @@ -670,20 +686,21 @@ namespace vcpkg::Install "The package ", bpgh.spec, " is header only and can be used from CMake via:\n\n"); Strings::append(msg, " find_path(", name, "_INCLUDE_DIRS \"", header_path, "\")\n"); Strings::append(msg, " target_include_directories(main PRIVATE ${", name, "_INCLUDE_DIRS})\n\n"); - System::print2(msg); + + ret.message = std::move(msg); } } else { - System::print2("The package ", bpgh.spec, " provides CMake targets:\n\n"); + auto msg = Strings::concat("The package ", bpgh.spec, " provides CMake targets:\n\n"); for (auto&& library_target_pair : library_targets) { auto config_it = config_files.find(library_target_pair.first); if (config_it != config_files.end()) - System::printf(" find_package(%s CONFIG REQUIRED)\n", config_it->second); + Strings::append(msg, " find_package(", config_it->second, " CONFIG REQUIRED)\n "); else - System::printf(" find_package(%s CONFIG REQUIRED)\n", library_target_pair.first); + Strings::append(msg, " find_package(", library_target_pair.first, " CONFIG REQUIRED)\n "); std::sort(library_target_pair.second.begin(), library_target_pair.second.end(), @@ -695,22 +712,27 @@ namespace vcpkg::Install if (library_target_pair.second.size() <= 4) { - System::printf(" target_link_libraries(main PRIVATE %s)\n\n", - Strings::join(" ", library_target_pair.second)); + Strings::append(msg, + " target_link_libraries(main PRIVATE ", + Strings::join(" ", library_target_pair.second), + ")\n\n"); } else { auto omitted = library_target_pair.second.size() - 4; library_target_pair.second.erase(library_target_pair.second.begin() + 4, library_target_pair.second.end()); - System::printf(" # Note: %zd target(s) were omitted.\n" - " target_link_libraries(main PRIVATE %s)\n\n", - omitted, - Strings::join(" ", library_target_pair.second)); + msg += Strings::format(" # Note: %zd target(s) were omitted.\n" + " target_link_libraries(main PRIVATE %s)\n\n", + omitted, + Strings::join(" ", library_target_pair.second)); } } + ret.message = std::move(msg); } + ret.cmake_targets_map = std::move(library_targets); } + return ret; } /// diff --git a/toolsrc/src/vcpkg/statusparagraphs.cpp b/toolsrc/src/vcpkg/statusparagraphs.cpp index d42174289..ba1815224 100644 --- a/toolsrc/src/vcpkg/statusparagraphs.cpp +++ b/toolsrc/src/vcpkg/statusparagraphs.cpp @@ -1,6 +1,8 @@ #include <vcpkg/base/checks.h> +#include <vcpkg/install.h> #include <vcpkg/statusparagraphs.h> +#include <vcpkg/vcpkgpaths.h> namespace vcpkg { @@ -143,4 +145,42 @@ namespace vcpkg out_str.push_back('\n'); } } + + Json::Value serialize_ipv(const InstalledPackageView& ipv, const VcpkgPaths& paths) + { + const auto& fs = paths.get_filesystem(); + Json::Object iobj; + iobj.insert("version-string", Json::Value::string(ipv.core->package.version)); + iobj.insert("port-version", Json::Value::integer(ipv.core->package.port_version)); + iobj.insert("triplet", Json::Value::string(ipv.spec().triplet().to_string())); + iobj.insert("abi", Json::Value::string(ipv.core->package.abi)); + Json::Array deps; + for (auto&& dep : ipv.dependencies()) + deps.push_back(Json::Value::string(dep.to_string())); + if (deps.size() != 0) + { + iobj.insert("dependencies", std::move(deps)); + } + Json::Array features; + for (auto&& feature : ipv.features) + { + features.push_back(Json::Value::string(feature->package.feature)); + } + if (features.size() != 0) + { + iobj.insert("features", std::move(features)); + } + auto usage = Install::get_cmake_usage(ipv.core->package, paths); + if (!usage.message.empty()) + { + iobj.insert("usage", Json::Value::string(std::move(usage.message))); + } + auto owns_files = fs.read_lines(paths.listfile_path(ipv.core->package)).value_or_exit(VCPKG_LINE_INFO); + Json::Array owns; + for (auto&& owns_file : owns_files) + owns.push_back(Json::Value::string(std::move(owns_file))); + + iobj.insert("owns", std::move(owns)); + return Json::Value::object(std::move(iobj)); + } } diff --git a/toolsrc/src/vcpkg/vcpkgcmdarguments.cpp b/toolsrc/src/vcpkg/vcpkgcmdarguments.cpp index 7354dbae2..7377baafb 100644 --- a/toolsrc/src/vcpkg/vcpkgcmdarguments.cpp +++ b/toolsrc/src/vcpkg/vcpkgcmdarguments.cpp @@ -308,6 +308,7 @@ namespace vcpkg {FEATURE_PACKAGES_SWITCH, &VcpkgCmdArguments::feature_packages}, {BINARY_CACHING_SWITCH, &VcpkgCmdArguments::binary_caching}, {WAIT_FOR_LOCK_SWITCH, &VcpkgCmdArguments::wait_for_lock}, + {JSON_SWITCH, &VcpkgCmdArguments::json}, }; bool found = false; @@ -604,7 +605,7 @@ namespace vcpkg void VcpkgCmdArguments::append_common_options(HelpTableFormatter& table) { static auto opt = [](StringView arg, StringView joiner, StringView value) { - return Strings::format("--%s%s%s", arg, joiner, value); + return Strings::concat("--", arg, joiner, value); }; table.format(opt(TRIPLET_ARG, " ", "<t>"), "Specify the target architecture triplet. See 'vcpkg help triplet'"); @@ -623,6 +624,7 @@ namespace vcpkg table.format(opt(INSTALL_ROOT_DIR_ARG, "=", "<path>"), "(Experimental) Specify the install root directory"); table.format(opt(PACKAGES_ROOT_DIR_ARG, "=", "<path>"), "(Experimental) Specify the packages root directory"); table.format(opt(SCRIPTS_ROOT_DIR_ARG, "=", "<path>"), "(Experimental) Specify the scripts root directory"); + table.format(opt(JSON_SWITCH, "", ""), "(Experimental) Request JSON output"); } void VcpkgCmdArguments::imbue_from_environment() diff --git a/toolsrc/src/vcpkg/vcpkglib.cpp b/toolsrc/src/vcpkg/vcpkglib.cpp index 801e39541..a158cf74b 100644 --- a/toolsrc/src/vcpkg/vcpkglib.cpp +++ b/toolsrc/src/vcpkg/vcpkglib.cpp @@ -172,7 +172,6 @@ namespace vcpkg { std::map<PackageSpec, InstalledPackageView> ipv_map; - std::vector<InstalledPackageView> installed_packages; for (auto&& pgh : status_db) { if (!pgh->is_installed()) continue; diff --git a/toolsrc/src/vcpkg/vcpkgpaths.cpp b/toolsrc/src/vcpkg/vcpkgpaths.cpp index 2448d525d..6572b44f1 100644 --- a/toolsrc/src/vcpkg/vcpkgpaths.cpp +++ b/toolsrc/src/vcpkg/vcpkgpaths.cpp @@ -163,7 +163,7 @@ namespace vcpkg else { // we ignore the manifest root dir if the user requests -manifest - if (!manifest_root_dir.empty() && !args.manifest_mode.has_value()) + if (!manifest_root_dir.empty() && !args.manifest_mode.has_value() && !args.output_json()) { System::print2(System::Color::warning, "Warning: manifest-root detected at ", diff --git a/toolsrc/windows-bootstrap/vcpkglib/vcpkglib.vcxproj b/toolsrc/windows-bootstrap/vcpkglib/vcpkglib.vcxproj index 2c980039e..660459024 100644 --- a/toolsrc/windows-bootstrap/vcpkglib/vcpkglib.vcxproj +++ b/toolsrc/windows-bootstrap/vcpkglib/vcpkglib.vcxproj @@ -197,6 +197,7 @@ <ClInclude Include="..\..\include\vcpkg\commands.fetch.h" />
<ClInclude Include="..\..\include\vcpkg\commands.format-manifest.h" />
<ClInclude Include="..\..\include\vcpkg\commands.hash.h" />
+ <ClInclude Include="..\..\include\vcpkg\commands.info.h" />
<ClInclude Include="..\..\include\vcpkg\commands.integrate.h" />
<ClInclude Include="..\..\include\vcpkg\commands.interface.h" />
<ClInclude Include="..\..\include\vcpkg\commands.list.h" />
@@ -284,6 +285,7 @@ <ClCompile Include="..\..\src\vcpkg\commands.fetch.cpp" />
<ClCompile Include="..\..\src\vcpkg\commands.format-manifest.cpp" />
<ClCompile Include="..\..\src\vcpkg\commands.hash.cpp" />
+ <ClCompile Include="..\..\src\vcpkg\commands.info.cpp" />
<ClCompile Include="..\..\src\vcpkg\commands.integrate.cpp" />
<ClCompile Include="..\..\src\vcpkg\commands.list.cpp" />
<ClCompile Include="..\..\src\vcpkg\commands.owns.cpp" />
|
