Skip to content

Commit 67931f1

Browse files
authored
Support Azure universal packages as a binary caching provider (#1491)
* add universal support * fix * fix * review * review * fix
1 parent 7869ef3 commit 67931f1

File tree

12 files changed

+364
-38
lines changed

12 files changed

+364
-38
lines changed

include/vcpkg/base/message-data.inc.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1490,6 +1490,12 @@ DECLARE_MESSAGE(HelpBinaryCachingAzBlob,
14901490
"**Experimental: will change or be removed without warning**\n"
14911491
"Adds an Azure Blob Storage source. Uses Shared Access Signature validation. <url> should include "
14921492
"the container path. <sas> must be be prefixed with a \"?\".")
1493+
DECLARE_MESSAGE(HelpBinaryCachingAzUpkg,
1494+
(),
1495+
"Printed as the 'definition' for 'x-az-universal,<organization>,<project>,<feed>[,<rw>]'.",
1496+
"**Experimental: will change or be removed without warning**\n"
1497+
"Adds a Universal Package Azure Artifacts source. Uses the Azure CLI "
1498+
"(az artifacts) for uploads and downloads.")
14931499
DECLARE_MESSAGE(HelpBinaryCachingCos,
14941500
(),
14951501
"Printed as the 'definition' for 'x-cos,<prefix>[,<rw>]'.",
@@ -1811,6 +1817,10 @@ DECLARE_MESSAGE(InvalidArgumentRequiresBaseUrlAndToken,
18111817
(msg::binary_source),
18121818
"",
18131819
"invalid argument: binary config '{binary_source}' requires at least a base-url and a SAS token")
1820+
DECLARE_MESSAGE(InvalidArgumentRequiresFourOrFiveArguments,
1821+
(msg::binary_source),
1822+
"",
1823+
"invalid argument: binary config '{binary_source}' requires 4 or 5 arguments")
18141824
DECLARE_MESSAGE(InvalidArgumentRequiresNoneArguments,
18151825
(msg::binary_source),
18161826
"",
@@ -2576,6 +2586,11 @@ DECLARE_MESSAGE(RestoredPackagesFromAWS,
25762586
(msg::count, msg::elapsed),
25772587
"",
25782588
"Restored {count} package(s) from AWS in {elapsed}. Use --debug to see more details.")
2589+
DECLARE_MESSAGE(RestoredPackagesFromAZUPKG,
2590+
(msg::count, msg::elapsed),
2591+
"",
2592+
"Restored {count} package(s) from Universal Packages in {elapsed}. "
2593+
"Use --debug to see more details.")
25792594
DECLARE_MESSAGE(RestoredPackagesFromCOS,
25802595
(msg::count, msg::elapsed),
25812596
"",

include/vcpkg/binarycaching.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,13 @@ namespace vcpkg
121121
std::string commit;
122122
};
123123

124+
struct AzureUpkgSource
125+
{
126+
std::string organization;
127+
std::string project;
128+
std::string feed;
129+
};
130+
124131
struct BinaryConfigParserState
125132
{
126133
bool nuget_interactive = false;
@@ -147,6 +154,9 @@ namespace vcpkg
147154
bool gha_write = false;
148155
bool gha_read = false;
149156

157+
std::vector<AzureUpkgSource> upkg_templates_to_get;
158+
std::vector<AzureUpkgSource> upkg_templates_to_put;
159+
150160
std::vector<std::string> sources_to_read;
151161
std::vector<std::string> sources_to_write;
152162

include/vcpkg/binarycaching.private.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,19 +19,19 @@ namespace vcpkg
1919
// - v?<X>.<Y><whatever> -> <X>.<Y>.0-vcpkg<abitag>
2020
// - v?<X>.<Y>.<Z><whatever> -> <X>.<Y>.<Z>-vcpkg<abitag>
2121
// - anything else -> 0.0.0-vcpkg<abitag>
22-
std::string format_version_for_nugetref(StringView version_text, StringView abi_tag);
22+
std::string format_version_for_feedref(StringView version_text, StringView abi_tag);
2323

24-
struct NugetReference
24+
struct FeedReference
2525
{
26-
NugetReference(std::string id, std::string version) : id(std::move(id)), version(std::move(version)) { }
26+
FeedReference(std::string id, std::string version) : id(std::move(id)), version(std::move(version)) { }
2727

2828
std::string id;
2929
std::string version;
3030

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

34-
NugetReference make_nugetref(const InstallPlanAction& action, StringView prefix);
34+
FeedReference make_nugetref(const InstallPlanAction& action, StringView prefix);
3535

3636
std::string generate_nuspec(const Path& package_dir,
3737
const InstallPlanAction& action,

include/vcpkg/metrics.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ namespace vcpkg
2424
BinaryCachingHttp,
2525
BinaryCachingNuget,
2626
BinaryCachingSource,
27+
BinaryCachingUpkg,
2728
ErrorVersioningDisabled,
2829
ErrorVersioningNoBaseline,
2930
GitHubRepository,

include/vcpkg/tools.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ namespace vcpkg
2323
static constexpr StringLiteral GIT = "git";
2424
static constexpr StringLiteral GSUTIL = "gsutil";
2525
static constexpr StringLiteral AWSCLI = "aws";
26+
static constexpr StringLiteral AZCLI = "az";
2627
static constexpr StringLiteral COSCLI = "coscli";
2728
static constexpr StringLiteral MONO = "mono";
2829
static constexpr StringLiteral NINJA = "ninja";
@@ -45,6 +46,11 @@ namespace vcpkg
4546
virtual const std::string& get_tool_version(StringView tool, MessageSink& status_sink) const = 0;
4647
};
4748

49+
ExpectedL<std::string> extract_prefixed_nonquote(StringLiteral prefix,
50+
StringLiteral tool_name,
51+
std::string&& output,
52+
const Path& exe_path);
53+
4854
ExpectedL<std::string> extract_prefixed_nonwhitespace(StringLiteral prefix,
4955
StringLiteral tool_name,
5056
std::string&& output,

locales/messages.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -858,6 +858,8 @@
858858
"HelpBinaryCachingAwsHeader": "Azure Web Services sources",
859859
"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 \"?\".",
860860
"_HelpBinaryCachingAzBlob.comment": "Printed as the 'definition' for 'x-azblob,<url>,<sas>[,<rw>]'.",
861+
"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.",
862+
"_HelpBinaryCachingAzUpkg.comment": "Printed as the 'definition' for 'x-az-universal,<organization>,<project>,<feed>[,<rw>]'.",
861863
"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 \"/\".",
862864
"_HelpBinaryCachingCos.comment": "Printed as the 'definition' for 'x-cos,<prefix>[,<rw>]'.",
863865
"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.",
@@ -997,6 +999,8 @@
997999
"_InvalidArgumentRequiresBaseUrl.comment": "An example of {base_url} is azblob://. An example of {binary_source} is azblob.",
9981000
"InvalidArgumentRequiresBaseUrlAndToken": "invalid argument: binary config '{binary_source}' requires at least a base-url and a SAS token",
9991001
"_InvalidArgumentRequiresBaseUrlAndToken.comment": "An example of {binary_source} is azblob.",
1002+
"InvalidArgumentRequiresFourOrFiveArguments": "invalid argument: binary config '{binary_source}' requires 4 or 5 arguments",
1003+
"_InvalidArgumentRequiresFourOrFiveArguments.comment": "An example of {binary_source} is azblob.",
10001004
"InvalidArgumentRequiresNoWildcards": "cannot fix Windows path case for path containing wildcards: {path}",
10011005
"_InvalidArgumentRequiresNoWildcards.comment": "An example of {path} is /foo/bar.",
10021006
"InvalidArgumentRequiresNoneArguments": "invalid argument: binary config '{binary_source}' does not take arguments",
@@ -1359,6 +1363,8 @@
13591363
"_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.",
13601364
"RestoredPackagesFromAWS": "Restored {count} package(s) from AWS in {elapsed}. Use --debug to see more details.",
13611365
"_RestoredPackagesFromAWS.comment": "An example of {count} is 42. An example of {elapsed} is 3.532 min.",
1366+
"RestoredPackagesFromAZUPKG": "Restored {count} package(s) from Universal Packages in {elapsed}. Use --debug to see more details.",
1367+
"_RestoredPackagesFromAZUPKG.comment": "An example of {count} is 42. An example of {elapsed} is 3.532 min.",
13621368
"RestoredPackagesFromCOS": "Restored {count} package(s) from COS in {elapsed}. Use --debug to see more details.",
13631369
"_RestoredPackagesFromCOS.comment": "An example of {count} is 42. An example of {elapsed} is 3.532 min.",
13641370
"RestoredPackagesFromFiles": "Restored {count} package(s) from {path} in {elapsed}. Use --debug to see more details.",

src/vcpkg-test/binarycaching.cpp

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -166,30 +166,30 @@ TEST_CASE ("CacheStatus operations", "[BinaryCache]")
166166
REQUIRE(assignee.is_restored());
167167
}
168168

169-
TEST_CASE ("format_version_for_nugetref semver-ish", "[format_version_for_nugetref]")
169+
TEST_CASE ("format_version_for_feedref semver-ish", "[format_version_for_feedref]")
170170
{
171-
REQUIRE(format_version_for_nugetref("0.0.0", "abitag") == "0.0.0-vcpkgabitag");
172-
REQUIRE(format_version_for_nugetref("1.0.1", "abitag") == "1.0.1-vcpkgabitag");
173-
REQUIRE(format_version_for_nugetref("1.01.000", "abitag") == "1.1.0-vcpkgabitag");
174-
REQUIRE(format_version_for_nugetref("1.2", "abitag") == "1.2.0-vcpkgabitag");
175-
REQUIRE(format_version_for_nugetref("v52", "abitag") == "52.0.0-vcpkgabitag");
176-
REQUIRE(format_version_for_nugetref("v09.01.02", "abitag") == "9.1.2-vcpkgabitag");
177-
REQUIRE(format_version_for_nugetref("1.1.1q", "abitag") == "1.1.1-vcpkgabitag");
178-
REQUIRE(format_version_for_nugetref("1", "abitag") == "1.0.0-vcpkgabitag");
171+
REQUIRE(format_version_for_feedref("0.0.0", "abitag") == "0.0.0-vcpkgabitag");
172+
REQUIRE(format_version_for_feedref("1.0.1", "abitag") == "1.0.1-vcpkgabitag");
173+
REQUIRE(format_version_for_feedref("1.01.000", "abitag") == "1.1.0-vcpkgabitag");
174+
REQUIRE(format_version_for_feedref("1.2", "abitag") == "1.2.0-vcpkgabitag");
175+
REQUIRE(format_version_for_feedref("v52", "abitag") == "52.0.0-vcpkgabitag");
176+
REQUIRE(format_version_for_feedref("v09.01.02", "abitag") == "9.1.2-vcpkgabitag");
177+
REQUIRE(format_version_for_feedref("1.1.1q", "abitag") == "1.1.1-vcpkgabitag");
178+
REQUIRE(format_version_for_feedref("1", "abitag") == "1.0.0-vcpkgabitag");
179179
}
180180

181-
TEST_CASE ("format_version_for_nugetref date", "[format_version_for_nugetref]")
181+
TEST_CASE ("format_version_for_feedref date", "[format_version_for_feedref]")
182182
{
183-
REQUIRE(format_version_for_nugetref("2020-06-26", "abitag") == "2020.6.26-vcpkgabitag");
184-
REQUIRE(format_version_for_nugetref("20-06-26", "abitag") == "0.0.0-vcpkgabitag");
185-
REQUIRE(format_version_for_nugetref("2020-06-26-release", "abitag") == "2020.6.26-vcpkgabitag");
186-
REQUIRE(format_version_for_nugetref("2020-06-26000", "abitag") == "2020.6.26-vcpkgabitag");
183+
REQUIRE(format_version_for_feedref("2020-06-26", "abitag") == "2020.6.26-vcpkgabitag");
184+
REQUIRE(format_version_for_feedref("20-06-26", "abitag") == "0.0.0-vcpkgabitag");
185+
REQUIRE(format_version_for_feedref("2020-06-26-release", "abitag") == "2020.6.26-vcpkgabitag");
186+
REQUIRE(format_version_for_feedref("2020-06-26000", "abitag") == "2020.6.26-vcpkgabitag");
187187
}
188188

189-
TEST_CASE ("format_version_for_nugetref generic", "[format_version_for_nugetref]")
189+
TEST_CASE ("format_version_for_feedref generic", "[format_version_for_feedref]")
190190
{
191-
REQUIRE(format_version_for_nugetref("apr", "abitag") == "0.0.0-vcpkgabitag");
192-
REQUIRE(format_version_for_nugetref("", "abitag") == "0.0.0-vcpkgabitag");
191+
REQUIRE(format_version_for_feedref("apr", "abitag") == "0.0.0-vcpkgabitag");
192+
REQUIRE(format_version_for_feedref("", "abitag") == "0.0.0-vcpkgabitag");
193193
}
194194

195195
TEST_CASE ("generate_nuspec", "[generate_nuspec]")
@@ -236,11 +236,11 @@ Build-Depends: bzip
236236
compiler_info.version = "compilerversion";
237237
ipa.abi_info.get()->compiler_info = compiler_info;
238238

239-
NugetReference ref2 = make_nugetref(ipa, "prefix_");
239+
FeedReference ref2 = make_nugetref(ipa, "prefix_");
240240

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

243-
NugetReference ref = make_nugetref(ipa, "");
243+
FeedReference ref = make_nugetref(ipa, "");
244244

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

src/vcpkg-test/configparser.cpp

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -560,6 +560,42 @@ TEST_CASE ("BinaryConfigParser HTTP provider", "[binaryconfigparser]")
560560
}
561561
}
562562

563+
TEST_CASE ("BinaryConfigParser Universal Packages provider", "[binaryconfigparser]")
564+
{
565+
// Scheme: x-az-universal,<organization>,<project>,<feed>[,<readwrite>]
566+
{
567+
auto parsed =
568+
parse_binary_provider_configs("x-az-universal,test_organization,test_project_name,test_feed,read", {});
569+
auto state = parsed.value_or_exit(VCPKG_LINE_INFO);
570+
REQUIRE(state.upkg_templates_to_get.size() == 1);
571+
REQUIRE(state.upkg_templates_to_get[0].feed == "test_feed");
572+
REQUIRE(state.upkg_templates_to_get[0].organization == "test_organization");
573+
REQUIRE(state.upkg_templates_to_get[0].project == "test_project_name");
574+
}
575+
{
576+
auto parsed =
577+
parse_binary_provider_configs("x-az-universal,test_organization,test_project_name,test_feed,readwrite", {});
578+
auto state = parsed.value_or_exit(VCPKG_LINE_INFO);
579+
REQUIRE(state.upkg_templates_to_get.size() == 1);
580+
REQUIRE(state.upkg_templates_to_put.size() == 1);
581+
REQUIRE(state.upkg_templates_to_get[0].feed == "test_feed");
582+
REQUIRE(state.upkg_templates_to_get[0].organization == "test_organization");
583+
REQUIRE(state.upkg_templates_to_get[0].project == "test_project_name");
584+
REQUIRE(state.upkg_templates_to_put[0].feed == "test_feed");
585+
REQUIRE(state.upkg_templates_to_put[0].organization == "test_organization");
586+
REQUIRE(state.upkg_templates_to_put[0].project == "test_project_name");
587+
}
588+
{
589+
auto parsed = parse_binary_provider_configs(
590+
"x-az-universal,test_organization,test_project_name,test_feed,extra_argument,readwrite", {});
591+
REQUIRE(!parsed.has_value());
592+
}
593+
{
594+
auto parsed = parse_binary_provider_configs("x-az-universal,missing_args,read", {});
595+
REQUIRE(!parsed.has_value());
596+
}
597+
}
598+
563599
TEST_CASE ("AssetConfigParser azurl provider", "[assetconfigparser]")
564600
{
565601
CHECK(parse_download_configuration({}));

src/vcpkg-test/tools.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,3 +128,15 @@ TEST_CASE ("extract_prefixed_nonwhitespace", "[tools]")
128128
CHECK(error_result.error() == "error: fooutil (fooutil.exe) produced unexpected output when attempting to "
129129
"determine the version:\nmalformed output");
130130
}
131+
132+
TEST_CASE ("extract_prefixed_nonquote", "[tools]")
133+
{
134+
CHECK(extract_prefixed_nonquote("fooutil version ", "fooutil", "fooutil version 1.2\"", "fooutil.exe")
135+
.value_or_exit(VCPKG_LINE_INFO) == "1.2");
136+
CHECK(extract_prefixed_nonquote("fooutil version ", "fooutil", "fooutil version 1.2 \" ", "fooutil.exe")
137+
.value_or_exit(VCPKG_LINE_INFO) == "1.2 ");
138+
auto error_result = extract_prefixed_nonquote("fooutil version ", "fooutil", "malformed output", "fooutil.exe");
139+
CHECK(!error_result.has_value());
140+
CHECK(error_result.error() == "error: fooutil (fooutil.exe) produced unexpected output when attempting to "
141+
"determine the version:\nmalformed output");
142+
}

0 commit comments

Comments
 (0)