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

Support Azure universal packages as a binary caching provider #1491

Merged
merged 6 commits into from
Oct 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
15 changes: 15 additions & 0 deletions include/vcpkg/base/message-data.inc.h
Original file line number Diff line number Diff line change
Expand Up @@ -1477,6 +1477,12 @@ DECLARE_MESSAGE(HelpBinaryCachingAzBlob,
"**Experimental: will change or be removed without warning**\n"
"Adds an Azure Blob Storage source. Uses Shared Access Signature validation. <url> should include "
"the container path. <sas> must be be prefixed with a \"?\".")
DECLARE_MESSAGE(HelpBinaryCachingAzUpkg,
(),
"Printed as the 'definition' for 'x-az-universal,<organization>,<project>,<feed>[,<rw>]'.",
"**Experimental: will change or be removed without warning**\n"
"Adds a Universal Package Azure Artifacts source. Uses the Azure CLI "
"(az artifacts) for uploads and downloads.")
DECLARE_MESSAGE(HelpBinaryCachingCos,
(),
"Printed as the 'definition' for 'x-cos,<prefix>[,<rw>]'.",
Expand Down Expand Up @@ -1798,6 +1804,10 @@ DECLARE_MESSAGE(InvalidArgumentRequiresBaseUrlAndToken,
(msg::binary_source),
"",
"invalid argument: binary config '{binary_source}' requires at least a base-url and a SAS token")
DECLARE_MESSAGE(InvalidArgumentRequiresFourOrFiveArguments,
(msg::binary_source),
"",
"invalid argument: binary config '{binary_source}' requires 4 or 5 arguments")
DECLARE_MESSAGE(InvalidArgumentRequiresNoneArguments,
(msg::binary_source),
"",
Expand Down Expand Up @@ -2559,6 +2569,11 @@ DECLARE_MESSAGE(RestoredPackagesFromAWS,
(msg::count, msg::elapsed),
"",
"Restored {count} package(s) from AWS in {elapsed}. Use --debug to see more details.")
DECLARE_MESSAGE(RestoredPackagesFromAZUPKG,
(msg::count, msg::elapsed),
"",
"Restored {count} package(s) from Universal Packages in {elapsed}. "
"Use --debug to see more details.")
DECLARE_MESSAGE(RestoredPackagesFromCOS,
(msg::count, msg::elapsed),
"",
Expand Down
10 changes: 10 additions & 0 deletions include/vcpkg/binarycaching.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,13 @@ namespace vcpkg
std::string commit;
};

struct AzureUpkgSource
{
std::string organization;
std::string project;
std::string feed;
};

struct BinaryConfigParserState
{
bool nuget_interactive = false;
Expand All @@ -147,6 +154,9 @@ namespace vcpkg
bool gha_write = false;
bool gha_read = false;

std::vector<AzureUpkgSource> upkg_templates_to_get;
std::vector<AzureUpkgSource> upkg_templates_to_put;

std::vector<std::string> sources_to_read;
std::vector<std::string> sources_to_write;

Expand Down
8 changes: 4 additions & 4 deletions include/vcpkg/binarycaching.private.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,19 @@ namespace vcpkg
// - v?<X>.<Y><whatever> -> <X>.<Y>.0-vcpkg<abitag>
// - v?<X>.<Y>.<Z><whatever> -> <X>.<Y>.<Z>-vcpkg<abitag>
// - anything else -> 0.0.0-vcpkg<abitag>
std::string format_version_for_nugetref(StringView version_text, StringView abi_tag);
std::string format_version_for_feedref(StringView version_text, StringView abi_tag);

struct NugetReference
struct FeedReference
{
NugetReference(std::string id, std::string version) : id(std::move(id)), version(std::move(version)) { }
FeedReference(std::string id, std::string version) : id(std::move(id)), version(std::move(version)) { }

std::string id;
std::string version;

std::string nupkg_filename() const { return Strings::concat(id, '.', version, ".nupkg"); }
};

NugetReference make_nugetref(const InstallPlanAction& action, StringView prefix);
FeedReference make_nugetref(const InstallPlanAction& action, StringView prefix);

std::string generate_nuspec(const Path& package_dir,
const InstallPlanAction& action,
Expand Down
1 change: 1 addition & 0 deletions include/vcpkg/metrics.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ namespace vcpkg
BinaryCachingHttp,
BinaryCachingNuget,
BinaryCachingSource,
BinaryCachingUpkg,
ErrorVersioningDisabled,
ErrorVersioningNoBaseline,
GitHubRepository,
Expand Down
6 changes: 6 additions & 0 deletions include/vcpkg/tools.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ namespace vcpkg
static constexpr StringLiteral GIT = "git";
static constexpr StringLiteral GSUTIL = "gsutil";
static constexpr StringLiteral AWSCLI = "aws";
static constexpr StringLiteral AZCLI = "az";
static constexpr StringLiteral COSCLI = "coscli";
static constexpr StringLiteral MONO = "mono";
static constexpr StringLiteral NINJA = "ninja";
Expand All @@ -46,6 +47,11 @@ namespace vcpkg
virtual const std::string& get_tool_version(StringView tool, MessageSink& status_sink) const = 0;
};

ExpectedL<std::string> extract_prefixed_nonquote(StringLiteral prefix,
StringLiteral tool_name,
std::string&& output,
const Path& exe_path);

ExpectedL<std::string> extract_prefixed_nonwhitespace(StringLiteral prefix,
StringLiteral tool_name,
std::string&& output,
Expand Down
6 changes: 6 additions & 0 deletions locales/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -854,6 +854,8 @@
"HelpBinaryCachingAwsHeader": "Azure Web Services sources",
"HelpBinaryCachingAzBlob": "**Experimental: will change or be removed without warning**\nAdds an Azure Blob Storage source. Uses Shared Access Signature validation. <url> should include the container path. <sas> must be be prefixed with a \"?\".",
"_HelpBinaryCachingAzBlob.comment": "Printed as the 'definition' for 'x-azblob,<url>,<sas>[,<rw>]'.",
"HelpBinaryCachingAzUpkg": "**Experimental: will change or be removed without warning**\nAdds a Universal Package Azure Artifacts source. Uses the Azure CLI (az artifacts) for uploads and downloads.",
"_HelpBinaryCachingAzUpkg.comment": "Printed as the 'definition' for 'x-az-universal,<organization>,<project>,<feed>[,<rw>]'.",
"HelpBinaryCachingCos": "**Experimental: will change or be removed without warning**\nAdds an COS source. Uses the cos CLI for uploads and downloads. <prefix> should include the scheme 'cos://' and be suffixed with a \"/\".",
"_HelpBinaryCachingCos.comment": "Printed as the 'definition' for 'x-cos,<prefix>[,<rw>]'.",
"HelpBinaryCachingDefaults": "Adds the default file-based location. Based on your system settings, the default path to store binaries is \"{path}\". This consults %LOCALAPPDATA%/%APPDATA% on Windows and $XDG_CACHE_HOME or $HOME on other platforms.",
Expand Down Expand Up @@ -993,6 +995,8 @@
"_InvalidArgumentRequiresBaseUrl.comment": "An example of {base_url} is azblob://. An example of {binary_source} is azblob.",
"InvalidArgumentRequiresBaseUrlAndToken": "invalid argument: binary config '{binary_source}' requires at least a base-url and a SAS token",
"_InvalidArgumentRequiresBaseUrlAndToken.comment": "An example of {binary_source} is azblob.",
"InvalidArgumentRequiresFourOrFiveArguments": "invalid argument: binary config '{binary_source}' requires 4 or 5 arguments",
"_InvalidArgumentRequiresFourOrFiveArguments.comment": "An example of {binary_source} is azblob.",
"InvalidArgumentRequiresNoWildcards": "cannot fix Windows path case for path containing wildcards: {path}",
"_InvalidArgumentRequiresNoWildcards.comment": "An example of {path} is /foo/bar.",
"InvalidArgumentRequiresNoneArguments": "invalid argument: binary config '{binary_source}' does not take arguments",
Expand Down Expand Up @@ -1354,6 +1358,8 @@
"_ResponseFileCode.comment": "Explains to the user that they can use response files on the command line, 'response_file' must have no spaces and be a legal file name.",
"RestoredPackagesFromAWS": "Restored {count} package(s) from AWS in {elapsed}. Use --debug to see more details.",
"_RestoredPackagesFromAWS.comment": "An example of {count} is 42. An example of {elapsed} is 3.532 min.",
"RestoredPackagesFromAZUPKG": "Restored {count} package(s) from Universal Packages in {elapsed}. Use --debug to see more details.",
"_RestoredPackagesFromAZUPKG.comment": "An example of {count} is 42. An example of {elapsed} is 3.532 min.",
"RestoredPackagesFromCOS": "Restored {count} package(s) from COS in {elapsed}. Use --debug to see more details.",
"_RestoredPackagesFromCOS.comment": "An example of {count} is 42. An example of {elapsed} is 3.532 min.",
"RestoredPackagesFromFiles": "Restored {count} package(s) from {path} in {elapsed}. Use --debug to see more details.",
Expand Down
38 changes: 19 additions & 19 deletions src/vcpkg-test/binarycaching.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -166,30 +166,30 @@ TEST_CASE ("CacheStatus operations", "[BinaryCache]")
REQUIRE(assignee.is_restored());
}

TEST_CASE ("format_version_for_nugetref semver-ish", "[format_version_for_nugetref]")
TEST_CASE ("format_version_for_feedref semver-ish", "[format_version_for_feedref]")
{
REQUIRE(format_version_for_nugetref("0.0.0", "abitag") == "0.0.0-vcpkgabitag");
REQUIRE(format_version_for_nugetref("1.0.1", "abitag") == "1.0.1-vcpkgabitag");
REQUIRE(format_version_for_nugetref("1.01.000", "abitag") == "1.1.0-vcpkgabitag");
REQUIRE(format_version_for_nugetref("1.2", "abitag") == "1.2.0-vcpkgabitag");
REQUIRE(format_version_for_nugetref("v52", "abitag") == "52.0.0-vcpkgabitag");
REQUIRE(format_version_for_nugetref("v09.01.02", "abitag") == "9.1.2-vcpkgabitag");
REQUIRE(format_version_for_nugetref("1.1.1q", "abitag") == "1.1.1-vcpkgabitag");
REQUIRE(format_version_for_nugetref("1", "abitag") == "1.0.0-vcpkgabitag");
REQUIRE(format_version_for_feedref("0.0.0", "abitag") == "0.0.0-vcpkgabitag");
REQUIRE(format_version_for_feedref("1.0.1", "abitag") == "1.0.1-vcpkgabitag");
REQUIRE(format_version_for_feedref("1.01.000", "abitag") == "1.1.0-vcpkgabitag");
REQUIRE(format_version_for_feedref("1.2", "abitag") == "1.2.0-vcpkgabitag");
REQUIRE(format_version_for_feedref("v52", "abitag") == "52.0.0-vcpkgabitag");
REQUIRE(format_version_for_feedref("v09.01.02", "abitag") == "9.1.2-vcpkgabitag");
REQUIRE(format_version_for_feedref("1.1.1q", "abitag") == "1.1.1-vcpkgabitag");
REQUIRE(format_version_for_feedref("1", "abitag") == "1.0.0-vcpkgabitag");
}

TEST_CASE ("format_version_for_nugetref date", "[format_version_for_nugetref]")
TEST_CASE ("format_version_for_feedref date", "[format_version_for_feedref]")
{
REQUIRE(format_version_for_nugetref("2020-06-26", "abitag") == "2020.6.26-vcpkgabitag");
REQUIRE(format_version_for_nugetref("20-06-26", "abitag") == "0.0.0-vcpkgabitag");
REQUIRE(format_version_for_nugetref("2020-06-26-release", "abitag") == "2020.6.26-vcpkgabitag");
REQUIRE(format_version_for_nugetref("2020-06-26000", "abitag") == "2020.6.26-vcpkgabitag");
REQUIRE(format_version_for_feedref("2020-06-26", "abitag") == "2020.6.26-vcpkgabitag");
REQUIRE(format_version_for_feedref("20-06-26", "abitag") == "0.0.0-vcpkgabitag");
REQUIRE(format_version_for_feedref("2020-06-26-release", "abitag") == "2020.6.26-vcpkgabitag");
REQUIRE(format_version_for_feedref("2020-06-26000", "abitag") == "2020.6.26-vcpkgabitag");
}

TEST_CASE ("format_version_for_nugetref generic", "[format_version_for_nugetref]")
TEST_CASE ("format_version_for_feedref generic", "[format_version_for_feedref]")
{
REQUIRE(format_version_for_nugetref("apr", "abitag") == "0.0.0-vcpkgabitag");
REQUIRE(format_version_for_nugetref("", "abitag") == "0.0.0-vcpkgabitag");
REQUIRE(format_version_for_feedref("apr", "abitag") == "0.0.0-vcpkgabitag");
REQUIRE(format_version_for_feedref("", "abitag") == "0.0.0-vcpkgabitag");
}

TEST_CASE ("generate_nuspec", "[generate_nuspec]")
Expand Down Expand Up @@ -236,11 +236,11 @@ Build-Depends: bzip
compiler_info.version = "compilerversion";
ipa.abi_info.get()->compiler_info = compiler_info;

NugetReference ref2 = make_nugetref(ipa, "prefix_");
FeedReference ref2 = make_nugetref(ipa, "prefix_");

REQUIRE(ref2.nupkg_filename() == "prefix_zlib2_x64-windows.1.5.0-vcpkgpackageabi.nupkg");

NugetReference ref = make_nugetref(ipa, "");
FeedReference ref = make_nugetref(ipa, "");

REQUIRE(ref.nupkg_filename() == "zlib2_x64-windows.1.5.0-vcpkgpackageabi.nupkg");

Expand Down
36 changes: 36 additions & 0 deletions src/vcpkg-test/configparser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -560,6 +560,42 @@ TEST_CASE ("BinaryConfigParser HTTP provider", "[binaryconfigparser]")
}
}

TEST_CASE ("BinaryConfigParser Universal Packages provider", "[binaryconfigparser]")
{
// Scheme: x-az-universal,<organization>,<project>,<feed>[,<readwrite>]
{
auto parsed =
parse_binary_provider_configs("x-az-universal,test_organization,test_project_name,test_feed,read", {});
auto state = parsed.value_or_exit(VCPKG_LINE_INFO);
REQUIRE(state.upkg_templates_to_get.size() == 1);
REQUIRE(state.upkg_templates_to_get[0].feed == "test_feed");
REQUIRE(state.upkg_templates_to_get[0].organization == "test_organization");
REQUIRE(state.upkg_templates_to_get[0].project == "test_project_name");
}
{
auto parsed =
parse_binary_provider_configs("x-az-universal,test_organization,test_project_name,test_feed,readwrite", {});
auto state = parsed.value_or_exit(VCPKG_LINE_INFO);
REQUIRE(state.upkg_templates_to_get.size() == 1);
REQUIRE(state.upkg_templates_to_put.size() == 1);
REQUIRE(state.upkg_templates_to_get[0].feed == "test_feed");
REQUIRE(state.upkg_templates_to_get[0].organization == "test_organization");
REQUIRE(state.upkg_templates_to_get[0].project == "test_project_name");
REQUIRE(state.upkg_templates_to_put[0].feed == "test_feed");
REQUIRE(state.upkg_templates_to_put[0].organization == "test_organization");
REQUIRE(state.upkg_templates_to_put[0].project == "test_project_name");
}
{
auto parsed = parse_binary_provider_configs(
"x-az-universal,test_organization,test_project_name,test_feed,extra_argument,readwrite", {});
REQUIRE(!parsed.has_value());
}
{
auto parsed = parse_binary_provider_configs("x-az-universal,missing_args,read", {});
REQUIRE(!parsed.has_value());
}
}

TEST_CASE ("AssetConfigParser azurl provider", "[assetconfigparser]")
{
CHECK(parse_download_configuration({}));
Expand Down
12 changes: 12 additions & 0 deletions src/vcpkg-test/tools.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,3 +128,15 @@ TEST_CASE ("extract_prefixed_nonwhitespace", "[tools]")
CHECK(error_result.error() == "error: fooutil (fooutil.exe) produced unexpected output when attempting to "
"determine the version:\nmalformed output");
}

TEST_CASE ("extract_prefixed_nonquote", "[tools]")
{
CHECK(extract_prefixed_nonquote("fooutil version ", "fooutil", "fooutil version 1.2\"", "fooutil.exe")
.value_or_exit(VCPKG_LINE_INFO) == "1.2");
CHECK(extract_prefixed_nonquote("fooutil version ", "fooutil", "fooutil version 1.2 \" ", "fooutil.exe")
.value_or_exit(VCPKG_LINE_INFO) == "1.2 ");
auto error_result = extract_prefixed_nonquote("fooutil version ", "fooutil", "malformed output", "fooutil.exe");
CHECK(!error_result.has_value());
CHECK(error_result.error() == "error: fooutil (fooutil.exe) produced unexpected output when attempting to "
"determine the version:\nmalformed output");
}
Loading
Loading