[x-update-baseline] Initial implementation (#341)
* start working * update vcpkgpaths to better support what I want * optional: make certain `get()` is only called when it won't result in a dangling pointer * vcpkgpaths: remove JsonStyle support as it isn't used * vcpkgpaths: switch from two functions returning Optional<Manifest> + Optional<Path>, to one function returning Optional<ManifestAndLocation> * vcpkgpaths: add `get_configuration_and_location` * rename get_*_and_location -> get_* * lots of CRs * get_latest_baseline -> configuration.cpp * format * optional - add see-through operator== * add `--add-initial-baseline` option * more correct if-elses * add messages! ``` PS /../nimazzuc/projects/testproj> ../vcpkg-tool/build/vcpkg x-update-baseline --dry-run registry 'https://github.com/microsoft/vcpkg' already up to date: 89295c9fe22e97ca9e380a6c771ccf2ff09dca95 registry '/a/b' not updated: default registry 'https://foobar' not updated: default warning: git failed to fetch remote repository https://foobar Error: Failed to fetch ref HEAD from repository https://foobar. fatal: unable to access 'https://foobar/': Could not resolve host: foobar ``` * update - hopefully fix Billy's CRs * fix formatting * (optional::operator==) add tests, add opt<T> == opt<U> * rename things * registry_location -> pretty_location * ManifestAndLocation -> ManifestAndPath * ConfigurationAndLocation -> ConfigurationAndSource * minor other CRs * forgot to to_string * format * I think this is what robert wants? * format
This commit is contained in:
Родитель
48006ab73a
Коммит
1cf1f7f126
|
@ -106,6 +106,9 @@ namespace vcpkg
|
|||
return lhs.data() >= rhs.data();
|
||||
}
|
||||
|
||||
bool empty() { return m_data.empty(); }
|
||||
void clear() { m_data.clear(); }
|
||||
|
||||
private:
|
||||
std::string m_data;
|
||||
|
||||
|
@ -244,6 +247,8 @@ namespace vcpkg::msg
|
|||
DECLARE_MSG_ARG(expected, "");
|
||||
DECLARE_MSG_ARG(actual, "");
|
||||
DECLARE_MSG_ARG(list, "");
|
||||
DECLARE_MSG_ARG(old_value, "");
|
||||
DECLARE_MSG_ARG(new_value, "");
|
||||
|
||||
DECLARE_MSG_ARG(actual_version, "1.3.8");
|
||||
DECLARE_MSG_ARG(arch, "x64");
|
||||
|
@ -317,10 +322,10 @@ namespace vcpkg::msg
|
|||
|
||||
inline void print_warning(const LocalizedString& s)
|
||||
{
|
||||
print(Color::warning, format(msgErrorMessage).append(s).appendnl());
|
||||
print(Color::warning, format(msgWarningMessage).append(s).appendnl());
|
||||
}
|
||||
template<class Message, class... Ts>
|
||||
void print_warning(Message m, Ts... args)
|
||||
typename Message::is_message_type print_warning(Message m, Ts... args)
|
||||
{
|
||||
print(Color::warning, format(msgWarningMessage).append(format(m, args...).appendnl()));
|
||||
}
|
||||
|
@ -330,7 +335,7 @@ namespace vcpkg::msg
|
|||
print(Color::error, format(msgErrorMessage).append(s).appendnl());
|
||||
}
|
||||
template<class Message, class... Ts>
|
||||
void print_error(Message m, Ts... args)
|
||||
typename Message::is_message_type print_error(Message m, Ts... args)
|
||||
{
|
||||
print(Color::error, format(msgErrorMessage).append(format(m, args...).appendnl()));
|
||||
}
|
||||
|
|
|
@ -107,6 +107,11 @@ namespace vcpkg
|
|||
const T& value() const { return this->m_t; }
|
||||
T& value() { return this->m_t; }
|
||||
|
||||
const T* get() const& { return m_is_present ? &m_t : nullptr; }
|
||||
T* get() & { return m_is_present ? &m_t : nullptr; }
|
||||
const T* get() const&& = delete;
|
||||
T* get() && = delete;
|
||||
|
||||
void destroy()
|
||||
{
|
||||
m_is_present = false;
|
||||
|
@ -180,6 +185,11 @@ namespace vcpkg
|
|||
const T& value() const { return this->m_t; }
|
||||
T& value() { return this->m_t; }
|
||||
|
||||
const T* get() const& { return m_is_present ? &m_t : nullptr; }
|
||||
T* get() & { return m_is_present ? &m_t : nullptr; }
|
||||
const T* get() const&& = delete;
|
||||
T* get() && = delete;
|
||||
|
||||
template<class... Args>
|
||||
T& emplace(Args&&... args)
|
||||
{
|
||||
|
@ -228,6 +238,8 @@ namespace vcpkg
|
|||
return *m_t;
|
||||
}
|
||||
|
||||
T* get() const { return m_t; }
|
||||
|
||||
private:
|
||||
T* m_t;
|
||||
};
|
||||
|
@ -246,6 +258,8 @@ namespace vcpkg
|
|||
|
||||
const T& value() const { return *this->m_t; }
|
||||
|
||||
const T* get() const { return m_t; }
|
||||
|
||||
const T& emplace(const T& t)
|
||||
{
|
||||
m_t = &t;
|
||||
|
@ -260,6 +274,10 @@ namespace vcpkg
|
|||
template<class T>
|
||||
struct Optional
|
||||
{
|
||||
private:
|
||||
details::OptionalStorage<T> m_base;
|
||||
|
||||
public:
|
||||
constexpr Optional() noexcept { }
|
||||
|
||||
// Constructors are intentionally implicit
|
||||
|
@ -320,12 +338,11 @@ namespace vcpkg
|
|||
return this->m_base.has_value() ? std::move(this->m_base.value()) : static_cast<T&&>(default_value);
|
||||
}
|
||||
|
||||
typename std::add_pointer<const T>::type get() const
|
||||
{
|
||||
return this->m_base.has_value() ? &this->m_base.value() : nullptr;
|
||||
}
|
||||
|
||||
typename std::add_pointer<T>::type get() { return this->m_base.has_value() ? &this->m_base.value() : nullptr; }
|
||||
// this allows us to error out when `.get()` would return a pointer to a temporary
|
||||
decltype(auto) get() const& { return this->m_base.get(); }
|
||||
decltype(auto) get() & { return this->m_base.get(); }
|
||||
decltype(auto) get() const&& { return std::move(this->m_base).get(); }
|
||||
decltype(auto) get() && { return std::move(this->m_base).get(); }
|
||||
|
||||
template<class F>
|
||||
using map_t = decltype(std::declval<F&>()(std::declval<const T&>()));
|
||||
|
@ -396,9 +413,6 @@ namespace vcpkg
|
|||
return !rhs.m_base.has_value();
|
||||
}
|
||||
friend bool operator!=(const Optional& lhs, const Optional& rhs) noexcept { return !(lhs == rhs); }
|
||||
|
||||
private:
|
||||
details::OptionalStorage<T> m_base;
|
||||
};
|
||||
|
||||
template<class U>
|
||||
|
@ -407,28 +421,44 @@ namespace vcpkg
|
|||
return Optional<std::decay_t<U>>(std::forward<U>(u));
|
||||
}
|
||||
|
||||
template<class T>
|
||||
bool operator==(const Optional<T>& o, const T& t)
|
||||
// these cannot be hidden friends, unfortunately
|
||||
template<class T, class U>
|
||||
auto operator==(const Optional<T>& lhs, const Optional<U>& rhs) -> decltype(*lhs.get() == *rhs.get())
|
||||
{
|
||||
if (auto p = o.get()) return *p == t;
|
||||
return false;
|
||||
if (lhs.has_value() && rhs.has_value())
|
||||
{
|
||||
return *lhs.get() == *rhs.get();
|
||||
}
|
||||
return lhs.has_value() == rhs.has_value();
|
||||
}
|
||||
template<class T>
|
||||
bool operator==(const T& t, const Optional<T>& o)
|
||||
template<class T, class U>
|
||||
auto operator==(const Optional<T>& lhs, const U& rhs) -> decltype(*lhs.get() == rhs)
|
||||
{
|
||||
if (auto p = o.get()) return t == *p;
|
||||
return false;
|
||||
return lhs.has_value() ? *lhs.get() == rhs : false;
|
||||
}
|
||||
template<class T>
|
||||
bool operator!=(const Optional<T>& o, const T& t)
|
||||
template<class T, class U>
|
||||
auto operator==(const T& lhs, const Optional<U>& rhs) -> decltype(lhs == *rhs.get())
|
||||
{
|
||||
if (auto p = o.get()) return *p != t;
|
||||
return true;
|
||||
return rhs.has_value() ? lhs == *rhs.get() : false;
|
||||
}
|
||||
template<class T>
|
||||
bool operator!=(const T& t, const Optional<T>& o)
|
||||
|
||||
template<class T, class U>
|
||||
auto operator!=(const Optional<T>& lhs, const Optional<U>& rhs) -> decltype(*lhs.get() != *rhs.get())
|
||||
{
|
||||
if (auto p = o.get()) return t != *p;
|
||||
return true;
|
||||
if (lhs.has_value() && rhs.has_value())
|
||||
{
|
||||
return *lhs.get() != *rhs.get();
|
||||
}
|
||||
return lhs.has_value() != rhs.has_value();
|
||||
}
|
||||
template<class T, class U>
|
||||
auto operator!=(const Optional<T>& lhs, const U& rhs) -> decltype(*lhs.get() != rhs)
|
||||
{
|
||||
return lhs.has_value() ? *lhs.get() != rhs : true;
|
||||
}
|
||||
template<class T, class U>
|
||||
auto operator!=(const T& lhs, const Optional<U>& rhs) -> decltype(lhs != *rhs.get())
|
||||
{
|
||||
return rhs.has_value() ? lhs != *rhs.get() : true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
#pragma once
|
||||
|
||||
#include <vcpkg/commands.interface.h>
|
||||
|
||||
namespace vcpkg::Commands
|
||||
{
|
||||
struct UpdateBaselineCommand : PathsCommand
|
||||
{
|
||||
virtual void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) const override;
|
||||
};
|
||||
}
|
|
@ -23,6 +23,9 @@ namespace vcpkg
|
|||
Optional<std::vector<std::string>> packages;
|
||||
|
||||
Json::Value serialize() const;
|
||||
|
||||
ExpectedL<Optional<std::string>> get_latest_baseline(const VcpkgPaths& paths) const;
|
||||
StringView pretty_location() const;
|
||||
};
|
||||
|
||||
struct Configuration
|
||||
|
@ -42,6 +45,25 @@ namespace vcpkg
|
|||
static View<StringView> known_fields();
|
||||
};
|
||||
|
||||
enum class ConfigurationSource
|
||||
{
|
||||
None,
|
||||
VcpkgConfigurationFile,
|
||||
ManifestFile,
|
||||
};
|
||||
|
||||
struct ConfigurationAndSource
|
||||
{
|
||||
Configuration config;
|
||||
Path directory;
|
||||
ConfigurationSource source = ConfigurationSource::None;
|
||||
|
||||
std::unique_ptr<RegistrySet> instantiate_registry_set(const VcpkgPaths& paths) const
|
||||
{
|
||||
return config.instantiate_registry_set(paths, directory);
|
||||
}
|
||||
};
|
||||
|
||||
struct ManifestConfiguration
|
||||
{
|
||||
Optional<std::string> builtin_baseline;
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
namespace vcpkg
|
||||
{
|
||||
struct Configuration;
|
||||
struct ConfigurationAndSource;
|
||||
struct RegistryConfig;
|
||||
struct ManifestConfiguration;
|
||||
}
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
|
||||
namespace vcpkg
|
||||
{
|
||||
constexpr StringLiteral builtin_registry_git_url() { return "https://github.com/microsoft/vcpkg"; }
|
||||
|
||||
struct LockFile
|
||||
{
|
||||
struct EntryData
|
||||
|
|
|
@ -58,6 +58,12 @@ namespace vcpkg
|
|||
struct PackageSpec;
|
||||
struct Triplet;
|
||||
|
||||
struct ManifestAndPath
|
||||
{
|
||||
Json::Object manifest;
|
||||
Path path;
|
||||
};
|
||||
|
||||
struct VcpkgPaths
|
||||
{
|
||||
struct TripletFile
|
||||
|
@ -147,8 +153,8 @@ namespace vcpkg
|
|||
const Path& relative_path_to_file) const;
|
||||
ExpectedS<Path> git_checkout_object_from_remote_registry(StringView tree) const;
|
||||
|
||||
Optional<const Json::Object&> get_manifest() const;
|
||||
Optional<const Path&> get_manifest_path() const;
|
||||
Optional<const ManifestAndPath&> get_manifest() const;
|
||||
const ConfigurationAndSource& get_configuration() const;
|
||||
const RegistrySet& get_registry_set() const;
|
||||
|
||||
// Retrieve a toolset matching the requirements in prebuildinfo
|
||||
|
|
|
@ -132,6 +132,13 @@
|
|||
"UnknownBinaryProviderType": "unknown binary provider type: valid providers are 'clear', 'default', 'nuget', 'nugetconfig', 'interactive', and 'files'",
|
||||
"UnsupportedSystemName": "Error: Could not map VCPKG_CMAKE_SYSTEM_NAME '{system_name}' to a vcvarsall platform. Supported system names are '', 'Windows' and 'WindowsStore'.",
|
||||
"UnsupportedToolchain": "Error: in triplet {triplet}: Unable to find a valid toolchain combination.\n The requested target architecture was {arch}\n The selected Visual Studio instance is at {path}\n The available toolchain combinations are {list}\n",
|
||||
"UpdateBaselineAddBaselineNoManifest": "the --{option} switch was passed, but there is no manifest file to add a `builtin-baseline` field to.",
|
||||
"UpdateBaselineLocalGitError": "git failed to parse HEAD for the local vcpkg registry at '{path}'",
|
||||
"UpdateBaselineNoConfiguration": "neither `vcpkg.json` nor `vcpkg-configuration.json` exist to update.",
|
||||
"UpdateBaselineNoExistingBuiltinBaseline": "the manifest file currently does not contain a `builtin-baseline` field; in order to add one, pass the --{option} switch.",
|
||||
"UpdateBaselineNoUpdate": "registry '{url}' not updated: '{value}'",
|
||||
"UpdateBaselineRemoteGitError": "git failed to fetch remote repository '{url}'",
|
||||
"UpdateBaselineUpdatedBaseline": "updated registry '{url}': baseline '{old_value}' -> '{new_value}'",
|
||||
"UploadedPackagesToVendor": "Uploaded {count} package(s) to {vendor} in {elapsed}",
|
||||
"UsingManifestAt": "Using manifest file at {path}.",
|
||||
"Utf8DecoderDereferencedAtEof": "dereferenced Utf8Decoder at the end of a string.",
|
||||
|
|
|
@ -228,6 +228,19 @@
|
|||
"_UnsupportedSystemName.comment": "example of {system_name} is 'Darwin'.\n",
|
||||
"UnsupportedToolchain": "Error: in triplet {triplet}: Unable to find a valid toolchain combination.\n The requested target architecture was {arch}\n The selected Visual Studio instance is at {path}\n The available toolchain combinations are {list}\n",
|
||||
"_UnsupportedToolchain.comment": "example for {list} is 'x86, arm64'\nexample of {triplet} is 'x64-windows'.\nexample of {arch} is 'x64'.\nexample of {path} is '/foo/bar'.\n",
|
||||
"UpdateBaselineAddBaselineNoManifest": "the --{option} switch was passed, but there is no manifest file to add a `builtin-baseline` field to.",
|
||||
"_UpdateBaselineAddBaselineNoManifest.comment": "example of {option} is 'editable'.\n",
|
||||
"UpdateBaselineLocalGitError": "git failed to parse HEAD for the local vcpkg registry at '{path}'",
|
||||
"_UpdateBaselineLocalGitError.comment": "example of {path} is '/foo/bar'.\n",
|
||||
"UpdateBaselineNoConfiguration": "neither `vcpkg.json` nor `vcpkg-configuration.json` exist to update.",
|
||||
"UpdateBaselineNoExistingBuiltinBaseline": "the manifest file currently does not contain a `builtin-baseline` field; in order to add one, pass the --{option} switch.",
|
||||
"_UpdateBaselineNoExistingBuiltinBaseline.comment": "example of {option} is 'editable'.\n",
|
||||
"UpdateBaselineNoUpdate": "registry '{url}' not updated: '{value}'",
|
||||
"_UpdateBaselineNoUpdate.comment": "example of {value} is '5507daa796359fe8d45418e694328e878ac2b82f'\nexample of {url} is 'https://github.com/microsoft/vcpkg'.\n",
|
||||
"UpdateBaselineRemoteGitError": "git failed to fetch remote repository '{url}'",
|
||||
"_UpdateBaselineRemoteGitError.comment": "example of {url} is 'https://github.com/microsoft/vcpkg'.\n",
|
||||
"UpdateBaselineUpdatedBaseline": "updated registry '{url}': baseline '{old_value}' -> '{new_value}'",
|
||||
"_UpdateBaselineUpdatedBaseline.comment": "example of {old_value}, {new_value} is '5507daa796359fe8d45418e694328e878ac2b82f'\nexample of {url} is 'https://github.com/microsoft/vcpkg'.\n",
|
||||
"UploadedPackagesToVendor": "Uploaded {count} package(s) to {vendor} in {elapsed}",
|
||||
"_UploadedPackagesToVendor.comment": "example of {count} is '42'.\nexample of {elapsed} is '3.532 min'.\nexample of {vendor} is 'Azure'.\n",
|
||||
"UsingManifestAt": "Using manifest file at {path}.",
|
||||
|
|
|
@ -63,6 +63,7 @@ TEST_CASE ("list of commands is correct", "[commands]")
|
|||
"remove",
|
||||
"search",
|
||||
"update",
|
||||
"x-update-baseline",
|
||||
"upgrade",
|
||||
"use",
|
||||
"version",
|
||||
|
|
|
@ -119,3 +119,127 @@ TEST_CASE ("common_projection", "[optional]")
|
|||
input.push_back(1729);
|
||||
CHECK(!common_projection(input, identity_projection{}).has_value());
|
||||
}
|
||||
|
||||
TEST_CASE ("operator==/operator!=", "[optional]")
|
||||
{
|
||||
using vcpkg::Optional;
|
||||
using vcpkg::StringLiteral;
|
||||
|
||||
SECTION ("same type - opt == opt")
|
||||
{
|
||||
Optional<std::string> s1;
|
||||
Optional<std::string> s2;
|
||||
|
||||
// none == none
|
||||
CHECK(s1 == s2);
|
||||
CHECK_FALSE(s1 != s2);
|
||||
CHECK(s2 == s1);
|
||||
CHECK_FALSE(s2 != s1);
|
||||
|
||||
// some("") != none
|
||||
s1 = "";
|
||||
CHECK_FALSE(s1 == s2);
|
||||
CHECK(s1 != s2);
|
||||
CHECK_FALSE(s2 == s1);
|
||||
CHECK(s2 != s1);
|
||||
|
||||
// some("") == some("")
|
||||
s2 = "";
|
||||
CHECK(s1 == s2);
|
||||
CHECK_FALSE(s1 != s2);
|
||||
CHECK(s2 == s1);
|
||||
CHECK_FALSE(s2 != s1);
|
||||
|
||||
// some("hi") != some("")
|
||||
s1 = "hi";
|
||||
CHECK_FALSE(s1 == s2);
|
||||
CHECK(s1 != s2);
|
||||
CHECK_FALSE(s2 == s1);
|
||||
CHECK(s2 != s1);
|
||||
};
|
||||
|
||||
SECTION ("same type - opt == raw")
|
||||
{
|
||||
Optional<std::string> opt_string;
|
||||
std::string string;
|
||||
|
||||
// none != ""
|
||||
CHECK_FALSE(opt_string == string);
|
||||
CHECK(opt_string != string);
|
||||
CHECK_FALSE(string == opt_string);
|
||||
CHECK(string != opt_string);
|
||||
|
||||
// some("") == ""
|
||||
opt_string = "";
|
||||
CHECK(opt_string == string);
|
||||
CHECK_FALSE(opt_string != string);
|
||||
CHECK(string == opt_string);
|
||||
CHECK_FALSE(string != opt_string);
|
||||
|
||||
// some("hi") != ""
|
||||
opt_string = "hi";
|
||||
CHECK_FALSE(opt_string == string);
|
||||
CHECK(opt_string != string);
|
||||
CHECK_FALSE(string == opt_string);
|
||||
CHECK(string != opt_string);
|
||||
};
|
||||
|
||||
SECTION ("different types - opt == opt")
|
||||
{
|
||||
Optional<std::string> opt_string;
|
||||
Optional<StringLiteral> opt_literal;
|
||||
|
||||
// none == none
|
||||
CHECK(opt_string == opt_literal);
|
||||
CHECK_FALSE(opt_string != opt_literal);
|
||||
CHECK(opt_literal == opt_string);
|
||||
CHECK_FALSE(opt_literal != opt_string);
|
||||
|
||||
// some("") != none
|
||||
opt_string = "";
|
||||
CHECK_FALSE(opt_string == opt_literal);
|
||||
CHECK(opt_string != opt_literal);
|
||||
CHECK_FALSE(opt_literal == opt_string);
|
||||
CHECK(opt_literal != opt_string);
|
||||
|
||||
// some("") == some("")
|
||||
opt_literal = "";
|
||||
CHECK(opt_string == opt_literal);
|
||||
CHECK_FALSE(opt_string != opt_literal);
|
||||
CHECK(opt_literal == opt_string);
|
||||
CHECK_FALSE(opt_literal != opt_string);
|
||||
|
||||
// some("hi") != some("")
|
||||
opt_string = "hi";
|
||||
CHECK_FALSE(opt_string == opt_literal);
|
||||
CHECK(opt_string != opt_literal);
|
||||
CHECK_FALSE(opt_literal == opt_string);
|
||||
CHECK(opt_literal != opt_string);
|
||||
};
|
||||
|
||||
SECTION ("different types - opt == raw")
|
||||
{
|
||||
Optional<std::string> opt_string;
|
||||
StringLiteral literal = "";
|
||||
|
||||
// none != ""
|
||||
CHECK_FALSE(opt_string == literal);
|
||||
CHECK(opt_string != literal);
|
||||
CHECK_FALSE(literal == opt_string);
|
||||
CHECK(literal != opt_string);
|
||||
|
||||
// some("") == ""
|
||||
opt_string = "";
|
||||
CHECK(opt_string == literal);
|
||||
CHECK_FALSE(opt_string != literal);
|
||||
CHECK(literal == opt_string);
|
||||
CHECK_FALSE(literal != opt_string);
|
||||
|
||||
// some("hi") != ""
|
||||
opt_string = "hi";
|
||||
CHECK_FALSE(opt_string == literal);
|
||||
CHECK(opt_string != literal);
|
||||
CHECK_FALSE(literal == opt_string);
|
||||
CHECK(literal != opt_string);
|
||||
};
|
||||
}
|
||||
|
|
|
@ -99,8 +99,7 @@ namespace vcpkg::Commands
|
|||
specs.push_back(std::move(value));
|
||||
}
|
||||
|
||||
const auto& manifest_path = paths.get_manifest_path().value_or_exit(VCPKG_LINE_INFO);
|
||||
auto maybe_manifest_scf = SourceControlFile::parse_manifest_object(manifest_path, *manifest);
|
||||
auto maybe_manifest_scf = SourceControlFile::parse_manifest_object(manifest->path, manifest->manifest);
|
||||
if (!maybe_manifest_scf)
|
||||
{
|
||||
print_error_message(maybe_manifest_scf.error());
|
||||
|
@ -133,7 +132,7 @@ namespace vcpkg::Commands
|
|||
}
|
||||
|
||||
paths.get_filesystem().write_contents(
|
||||
manifest_path, Json::stringify(serialize_manifest(manifest_scf), {}), VCPKG_LINE_INFO);
|
||||
manifest->path, Json::stringify(serialize_manifest(manifest_scf), {}), VCPKG_LINE_INFO);
|
||||
msg::println(msgAddPortSucceded);
|
||||
|
||||
auto metrics = LockGuardPtr<Metrics>(g_metrics);
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include <vcpkg/commands.regenerate.h>
|
||||
#include <vcpkg/commands.search.h>
|
||||
#include <vcpkg/commands.setinstalled.h>
|
||||
#include <vcpkg/commands.update-baseline.h>
|
||||
#include <vcpkg/commands.upgrade.h>
|
||||
#include <vcpkg/commands.upload-metrics.h>
|
||||
#include <vcpkg/commands.use.h>
|
||||
|
@ -103,6 +104,7 @@ namespace vcpkg::Commands
|
|||
static const RegenerateCommand regenerate{};
|
||||
static const SearchCommand search{};
|
||||
static const Update::UpdateCommand update{};
|
||||
static const UpdateBaselineCommand update_baseline{};
|
||||
static const UseCommand use{};
|
||||
static const X_VSInstances::VSInstancesCommand vsinstances{};
|
||||
static const ZCeCommand ce{};
|
||||
|
@ -126,6 +128,7 @@ namespace vcpkg::Commands
|
|||
{"portsdiff", &portsdiff},
|
||||
{"search", &search},
|
||||
{"update", &update},
|
||||
{"x-update-baseline", &update_baseline},
|
||||
{"use", &use},
|
||||
{"x-add-version", &add_version},
|
||||
{"x-ci-clean", &ciclean},
|
||||
|
|
|
@ -0,0 +1,167 @@
|
|||
#include <vcpkg/base/files.h>
|
||||
#include <vcpkg/base/messages.h>
|
||||
|
||||
#include <vcpkg/commands.update-baseline.h>
|
||||
#include <vcpkg/configuration.h>
|
||||
#include <vcpkg/vcpkgcmdarguments.h>
|
||||
#include <vcpkg/vcpkgpaths.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
using namespace vcpkg;
|
||||
|
||||
DECLARE_AND_REGISTER_MESSAGE(UpdateBaselineNoConfiguration,
|
||||
(),
|
||||
"",
|
||||
"neither `vcpkg.json` nor `vcpkg-configuration.json` exist to update.");
|
||||
|
||||
DECLARE_AND_REGISTER_MESSAGE(UpdateBaselineNoExistingBuiltinBaseline,
|
||||
(msg::option),
|
||||
"",
|
||||
"the manifest file currently does not contain a `builtin-baseline` field; in order to "
|
||||
"add one, pass the --{option} switch.");
|
||||
DECLARE_AND_REGISTER_MESSAGE(
|
||||
UpdateBaselineAddBaselineNoManifest,
|
||||
(msg::option),
|
||||
"",
|
||||
"the --{option} switch was passed, but there is no manifest file to add a `builtin-baseline` field to.");
|
||||
|
||||
DECLARE_AND_REGISTER_MESSAGE(UpdateBaselineUpdatedBaseline,
|
||||
(msg::url, msg::old_value, msg::new_value),
|
||||
"example of {old_value}, {new_value} is '5507daa796359fe8d45418e694328e878ac2b82f'",
|
||||
"updated registry '{url}': baseline '{old_value}' -> '{new_value}'");
|
||||
DECLARE_AND_REGISTER_MESSAGE(UpdateBaselineNoUpdate,
|
||||
(msg::url, msg::value),
|
||||
"example of {value} is '5507daa796359fe8d45418e694328e878ac2b82f'",
|
||||
"registry '{url}' not updated: '{value}'");
|
||||
}
|
||||
|
||||
namespace vcpkg::Commands
|
||||
{
|
||||
static constexpr StringLiteral OPTION_ADD_INITIAL_BASELINE = "add-initial-baseline";
|
||||
static constexpr StringLiteral OPTION_DRY_RUN = "dry-run";
|
||||
|
||||
static constexpr CommandSwitch switches[] = {
|
||||
{OPTION_ADD_INITIAL_BASELINE, "add a `builtin-baseline` to a vcpkg.json that doesn't already have it"},
|
||||
{OPTION_DRY_RUN, "Print out plan without execution"},
|
||||
};
|
||||
|
||||
static const CommandStructure COMMAND_STRUCTURE{
|
||||
create_example_string("x-update-baseline"),
|
||||
0,
|
||||
0,
|
||||
{switches},
|
||||
};
|
||||
|
||||
static void update_baseline_in_config(const VcpkgPaths& paths, RegistryConfig& reg)
|
||||
{
|
||||
auto url = reg.pretty_location();
|
||||
auto new_baseline_res = reg.get_latest_baseline(paths);
|
||||
|
||||
if (auto new_baseline = new_baseline_res.get())
|
||||
{
|
||||
if (*new_baseline != reg.baseline)
|
||||
{
|
||||
msg::println(msgUpdateBaselineUpdatedBaseline,
|
||||
msg::url = url,
|
||||
msg::old_value = reg.baseline.value_or(""),
|
||||
msg::new_value = new_baseline->value_or(""));
|
||||
reg.baseline = std::move(*new_baseline);
|
||||
}
|
||||
// new_baseline == reg.baseline
|
||||
else
|
||||
{
|
||||
msg::println(msgUpdateBaselineNoUpdate, msg::url = url, msg::value = reg.baseline.value_or(""));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// this isn't an error, since we want to continue attempting to update baselines
|
||||
msg::print_warning(
|
||||
msg::format(msgUpdateBaselineNoUpdate, msg::url = url, msg::value = reg.baseline.value_or(""))
|
||||
.appendnl()
|
||||
.append(new_baseline_res.error()));
|
||||
}
|
||||
|
||||
void UpdateBaselineCommand::perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) const
|
||||
{
|
||||
auto options = args.parse_arguments(COMMAND_STRUCTURE);
|
||||
|
||||
const bool add_builtin_baseline = Util::Sets::contains(options.switches, OPTION_ADD_INITIAL_BASELINE);
|
||||
const bool dry_run = Util::Sets::contains(options.switches, OPTION_DRY_RUN);
|
||||
|
||||
auto configuration = paths.get_configuration();
|
||||
const bool has_manifest = paths.get_manifest().has_value();
|
||||
auto manifest = has_manifest ? *paths.get_manifest().get() : ManifestAndPath{};
|
||||
|
||||
if (configuration.source == ConfigurationSource::None && !has_manifest)
|
||||
{
|
||||
msg::print_warning(msgUpdateBaselineNoConfiguration);
|
||||
Checks::exit_success(VCPKG_LINE_INFO);
|
||||
}
|
||||
|
||||
bool has_builtin_baseline = manifest.manifest.contains("builtin-baseline");
|
||||
|
||||
if (add_builtin_baseline && !has_manifest)
|
||||
{
|
||||
Checks::msg_exit_with_error(
|
||||
VCPKG_LINE_INFO, msgUpdateBaselineAddBaselineNoManifest, msg::option = OPTION_ADD_INITIAL_BASELINE);
|
||||
}
|
||||
if (!has_builtin_baseline && !add_builtin_baseline && configuration.source == ConfigurationSource::None)
|
||||
{
|
||||
msg::print_warning(msgUpdateBaselineNoExistingBuiltinBaseline, msg::option = OPTION_ADD_INITIAL_BASELINE);
|
||||
Checks::exit_success(VCPKG_LINE_INFO);
|
||||
}
|
||||
|
||||
if (has_builtin_baseline || add_builtin_baseline)
|
||||
{
|
||||
// remove default_reg, since that's filled in with the builtin-baseline
|
||||
configuration.config.default_reg = nullopt;
|
||||
|
||||
RegistryConfig synthesized_registry;
|
||||
synthesized_registry.kind = "builtin";
|
||||
if (auto p = manifest.manifest.get("builtin-baseline"))
|
||||
{
|
||||
synthesized_registry.baseline = p->string().to_string();
|
||||
}
|
||||
|
||||
update_baseline_in_config(paths, synthesized_registry);
|
||||
|
||||
if (auto p = synthesized_registry.baseline.get())
|
||||
{
|
||||
manifest.manifest.insert_or_replace("builtin-baseline", std::move(*p));
|
||||
}
|
||||
}
|
||||
|
||||
if (auto default_reg = configuration.config.default_reg.get())
|
||||
{
|
||||
update_baseline_in_config(paths, *default_reg);
|
||||
}
|
||||
|
||||
for (auto& reg : configuration.config.registries)
|
||||
{
|
||||
update_baseline_in_config(paths, reg);
|
||||
}
|
||||
|
||||
if (configuration.source == ConfigurationSource::ManifestFile)
|
||||
{
|
||||
manifest.manifest.insert_or_replace("vcpkg-configuration", configuration.config.serialize());
|
||||
}
|
||||
|
||||
if (!dry_run && configuration.source == ConfigurationSource::VcpkgConfigurationFile)
|
||||
{
|
||||
paths.get_filesystem().write_contents(configuration.directory / "vcpkg-configuration.json",
|
||||
Json::stringify(configuration.config.serialize(), {}),
|
||||
VCPKG_LINE_INFO);
|
||||
}
|
||||
|
||||
if (!dry_run && has_manifest)
|
||||
{
|
||||
paths.get_filesystem().write_contents(
|
||||
manifest.path, Json::stringify(manifest.manifest, {}), VCPKG_LINE_INFO);
|
||||
}
|
||||
|
||||
Checks::exit_success(VCPKG_LINE_INFO);
|
||||
}
|
||||
}
|
|
@ -10,6 +10,15 @@ namespace
|
|||
{
|
||||
using namespace vcpkg;
|
||||
|
||||
DECLARE_AND_REGISTER_MESSAGE(UpdateBaselineRemoteGitError,
|
||||
(msg::url),
|
||||
"",
|
||||
"git failed to fetch remote repository '{url}'");
|
||||
DECLARE_AND_REGISTER_MESSAGE(UpdateBaselineLocalGitError,
|
||||
(msg::path),
|
||||
"",
|
||||
"git failed to parse HEAD for the local vcpkg registry at '{path}'");
|
||||
|
||||
struct RegistryConfigDeserializer : Json::IDeserializer<RegistryConfig>
|
||||
{
|
||||
constexpr static StringLiteral KIND = "kind";
|
||||
|
@ -535,6 +544,77 @@ namespace
|
|||
|
||||
namespace vcpkg
|
||||
{
|
||||
static ExpectedL<Optional<std::string>> get_baseline_from_git_repo(const VcpkgPaths& paths, StringView url)
|
||||
{
|
||||
auto res = paths.git_fetch_from_remote_registry(url, "HEAD");
|
||||
if (auto p = res.get())
|
||||
{
|
||||
return Optional<std::string>(std::move(*p));
|
||||
}
|
||||
else
|
||||
{
|
||||
return msg::format(msgUpdateBaselineRemoteGitError, msg::url = url)
|
||||
.appendnl()
|
||||
.append_raw(Strings::trim(res.error()));
|
||||
}
|
||||
}
|
||||
|
||||
ExpectedL<Optional<std::string>> RegistryConfig::get_latest_baseline(const VcpkgPaths& paths) const
|
||||
{
|
||||
if (kind == RegistryConfigDeserializer::KIND_GIT)
|
||||
{
|
||||
return get_baseline_from_git_repo(paths, repo.value_or_exit(VCPKG_LINE_INFO));
|
||||
}
|
||||
else if (kind == RegistryConfigDeserializer::KIND_BUILTIN)
|
||||
{
|
||||
if (paths.use_git_default_registry())
|
||||
{
|
||||
return get_baseline_from_git_repo(paths, builtin_registry_git_url());
|
||||
}
|
||||
else
|
||||
{
|
||||
// use the vcpkg git repository sha from the user's machine
|
||||
auto res = paths.get_current_git_sha();
|
||||
if (auto p = res.get())
|
||||
{
|
||||
return Optional<std::string>(std::move(*p));
|
||||
}
|
||||
else
|
||||
{
|
||||
return msg::format(msgUpdateBaselineLocalGitError, msg::path = paths.root)
|
||||
.appendnl()
|
||||
.append_raw(Strings::trim(res.error()));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return baseline;
|
||||
}
|
||||
}
|
||||
|
||||
StringView RegistryConfig::pretty_location() const
|
||||
{
|
||||
if (kind == RegistryConfigDeserializer::KIND_BUILTIN)
|
||||
{
|
||||
return builtin_registry_git_url();
|
||||
}
|
||||
if (kind == RegistryConfigDeserializer::KIND_FILESYSTEM)
|
||||
{
|
||||
return path.value_or_exit(VCPKG_LINE_INFO);
|
||||
}
|
||||
if (kind == RegistryConfigDeserializer::KIND_GIT)
|
||||
{
|
||||
return repo.value_or_exit(VCPKG_LINE_INFO);
|
||||
}
|
||||
if (kind == RegistryConfigDeserializer::KIND_ARTIFACT)
|
||||
{
|
||||
return location.value_or_exit(VCPKG_LINE_INFO);
|
||||
}
|
||||
|
||||
Checks::unreachable(VCPKG_LINE_INFO);
|
||||
}
|
||||
|
||||
View<StringView> Configuration::known_fields()
|
||||
{
|
||||
static constexpr StringView known_fields[]{
|
||||
|
|
|
@ -927,7 +927,7 @@ namespace vcpkg::Install
|
|||
|
||||
LockGuardPtr<Metrics>(g_metrics)->track_property("install_manifest_mode", paths.manifest_mode_enabled());
|
||||
|
||||
if (paths.manifest_mode_enabled())
|
||||
if (auto p = paths.get_manifest().get())
|
||||
{
|
||||
bool failure = false;
|
||||
if (!args.command_arguments.empty())
|
||||
|
@ -948,7 +948,7 @@ namespace vcpkg::Install
|
|||
}
|
||||
if (failure)
|
||||
{
|
||||
msg::println(msgUsingManifestAt, msg::path = paths.get_manifest_path().value_or_exit(VCPKG_LINE_INFO));
|
||||
msg::println(msgUsingManifestAt, msg::path = p->path);
|
||||
print2("\n");
|
||||
print_usage(MANIFEST_COMMAND_STRUCTURE);
|
||||
Checks::exit_fail(VCPKG_LINE_INFO);
|
||||
|
@ -1018,8 +1018,7 @@ namespace vcpkg::Install
|
|||
LockGuardPtr<Metrics>(g_metrics)->track_property("x-write-nuget-packages-config", "defined");
|
||||
pkgsconfig = Path(it_pkgsconfig->second);
|
||||
}
|
||||
const auto& manifest_path = paths.get_manifest_path().value_or_exit(VCPKG_LINE_INFO);
|
||||
auto maybe_manifest_scf = SourceControlFile::parse_manifest_object(manifest_path, *manifest);
|
||||
auto maybe_manifest_scf = SourceControlFile::parse_manifest_object(manifest->path, manifest->manifest);
|
||||
if (!maybe_manifest_scf)
|
||||
{
|
||||
print_error_message(maybe_manifest_scf.error());
|
||||
|
@ -1030,7 +1029,7 @@ namespace vcpkg::Install
|
|||
auto& manifest_scf = *maybe_manifest_scf.value_or_exit(VCPKG_LINE_INFO);
|
||||
|
||||
if (auto maybe_error = manifest_scf.check_against_feature_flags(
|
||||
manifest_path, paths.get_feature_flags(), paths.get_registry_set().is_default_builtin_registry()))
|
||||
manifest->path, paths.get_feature_flags(), paths.get_registry_set().is_default_builtin_registry()))
|
||||
{
|
||||
Checks::exit_with_message(VCPKG_LINE_INFO, maybe_error.value_or_exit(VCPKG_LINE_INFO));
|
||||
}
|
||||
|
@ -1096,7 +1095,7 @@ namespace vcpkg::Install
|
|||
|
||||
std::vector<std::string> extended_overlay_ports;
|
||||
extended_overlay_ports.reserve(args.overlay_ports.size() + 2);
|
||||
extended_overlay_ports.push_back(manifest_path.parent_path().to_string());
|
||||
extended_overlay_ports.push_back(manifest->path.parent_path().to_string());
|
||||
Util::Vectors::append(&extended_overlay_ports, args.overlay_ports);
|
||||
if (paths.get_registry_set().is_default_builtin_registry() && !paths.use_git_default_registry())
|
||||
{
|
||||
|
|
|
@ -1246,7 +1246,7 @@ namespace vcpkg
|
|||
if (paths.use_git_default_registry())
|
||||
{
|
||||
return std::make_unique<GitRegistry>(
|
||||
paths, "https://github.com/Microsoft/vcpkg", "HEAD", std::move(baseline));
|
||||
paths, builtin_registry_git_url().to_string(), "HEAD", std::move(baseline));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -60,7 +60,7 @@ namespace
|
|||
|
||||
namespace vcpkg
|
||||
{
|
||||
static std::pair<Json::Object, Json::JsonStyle> load_manifest(const Filesystem& fs, const Path& manifest_dir)
|
||||
static ManifestAndPath load_manifest(const Filesystem& fs, const Path& manifest_dir)
|
||||
{
|
||||
std::error_code ec;
|
||||
auto manifest_path = manifest_dir / "vcpkg.json";
|
||||
|
@ -86,15 +86,15 @@ namespace vcpkg
|
|||
": Manifest files must have a top-level object\n");
|
||||
Checks::exit_fail(VCPKG_LINE_INFO);
|
||||
}
|
||||
return {std::move(manifest_value.first.object()), std::move(manifest_value.second)};
|
||||
return {std::move(manifest_value.first.object()), std::move(manifest_path)};
|
||||
}
|
||||
|
||||
static Optional<ManifestConfiguration> config_from_manifest(
|
||||
const Path& manifest_path, const Optional<std::pair<Json::Object, Json::JsonStyle>>& manifest_doc)
|
||||
static Optional<ManifestConfiguration> config_from_manifest(const Path& manifest_path,
|
||||
const Optional<ManifestAndPath>& manifest_doc)
|
||||
{
|
||||
if (auto manifest = manifest_doc.get())
|
||||
{
|
||||
return parse_manifest_configuration(manifest_path, manifest->first).value_or_exit(VCPKG_LINE_INFO);
|
||||
return parse_manifest_configuration(manifest_path, manifest->manifest).value_or_exit(VCPKG_LINE_INFO);
|
||||
}
|
||||
return nullopt;
|
||||
}
|
||||
|
@ -131,13 +131,13 @@ namespace vcpkg
|
|||
return parsed_config_opt;
|
||||
}
|
||||
|
||||
static Configuration merge_validate_configs(Optional<ManifestConfiguration>&& manifest_data,
|
||||
const Path& manifest_dir,
|
||||
Optional<Configuration>&& config_data,
|
||||
const Path& config_dir,
|
||||
const VcpkgPaths& paths)
|
||||
static ConfigurationAndSource merge_validate_configs(Optional<ManifestConfiguration>&& manifest_data,
|
||||
const Path& manifest_dir,
|
||||
Optional<Configuration>&& config_data,
|
||||
const Path& config_dir,
|
||||
const VcpkgPaths& paths)
|
||||
{
|
||||
Configuration ret;
|
||||
ConfigurationAndSource ret;
|
||||
|
||||
if (auto manifest = manifest_data.get())
|
||||
{
|
||||
|
@ -169,7 +169,7 @@ namespace vcpkg
|
|||
Checks::exit_fail(VCPKG_LINE_INFO);
|
||||
}
|
||||
|
||||
ret = std::move(*config);
|
||||
ret = ConfigurationAndSource{std::move(*config), config_dir, ConfigurationSource::ManifestFile};
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -177,7 +177,7 @@ namespace vcpkg
|
|||
{
|
||||
config->validate_as_active();
|
||||
|
||||
ret = std::move(*config);
|
||||
ret = ConfigurationAndSource{std::move(*config), config_dir, ConfigurationSource::VcpkgConfigurationFile};
|
||||
}
|
||||
|
||||
if (auto manifest = manifest_data.get())
|
||||
|
@ -195,7 +195,7 @@ namespace vcpkg
|
|||
paths.get_current_git_sha_baseline_message());
|
||||
}
|
||||
|
||||
if (ret.default_reg)
|
||||
if (ret.config.default_reg)
|
||||
{
|
||||
print2(Color::warning,
|
||||
"warning: attempting to set builtin-baseline in vcpkg.json while overriding the "
|
||||
|
@ -204,7 +204,7 @@ namespace vcpkg
|
|||
}
|
||||
else
|
||||
{
|
||||
auto& default_reg = ret.default_reg.emplace();
|
||||
auto& default_reg = ret.config.default_reg.emplace();
|
||||
default_reg.kind = "builtin";
|
||||
default_reg.baseline = std::move(*p_baseline);
|
||||
}
|
||||
|
@ -436,6 +436,7 @@ namespace vcpkg
|
|||
VcpkgPathsImpl(Filesystem& fs, const VcpkgCmdArguments& args, const Path& root, const Path& original_cwd)
|
||||
: VcpkgPathsImplStage1(fs, args, root, original_cwd)
|
||||
, m_config_dir(m_manifest_dir.empty() ? root : m_manifest_dir)
|
||||
, m_has_configuration_file(fs.exists(m_config_dir / "vcpkg-configuration.json", VCPKG_LINE_INFO))
|
||||
, m_manifest_path(m_manifest_dir.empty() ? Path{} : m_manifest_dir / "vcpkg.json")
|
||||
, m_registries_work_tree_dir(m_cache_root / "git")
|
||||
, m_registries_dot_git_dir(m_cache_root / "git" / ".git")
|
||||
|
@ -501,6 +502,7 @@ namespace vcpkg
|
|||
}
|
||||
|
||||
const Path m_config_dir;
|
||||
const bool m_has_configuration_file;
|
||||
const Path m_manifest_path;
|
||||
const Path m_registries_work_tree_dir;
|
||||
const Path m_registries_dot_git_dir;
|
||||
|
@ -513,8 +515,8 @@ namespace vcpkg
|
|||
|
||||
std::unique_ptr<IExclusiveFileLock> file_lock_handle;
|
||||
|
||||
Optional<std::pair<Json::Object, Json::JsonStyle>> m_manifest_doc;
|
||||
Configuration m_config;
|
||||
Optional<ManifestAndPath> m_manifest_doc;
|
||||
ConfigurationAndSource m_config;
|
||||
std::unique_ptr<RegistrySet> m_registry_set;
|
||||
};
|
||||
}
|
||||
|
@ -662,7 +664,7 @@ namespace vcpkg
|
|||
m_pimpl->m_config_dir,
|
||||
*this);
|
||||
|
||||
m_pimpl->m_registry_set = m_pimpl->m_config.instantiate_registry_set(*this, m_pimpl->m_config_dir);
|
||||
m_pimpl->m_registry_set = m_pimpl->m_config.instantiate_registry_set(*this);
|
||||
}
|
||||
|
||||
// metrics from configuration
|
||||
|
@ -1275,29 +1277,17 @@ namespace vcpkg
|
|||
}
|
||||
}
|
||||
|
||||
Optional<const Json::Object&> VcpkgPaths::get_manifest() const
|
||||
Optional<const ManifestAndPath&> VcpkgPaths::get_manifest() const
|
||||
{
|
||||
if (auto p = m_pimpl->m_manifest_doc.get())
|
||||
{
|
||||
return p->first;
|
||||
}
|
||||
else
|
||||
{
|
||||
return nullopt;
|
||||
}
|
||||
}
|
||||
Optional<const Path&> VcpkgPaths::get_manifest_path() const
|
||||
{
|
||||
if (m_pimpl->m_manifest_doc)
|
||||
{
|
||||
return m_pimpl->m_manifest_path;
|
||||
}
|
||||
else
|
||||
{
|
||||
return nullopt;
|
||||
return *p;
|
||||
}
|
||||
return nullopt;
|
||||
}
|
||||
|
||||
const ConfigurationAndSource& VcpkgPaths::get_configuration() const { return m_pimpl->m_config; }
|
||||
|
||||
const RegistrySet& VcpkgPaths::get_registry_set() const
|
||||
{
|
||||
Checks::check_exit(VCPKG_LINE_INFO, m_pimpl->m_registry_set != nullptr);
|
||||
|
|
Загрузка…
Ссылка в новой задаче