aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornicole mazzuca <mazzucan@outlook.com>2020-04-17 15:49:59 -0700
committerGitHub <noreply@github.com>2020-04-17 15:49:59 -0700
commit556325a1f7b6049d91565257c00db2f0bf1eadc5 (patch)
tree82485596a6285844862b431e6930c306b33cd484
parent71377f69e255414ccf3569a8a772fc89ee9f89ff (diff)
downloadvcpkg-556325a1f7b6049d91565257c00db2f0bf1eadc5.tar.gz
vcpkg-556325a1f7b6049d91565257c00db2f0bf1eadc5.zip
[vcpkg] Add x-set-installed command (#10817)
This command takes a list of ports, and causes the final state of the installed directory to be as-if one ran the install on an empty installed directory (removing any unnecessary packages). This is especially useful with the new `--x-install-root` option, which allows one to set the `installed` directory for vcpkg to use. Additionally, as a drive-by, we do some `stdfs` clean-up and add a `.is_feature()` member function to BinaryParagraph (as opposed to checking for `.feature().empty()`, which is far less clear to read). This feature is experimental.
-rw-r--r--toolsrc/include/vcpkg/base/files.h5
-rw-r--r--toolsrc/include/vcpkg/binaryparagraph.h2
-rw-r--r--toolsrc/include/vcpkg/commands.h6
-rw-r--r--toolsrc/include/vcpkg/statusparagraphs.h2
-rw-r--r--toolsrc/include/vcpkg/vcpkgcmdarguments.h1
-rw-r--r--toolsrc/include/vcpkg/vcpkgpaths.h1
-rw-r--r--toolsrc/src/vcpkg.cpp28
-rw-r--r--toolsrc/src/vcpkg/base/files.cpp41
-rw-r--r--toolsrc/src/vcpkg/binarycaching.cpp2
-rw-r--r--toolsrc/src/vcpkg/binaryparagraph.cpp6
-rw-r--r--toolsrc/src/vcpkg/build.cpp2
-rw-r--r--toolsrc/src/vcpkg/commands.cpp1
-rw-r--r--toolsrc/src/vcpkg/commands.setinstalled.cpp111
-rw-r--r--toolsrc/src/vcpkg/dependencies.cpp2
-rw-r--r--toolsrc/src/vcpkg/portfileprovider.cpp2
-rw-r--r--toolsrc/src/vcpkg/remove.cpp3
-rw-r--r--toolsrc/src/vcpkg/statusparagraphs.cpp15
-rw-r--r--toolsrc/src/vcpkg/vcpkgcmdarguments.cpp6
-rw-r--r--toolsrc/src/vcpkg/vcpkglib.cpp4
-rw-r--r--toolsrc/src/vcpkg/vcpkgpaths.cpp17
-rw-r--r--toolsrc/vcpkglib/vcpkglib.vcxproj1
-rw-r--r--toolsrc/vcpkglib/vcpkglib.vcxproj.filters5
22 files changed, 227 insertions, 36 deletions
diff --git a/toolsrc/include/vcpkg/base/files.h b/toolsrc/include/vcpkg/base/files.h
index 0bad428c0..8f278cd20 100644
--- a/toolsrc/include/vcpkg/base/files.h
+++ b/toolsrc/include/vcpkg/base/files.h
@@ -22,6 +22,7 @@ namespace fs
using stdfs::path;
using stdfs::perms;
using stdfs::u8path;
+ using stdfs::directory_iterator;
#if defined(_WIN32)
enum class file_type
@@ -155,9 +156,13 @@ namespace vcpkg::Files
fs::file_status status(const fs::path& p, ignore_errors_t) const noexcept;
fs::file_status symlink_status(LineInfo li, const fs::path& p) const noexcept;
fs::file_status symlink_status(const fs::path& p, ignore_errors_t) const noexcept;
+ virtual fs::path absolute(const fs::path& path, std::error_code& ec) const = 0;
+ fs::path absolute(LineInfo li, const fs::path& path) const;
virtual fs::path canonical(const fs::path& path, std::error_code& ec) const = 0;
fs::path canonical(LineInfo li, const fs::path& path) const;
fs::path canonical(const fs::path& path, ignore_errors_t) const;
+ virtual fs::path current_path(std::error_code&) const = 0;
+ fs::path current_path(LineInfo li) const;
virtual std::vector<fs::path> find_from_PATH(const std::string& name) const = 0;
};
diff --git a/toolsrc/include/vcpkg/binaryparagraph.h b/toolsrc/include/vcpkg/binaryparagraph.h
index edb2b6a13..d556a40c8 100644
--- a/toolsrc/include/vcpkg/binaryparagraph.h
+++ b/toolsrc/include/vcpkg/binaryparagraph.h
@@ -28,6 +28,8 @@ namespace vcpkg
std::string dir() const;
+ bool is_feature() const { return !feature.empty(); }
+
PackageSpec spec;
std::string version;
std::string description;
diff --git a/toolsrc/include/vcpkg/commands.h b/toolsrc/include/vcpkg/commands.h
index 9d2d0b6c6..3ce182410 100644
--- a/toolsrc/include/vcpkg/commands.h
+++ b/toolsrc/include/vcpkg/commands.h
@@ -139,6 +139,12 @@ namespace vcpkg::Commands
void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths);
}
+ namespace SetInstalled
+ {
+ extern const CommandStructure COMMAND_STRUCTURE;
+ void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, Triplet default_triplet);
+ }
+
template<class T>
struct PackageNameAndFunction
{
diff --git a/toolsrc/include/vcpkg/statusparagraphs.h b/toolsrc/include/vcpkg/statusparagraphs.h
index 7fcf0e916..1fda81316 100644
--- a/toolsrc/include/vcpkg/statusparagraphs.h
+++ b/toolsrc/include/vcpkg/statusparagraphs.h
@@ -40,7 +40,7 @@ namespace vcpkg
std::vector<std::unique_ptr<StatusParagraph>*> find_all(const std::string& name, Triplet triplet);
- Optional<InstalledPackageView> find_all_installed(const PackageSpec& spec) const;
+ Optional<InstalledPackageView> get_installed_package_view(const PackageSpec& spec) const;
/// <summary>Find the StatusParagraph for given spec if installed</summary>
/// <param name="spec">Package specification to find the status for</param>
diff --git a/toolsrc/include/vcpkg/vcpkgcmdarguments.h b/toolsrc/include/vcpkg/vcpkgcmdarguments.h
index fe7911ae3..e5b26c25a 100644
--- a/toolsrc/include/vcpkg/vcpkgcmdarguments.h
+++ b/toolsrc/include/vcpkg/vcpkgcmdarguments.h
@@ -86,6 +86,7 @@ namespace vcpkg
static VcpkgCmdArguments create_from_arg_sequence(const std::string* arg_begin, const std::string* arg_end);
std::unique_ptr<std::string> vcpkg_root_dir;
+ std::unique_ptr<std::string> install_root_dir;
std::unique_ptr<std::string> scripts_root_dir;
std::unique_ptr<std::string> triplet;
std::unique_ptr<std::vector<std::string>> overlay_ports;
diff --git a/toolsrc/include/vcpkg/vcpkgpaths.h b/toolsrc/include/vcpkg/vcpkgpaths.h
index 31d8374f1..c95515aee 100644
--- a/toolsrc/include/vcpkg/vcpkgpaths.h
+++ b/toolsrc/include/vcpkg/vcpkgpaths.h
@@ -58,6 +58,7 @@ namespace vcpkg
};
static Expected<VcpkgPaths> create(const fs::path& vcpkg_root_dir,
+ const Optional<fs::path>& install_root_dir,
const Optional<fs::path>& vcpkg_scripts_root_dir,
const std::string& default_vs_path,
const std::vector<std::string>* triplets_dirs);
diff --git a/toolsrc/src/vcpkg.cpp b/toolsrc/src/vcpkg.cpp
index c2ee42200..4e6109c38 100644
--- a/toolsrc/src/vcpkg.cpp
+++ b/toolsrc/src/vcpkg.cpp
@@ -62,6 +62,8 @@ static void invalid_command(const std::string& cmd)
static void inner(const VcpkgCmdArguments& args)
{
+ auto& fs = Files::get_real_filesystem();
+
Metrics::g_metrics.lock()->track_property("command", args.command);
if (args.command.empty())
{
@@ -88,26 +90,26 @@ static void inner(const VcpkgCmdArguments& args)
}
fs::path vcpkg_root_dir;
- if (args.vcpkg_root_dir != nullptr)
+ if (args.vcpkg_root_dir)
{
- vcpkg_root_dir = fs::stdfs::absolute(fs::u8path(*args.vcpkg_root_dir));
+ vcpkg_root_dir = fs.absolute(VCPKG_LINE_INFO, fs::u8path(*args.vcpkg_root_dir));
}
else
{
const auto vcpkg_root_dir_env = System::get_environment_variable("VCPKG_ROOT");
if (const auto v = vcpkg_root_dir_env.get())
{
- vcpkg_root_dir = fs::stdfs::absolute(*v);
+ vcpkg_root_dir = fs.absolute(VCPKG_LINE_INFO, *v);
}
else
{
- const fs::path current_path = fs::stdfs::current_path();
- vcpkg_root_dir = Files::get_real_filesystem().find_file_recursively_up(current_path, ".vcpkg-root");
+ const fs::path current_path = fs.current_path(VCPKG_LINE_INFO);
+ vcpkg_root_dir = fs.find_file_recursively_up(current_path, ".vcpkg-root");
if (vcpkg_root_dir.empty())
{
- vcpkg_root_dir = Files::get_real_filesystem().find_file_recursively_up(
- fs::stdfs::absolute(System::get_exe_path_of_current_process()), ".vcpkg-root");
+ vcpkg_root_dir = fs.find_file_recursively_up(
+ fs.absolute(VCPKG_LINE_INFO, System::get_exe_path_of_current_process()), ".vcpkg-root");
}
}
}
@@ -116,17 +118,23 @@ static void inner(const VcpkgCmdArguments& args)
Debug::print("Using vcpkg-root: ", vcpkg_root_dir.u8string(), '\n');
+ Optional<fs::path> install_root_dir;
+ if (args.install_root_dir) {
+ install_root_dir = Files::get_real_filesystem().canonical(VCPKG_LINE_INFO, fs::u8path(*args.install_root_dir));
+ Debug::print("Using install-root: ", install_root_dir.value_or_exit(VCPKG_LINE_INFO).u8string(), '\n');
+ }
+
Optional<fs::path> vcpkg_scripts_root_dir = nullopt;
- if (nullptr != args.scripts_root_dir)
+ if (args.scripts_root_dir)
{
- vcpkg_scripts_root_dir = fs::stdfs::canonical(fs::u8path(*args.scripts_root_dir));
+ vcpkg_scripts_root_dir = Files::get_real_filesystem().canonical(VCPKG_LINE_INFO, 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<VcpkgPaths> expected_paths =
- VcpkgPaths::create(vcpkg_root_dir, vcpkg_scripts_root_dir, default_vs_path, args.overlay_triplets.get());
+ VcpkgPaths::create(vcpkg_root_dir, install_root_dir, vcpkg_scripts_root_dir, default_vs_path, args.overlay_triplets.get());
Checks::check_exit(VCPKG_LINE_INFO,
!expected_paths.error(),
"Error: Invalid vcpkg root directory %s: %s",
diff --git a/toolsrc/src/vcpkg/base/files.cpp b/toolsrc/src/vcpkg/base/files.cpp
index 0bd1cb893..71cc7275a 100644
--- a/toolsrc/src/vcpkg/base/files.cpp
+++ b/toolsrc/src/vcpkg/base/files.cpp
@@ -272,6 +272,14 @@ namespace vcpkg::Files
this->remove_all(path, ec, failure_point);
}
+ fs::path Filesystem::absolute(LineInfo li, const fs::path& path) const
+ {
+ std::error_code ec;
+ const auto result = this->absolute(path, ec);
+ if (ec) Checks::exit_with_message(li, "Error getting absolute path of %s: %s", path.string(), ec.message());
+ return result;
+ }
+
fs::path Filesystem::canonical(LineInfo li, const fs::path& path) const
{
std::error_code ec;
@@ -286,6 +294,14 @@ namespace vcpkg::Files
std::error_code ec;
return this->canonical(path, ec);
}
+ fs::path Filesystem::current_path(LineInfo li) const
+ {
+ std::error_code ec;
+ const auto result = this->current_path(ec);
+
+ if (ec) Checks::exit_with_message(li, "Error getting current path: %s", ec.message());
+ return result;
+ }
struct RealFilesystem final : Filesystem
{
@@ -699,11 +715,36 @@ namespace vcpkg::Files
}
}
+ virtual fs::path absolute(const fs::path& path, std::error_code& ec) const override
+ {
+#if USE_STD_FILESYSTEM
+ return fs::stdfs::absolute(path, ec);
+#else // ^^^ USE_STD_FILESYSTEM / !USE_STD_FILESYSTEM vvv
+#if _WIN32
+ // absolute was called system_complete in experimental filesystem
+ return fs::stdfs::system_complete(path, ec);
+#else // ^^^ _WIN32 / !_WIN32 vvv
+ if (path.is_absolute()) {
+ auto current_path = this->current_path(ec);
+ if (ec) return fs::path();
+ return std::move(current_path) / path;
+ } else {
+ return path;
+ }
+#endif
+#endif
+ }
+
virtual fs::path canonical(const fs::path& path, std::error_code& ec) const override
{
return fs::stdfs::canonical(path, ec);
}
+ virtual fs::path current_path(std::error_code& ec) const override
+ {
+ return fs::stdfs::current_path(ec);
+ }
+
virtual std::vector<fs::path> find_from_PATH(const std::string& name) const override
{
#if defined(_WIN32)
diff --git a/toolsrc/src/vcpkg/binarycaching.cpp b/toolsrc/src/vcpkg/binarycaching.cpp
index 0750366ff..c8e77d938 100644
--- a/toolsrc/src/vcpkg/binarycaching.cpp
+++ b/toolsrc/src/vcpkg/binarycaching.cpp
@@ -171,7 +171,7 @@ namespace
{
fs.copy_file(log_file.path(),
tmp_log_path_destination / log_file.path().filename(),
- fs::stdfs::copy_options::none,
+ fs::copy_options::none,
ec);
}
}
diff --git a/toolsrc/src/vcpkg/binaryparagraph.cpp b/toolsrc/src/vcpkg/binaryparagraph.cpp
index f142c307d..45638e1f5 100644
--- a/toolsrc/src/vcpkg/binaryparagraph.cpp
+++ b/toolsrc/src/vcpkg/binaryparagraph.cpp
@@ -62,7 +62,7 @@ namespace vcpkg
// for compatibility with previous vcpkg versions, we discard all irrelevant information
return dep.name;
});
- if (this->feature.empty())
+ if (!this->is_feature())
{
this->default_features = parse_default_features_list(parser.optional_field(Fields::DEFAULTFEATURES))
.value_or_exit(VCPKG_LINE_INFO);
@@ -109,7 +109,7 @@ namespace vcpkg
std::string BinaryParagraph::displayname() const
{
- if (this->feature.empty() || this->feature == "core")
+ if (!this->is_feature() || this->feature == "core")
return Strings::format("%s:%s", this->spec.name(), this->spec.triplet());
return Strings::format("%s[%s]:%s", this->spec.name(), this->feature, this->spec.triplet());
}
@@ -126,7 +126,7 @@ namespace vcpkg
out_str.append("Package: ").append(pgh.spec.name()).push_back('\n');
if (!pgh.version.empty())
out_str.append("Version: ").append(pgh.version).push_back('\n');
- else if (!pgh.feature.empty())
+ else if (pgh.is_feature())
out_str.append("Feature: ").append(pgh.feature).push_back('\n');
if (!pgh.depends.empty())
{
diff --git a/toolsrc/src/vcpkg/build.cpp b/toolsrc/src/vcpkg/build.cpp
index fe17c490a..b3168075d 100644
--- a/toolsrc/src/vcpkg/build.cpp
+++ b/toolsrc/src/vcpkg/build.cpp
@@ -890,7 +890,7 @@ namespace vcpkg::Build
ExtendedBuildResult result = do_build_package_and_clean_buildtrees(paths, action);
fs.create_directories(abi_package_dir, ec);
- fs.copy_file(abi_file, abi_file_in_package, fs::stdfs::copy_options::none, ec);
+ fs.copy_file(abi_file, abi_file_in_package, fs::copy_options::none, ec);
Checks::check_exit(VCPKG_LINE_INFO, !ec, "Could not copy into file: %s", abi_file_in_package.u8string());
if (binary_caching_enabled && result.code == BuildResult::SUCCEEDED)
diff --git a/toolsrc/src/vcpkg/commands.cpp b/toolsrc/src/vcpkg/commands.cpp
index 1f424a559..0db6ddb8f 100644
--- a/toolsrc/src/vcpkg/commands.cpp
+++ b/toolsrc/src/vcpkg/commands.cpp
@@ -17,6 +17,7 @@ namespace vcpkg::Commands
{
static std::vector<PackageNameAndFunction<CommandTypeA>> t = {
{"install", &Install::perform_and_exit},
+ {"x-set-installed", &SetInstalled::perform_and_exit},
{"ci", &CI::perform_and_exit},
{"remove", &Remove::perform_and_exit},
{"upgrade", &Upgrade::perform_and_exit},
diff --git a/toolsrc/src/vcpkg/commands.setinstalled.cpp b/toolsrc/src/vcpkg/commands.setinstalled.cpp
new file mode 100644
index 000000000..344892fe8
--- /dev/null
+++ b/toolsrc/src/vcpkg/commands.setinstalled.cpp
@@ -0,0 +1,111 @@
+#include "pch.h"
+
+#include <vcpkg/base/system.print.h>
+#include <vcpkg/commands.h>
+#include <vcpkg/globalstate.h>
+#include <vcpkg/help.h>
+#include <vcpkg/input.h>
+#include <vcpkg/install.h>
+#include <vcpkg/remove.h>
+#include <vcpkg/portfileprovider.h>
+#include <vcpkg/vcpkglib.h>
+
+namespace vcpkg::Commands::SetInstalled
+{
+ const CommandStructure COMMAND_STRUCTURE = {
+ Help::create_example_string(R"(x-set-installed <package>...)"),
+ 1,
+ SIZE_MAX,
+ {},
+ nullptr,
+ };
+
+ void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, Triplet default_triplet)
+ {
+ // input sanitization
+ const ParsedArguments options = args.parse_arguments(COMMAND_STRUCTURE);
+
+ const std::vector<FullPackageSpec> specs = Util::fmap(args.command_arguments, [&](auto&& arg) {
+ return Input::check_and_get_full_package_spec(
+ std::string(arg), default_triplet, COMMAND_STRUCTURE.example_text);
+ });
+
+ for (auto&& spec : specs)
+ {
+ Input::check_triplet(spec.package_spec.triplet(), paths);
+ }
+
+ const Build::BuildPackageOptions install_plan_options = {
+ Build::UseHeadVersion::NO,
+ Build::AllowDownloads::YES,
+ Build::OnlyDownloads::NO,
+ Build::CleanBuildtrees::YES,
+ Build::CleanPackages::YES,
+ Build::CleanDownloads::YES,
+ Build::DownloadTool::BUILT_IN,
+ GlobalState::g_binary_caching ? Build::BinaryCaching::YES : Build::BinaryCaching::NO,
+ Build::FailOnTombstone::NO,
+ };
+
+
+ PortFileProvider::PathsPortFileProvider provider(paths, args.overlay_ports.get());
+ auto cmake_vars = CMakeVars::make_triplet_cmake_var_provider(paths);
+
+ // We have a set of user-requested specs.
+ // We need to know all the specs which are required to fulfill dependencies for those specs.
+ // Therefore, we see what we would install into an empty installed tree, so we can use the existing code.
+ auto action_plan = Dependencies::create_feature_install_plan(provider, *cmake_vars, specs, {});
+
+ for (auto&& action : action_plan.install_actions)
+ {
+ action.build_options = install_plan_options;
+ }
+
+ cmake_vars->load_tag_vars(action_plan, provider);
+ Build::compute_all_abis(paths, action_plan, *cmake_vars, {});
+
+ std::set<std::string> all_abis;
+
+ for (const auto& action : action_plan.install_actions) {
+ all_abis.insert(action.package_abi.value_or_exit(VCPKG_LINE_INFO));
+ }
+
+ // currently (or once) installed specifications
+ auto status_db = database_load_check(paths);
+ std::vector<PackageSpec> specs_to_remove;
+ for (auto&& status_pgh : status_db)
+ {
+ if (!status_pgh->is_installed()) continue;
+ if (status_pgh->package.is_feature()) continue;
+
+ const auto& abi = status_pgh->package.abi;
+ if (abi.empty() || !Util::Sets::contains(all_abis, abi))
+ {
+ specs_to_remove.push_back(status_pgh->package.spec);
+ }
+ }
+
+ auto remove_plan = Dependencies::create_remove_plan(specs_to_remove, status_db);
+
+ for (const auto& action : remove_plan)
+ {
+ Remove::perform_remove_plan_action(paths, action, Remove::Purge::NO, &status_db);
+ }
+
+ auto real_action_plan = Dependencies::create_feature_install_plan(provider, *cmake_vars, specs, status_db);
+
+ for (auto& action : real_action_plan.install_actions)
+ {
+ action.build_options = install_plan_options;
+ }
+
+ Dependencies::print_plan(real_action_plan, true);
+
+ const auto summary = Install::perform(real_action_plan, Install::KeepGoing::NO, paths, status_db, *cmake_vars);
+
+ System::print2("\nTotal elapsed time: ", summary.total_elapsed_time, "\n\n");
+
+ Checks::exit_success(VCPKG_LINE_INFO);
+ }
+
+}
diff --git a/toolsrc/src/vcpkg/dependencies.cpp b/toolsrc/src/vcpkg/dependencies.cpp
index 07aad4d22..120f84aef 100644
--- a/toolsrc/src/vcpkg/dependencies.cpp
+++ b/toolsrc/src/vcpkg/dependencies.cpp
@@ -560,7 +560,7 @@ namespace vcpkg::Dependencies
? RequestType::USER_REQUESTED
: RequestType::AUTO_SELECTED;
- auto maybe_ipv = status_db.find_all_installed(spec);
+ auto maybe_ipv = status_db.get_installed_package_view(spec);
if (auto p_ipv = maybe_ipv.get())
{
diff --git a/toolsrc/src/vcpkg/portfileprovider.cpp b/toolsrc/src/vcpkg/portfileprovider.cpp
index e43fa862a..0b0ef4aaf 100644
--- a/toolsrc/src/vcpkg/portfileprovider.cpp
+++ b/toolsrc/src/vcpkg/portfileprovider.cpp
@@ -34,7 +34,7 @@ namespace vcpkg::PortFileProvider
{
if (!overlay_path.empty())
{
- auto overlay = fs::stdfs::canonical(fs::u8path(overlay_path));
+ auto overlay = fs.canonical(VCPKG_LINE_INFO, fs::u8path(overlay_path));
Checks::check_exit(VCPKG_LINE_INFO,
filesystem.exists(overlay),
diff --git a/toolsrc/src/vcpkg/remove.cpp b/toolsrc/src/vcpkg/remove.cpp
index e1a03b808..bb25cd21d 100644
--- a/toolsrc/src/vcpkg/remove.cpp
+++ b/toolsrc/src/vcpkg/remove.cpp
@@ -21,7 +21,7 @@ namespace vcpkg::Remove
void remove_package(const VcpkgPaths& paths, const PackageSpec& spec, StatusParagraphs* status_db)
{
auto& fs = paths.get_filesystem();
- auto maybe_ipv = status_db->find_all_installed(spec);
+ auto maybe_ipv = status_db->get_installed_package_view(spec);
Checks::check_exit(
VCPKG_LINE_INFO, maybe_ipv.has_value(), "unable to remove package %s: already removed", spec);
@@ -72,6 +72,7 @@ namespace vcpkg::Remove
fs.remove(target, ec);
if (ec)
{
+ // TODO: this is racy; should we ignore this error?
#if defined(_WIN32)
fs::stdfs::permissions(target, fs::perms::owner_all | fs::perms::group_all, ec);
fs.remove(target, ec);
diff --git a/toolsrc/src/vcpkg/statusparagraphs.cpp b/toolsrc/src/vcpkg/statusparagraphs.cpp
index 2621c43e3..91058a473 100644
--- a/toolsrc/src/vcpkg/statusparagraphs.cpp
+++ b/toolsrc/src/vcpkg/statusparagraphs.cpp
@@ -18,16 +18,16 @@ namespace vcpkg
{
if (p->package.spec.name() == name && p->package.spec.triplet() == triplet)
{
- if (p->package.feature.empty())
- spghs.emplace(spghs.begin(), &p);
- else
+ if (p->package.is_feature())
spghs.emplace_back(&p);
+ else
+ spghs.emplace(spghs.begin(), &p);
}
}
return spghs;
}
- Optional<InstalledPackageView> StatusParagraphs::find_all_installed(const PackageSpec& spec) const
+ Optional<InstalledPackageView> StatusParagraphs::get_installed_package_view(const PackageSpec& spec) const
{
InstalledPackageView ipv;
for (auto&& p : *this)
@@ -35,13 +35,12 @@ namespace vcpkg
if (p->package.spec.name() == spec.name() && p->package.spec.triplet() == spec.triplet() &&
p->is_installed())
{
- if (p->package.feature.empty())
- {
+ if (p->package.is_feature()) {
+ ipv.features.emplace_back(p.get());
+ } else {
Checks::check_exit(VCPKG_LINE_INFO, ipv.core == nullptr);
ipv.core = p.get();
}
- else
- ipv.features.emplace_back(p.get());
}
}
if (ipv.core != nullptr)
diff --git a/toolsrc/src/vcpkg/vcpkgcmdarguments.cpp b/toolsrc/src/vcpkg/vcpkgcmdarguments.cpp
index 46e4c86ea..d8deae566 100644
--- a/toolsrc/src/vcpkg/vcpkgcmdarguments.cpp
+++ b/toolsrc/src/vcpkg/vcpkgcmdarguments.cpp
@@ -152,6 +152,12 @@ namespace vcpkg
arg.substr(sizeof("--x-scripts-root=") - 1), "--x-scripts-root", args.scripts_root_dir);
continue;
}
+ if (Strings::starts_with(arg, "--x-install-root="))
+ {
+ parse_cojoined_value(
+ arg.substr(sizeof("--x-install-root=") - 1), "--x-install-root=", args.install_root_dir);
+ continue;
+ }
if (arg == "--triplet")
{
++arg_begin;
diff --git a/toolsrc/src/vcpkg/vcpkglib.cpp b/toolsrc/src/vcpkg/vcpkglib.cpp
index 2a52111a6..366e2aa85 100644
--- a/toolsrc/src/vcpkg/vcpkglib.cpp
+++ b/toolsrc/src/vcpkg/vcpkglib.cpp
@@ -178,7 +178,7 @@ namespace vcpkg
{
if (!pgh->is_installed()) continue;
auto& ipv = ipv_map[pgh->package.spec];
- if (pgh->package.feature.empty())
+ if (!pgh->package.is_feature())
{
ipv.core = pgh.get();
}
@@ -206,7 +206,7 @@ namespace vcpkg
for (const std::unique_ptr<StatusParagraph>& pgh : status_db)
{
- if (!pgh->is_installed() || !pgh->package.feature.empty())
+ if (!pgh->is_installed() || pgh->package.is_feature())
{
continue;
}
diff --git a/toolsrc/src/vcpkg/vcpkgpaths.cpp b/toolsrc/src/vcpkg/vcpkgpaths.cpp
index bf16f09f3..52dd06b7b 100644
--- a/toolsrc/src/vcpkg/vcpkgpaths.cpp
+++ b/toolsrc/src/vcpkg/vcpkgpaths.cpp
@@ -14,6 +14,7 @@
namespace vcpkg
{
Expected<VcpkgPaths> VcpkgPaths::create(const fs::path& vcpkg_root_dir,
+ const Optional<fs::path>& install_root_dir,
const Optional<fs::path>& vcpkg_scripts_root_dir,
const std::string& default_vs_path,
const std::vector<std::string>* triplets_dirs)
@@ -53,7 +54,7 @@ namespace vcpkg
asPath.u8string());
}
- paths.downloads = fs::stdfs::canonical(std::move(asPath), ec);
+ paths.downloads = fs.canonical(std::move(asPath), ec);
if (ec)
{
return ec;
@@ -65,13 +66,17 @@ namespace vcpkg
}
paths.ports = paths.root / "ports";
- paths.installed = paths.root / "installed";
+ if (auto d = install_root_dir.get()) {
+ paths.installed = fs.absolute(VCPKG_LINE_INFO, std::move(*d));
+ } else {
+ paths.installed = paths.root / "installed";
+ }
paths.triplets = paths.root / "triplets";
paths.community_triplets = paths.triplets / "community";
if (auto scripts_dir = vcpkg_scripts_root_dir.get())
{
- if (scripts_dir->empty() || !fs::stdfs::is_directory(*scripts_dir))
+ if (scripts_dir->empty() || !fs::is_directory(fs.status(VCPKG_LINE_INFO, *scripts_dir)))
{
Metrics::g_metrics.lock()->track_property("error", "Invalid scripts override directory.");
Checks::exit_with_message(
@@ -108,11 +113,11 @@ namespace vcpkg
paths.get_filesystem().exists(path),
"Error: Path does not exist '%s'",
triplets_dir);
- paths.triplets_dirs.emplace_back(fs::stdfs::canonical(path));
+ paths.triplets_dirs.emplace_back(fs.canonical(VCPKG_LINE_INFO, path));
}
}
- paths.triplets_dirs.emplace_back(fs::stdfs::canonical(paths.triplets));
- paths.triplets_dirs.emplace_back(fs::stdfs::canonical(paths.community_triplets));
+ paths.triplets_dirs.emplace_back(fs.canonical(VCPKG_LINE_INFO, paths.triplets));
+ paths.triplets_dirs.emplace_back(fs.canonical(VCPKG_LINE_INFO, paths.community_triplets));
return paths;
}
diff --git a/toolsrc/vcpkglib/vcpkglib.vcxproj b/toolsrc/vcpkglib/vcpkglib.vcxproj
index ed80a210e..f054fe1ad 100644
--- a/toolsrc/vcpkglib/vcpkglib.vcxproj
+++ b/toolsrc/vcpkglib/vcpkglib.vcxproj
@@ -253,6 +253,7 @@
<ClCompile Include="..\src\vcpkg\commands.porthistory.cpp" />
<ClCompile Include="..\src\vcpkg\commands.portsdiff.cpp" />
<ClCompile Include="..\src\vcpkg\commands.search.cpp" />
+ <ClCompile Include="..\src\vcpkg\commands.setinstalled.cpp" />
<ClCompile Include="..\src\vcpkg\commands.upgrade.cpp" />
<ClCompile Include="..\src\vcpkg\commands.version.cpp" />
<ClCompile Include="..\src\vcpkg\commands.xvsinstances.cpp" />
diff --git a/toolsrc/vcpkglib/vcpkglib.vcxproj.filters b/toolsrc/vcpkglib/vcpkglib.vcxproj.filters
index 4e2bbb45a..e9441f72c 100644
--- a/toolsrc/vcpkglib/vcpkglib.vcxproj.filters
+++ b/toolsrc/vcpkglib/vcpkglib.vcxproj.filters
@@ -87,6 +87,9 @@
<ClCompile Include="..\src\vcpkg\commands.search.cpp">
<Filter>Source Files\vcpkg</Filter>
</ClCompile>
+ <ClCompile Include="..\src\vcpkg\commands.setinstalled.cpp">
+ <Filter>Source Files\vcpkg</Filter>
+ </ClCompile>
<ClCompile Include="..\src\vcpkg\commands.version.cpp">
<Filter>Source Files\vcpkg</Filter>
</ClCompile>
@@ -441,4 +444,4 @@
<Filter>Header Files\vcpkg</Filter>
</ClInclude>
</ItemGroup>
-</Project> \ No newline at end of file
+</Project>