From 91da4aab4c74af1d30c68896a058100257910e8d Mon Sep 17 00:00:00 2001 From: martin-s Date: Tue, 2 Jul 2019 05:51:07 +0000 Subject: Allow redirection of the scripts folder. (#6552) * Allow redirection of the scripts folder with an environment variable. * - Updated feature from environment variable to argument. * Fix crash when no scripts override is given and use --scripts-root= format * Update help messages to use --scripts-root= format --- toolsrc/src/tests.arguments.cpp | 6 ++-- toolsrc/src/vcpkg.cpp | 10 +++++++ toolsrc/src/vcpkg/help.cpp | 2 ++ toolsrc/src/vcpkg/vcpkgcmdarguments.cpp | 30 +++++++++++++++++-- toolsrc/src/vcpkg/vcpkgpaths.cpp | 53 ++++++++++++++++++++++----------- 5 files changed, 80 insertions(+), 21 deletions(-) (limited to 'toolsrc/src') diff --git a/toolsrc/src/tests.arguments.cpp b/toolsrc/src/tests.arguments.cpp index 51ababd3d..533b3a0d0 100644 --- a/toolsrc/src/tests.arguments.cpp +++ b/toolsrc/src/tests.arguments.cpp @@ -15,9 +15,10 @@ namespace UnitTest1 { TEST_METHOD(create_from_arg_sequence_options_lower) { - std::vector t = {"--vcpkg-root", "C:\\vcpkg", "--debug", "--sendmetrics", "--printmetrics"}; + std::vector t = {"--vcpkg-root", "C:\\vcpkg", "--scripts-root", "C:\\scripts", "--debug", "--sendmetrics", "--printmetrics"}; auto v = VcpkgCmdArguments::create_from_arg_sequence(t.data(), t.data() + t.size()); Assert::AreEqual("C:\\vcpkg", v.vcpkg_root_dir.get()->c_str()); + Assert::AreEqual("C:\\scripts", v.scripts_root_dir.get()->c_str()); Assert::IsTrue(v.debug && *v.debug.get()); Assert::IsTrue(v.sendmetrics && v.sendmetrics.get()); Assert::IsTrue(v.printmetrics && *v.printmetrics.get()); @@ -25,9 +26,10 @@ namespace UnitTest1 TEST_METHOD(create_from_arg_sequence_options_upper) { - std::vector t = {"--VCPKG-ROOT", "C:\\vcpkg", "--DEBUG", "--SENDMETRICS", "--PRINTMETRICS"}; + std::vector t = {"--VCPKG-ROOT", "C:\\vcpkg", "--SCRIPTS-ROOT", "C:\\scripts", "--DEBUG", "--SENDMETRICS", "--PRINTMETRICS"}; auto v = VcpkgCmdArguments::create_from_arg_sequence(t.data(), t.data() + t.size()); Assert::AreEqual("C:\\vcpkg", v.vcpkg_root_dir.get()->c_str()); + Assert::AreEqual("C:\\scripts", v.scripts_root_dir.get()->c_str()); Assert::IsTrue(v.debug && *v.debug.get()); Assert::IsTrue(v.sendmetrics && v.sendmetrics.get()); Assert::IsTrue(v.printmetrics && *v.printmetrics.get()); diff --git a/toolsrc/src/vcpkg.cpp b/toolsrc/src/vcpkg.cpp index 5da97b136..363b39814 100644 --- a/toolsrc/src/vcpkg.cpp +++ b/toolsrc/src/vcpkg.cpp @@ -116,9 +116,19 @@ static void inner(const VcpkgCmdArguments& args) Debug::print("Using vcpkg-root: ", vcpkg_root_dir.u8string(), '\n'); + Optional vcpkg_scripts_root_dir = nullopt; + if (nullptr != args.scripts_root_dir) + { + vcpkg_scripts_root_dir = fs::stdfs::canonical(fs::u8path(*args.scripts_root_dir)); + Debug::print("Using scripts-root: ", vcpkg_scripts_root_dir.value_or_exit(VCPKG_LINE_INFO).u8string(), '\n'); + } + auto default_vs_path = System::get_environment_variable("VCPKG_VISUAL_STUDIO_PATH").value_or(""); + + const Expected expected_paths = VcpkgPaths::create(vcpkg_root_dir, + vcpkg_scripts_root_dir, default_vs_path, args.overlay_triplets.get()); Checks::check_exit(VCPKG_LINE_INFO, diff --git a/toolsrc/src/vcpkg/help.cpp b/toolsrc/src/vcpkg/help.cpp index 896f62661..9b2751739 100644 --- a/toolsrc/src/vcpkg/help.cpp +++ b/toolsrc/src/vcpkg/help.cpp @@ -124,6 +124,8 @@ namespace vcpkg::Help " (default: " ENVVAR(VCPKG_ROOT) // ")\n" "\n" + " --scripts-root= Specify the scripts root directory\n" + "\n" " @response_file Specify a " "response file to provide additional parameters\n" "\n" diff --git a/toolsrc/src/vcpkg/vcpkgcmdarguments.cpp b/toolsrc/src/vcpkg/vcpkgcmdarguments.cpp index 3c1452d47..7a28fb571 100644 --- a/toolsrc/src/vcpkg/vcpkgcmdarguments.cpp +++ b/toolsrc/src/vcpkg/vcpkgcmdarguments.cpp @@ -33,6 +33,21 @@ namespace vcpkg option_field = std::make_unique(*arg_begin); } + static void parse_cojoined_value(std::string new_value, + const std::string& option_name, + std::unique_ptr& option_field) + { + if (nullptr != option_field) + { + System::printf(System::Color::error, "Error: %s specified multiple times\n", option_name); + Metrics::g_metrics.lock()->track_property("error", "error option specified multiple times"); + Help::print_usage(); + Checks::exit_fail(VCPKG_LINE_INFO); + } + + option_field = std::make_unique(std::move(new_value)); + } + static void parse_switch(bool new_setting, const std::string& option_name, Optional& option_field) { if (option_field && option_field != new_setting) @@ -120,9 +135,10 @@ namespace vcpkg if (arg[0] == '-' && arg[1] == '-') { - // make argument case insensitive + // make argument case insensitive before the first = auto& f = std::use_facet>(std::locale()); - f.tolower(&arg[0], &arg[0] + arg.size()); + auto first_eq = std::find(std::begin(arg), std::end(arg), '='); + f.tolower(&arg[0], &arg[0] + (first_eq - std::begin(arg))); // command switch if (arg == "--vcpkg-root") { @@ -130,6 +146,13 @@ namespace vcpkg parse_value(arg_begin, arg_end, "--vcpkg-root", args.vcpkg_root_dir); continue; } + if (Strings::starts_with(arg, "--scripts-root=")) + { + parse_cojoined_value(arg.substr(sizeof("--scripts-root=") - 1), + "--scripts-root", + args.scripts_root_dir); + continue; + } if (arg == "--triplet") { ++arg_begin; @@ -411,5 +434,8 @@ namespace vcpkg System::printf(" %-40s %s\n", "--vcpkg-root ", "Specify the vcpkg directory to use instead of current directory or tool directory"); + System::printf(" %-40s %s\n", + "--scripts-root=", + "Specify the scripts directory to use instead of default vcpkg scripts directory"); } } diff --git a/toolsrc/src/vcpkg/vcpkgpaths.cpp b/toolsrc/src/vcpkg/vcpkgpaths.cpp index 909fbeb44..d16acf2e8 100644 --- a/toolsrc/src/vcpkg/vcpkgpaths.cpp +++ b/toolsrc/src/vcpkg/vcpkgpaths.cpp @@ -13,7 +13,8 @@ namespace vcpkg { - Expected VcpkgPaths::create(const fs::path& vcpkg_root_dir, + Expected VcpkgPaths::create(const fs::path& vcpkg_root_dir, + const Optional& vcpkg_scripts_root_dir, const std::string& default_vs_path, const std::vector* triplets_dirs) { @@ -65,7 +66,25 @@ namespace vcpkg paths.ports = paths.root / "ports"; paths.installed = paths.root / "installed"; paths.triplets = paths.root / "triplets"; - paths.scripts = paths.root / "scripts"; + + if (auto scripts_dir = vcpkg_scripts_root_dir.get()) + { + if (scripts_dir->empty() || !fs::stdfs::is_directory(*scripts_dir)) + { + Metrics::g_metrics.lock()->track_property("error", "Invalid scripts override directory."); + Checks::exit_with_message( + VCPKG_LINE_INFO, + "Invalid scripts override directory: %s; " + "create that directory or unset --scripts-root to use the default scripts location.", + scripts_dir->u8string()); + } + + paths.scripts = *scripts_dir; + } + else + { + paths.scripts = paths.root / "scripts"; + } paths.tools = paths.downloads / "tools"; paths.buildsystems = paths.scripts / "buildsystems"; @@ -132,21 +151,21 @@ namespace vcpkg } const fs::path VcpkgPaths::get_triplet_file_path(const Triplet& triplet) const - { - return m_triplets_cache.get_lazy(triplet, [&]()-> auto { - for (auto&& triplet_dir : triplets_dirs) - { - auto&& path = triplet_dir / (triplet.canonical_name() + ".cmake"); - if (this->get_filesystem().exists(path)) - { - return path; - } - } - - Checks::exit_with_message(VCPKG_LINE_INFO, - "Error: Triplet file %s.cmake not found", - triplet.canonical_name()); - }); + { + return m_triplets_cache.get_lazy(triplet, [&]()-> auto { + for (auto&& triplet_dir : triplets_dirs) + { + auto&& path = triplet_dir / (triplet.canonical_name() + ".cmake"); + if (this->get_filesystem().exists(path)) + { + return path; + } + } + + Checks::exit_with_message(VCPKG_LINE_INFO, + "Error: Triplet file %s.cmake not found", + triplet.canonical_name()); + }); } -- cgit v1.2.3