Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Teach x-ci-verify-versions to check that versions exist in the database #1210

Merged
merged 68 commits into from
Jun 22, 2024
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
68 commits
Select commit Hold shift + click to select a range
e7a6683
Make registries distinguish between 'baseline is broken' and 'baselin…
BillyONeal Aug 12, 2023
09e135c
Fix move on constant variable.
BillyONeal Aug 15, 2023
4d8ca9e
Fix merge conflict error.
BillyONeal Sep 19, 2023
ac43653
Merge remote-tracking branch 'origin/main' into clarify-no-baseline-v…
BillyONeal Sep 20, 2023
21bb633
Substantially overhaul how x-ci-verify-versions works:
BillyONeal Sep 21, 2023
a741b84
Teach vcpkg to find bogus version constraints and overrides that are …
BillyONeal Sep 23, 2023
d9dcaae
Clarify that source_location is path to CONTROL, not port_directory.
BillyONeal Sep 26, 2023
1e9673c
Fix e2e test failures by also making JSON parse errors print the file…
BillyONeal Sep 27, 2023
40bdceb
Fix output claiming that a port isn't in the versions database when i…
BillyONeal Sep 27, 2023
7b3682f
oops
BillyONeal Sep 27, 2023
13a30de
oops2
BillyONeal Sep 27, 2023
8dd6ad8
Try to workaround macos compile failure by just not providing copy op…
BillyONeal Sep 27, 2023
9ad36ac
Merge remote-tracking branch 'origin/main' into version-verification
BillyONeal Sep 27, 2023
b094ab1
Get rid of one more CONTROL/vcpkg.json tester by using git_checkout_p…
BillyONeal Sep 27, 2023
58452c1
Print success and failure messages at the same time and deduplicate g…
BillyONeal Sep 27, 2023
dac383c
Add comment explaining funny output.
BillyONeal Sep 27, 2023
8786bab
Deduplicate 'failed to load port' message.
BillyONeal Sep 28, 2023
de7428c
Add a notice of which version we are loading back.
BillyONeal Sep 28, 2023
68122ce
Fix crash while parsing malformed manifest files.
BillyONeal Sep 28, 2023
b04a5b2
Remove semantic constraints on the deserialized type and add specific…
BillyONeal Sep 29, 2023
43c98e5
Merge remote-tracking branch 'origin/main' into clarify-no-baseline-v…
BillyONeal Sep 29, 2023
38f738d
Code review feedback
BillyONeal Sep 29, 2023
80fa913
Make the e2e tests into unit tests and make the errors a bit prettier.
BillyONeal Sep 29, 2023
918269b
Burninate Expr::Empty
BillyONeal Sep 29, 2023
7f9ac40
Merge remote-tracking branch 'origin/main' into add-error-for-bad-dep…
BillyONeal Sep 30, 2023
582382f
Code review feedback
BillyONeal Sep 30, 2023
09cbd98
Merge branch 'clarify-no-baseline-vs-error' into version-verification
BillyONeal Sep 30, 2023
580244c
Merge branch 'add-error-for-bad-dependency-features' into version-ver…
BillyONeal Sep 30, 2023
b2a6334
Fix merge conflicts
BillyONeal Sep 30, 2023
ae5300b
Restore spdx_location.
BillyONeal Sep 30, 2023
e2f38d8
Add end to end tests and make errors more pretty.
BillyONeal Sep 30, 2023
cdcbfb5
Tolerate no user.name etc.
BillyONeal Sep 30, 2023
5c26031
Fix registries test that tried to set --x-builtin-registry-versions-d…
BillyONeal Sep 30, 2023
fd4e9c4
Merge remote-tracking branch 'origin/main' into version-verification
BillyONeal Oct 2, 2023
c77b92b
Also fix broken versions e2e tests.
BillyONeal Oct 2, 2023
89e216e
Attempt better *nix defenses
BillyONeal Oct 2, 2023
78c4aaf
Try to sanitize whitespace
BillyONeal Oct 2, 2023
0dd96ee
clang-format
BillyONeal Oct 2, 2023
ede9734
Merge remote-tracking branch 'origin/main' into version-verification
BillyONeal Oct 10, 2023
70e914b
Collapse out a few more maybe_maybes and respond to comments of https…
BillyONeal Oct 10, 2023
57340d0
Reduce join() code size after discussion with @JavierMatosD
BillyONeal Oct 10, 2023
251334b
Fix macos error and use lookup_in_maybe_baseline in one more place.
BillyONeal Oct 10, 2023
d5e4042
Fix output nitpicks
BillyONeal Oct 10, 2023
95936ec
Change all errors to always print paths at the beginning of a line
BillyONeal Oct 10, 2023
1cfa496
Fixed 2 missing then patterns
BillyONeal Oct 10, 2023
f7a9589
Add diff output on test failure
BillyONeal Oct 10, 2023
392a47c
Try to fix linux and macos diffing
BillyONeal Oct 10, 2023
6a7bbd2
Merge remote-tracking branch 'origin/main' into version-verification
BillyONeal Oct 10, 2023
afdbeea
Merge remote-tracking branch 'origin/main' into version-verification
BillyONeal Oct 18, 2023
903cb74
Ensure spdx_location is not dropped when loading ports.
BillyONeal Oct 18, 2023
a4b7fa1
Use SchemedVersion in DependencyOverride rather than reinventing it.
BillyONeal Oct 18, 2023
db17508
Back off to Version given that the scheme is not significant to overr…
BillyONeal Oct 19, 2023
36b33a2
Merge remote-tracking branch 'BillyONeal/use-schemed-version' into ve…
BillyONeal Oct 20, 2023
2291b0a
Merge remote-tracking branch 'origin/main' into version-verification
BillyONeal Oct 24, 2023
dc0110e
Merge remote-tracking branch 'origin/main' into spdx_location
BillyONeal Oct 26, 2023
a18997b
Persist the correct path.
BillyONeal Oct 26, 2023
6e794ec
Code review feedback from 2023-10-26.
BillyONeal Oct 28, 2023
a922e76
Merge remote-tracking branch 'origin/main' into spdx_location
BillyONeal Nov 4, 2023
4434e81
Merge remote-tracking branch 'origin/main' into spdx_location
BillyONeal Nov 7, 2023
b70ddbe
Merge branch 'spdx_location' into version-verification
BillyONeal Nov 7, 2023
570d2f3
Merge gore. Not sure if I want to keep format-manifest changes lookin…
BillyONeal Nov 7, 2023
b195ca2
Merge remote-tracking branch 'origin/main' into version-verification
BillyONeal Nov 10, 2023
696c90d
Merge gore
BillyONeal Nov 10, 2023
f38ed65
Merge remote-tracking branch 'origin/main' into version-verification
BillyONeal Nov 16, 2023
d3d53c9
Merge remote-tracking branch 'origin/main' into version-verification
BillyONeal Jun 7, 2024
fa86593
Revert the `ReaderMessage` part of the change which became https://gi…
BillyONeal Jun 7, 2024
3d2f9b0
Remove unused messages.
BillyONeal Jun 7, 2024
c2e82e5
Merge remote-tracking branch 'origin/main' into version-verification
BillyONeal Jun 21, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions include/vcpkg/base/expected.h
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,12 @@ namespace vcpkg
return std::move(*m_t.get());
}

Error& error() &
{
unreachable_if_not_error(VCPKG_LINE_INFO);
return m_error;
}

const Error& error() const&
{
unreachable_if_not_error(VCPKG_LINE_INFO);
Expand All @@ -232,6 +238,12 @@ namespace vcpkg
return std::move(m_error);
}

const Error&& error() const&&
{
unreachable_if_not_error(VCPKG_LINE_INFO);
return std::move(m_error);
}

typename ExpectedHolder<T>::const_pointer get() const noexcept
{
if (value_is_error)
Expand Down
30 changes: 23 additions & 7 deletions include/vcpkg/base/jsonreader.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include <vcpkg/base/fwd/json.h>
#include <vcpkg/base/fwd/parse.h>

#include <vcpkg/base/chrono.h>
#include <vcpkg/base/json.h>
Expand Down Expand Up @@ -42,29 +43,43 @@ namespace vcpkg::Json
IDeserializer& operator=(IDeserializer&&) = default;
};

struct ReaderMessage
{
MessageKind kind;
LocalizedString message;

ReaderMessage(MessageKind kind, LocalizedString&& message);
ReaderMessage(const ReaderMessage&);
ReaderMessage(ReaderMessage&&);
ReaderMessage& operator=(const ReaderMessage&);
ReaderMessage& operator=(ReaderMessage&&);
};

LocalizedString join(const std::vector<ReaderMessage>& messages);
LocalizedString flatten_reader_messages(const std::vector<ReaderMessage>& messages, MessageSink& warningsSink);

struct Reader
{
Reader();
explicit Reader(StringView origin);

const std::vector<LocalizedString>& errors() const { return m_errors; }
const std::vector<ReaderMessage>& messages() const { return m_messages; }
std::size_t error_count() const { return m_error_count; }

void add_missing_field_error(const LocalizedString& type, StringView key, const LocalizedString& key_type);
void add_expected_type_error(const LocalizedString& expected_type);
void add_extra_field_error(const LocalizedString& type, StringView fields, StringView suggestion = {});
void add_generic_error(const LocalizedString& type, LocalizedString&& message);
void add_generic_error(const LocalizedString& type, StringView message);

void add_warning(LocalizedString type, StringView msg);

const std::vector<LocalizedString>& warnings() const { return m_warnings; }

std::string path() const noexcept;

private:
template<class Type>
friend struct IDeserializer;

std::vector<LocalizedString> m_errors;
std::vector<LocalizedString> m_warnings;
std::vector<ReaderMessage> m_messages;
std::size_t m_error_count;
struct JsonPathElement
{
constexpr JsonPathElement() = default;
Expand All @@ -88,6 +103,7 @@ namespace vcpkg::Json
std::vector<JsonPathElement>& m_path;
};

StringView m_origin;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
StringView m_origin;
std::string m_origin;

std::vector<JsonPathElement> m_path;

public:
Expand Down
150 changes: 81 additions & 69 deletions include/vcpkg/base/message-data.inc.h

Large diffs are not rendered by default.

29 changes: 22 additions & 7 deletions include/vcpkg/base/messages.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,27 +84,42 @@ namespace vcpkg
static LocalizedString from_raw(std::basic_string<T>&& s) noexcept;
static LocalizedString from_raw(StringView s);

LocalizedString& append_raw(char c);
LocalizedString& append_raw(StringView s);
LocalizedString& append_raw(char c) &;
LocalizedString&& append_raw(char c) &&;
LocalizedString& append_raw(StringView s) &;
LocalizedString&& append_raw(StringView s) &&;
template<class T, class = decltype(std::declval<const T&>().to_string(std::declval<std::string&>()))>
LocalizedString& append_raw(const T& s)
LocalizedString& append_raw(const T& s) &
{
s.to_string(m_data);
return *this;
}
LocalizedString& append(const LocalizedString& s);
template<class T, class = decltype(std::declval<const T&>().to_string(std::declval<std::string&>()))>
LocalizedString&& append_raw(const T& s) &&
{
return std::move(append_raw(s));
}
LocalizedString& append(const LocalizedString& s) &;
LocalizedString&& append(const LocalizedString& s) &&;
template<VCPKG_DECL_MSG_TEMPLATE>
LocalizedString& append(VCPKG_DECL_MSG_ARGS)
LocalizedString& append(VCPKG_DECL_MSG_ARGS) &
{
msg::format_to(*this, VCPKG_EXPAND_MSG_ARGS);
return *this;
}
LocalizedString& append_indent(size_t indent = 1);
template<VCPKG_DECL_MSG_TEMPLATE>
LocalizedString&& append(VCPKG_DECL_MSG_ARGS) &&
{
return std::move(append(VCPKG_EXPAND_MSG_ARGS));
}
LocalizedString& append_indent(size_t indent = 1) &;
LocalizedString&& append_indent(size_t indent = 1) &&;

// 0 items - Does nothing
// 1 item - .append_raw(' ').append(item)
// 2+ items - foreach: .append_raw('\n').append_indent(indent).append(item)
LocalizedString& append_floating_list(int indent, View<LocalizedString> items);
LocalizedString& append_floating_list(int indent, View<LocalizedString> items) &;
LocalizedString&& append_floating_list(int indent, View<LocalizedString> items) &&;
friend bool operator==(const LocalizedString& lhs, const LocalizedString& rhs) noexcept;
friend bool operator!=(const LocalizedString& lhs, const LocalizedString& rhs) noexcept;
friend bool operator<(const LocalizedString& lhs, const LocalizedString& rhs) noexcept;
Expand Down
2 changes: 1 addition & 1 deletion include/vcpkg/base/strings.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ namespace vcpkg::Strings
if (first != last)
{
Strings::append(output, transformer(*first));
for (++first; first != last; ++first)
while (++first != last)
{
output.append(delimiter.data(), delimiter.size());
Strings::append(output, transformer(*first));
Expand Down
6 changes: 6 additions & 0 deletions include/vcpkg/base/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,12 @@ namespace vcpkg::Util
return std::any_of(rng.begin(), rng.end(), std::move(pred));
}

template<class Range, class Pred>
bool none_of(Range&& rng, Pred pred)
{
return std::none_of(rng.begin(), rng.end(), std::move(pred));
}

template<class Range, class Comp = std::less<>>
Range&& sort_unique_erase(Range&& cont, Comp comp = Comp())
{
Expand Down
4 changes: 2 additions & 2 deletions include/vcpkg/paragraphparser.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,11 @@ namespace vcpkg
using ParseExpected = vcpkg::ExpectedT<std::unique_ptr<P>, std::unique_ptr<ParseControlErrorInfo>>;

template<class P>
ExpectedL<P> map_parse_expected_to_localized_string(ParseExpected<P>&& parse_expected)
ExpectedL<std::unique_ptr<P>> map_parse_expected_to_localized_string(ParseExpected<P>&& parse_expected)
{
if (auto value = parse_expected.get())
{
return std::move(**value);
return std::move(*value);
}

return LocalizedString::from_raw(parse_expected.error()->to_string());
Expand Down
32 changes: 26 additions & 6 deletions include/vcpkg/paragraphs.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,13 @@
#include <vcpkg/fwd/registries.h>

#include <vcpkg/base/expected.h>
#include <vcpkg/base/stringview.h>

#include <vcpkg/sourceparagraph.h>

#include <utility>
#include <vector>

namespace vcpkg::Paragraphs
{
uint64_t get_load_ports_stats();
Expand All @@ -22,11 +26,27 @@ namespace vcpkg::Paragraphs

bool is_port_directory(const ReadOnlyFilesystem& fs, const Path& maybe_directory);

ParseExpected<SourceControlFile> try_load_port(const ReadOnlyFilesystem& fs, const Path& port_directory);
ParseExpected<SourceControlFile> try_load_port_text(const std::string& text,
StringView origin,
bool is_manifest,
MessageSink& warning_sink);
struct PortLoadResult
{
ExpectedL<SourceControlFileAndLocation> maybe_scfl;
std::string on_disk_contents;
};

// If an error occurs, the Expected will be in the error state.
// Otherwise, if the port is known, the maybe_scfl->source_control_file contains the loaded port information.
// Otherwise, maybe_scfl->source_control_file is nullptr.
PortLoadResult try_load_port(const ReadOnlyFilesystem& fs, StringView port_name, const Path& port_directory);
// Identical to try_load_port, but the port unknown condition is mapped to an error.
PortLoadResult try_load_port_required(const ReadOnlyFilesystem& fs,
StringView port_name,
const Path& port_directory);
ExpectedL<SourceControlFileAndLocation> try_load_project_manifest_text(StringView text,
StringView origin,
MessageSink& warning_sink);
ExpectedL<SourceControlFileAndLocation> try_load_port_manifest_text(StringView text,
StringView origin,
MessageSink& warning_sink);
ExpectedL<SourceControlFileAndLocation> try_load_control_file_text(StringView text, StringView origin);

ExpectedL<BinaryControlFile> try_load_cached_package(const ReadOnlyFilesystem& fs,
const Path& package_dir,
Expand All @@ -35,7 +55,7 @@ namespace vcpkg::Paragraphs
struct LoadResults
{
std::vector<SourceControlFileAndLocation> paragraphs;
std::vector<std::unique_ptr<ParseControlErrorInfo>> errors;
std::vector<std::pair<std::string, LocalizedString>> errors;
};

LoadResults try_load_all_registry_ports(const ReadOnlyFilesystem& fs, const RegistrySet& registries);
Expand Down
70 changes: 54 additions & 16 deletions include/vcpkg/registries.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
#include <map>
#include <memory>
#include <string>
#include <system_error>
#include <vector>

namespace vcpkg
Expand Down Expand Up @@ -76,19 +75,24 @@ namespace vcpkg
{
virtual StringLiteral kind() const = 0;

// returns nullptr if the port doesn't exist
// If an error occurs, the ExpectedL will be in an error state.
// Otherwise, if the port is known, returns a pointer to RegistryEntry describing the port.
// Otherwise, returns a nullptr unique_ptr.
virtual ExpectedL<std::unique_ptr<RegistryEntry>> get_port_entry(StringView port_name) const = 0;

// appends the names of the ports to the out parameter
// may result in duplicated port names; make sure to Util::sort_unique_erase at the end
// Appends the names of the known ports to the out parameter.
// May result in duplicated port names; make sure to Util::sort_unique_erase at the end
virtual ExpectedL<Unit> append_all_port_names(std::vector<std::string>& port_names) const = 0;

// appends the names of the ports to the out parameter if this can be known without
// Appends the names of the ports to the out parameter if this can be known without
// network access.
// returns true if names were appended, otherwise returns false.
// Returns true iff names were appended.
virtual ExpectedL<bool> try_append_all_port_names_no_network(std::vector<std::string>& port_names) const = 0;

virtual ExpectedL<Version> get_baseline_version(StringView port_name) const = 0;
// If an error occurs, the ExpectedL will be in an error state.
// Otherwise, if the port is in the baseline, returns the version that baseline denotes.
// Otherwise, the Optional is disengaged.
virtual ExpectedL<Optional<Version>> get_baseline_version(StringView port_name) const = 0;

virtual ~RegistryImplementation() = default;
};
Expand Down Expand Up @@ -130,7 +134,7 @@ namespace vcpkg
// the returned list is sorted by priority.
std::vector<const RegistryImplementation*> registries_for_port(StringView name) const;

ExpectedL<Version> baseline_for_port(StringView port_name) const;
ExpectedL<Optional<Version>> baseline_for_port(StringView port_name) const;

View<Registry> registries() const { return registries_; }

Expand Down Expand Up @@ -170,24 +174,58 @@ namespace vcpkg
std::string git_tree;
};

ExpectedL<Optional<std::vector<GitVersionDbEntry>>> get_builtin_versions(const VcpkgPaths& paths,
StringView port_name);
struct GitVersionsLoadResult
{
// If the versions database file does not exist, a disengaged Optional
// Otherwise, if a file I/O error occurred or the file is malformed, that error
// Otherwise, the loaded version database records
ExpectedL<Optional<std::vector<GitVersionDbEntry>>> entries;
Path versions_file_path;
};

ExpectedL<std::map<std::string, Version, std::less<>>> get_builtin_baseline(const VcpkgPaths& paths);
GitVersionsLoadResult load_git_versions_file(const ReadOnlyFilesystem& fs,
const Path& registry_versions,
StringView port_name);

bool is_git_commit_sha(StringView sv);
struct FullGitVersionsDatabase
{
explicit FullGitVersionsDatabase(const ReadOnlyFilesystem& fs,
const Path& registry_versions,
std::map<std::string, GitVersionsLoadResult, std::less<>>&& initial);
FullGitVersionsDatabase(FullGitVersionsDatabase&&);
FullGitVersionsDatabase& operator=(FullGitVersionsDatabase&&);

// Returns the effective match length of the package pattern `pattern` against `name`.
// No match is 0, exact match is SIZE_MAX, wildcard match is the length of the pattern.
// Note that the * is included in the match size to distinguish from 0 == no match.
size_t package_pattern_match(StringView name, StringView pattern);
const GitVersionsLoadResult& lookup(StringView port_name);
const std::map<std::string, GitVersionsLoadResult, std::less<>>& cache() const;

private:
const ReadOnlyFilesystem* m_fs;
Path m_registry_versions;
std::map<std::string, GitVersionsLoadResult, std::less<>> m_cache;
};

// The outer expected only contains directory enumeration errors; individual parse errors are within
ExpectedL<FullGitVersionsDatabase> load_all_git_versions_files(const ReadOnlyFilesystem& fs,
const Path& registry_versions);

struct FilesystemVersionDbEntry
{
SchemedVersion version;
Path p;
};

ExpectedL<Optional<std::vector<FilesystemVersionDbEntry>>> load_filesystem_versions_file(
const ReadOnlyFilesystem& fs, const Path& registry_versions, StringView port_name, const Path& registry_root);

ExpectedL<std::map<std::string, Version, std::less<>>> get_builtin_baseline(const VcpkgPaths& paths);

bool is_git_commit_sha(StringView sv);

// Returns the effective match length of the package pattern `pattern` against `name`.
// No match is 0, exact match is SIZE_MAX, wildcard match is the length of the pattern.
// Note that the * is included in the match size to distinguish from 0 == no match.
size_t package_pattern_match(StringView name, StringView pattern);

std::unique_ptr<Json::IDeserializer<std::vector<GitVersionDbEntry>>> make_git_version_db_deserializer();
std::unique_ptr<Json::IDeserializer<std::vector<FilesystemVersionDbEntry>>> make_filesystem_version_db_deserializer(
const Path& root);
Expand Down
Loading