diff options
| author | ras0219 <robertallenschumacher@gmail.com> | 2020-07-01 11:36:09 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-07-01 11:36:09 -0700 |
| commit | 135f91de1eef9e906eb7a5bcf323f6eff9a2b5da (patch) | |
| tree | 71dfb029d57d3a205a8685bd357586148480d09c /toolsrc/src | |
| parent | 42f70a42766ff3da9c0464dd78f1eed0e8ac3789 (diff) | |
| download | vcpkg-135f91de1eef9e906eb7a5bcf323f6eff9a2b5da.tar.gz vcpkg-135f91de1eef9e906eb7a5bcf323f6eff9a2b5da.zip | |
[vcpkg] Implement --x-write-nuget-packages-config= setting for `install` and `x-set-installed` (#12138)
* [vcpkg] Implement --x-write-nuget-packages-config= setting for `install` and `x-set-installed`.
* [vcpkg] Add end-to-end testing suite for install, remove, and binary caching
* [vcpkg] Define `$TestingRoot in end-to-end-tests.ps1
* [vcpkg] Address CR comments
Co-authored-by: Robert Schumacher <roschuma@microsoft.com>
Diffstat (limited to 'toolsrc/src')
| -rw-r--r-- | toolsrc/src/vcpkg-test/binarycaching.cpp | 88 | ||||
| -rw-r--r-- | toolsrc/src/vcpkg/base/files.cpp | 16 | ||||
| -rw-r--r-- | toolsrc/src/vcpkg/binarycaching.cpp | 59 | ||||
| -rw-r--r-- | toolsrc/src/vcpkg/build.cpp | 7 | ||||
| -rw-r--r-- | toolsrc/src/vcpkg/commands.setinstalled.cpp | 30 | ||||
| -rw-r--r-- | toolsrc/src/vcpkg/install.cpp | 42 |
6 files changed, 217 insertions, 25 deletions
diff --git a/toolsrc/src/vcpkg-test/binarycaching.cpp b/toolsrc/src/vcpkg-test/binarycaching.cpp index 817b85e03..b220b5ccb 100644 --- a/toolsrc/src/vcpkg-test/binarycaching.cpp +++ b/toolsrc/src/vcpkg-test/binarycaching.cpp @@ -1,10 +1,11 @@ #include <catch2/catch.hpp> #include <vcpkg/binarycaching.private.h> +#include <vcpkg/binarycaching.h> #include <vcpkg/base/files.h> +#include <vcpkg/dependencies.h> #include <vcpkg/vcpkgcmdarguments.h> #include <vcpkg/sourceparagraph.h> #include <vcpkg/paragraphs.h> -#include <vcpkg/dependencies.h> #include <string> using namespace vcpkg; @@ -96,9 +97,9 @@ Features: a, b Dependencies: </description> <packageTypes><packageType name="vcpkg"/></packageTypes> - </metadata> + </metadata> <files><file src=")" PKGPATH R"(" target=""/></files> - </package> +</package> )"; auto expected_lines = Strings::split(expected, '\n'); auto nuspec_lines = Strings::split(nuspec, '\n'); @@ -123,8 +124,14 @@ TEST_CASE ("XmlSerializer", "[XmlSerializer]") xml = XmlSerializer(); xml.emit_declaration(); - xml.start_complex_open_tag("a").text_attr("b", "<").text_attr("c", " ").finish_self_closing_complex_tag(); - REQUIRE(xml.buf == R"(<?xml version="1.0" encoding="utf-8"?><a b="<" c=" "/>)"); + xml.start_complex_open_tag("a") + .text_attr("b", "<") + .text_attr("c", " ") + .finish_self_closing_complex_tag() + .line_break(); + xml.simple_tag("d", "e"); + REQUIRE(xml.buf == R"(<?xml version="1.0" encoding="utf-8"?><a b="<" c=" "/>)" + "\n<d>e</d>"); xml = XmlSerializer(); xml.start_complex_open_tag("a").finish_complex_open_tag(); @@ -134,5 +141,72 @@ TEST_CASE ("XmlSerializer", "[XmlSerializer]") xml.line_break(); xml.open_tag("a").line_break().line_break(); xml.close_tag("a").line_break().line_break(); - REQUIRE(xml.buf == "\n<a>\n \n </a>\n\n"); -}
\ No newline at end of file + REQUIRE(xml.buf == "\n<a>\n\n</a>\n\n"); + + xml = XmlSerializer(); + xml.start_complex_open_tag("a") + .text_attr("b", "<") + .line_break() + .text_attr("c", " ") + .finish_complex_open_tag() + .line_break(); + xml.simple_tag("d", "e").line_break(); + REQUIRE(xml.buf == "<a b=\"<\"\n c=\" \">\n <d>e</d>\n"); +} + +TEST_CASE ("generate_nuget_packages_config", "[generate_nuget_packages_config]") +{ + Dependencies::ActionPlan plan; + auto packageconfig = generate_nuget_packages_config(plan); + REQUIRE(packageconfig == R"(<?xml version="1.0" encoding="utf-8"?> +<packages> +</packages> +)"); + + auto pghs = Paragraphs::parse_paragraphs(R"( +Source: zlib +Version: 1.5 +Description: a spiffy compression library wrapper +)", + "<testdata>"); + REQUIRE(pghs.has_value()); + auto maybe_scf = SourceControlFile::parse_control_file(fs::path(), std::move(*pghs.get())); + REQUIRE(maybe_scf.has_value()); + SourceControlFileLocation scfl{std::move(*maybe_scf.get()), fs::path()}; + plan.install_actions.push_back(Dependencies::InstallPlanAction()); + plan.install_actions[0].spec = PackageSpec("zlib", Triplet::X64_ANDROID); + plan.install_actions[0].source_control_file_location = scfl; + plan.install_actions[0].abi_info = Build::AbiInfo{}; + plan.install_actions[0].abi_info.get()->package_abi = "packageabi"; + + packageconfig = generate_nuget_packages_config(plan); + REQUIRE(packageconfig == R"(<?xml version="1.0" encoding="utf-8"?> +<packages> + <package id="zlib_x64-android" version="1.5.0-packageabi"/> +</packages> +)"); + + auto pghs2 = Paragraphs::parse_paragraphs(R"( +Source: zlib2 +Version: 1.52 +Description: a spiffy compression library wrapper +)", + "<testdata>"); + REQUIRE(pghs2.has_value()); + auto maybe_scf2 = SourceControlFile::parse_control_file(fs::path(), std::move(*pghs2.get())); + REQUIRE(maybe_scf2.has_value()); + SourceControlFileLocation scfl2{std::move(*maybe_scf2.get()), fs::path()}; + plan.install_actions.push_back(Dependencies::InstallPlanAction()); + plan.install_actions[1].spec = PackageSpec("zlib2", Triplet::X64_ANDROID); + plan.install_actions[1].source_control_file_location = scfl2; + plan.install_actions[1].abi_info = Build::AbiInfo{}; + plan.install_actions[1].abi_info.get()->package_abi = "packageabi2"; + + packageconfig = generate_nuget_packages_config(plan); + REQUIRE(packageconfig == R"(<?xml version="1.0" encoding="utf-8"?> +<packages> + <package id="zlib_x64-android" version="1.5.0-packageabi"/> + <package id="zlib2_x64-android" version="1.52.0-packageabi2"/> +</packages> +)"); +} diff --git a/toolsrc/src/vcpkg/base/files.cpp b/toolsrc/src/vcpkg/base/files.cpp index 9d9aecb69..2e39073ce 100644 --- a/toolsrc/src/vcpkg/base/files.cpp +++ b/toolsrc/src/vcpkg/base/files.cpp @@ -989,4 +989,20 @@ namespace vcpkg::Files message.push_back('\n'); System::print2(message); } + + fs::path combine(const fs::path& lhs, const fs::path& rhs) + { +#if VCPKG_USE_STD_FILESYSTEM + return lhs / rhs; +#else // ^^^ VCPKG_USE_STD_FILESYSTEM // !VCPKG_USE_STD_FILESYSTEM vvv + if (rhs.is_absolute()) + { + return rhs; + } + else + { + return lhs / rhs; + } +#endif + } } diff --git a/toolsrc/src/vcpkg/binarycaching.cpp b/toolsrc/src/vcpkg/binarycaching.cpp index 5bebc4fb8..532e07032 100644 --- a/toolsrc/src/vcpkg/binarycaching.cpp +++ b/toolsrc/src/vcpkg/binarycaching.cpp @@ -285,7 +285,7 @@ namespace for (auto&& action : plan.install_actions)
{
auto& spec = action.spec;
- fs.remove_all_inside(paths.package_dir(spec), VCPKG_LINE_INFO);
+ fs.remove_all(paths.package_dir(spec), VCPKG_LINE_INFO);
nuget_refs.emplace_back(spec, NugetReference(action));
}
@@ -615,42 +615,57 @@ XmlSerializer& XmlSerializer::emit_declaration() }
XmlSerializer& XmlSerializer::open_tag(StringLiteral sl)
{
+ emit_pending_indent();
Strings::append(buf, '<', sl, '>');
- indent += 2;
+ m_indent += 2;
return *this;
}
XmlSerializer& XmlSerializer::start_complex_open_tag(StringLiteral sl)
{
+ emit_pending_indent();
Strings::append(buf, '<', sl);
- indent += 2;
+ m_indent += 2;
return *this;
}
XmlSerializer& XmlSerializer::text_attr(StringLiteral name, StringView content)
{
- Strings::append(buf, ' ', name, "=\"");
+ if (m_pending_indent)
+ {
+ m_pending_indent = false;
+ buf.append(m_indent, ' ');
+ }
+ else
+ {
+ buf.push_back(' ');
+ }
+ Strings::append(buf, name, "=\"");
text(content);
Strings::append(buf, '"');
return *this;
}
XmlSerializer& XmlSerializer::finish_complex_open_tag()
{
+ emit_pending_indent();
Strings::append(buf, '>');
return *this;
}
XmlSerializer& XmlSerializer::finish_self_closing_complex_tag()
{
+ emit_pending_indent();
Strings::append(buf, "/>");
- indent -= 2;
+ m_indent -= 2;
return *this;
}
XmlSerializer& XmlSerializer::close_tag(StringLiteral sl)
{
+ m_indent -= 2;
+ emit_pending_indent();
Strings::append(buf, "</", sl, '>');
- indent -= 2;
return *this;
}
XmlSerializer& XmlSerializer::text(StringView sv)
{
+ emit_pending_indent();
for (auto ch : sv)
{
if (ch == '&')
@@ -682,12 +697,21 @@ XmlSerializer& XmlSerializer::text(StringView sv) }
XmlSerializer& XmlSerializer::simple_tag(StringLiteral tag, StringView content)
{
- return open_tag(tag).text(content).close_tag(tag);
+ return emit_pending_indent().open_tag(tag).text(content).close_tag(tag);
}
XmlSerializer& XmlSerializer::line_break()
{
buf.push_back('\n');
- buf.append(indent, ' ');
+ m_pending_indent = true;
+ return *this;
+}
+XmlSerializer& XmlSerializer::emit_pending_indent()
+{
+ if (m_pending_indent)
+ {
+ m_pending_indent = false;
+ buf.append(m_indent, ' ');
+ }
return *this;
}
@@ -1118,3 +1142,22 @@ void vcpkg::help_topic_binary_caching(const VcpkgPaths&) System::print2(tbl.m_str);
}
+
+std::string vcpkg::generate_nuget_packages_config(const Dependencies::ActionPlan& action)
+{
+ auto refs = Util::fmap(action.install_actions,
+ [&](const Dependencies::InstallPlanAction& ipa) { return NugetReference(ipa); });
+ XmlSerializer xml;
+ xml.emit_declaration().line_break();
+ xml.open_tag("packages").line_break();
+ for (auto&& ref : refs)
+ {
+ xml.start_complex_open_tag("package")
+ .text_attr("id", ref.id)
+ .text_attr("version", ref.version)
+ .finish_self_closing_complex_tag()
+ .line_break();
+ }
+ xml.close_tag("packages").line_break();
+ return std::move(xml.buf);
+}
diff --git a/toolsrc/src/vcpkg/build.cpp b/toolsrc/src/vcpkg/build.cpp index 5e2f8778b..7d2976165 100644 --- a/toolsrc/src/vcpkg/build.cpp +++ b/toolsrc/src/vcpkg/build.cpp @@ -484,8 +484,9 @@ namespace vcpkg::Build env);
out_file.close();
- Checks::check_exit(
- VCPKG_LINE_INFO, !compiler_hash.empty(), "Error occured while detecting compiler information");
+ Checks::check_exit(VCPKG_LINE_INFO,
+ !compiler_hash.empty(),
+ "Error occured while detecting compiler information. Pass `--debug` for more information.");
Debug::print("Detecting compiler hash for triplet ", triplet, ": ", compiler_hash, "\n");
return compiler_hash;
@@ -866,6 +867,8 @@ namespace vcpkg::Build for (auto it = action_plan.install_actions.begin(); it != action_plan.install_actions.end(); ++it)
{
auto& action = *it;
+ if (action.abi_info.has_value()) continue;
+
std::vector<AbiEntry> dependency_abis;
if (!Util::Enum::to_bool(action.build_options.only_downloads))
{
diff --git a/toolsrc/src/vcpkg/commands.setinstalled.cpp b/toolsrc/src/vcpkg/commands.setinstalled.cpp index f52e4942b..df191ee3e 100644 --- a/toolsrc/src/vcpkg/commands.setinstalled.cpp +++ b/toolsrc/src/vcpkg/commands.setinstalled.cpp @@ -14,16 +14,22 @@ namespace vcpkg::Commands::SetInstalled { static constexpr StringLiteral OPTION_DRY_RUN = "--dry-run"; + static constexpr StringLiteral OPTION_WRITE_PACKAGES_CONFIG = "--x-write-nuget-packages-config"; static constexpr CommandSwitch INSTALL_SWITCHES[] = { {OPTION_DRY_RUN, "Do not actually build or install"}, }; + static constexpr CommandSetting INSTALL_SETTINGS[] = { + {OPTION_WRITE_PACKAGES_CONFIG, + "Writes out a NuGet packages.config-formatted file for use with external binary caching.\n" + "See `vcpkg help binarycaching` for more information."}, + }; const CommandStructure COMMAND_STRUCTURE = { create_example_string(R"(x-set-installed <package>...)"), 0, SIZE_MAX, - {INSTALL_SWITCHES}, + {INSTALL_SWITCHES, INSTALL_SETTINGS}, nullptr, }; @@ -34,7 +40,8 @@ namespace vcpkg::Commands::SetInstalled const CMakeVars::CMakeVarProvider& cmake_vars, const std::vector<FullPackageSpec>& specs, const Build::BuildPackageOptions& install_plan_options, - DryRun dry_run) + DryRun dry_run, + const Optional<fs::path>& maybe_pkgsconfig) { // We have a set of user-requested specs. // We need to know all the specs which are required to fulfill dependencies for those specs. @@ -91,6 +98,16 @@ namespace vcpkg::Commands::SetInstalled Dependencies::print_plan(action_plan, true, paths.ports); + if (auto p_pkgsconfig = maybe_pkgsconfig.get()) + { + Build::compute_all_abis(paths, action_plan, cmake_vars, status_db); + auto& fs = paths.get_filesystem(); + auto pkgsconfig_path = Files::combine(paths.original_cwd, *p_pkgsconfig); + auto pkgsconfig_contents = generate_nuget_packages_config(action_plan); + fs.write_contents(pkgsconfig_path, pkgsconfig_contents, VCPKG_LINE_INFO); + System::print2("Wrote NuGet packages config information to ", pkgsconfig_path.u8string(), "\n"); + } + if (dry_run == DryRun::Yes) { Checks::exit_success(VCPKG_LINE_INFO); @@ -142,6 +159,12 @@ namespace vcpkg::Commands::SetInstalled PortFileProvider::PathsPortFileProvider provider(paths, args.overlay_ports); auto cmake_vars = CMakeVars::make_triplet_cmake_var_provider(paths); + Optional<fs::path> pkgsconfig; + auto it_pkgsconfig = options.settings.find(OPTION_WRITE_PACKAGES_CONFIG); + if (it_pkgsconfig != options.settings.end()) + { + pkgsconfig = it_pkgsconfig->second; + } perform_and_exit_ex(args, paths, provider, @@ -149,6 +172,7 @@ namespace vcpkg::Commands::SetInstalled *cmake_vars, specs, install_plan_options, - dry_run ? DryRun::Yes : DryRun::No); + dry_run ? DryRun::Yes : DryRun::No, + pkgsconfig); } } diff --git a/toolsrc/src/vcpkg/install.cpp b/toolsrc/src/vcpkg/install.cpp index 5750469ad..aa79bb1f2 100644 --- a/toolsrc/src/vcpkg/install.cpp +++ b/toolsrc/src/vcpkg/install.cpp @@ -500,6 +500,7 @@ namespace vcpkg::Install static constexpr StringLiteral OPTION_XUNIT = "--x-xunit"; static constexpr StringLiteral OPTION_USE_ARIA2 = "--x-use-aria2"; static constexpr StringLiteral OPTION_CLEAN_AFTER_BUILD = "--clean-after-build"; + static constexpr StringLiteral OPTION_WRITE_PACKAGES_CONFIG = "--x-write-nuget-packages-config"; static constexpr std::array<CommandSwitch, 8> INSTALL_SWITCHES = {{ {OPTION_DRY_RUN, "Do not actually build or install"}, @@ -511,8 +512,11 @@ namespace vcpkg::Install {OPTION_USE_ARIA2, "Use aria2 to perform download tasks"}, {OPTION_CLEAN_AFTER_BUILD, "Clean buildtrees, packages and downloads after building each package"}, }}; - static constexpr std::array<CommandSetting, 1> INSTALL_SETTINGS = {{ + static constexpr std::array<CommandSetting, 2> INSTALL_SETTINGS = {{ {OPTION_XUNIT, "File to output results in XUnit format (Internal use)"}, + {OPTION_WRITE_PACKAGES_CONFIG, + "Writes out a NuGet packages.config-formatted file for use with external binary caching.\nSee `vcpkg help " + "binarycaching` for more information."}, }}; std::vector<std::string> get_all_port_names(const VcpkgPaths& paths) @@ -654,7 +658,8 @@ namespace vcpkg::Install void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, Triplet default_triplet) { // input sanitization - const ParsedArguments options = args.parse_arguments(paths.manifest_mode_enabled() ? MANIFEST_COMMAND_STRUCTURE : COMMAND_STRUCTURE); + const ParsedArguments options = + args.parse_arguments(paths.manifest_mode_enabled() ? MANIFEST_COMMAND_STRUCTURE : COMMAND_STRUCTURE); auto binaryprovider = create_binary_provider_from_configs(paths, args.binary_sources).value_or_exit(VCPKG_LINE_INFO); @@ -697,8 +702,10 @@ namespace vcpkg::Install if (ec) { - Checks::exit_with_message(VCPKG_LINE_INFO, "Failed to load manifest file (%s): %s\n", - path_to_manifest.u8string(), ec.message()); + Checks::exit_with_message(VCPKG_LINE_INFO, + "Failed to load manifest file (%s): %s\n", + path_to_manifest.u8string(), + ec.message()); } std::vector<FullPackageSpec> specs; @@ -716,7 +723,21 @@ namespace vcpkg::Install Checks::exit_fail(VCPKG_LINE_INFO); } - Commands::SetInstalled::perform_and_exit_ex(args, paths, provider, *binaryprovider, var_provider, specs, install_plan_options, dry_run ? Commands::DryRun::Yes : Commands::DryRun::No); + Optional<fs::path> pkgsconfig; + auto it_pkgsconfig = options.settings.find(OPTION_WRITE_PACKAGES_CONFIG); + if (it_pkgsconfig != options.settings.end()) + { + pkgsconfig = fs::u8path(it_pkgsconfig->second); + } + Commands::SetInstalled::perform_and_exit_ex(args, + paths, + provider, + *binaryprovider, + var_provider, + specs, + install_plan_options, + dry_run ? Commands::DryRun::Yes : Commands::DryRun::No, + pkgsconfig); } const std::vector<FullPackageSpec> specs = Util::fmap(args.command_arguments, [&](auto&& arg) { @@ -799,6 +820,17 @@ namespace vcpkg::Install Dependencies::print_plan(action_plan, is_recursive, paths.ports); + auto it_pkgsconfig = options.settings.find(OPTION_WRITE_PACKAGES_CONFIG); + if (it_pkgsconfig != options.settings.end()) + { + Build::compute_all_abis(paths, action_plan, var_provider, status_db); + + auto pkgsconfig_path = Files::combine(paths.original_cwd, fs::u8path(it_pkgsconfig->second)); + auto pkgsconfig_contents = generate_nuget_packages_config(action_plan); + fs.write_contents(pkgsconfig_path, pkgsconfig_contents, VCPKG_LINE_INFO); + System::print2("Wrote NuGet packages config information to ", pkgsconfig_path.u8string(), "\n"); + } + if (dry_run) { Checks::exit_success(VCPKG_LINE_INFO); |
