diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000000..c5b108250f
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+/.vscode
diff --git a/Generate-SpdxLicenseList.ps1 b/Generate-SpdxLicenseList.ps1
new file mode 100644
index 0000000000..b73c3e70e0
--- /dev/null
+++ b/Generate-SpdxLicenseList.ps1
@@ -0,0 +1,63 @@
+<#
+#>
+[CmdletBinding(PositionalBinding=$False)]
+Param(
+ [Parameter(Mandatory=$True)]
+ [string]$Commit,
+
+ [Parameter()]
+ [string]$GithubRepository = "spdx/license-list-data",
+
+ [Parameter()]
+ [string]$LicensesOutFile = "$PSScriptRoot/src/vcpkg/spdx-licenses.inc",
+
+ [Parameter()]
+ [string]$ExceptionsOutFile = "$PSScriptRoot/src/vcpkg/spdx-exceptions.inc"
+)
+
+function Transform-JsonFile {
+ [CmdletBinding()]
+ Param(
+ [string]$Uri,
+ [string]$OutFile,
+ [string]$OuterName,
+ [string]$Id
+ )
+
+ $req = Invoke-WebRequest -Uri $Uri
+
+ if ($req.StatusCode -ne 200)
+ {
+ Write-Error "Failed to GET $Uri"
+ throw
+ }
+
+ $json = $req.Content | ConvertFrom-Json -Depth 10
+ Write-Verbose "Writing output to $OutFile"
+
+ $fileContent = @(
+ "// Data downloaded from $Uri",
+ "// Generated by scripts/Generate-SpdxLicenseList.ps1",
+ "{")
+ $json.$OuterName | ForEach-Object {
+ $fileContent += " `"$($_.$Id)`","
+ }
+ $fileContent += "}"
+
+ $fileContent -join "`n" | Out-File -FilePath $OutFile -Encoding 'utf8'
+}
+
+$baseUrl = "https://raw.githubusercontent.com/$GithubRepository/$Commit/json"
+Write-Verbose "Getting json files from $baseUrl"
+
+Transform-JsonFile `
+ -Uri "$baseUrl/licenses.json" `
+ -OutFile $LicensesOutFile `
+ -OuterName 'licenses' `
+ -Id 'licenseId'
+
+Transform-JsonFile `
+ -Uri "$baseUrl/exceptions.json" `
+ -OutFile $ExceptionsOutFile `
+ -OuterName 'exceptions' `
+ -Id 'licenseExceptionId'
diff --git a/azure-pipelines/Create-PRDiff.ps1 b/azure-pipelines/Create-PRDiff.ps1
new file mode 100644
index 0000000000..5da7e036d8
--- /dev/null
+++ b/azure-pipelines/Create-PRDiff.ps1
@@ -0,0 +1,19 @@
+[CmdletBinding(PositionalBinding=$False)]
+Param(
+ [Parameter(Mandatory=$True)]
+ [String]$DiffFile
+)
+
+Start-Process -FilePath 'git' -ArgumentList 'diff' `
+ -NoNewWindow -Wait `
+ -RedirectStandardOutput $DiffFile
+if (0 -ne (Get-Item -LiteralPath $DiffFile).Length)
+{
+ $msg = @(
+ 'The formatting of the files in the repo were not what we expected.',
+ 'Please access the diff from format.diff in the build artifacts,'
+ 'and apply the patch with `git apply`'
+ )
+ Write-Error ($msg -join "`n")
+ throw
+}
diff --git a/azure-pipelines/Format-CxxCode.ps1 b/azure-pipelines/Format-CxxCode.ps1
new file mode 100644
index 0000000000..fbd9185522
--- /dev/null
+++ b/azure-pipelines/Format-CxxCode.ps1
@@ -0,0 +1,35 @@
+[CmdletBinding()]
+$Root = Resolve-Path -LiteralPath "$PSScriptRoot/.."
+
+$clangFormat = Get-Command 'clang-format' -ErrorAction 'SilentlyContinue'
+if ($null -ne $clangFormat)
+{
+ $clangFormat = $clangFormat.Source
+}
+
+if ($IsWindows)
+{
+ if ([String]::IsNullOrEmpty($clangFormat) -or -not (Test-Path $clangFormat))
+ {
+ $clangFormat = 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\Llvm\x64\bin\clang-format.exe'
+ }
+ if (-not (Test-Path $clangFormat))
+ {
+ $clangFormat = 'C:\Program Files\LLVM\bin\clang-format.exe'
+ }
+}
+
+if ([String]::IsNullOrEmpty($clangFormat) -or -not (Test-Path $clangFormat))
+{
+ Write-Error 'clang-format not found; is it installed?'
+ throw
+}
+
+$files = Get-ChildItem -Recurse -LiteralPath "$Root/src" -Filter '*.cpp'
+$files += Get-ChildItem -Recurse -LiteralPath "$Root/src" -Filter '*.c'
+$files += Get-ChildItem -Recurse -LiteralPath "$Root/include/vcpkg" -Filter '*.h'
+$files += Get-ChildItem -Recurse -LiteralPath "$Root/include/vcpkg-test" -Filter '*.h'
+$files += Get-Item "$Root/include/pch.h"
+$fileNames = $files.FullName
+
+& $clangFormat -style=file -i @fileNames
diff --git a/azure-pipelines/e2e_ports/env-passthrough/passthrough.cmake b/azure-pipelines/e2e_ports/env-passthrough/passthrough.cmake
new file mode 100644
index 0000000000..071b8381ea
--- /dev/null
+++ b/azure-pipelines/e2e_ports/env-passthrough/passthrough.cmake
@@ -0,0 +1,6 @@
+set(VCPKG_TARGET_ARCHITECTURE x64)
+set(VCPKG_CRT_LINKAGE dynamic)
+set(VCPKG_LIBRARY_LINKAGE dynamic)
+
+set(VCPKG_ENV_PASSTHROUGH _VCPKG_TEST_TRACKED _VCPKG_TEST_TRACKED2)
+set(VCPKG_ENV_PASSTHROUGH_UNTRACKED _VCPKG_TEST_UNTRACKED _VCPKG_TEST_UNTRACKED2)
diff --git a/azure-pipelines/e2e_ports/integrate-install/NoProps.vcxproj b/azure-pipelines/e2e_ports/integrate-install/NoProps.vcxproj
new file mode 100644
index 0000000000..5b75d09615
--- /dev/null
+++ b/azure-pipelines/e2e_ports/integrate-install/NoProps.vcxproj
@@ -0,0 +1,145 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+
+ 16.0
+ {5AFB7AF5-D8FC-4A86-B0D2-3BBD039ED03A}
+ Project1
+ 10.0
+
+
+
+ Application
+ true
+ v142
+ Unicode
+
+
+ Application
+ false
+ v142
+ true
+ Unicode
+
+
+ Application
+ true
+ v142
+ Unicode
+
+
+ Application
+ false
+ v142
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+
+
+ true
+
+
+ false
+
+
+ false
+
+
+
+ Level3
+ true
+ _DEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+
+
+ Console
+ true
+
+
+
+
+ Level3
+ true
+ _DEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+
+
+ Console
+ true
+
+
+
+
+ Level3
+ true
+ true
+ true
+ NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+
+
+ Console
+ true
+ true
+ true
+
+
+
+
+ Level3
+ true
+ true
+ true
+ NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+
+
+ Console
+ true
+ true
+ true
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/azure-pipelines/e2e_ports/integrate-install/Project1.vcxproj b/azure-pipelines/e2e_ports/integrate-install/Project1.vcxproj
new file mode 100644
index 0000000000..a8896fe29d
--- /dev/null
+++ b/azure-pipelines/e2e_ports/integrate-install/Project1.vcxproj
@@ -0,0 +1,146 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+
+ 16.0
+ {5AFB7AF5-D8FC-4A86-B0D2-3BBD039ED03A}
+ Project1
+ 10.0
+
+
+
+ Application
+ true
+ v142
+ Unicode
+
+
+ Application
+ false
+ v142
+ true
+ Unicode
+
+
+ Application
+ true
+ v142
+ Unicode
+
+
+ Application
+ false
+ v142
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+
+
+ true
+
+
+ false
+
+
+ false
+
+
+
+ Level3
+ true
+ _DEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+
+
+ Console
+ true
+
+
+
+
+ Level3
+ true
+ _DEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+
+
+ Console
+ true
+
+
+
+
+ Level3
+ true
+ true
+ true
+ NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+
+
+ Console
+ true
+ true
+ true
+
+
+
+
+ Level3
+ true
+ true
+ true
+ NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+
+
+ Console
+ true
+ true
+ true
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/azure-pipelines/e2e_ports/integrate-install/Source.cpp b/azure-pipelines/e2e_ports/integrate-install/Source.cpp
new file mode 100644
index 0000000000..24a84e4d7f
--- /dev/null
+++ b/azure-pipelines/e2e_ports/integrate-install/Source.cpp
@@ -0,0 +1,6 @@
+#include
+
+int main() {
+ zlibVersion();
+ return 0;
+}
\ No newline at end of file
diff --git a/azure-pipelines/e2e_ports/integrate-install/VcpkgTriplet.vcxproj b/azure-pipelines/e2e_ports/integrate-install/VcpkgTriplet.vcxproj
new file mode 100644
index 0000000000..883fc8ec1a
--- /dev/null
+++ b/azure-pipelines/e2e_ports/integrate-install/VcpkgTriplet.vcxproj
@@ -0,0 +1,151 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+
+ 16.0
+ {5AFB7AF5-D8FC-4A86-B0D2-3BBD039ED03A}
+ VcpkgUseStatic
+ 10.0
+
+
+
+ Application
+ true
+ v142
+ Unicode
+
+
+ Application
+ false
+ v142
+ true
+ Unicode
+
+
+ Application
+ true
+ v142
+ Unicode
+
+
+ Application
+ false
+ v142
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+
+
+ true
+
+
+ false
+
+
+ false
+
+
+ x86-windows-static
+
+
+
+ Level3
+ true
+ _DEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+ MultiThreadedDebug
+
+
+ Console
+ true
+
+
+
+
+ Level3
+ true
+ _DEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+
+
+ Console
+ true
+
+
+
+
+ Level3
+ true
+ true
+ true
+ NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+ MultiThreaded
+
+
+ Console
+ true
+ true
+ true
+
+
+
+
+ Level3
+ true
+ true
+ true
+ NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+
+
+ Console
+ true
+ true
+ true
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/azure-pipelines/e2e_ports/integrate-install/VcpkgTriplet2.vcxproj b/azure-pipelines/e2e_ports/integrate-install/VcpkgTriplet2.vcxproj
new file mode 100644
index 0000000000..d3352e195b
--- /dev/null
+++ b/azure-pipelines/e2e_ports/integrate-install/VcpkgTriplet2.vcxproj
@@ -0,0 +1,149 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+
+ 16.0
+ {5AFB7AF5-D8FC-4A86-B0D2-3BBD039ED03A}
+ VcpkgUseStatic
+ 10.0
+ x86-windows-static
+
+
+
+ Application
+ true
+ v142
+ Unicode
+
+
+ Application
+ false
+ v142
+ true
+ Unicode
+
+
+ Application
+ true
+ v142
+ Unicode
+
+
+ Application
+ false
+ v142
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+
+
+ true
+
+
+ false
+
+
+ false
+
+
+
+ Level3
+ true
+ _DEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+ MultiThreadedDebug
+
+
+ Console
+ true
+
+
+
+
+ Level3
+ true
+ _DEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+
+
+ Console
+ true
+
+
+
+
+ Level3
+ true
+ true
+ true
+ NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+ MultiThreaded
+
+
+ Console
+ true
+ true
+ true
+
+
+
+
+ Level3
+ true
+ true
+ true
+ NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+
+
+ Console
+ true
+ true
+ true
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/azure-pipelines/e2e_ports/integrate-install/VcpkgUseStatic.vcxproj b/azure-pipelines/e2e_ports/integrate-install/VcpkgUseStatic.vcxproj
new file mode 100644
index 0000000000..28c4fc7158
--- /dev/null
+++ b/azure-pipelines/e2e_ports/integrate-install/VcpkgUseStatic.vcxproj
@@ -0,0 +1,151 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+
+ 16.0
+ {5AFB7AF5-D8FC-4A86-B0D2-3BBD039ED03A}
+ VcpkgUseStatic
+ 10.0
+
+
+
+ Application
+ true
+ v142
+ Unicode
+
+
+ Application
+ false
+ v142
+ true
+ Unicode
+
+
+ Application
+ true
+ v142
+ Unicode
+
+
+ Application
+ false
+ v142
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+
+
+ true
+
+
+ false
+
+
+ false
+
+
+ true
+
+
+
+ Level3
+ true
+ _DEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+ MultiThreadedDebug
+
+
+ Console
+ true
+
+
+
+
+ Level3
+ true
+ _DEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+
+
+ Console
+ true
+
+
+
+
+ Level3
+ true
+ true
+ true
+ NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+ MultiThreaded
+
+
+ Console
+ true
+ true
+ true
+
+
+
+
+ Level3
+ true
+ true
+ true
+ NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+
+
+ Console
+ true
+ true
+ true
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/azure-pipelines/e2e_ports/integrate-install/VcpkgUseStatic2.vcxproj b/azure-pipelines/e2e_ports/integrate-install/VcpkgUseStatic2.vcxproj
new file mode 100644
index 0000000000..98beaee4b1
--- /dev/null
+++ b/azure-pipelines/e2e_ports/integrate-install/VcpkgUseStatic2.vcxproj
@@ -0,0 +1,149 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+
+ 16.0
+ {5AFB7AF5-D8FC-4A86-B0D2-3BBD039ED03A}
+ VcpkgUseStatic
+ 10.0
+ true
+
+
+
+ Application
+ true
+ v142
+ Unicode
+
+
+ Application
+ false
+ v142
+ true
+ Unicode
+
+
+ Application
+ true
+ v142
+ Unicode
+
+
+ Application
+ false
+ v142
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+
+
+ true
+
+
+ false
+
+
+ false
+
+
+
+ Level3
+ true
+ _DEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+ MultiThreadedDebug
+
+
+ Console
+ true
+
+
+
+
+ Level3
+ true
+ _DEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+
+
+ Console
+ true
+
+
+
+
+ Level3
+ true
+ true
+ true
+ NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+ MultiThreaded
+
+
+ Console
+ true
+ true
+ true
+
+
+
+
+ Level3
+ true
+ true
+ true
+ NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+
+
+ Console
+ true
+ true
+ true
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/azure-pipelines/e2e_ports/overlays/vcpkg-requires-current-date/portfile.cmake b/azure-pipelines/e2e_ports/overlays/vcpkg-requires-current-date/portfile.cmake
new file mode 100644
index 0000000000..68dc779a84
--- /dev/null
+++ b/azure-pipelines/e2e_ports/overlays/vcpkg-requires-current-date/portfile.cmake
@@ -0,0 +1,2 @@
+vcpkg_minimum_required(VERSION ${VCPKG_BASE_VERSION})
+set(VCPKG_POLICY_EMPTY_PACKAGE enabled)
diff --git a/azure-pipelines/e2e_ports/overlays/vcpkg-requires-current-date/vcpkg.json b/azure-pipelines/e2e_ports/overlays/vcpkg-requires-current-date/vcpkg.json
new file mode 100644
index 0000000000..48debf1e76
--- /dev/null
+++ b/azure-pipelines/e2e_ports/overlays/vcpkg-requires-current-date/vcpkg.json
@@ -0,0 +1,6 @@
+{
+ "name": "vcpkg-requires-current-date",
+ "version-string": "1.0.0",
+ "description": "A test port that verifies that vcpkg_minimum_required is inclusive by using the current base version value.",
+ "homepage": ""
+}
diff --git a/azure-pipelines/e2e_ports/overlays/vcpkg-requires-future-date/portfile.cmake b/azure-pipelines/e2e_ports/overlays/vcpkg-requires-future-date/portfile.cmake
new file mode 100644
index 0000000000..b68e53e95c
--- /dev/null
+++ b/azure-pipelines/e2e_ports/overlays/vcpkg-requires-future-date/portfile.cmake
@@ -0,0 +1,2 @@
+vcpkg_minimum_required(VERSION 2999-12-31)
+set(VCPKG_POLICY_EMPTY_PACKAGE enabled)
diff --git a/azure-pipelines/e2e_ports/overlays/vcpkg-requires-future-date/vcpkg.json b/azure-pipelines/e2e_ports/overlays/vcpkg-requires-future-date/vcpkg.json
new file mode 100644
index 0000000000..f60901998f
--- /dev/null
+++ b/azure-pipelines/e2e_ports/overlays/vcpkg-requires-future-date/vcpkg.json
@@ -0,0 +1,6 @@
+{
+ "name": "vcpkg-requires-future-date",
+ "version-string": "1.0.0",
+ "description": "A test port that requires a vcpkg version from an impossibly far future.",
+ "homepage": ""
+}
diff --git a/azure-pipelines/e2e_ports/overlays/vcpkg-requires-old-date/portfile.cmake b/azure-pipelines/e2e_ports/overlays/vcpkg-requires-old-date/portfile.cmake
new file mode 100644
index 0000000000..5a4fbf4213
--- /dev/null
+++ b/azure-pipelines/e2e_ports/overlays/vcpkg-requires-old-date/portfile.cmake
@@ -0,0 +1,2 @@
+vcpkg_minimum_required(VERSION 2020-01-12)
+set(VCPKG_POLICY_EMPTY_PACKAGE enabled)
diff --git a/azure-pipelines/e2e_ports/overlays/vcpkg-requires-old-date/vcpkg.json b/azure-pipelines/e2e_ports/overlays/vcpkg-requires-old-date/vcpkg.json
new file mode 100644
index 0000000000..31e6fb62ff
--- /dev/null
+++ b/azure-pipelines/e2e_ports/overlays/vcpkg-requires-old-date/vcpkg.json
@@ -0,0 +1,6 @@
+{
+ "name": "vcpkg-requires-old-date",
+ "version-string": "1.0.0",
+ "description": "A test port that requires a vcpkg version from before vcpkg_minimum_required's introduction.",
+ "homepage": ""
+}
diff --git a/azure-pipelines/e2e_ports/overlays/vcpkg-uses-test-cmake/portfile.cmake b/azure-pipelines/e2e_ports/overlays/vcpkg-uses-test-cmake/portfile.cmake
new file mode 100644
index 0000000000..571ae3b7ab
--- /dev/null
+++ b/azure-pipelines/e2e_ports/overlays/vcpkg-uses-test-cmake/portfile.cmake
@@ -0,0 +1,3 @@
+set(VCPKG_POLICY_EMPTY_PACKAGE enabled)
+
+vcpkg_test_cmake(args args args)
diff --git a/azure-pipelines/e2e_ports/overlays/vcpkg-uses-test-cmake/vcpkg.json b/azure-pipelines/e2e_ports/overlays/vcpkg-uses-test-cmake/vcpkg.json
new file mode 100644
index 0000000000..9f34e058d6
--- /dev/null
+++ b/azure-pipelines/e2e_ports/overlays/vcpkg-uses-test-cmake/vcpkg.json
@@ -0,0 +1,6 @@
+{
+ "name": "vcpkg-uses-test-cmake",
+ "version-string": "1.0.0",
+ "description": "A test port that uses the deprecated function vcpkg_test_cmake.",
+ "homepage": ""
+}
diff --git a/azure-pipelines/e2e_ports/overlays/vcpkg-uses-vcpkg-common-functions/portfile.cmake b/azure-pipelines/e2e_ports/overlays/vcpkg-uses-vcpkg-common-functions/portfile.cmake
new file mode 100644
index 0000000000..9207d30b19
--- /dev/null
+++ b/azure-pipelines/e2e_ports/overlays/vcpkg-uses-vcpkg-common-functions/portfile.cmake
@@ -0,0 +1,3 @@
+set(VCPKG_POLICY_EMPTY_PACKAGE enabled)
+
+include(vcpkg_common_functions)
diff --git a/azure-pipelines/e2e_ports/overlays/vcpkg-uses-vcpkg-common-functions/vcpkg.json b/azure-pipelines/e2e_ports/overlays/vcpkg-uses-vcpkg-common-functions/vcpkg.json
new file mode 100644
index 0000000000..7c16ffe821
--- /dev/null
+++ b/azure-pipelines/e2e_ports/overlays/vcpkg-uses-vcpkg-common-functions/vcpkg.json
@@ -0,0 +1,6 @@
+{
+ "name": "vcpkg-uses-vcpkg-common-functions",
+ "version-string": "1.0.0",
+ "description": "A test port that uses the deprecated file vcpkg_common_functions.",
+ "homepage": ""
+}
diff --git a/azure-pipelines/e2e_ports/vcpkg-find-acquire-program/CONTROL b/azure-pipelines/e2e_ports/vcpkg-find-acquire-program/CONTROL
new file mode 100644
index 0000000000..6f248be58a
--- /dev/null
+++ b/azure-pipelines/e2e_ports/vcpkg-find-acquire-program/CONTROL
@@ -0,0 +1,4 @@
+Source: vcpkg-find-acquire-program
+Version: 0
+Description: Test port to exercise vcpkg_find_acquire_program
+Supports: windows
diff --git a/azure-pipelines/e2e_ports/vcpkg-find-acquire-program/portfile.cmake b/azure-pipelines/e2e_ports/vcpkg-find-acquire-program/portfile.cmake
new file mode 100644
index 0000000000..88a4856c5f
--- /dev/null
+++ b/azure-pipelines/e2e_ports/vcpkg-find-acquire-program/portfile.cmake
@@ -0,0 +1,21 @@
+set(VCPKG_POLICY_EMPTY_PACKAGE enabled)
+
+if(CMAKE_HOST_WIN32)
+ foreach(PROG GO JOM NASM PERL YASM GIT PYTHON3 PYTHON2 RUBY 7Z NUGET FLEX BISON GPERF GASPREPROCESSOR DARK SCONS SWIG DOXYGEN ARIA2 PKGCONFIG)
+ vcpkg_find_acquire_program(${PROG})
+ foreach(SUBPROG IN LISTS ${PROG})
+ if(NOT EXISTS "${SUBPROG}")
+ message(FATAL_ERROR "Program ${SUBPROG} did not exist.")
+ endif()
+ endforeach()
+ endforeach()
+endif()
+
+foreach(PROG GN NINJA MESON BAZEL)
+ vcpkg_find_acquire_program(${PROG})
+ foreach(SUBPROG IN LISTS ${PROG})
+ if(NOT EXISTS "${SUBPROG}")
+ message(FATAL_ERROR "Program ${SUBPROG} did not exist.")
+ endif()
+ endforeach()
+endforeach()
diff --git a/azure-pipelines/e2e_ports/vcpkg-internal-e2e-test-port/portfile.cmake b/azure-pipelines/e2e_ports/vcpkg-internal-e2e-test-port/portfile.cmake
new file mode 100644
index 0000000000..065116c276
--- /dev/null
+++ b/azure-pipelines/e2e_ports/vcpkg-internal-e2e-test-port/portfile.cmake
@@ -0,0 +1 @@
+set(VCPKG_POLICY_EMPTY_PACKAGE enabled)
diff --git a/azure-pipelines/e2e_ports/vcpkg-internal-e2e-test-port/vcpkg.json b/azure-pipelines/e2e_ports/vcpkg-internal-e2e-test-port/vcpkg.json
new file mode 100644
index 0000000000..a25da6d236
--- /dev/null
+++ b/azure-pipelines/e2e_ports/vcpkg-internal-e2e-test-port/vcpkg.json
@@ -0,0 +1,4 @@
+{
+ "name": "vcpkg-internal-e2e-test-port",
+ "version-string": "1.0.0"
+}
diff --git a/azure-pipelines/e2e_ports/versions/baseline.json b/azure-pipelines/e2e_ports/versions/baseline.json
new file mode 100644
index 0000000000..2413f8afc6
--- /dev/null
+++ b/azure-pipelines/e2e_ports/versions/baseline.json
@@ -0,0 +1,5 @@
+{
+ "default": {
+ "vcpkg-internal-e2e-test-port": { "baseline": "1.0.0" }
+ }
+}
diff --git a/azure-pipelines/e2e_ports/versions/v-/vcpkg-internal-e2e-test-port.json b/azure-pipelines/e2e_ports/versions/v-/vcpkg-internal-e2e-test-port.json
new file mode 100644
index 0000000000..ce7698ebb8
--- /dev/null
+++ b/azure-pipelines/e2e_ports/versions/v-/vcpkg-internal-e2e-test-port.json
@@ -0,0 +1,8 @@
+{
+ "versions": [
+ {
+ "version-string": "1.0.0",
+ "git-tree": "1dc3e42a3c0cafe2884d379af4399273238b986e"
+ }
+ ]
+}
diff --git a/azure-pipelines/end-to-end-tests-dir/backcompat-helpers.ps1 b/azure-pipelines/end-to-end-tests-dir/backcompat-helpers.ps1
new file mode 100644
index 0000000000..704b527523
--- /dev/null
+++ b/azure-pipelines/end-to-end-tests-dir/backcompat-helpers.ps1
@@ -0,0 +1,24 @@
+. $PSScriptRoot/../end-to-end-tests-prelude.ps1
+
+# Test that prohibiting backcompat features actually prohibits
+$backcompatFeaturePorts = @('vcpkg-uses-test-cmake', 'vcpkg-uses-vcpkg-common-functions')
+foreach ($backcompatFeaturePort in $backcompatFeaturePorts) {
+ $succeedArgs = $commonArgs + @('install',$backcompatFeaturePort,'--no-binarycaching')
+ $failArgs = $succeedArgs + @('--x-prohibit-backcompat-features')
+ $CurrentTest = "Should fail: ./vcpkg $($failArgs -join ' ')"
+ Run-Vcpkg @failArgs
+ if ($LastExitCode -ne 0) {
+ Write-Host "... failed (this is good!)."
+ } else {
+ throw $CurrentTest
+ }
+
+ # Install failed when prohibiting backcompat features, so it should succeed if we allow them
+ $CurrentTest = "Should succeeed: ./vcpkg $($succeedArgs -join ' ')"
+ Run-Vcpkg @succeedArgs
+ if ($LastExitCode -ne 0) {
+ throw $CurrentTest
+ } else {
+ Write-Host "... succeeded."
+ }
+}
diff --git a/azure-pipelines/end-to-end-tests-dir/binarycaching.ps1 b/azure-pipelines/end-to-end-tests-dir/binarycaching.ps1
new file mode 100644
index 0000000000..924e5da9a3
--- /dev/null
+++ b/azure-pipelines/end-to-end-tests-dir/binarycaching.ps1
@@ -0,0 +1,86 @@
+if ($IsLinux) {
+ # The tests below need a mono installation not currently available on the Linux agents.
+ return
+}
+
+. $PSScriptRoot/../end-to-end-tests-prelude.ps1
+
+# Test simple installation
+Run-Vcpkg -TestArgs ($commonArgs + @("install", "rapidjson", "--binarycaching", "--x-binarysource=clear;files,$ArchiveRoot,write;nuget,$NuGetRoot,readwrite"))
+Throw-IfFailed
+Require-FileExists "$installRoot/$Triplet/include/rapidjson/rapidjson.h"
+
+# Test simple removal
+Run-Vcpkg -TestArgs ($commonArgs + @("remove", "rapidjson"))
+Throw-IfFailed
+Require-FileNotExists "$installRoot/$Triplet/include/rapidjson/rapidjson.h"
+
+# Test restoring from files archive
+Remove-Item -Recurse -Force $installRoot
+Remove-Item -Recurse -Force $buildtreesRoot
+Run-Vcpkg -TestArgs ($commonArgs + @("install","rapidjson","--binarycaching","--x-binarysource=clear;files,$ArchiveRoot,read"))
+Throw-IfFailed
+Require-FileExists "$installRoot/$Triplet/include/rapidjson/rapidjson.h"
+Require-FileNotExists "$buildtreesRoot/rapidjson/src"
+Require-FileExists "$buildtreesRoot/detect_compiler"
+
+# Test --no-binarycaching
+Remove-Item -Recurse -Force $installRoot
+Remove-Item -Recurse -Force $buildtreesRoot
+Run-Vcpkg -TestArgs ($commonArgs + @("install","rapidjson","--no-binarycaching","--x-binarysource=clear;files,$ArchiveRoot,read"))
+Throw-IfFailed
+Require-FileExists "$installRoot/$Triplet/include/rapidjson/rapidjson.h"
+Require-FileExists "$buildtreesRoot/rapidjson/src"
+Require-FileExists "$buildtreesRoot/detect_compiler"
+
+# Test --editable
+Remove-Item -Recurse -Force $installRoot
+Remove-Item -Recurse -Force $buildtreesRoot
+Run-Vcpkg -TestArgs ($commonArgs + @("install","rapidjson","--editable","--x-binarysource=clear;files,$ArchiveRoot,read"))
+Throw-IfFailed
+Require-FileExists "$installRoot/$Triplet/include/rapidjson/rapidjson.h"
+Require-FileExists "$buildtreesRoot/rapidjson/src"
+Require-FileNotExists "$buildtreesRoot/detect_compiler"
+
+# Test restoring from nuget
+Remove-Item -Recurse -Force $installRoot
+Remove-Item -Recurse -Force $buildtreesRoot
+Run-Vcpkg -TestArgs ($commonArgs + @("install", "rapidjson", "--binarycaching", "--x-binarysource=clear;nuget,$NuGetRoot"))
+Throw-IfFailed
+Require-FileExists "$installRoot/$Triplet/include/rapidjson/rapidjson.h"
+Require-FileNotExists "$buildtreesRoot/rapidjson/src"
+
+# Test four-phase flow
+Remove-Item -Recurse -Force $installRoot -ErrorAction SilentlyContinue
+Run-Vcpkg -TestArgs ($commonArgs + @("install", "rapidjson", "--dry-run", "--x-write-nuget-packages-config=$TestingRoot/packages.config"))
+Throw-IfFailed
+Require-FileNotExists "$installRoot/$Triplet/include/rapidjson/rapidjson.h"
+Require-FileNotExists "$buildtreesRoot/rapidjson/src"
+Require-FileExists "$TestingRoot/packages.config"
+if ($IsLinux -or $IsMacOS) {
+ mono $(./vcpkg fetch nuget) restore $TestingRoot/packages.config -OutputDirectory "$NuGetRoot2" -Source "$NuGetRoot"
+} else {
+ & $(./vcpkg fetch nuget) restore $TestingRoot/packages.config -OutputDirectory "$NuGetRoot2" -Source "$NuGetRoot"
+}
+Throw-IfFailed
+Remove-Item -Recurse -Force $NuGetRoot -ErrorAction SilentlyContinue
+mkdir $NuGetRoot
+Run-Vcpkg -TestArgs ($commonArgs + @("install", "rapidjson", "zlib", "--binarycaching", "--x-binarysource=clear;nuget,$NuGetRoot2;nuget,$NuGetRoot,write"))
+Throw-IfFailed
+Require-FileExists "$installRoot/$Triplet/include/rapidjson/rapidjson.h"
+Require-FileExists "$installRoot/$Triplet/include/zlib.h"
+Require-FileNotExists "$buildtreesRoot/rapidjson/src"
+Require-FileExists "$buildtreesRoot/zlib/src"
+if ((Get-ChildItem $NuGetRoot -Filter '*.nupkg' | Measure-Object).Count -ne 1) {
+ throw "In '$CurrentTest': did not create exactly 1 NuGet package"
+}
+
+# Test export
+$CurrentTest = 'Exporting'
+Require-FileNotExists "$TestingRoot/vcpkg-export-output"
+Require-FileNotExists "$TestingRoot/vcpkg-export.1.0.0.nupkg"
+Require-FileNotExists "$TestingRoot/vcpkg-export-output.zip"
+Run-Vcpkg -TestArgs ($commonArgs + @("export", "rapidjson", "zlib", "--nuget", "--nuget-id=vcpkg-export", "--nuget-version=1.0.0", "--output=vcpkg-export-output", "--raw", "--zip", "--output-dir=$TestingRoot"))
+Require-FileExists "$TestingRoot/vcpkg-export-output"
+Require-FileExists "$TestingRoot/vcpkg-export.1.0.0.nupkg"
+Require-FileExists "$TestingRoot/vcpkg-export-output.zip"
diff --git a/azure-pipelines/end-to-end-tests-dir/build-missing.ps1 b/azure-pipelines/end-to-end-tests-dir/build-missing.ps1
new file mode 100644
index 0000000000..5f318e6af9
--- /dev/null
+++ b/azure-pipelines/end-to-end-tests-dir/build-missing.ps1
@@ -0,0 +1,18 @@
+. $PSScriptRoot/../end-to-end-tests-prelude.ps1
+
+$CurrentTest = "Build Missing tests"
+
+Run-Vcpkg -TestArgs ($commonArgs + @("install", "rapidjson", "--only-binarycaching","--x-binarysource=clear;files,$ArchiveRoot,read"))
+Throw-IfNotFailed
+Require-FileNotExists "$installRoot/$Triplet/include/rapidjson/rapidjson.h"
+
+# Create the rapidjson archive
+Remove-Item -Recurse -Force $installRoot
+Run-Vcpkg -TestArgs ($commonArgs + @("install", "rapidjson","--x-binarysource=clear;files,$ArchiveRoot,write"))
+Throw-IfFailed
+Require-FileExists "$installRoot/$Triplet/include/rapidjson/rapidjson.h"
+
+Remove-Item -Recurse -Force $installRoot
+Run-Vcpkg -TestArgs ($commonArgs + @("install", "rapidjson", "--only-binarycaching","--x-binarysource=clear;files,$ArchiveRoot,read"))
+Throw-IfFailed
+Require-FileExists "$installRoot/$Triplet/include/rapidjson/rapidjson.h"
diff --git a/azure-pipelines/end-to-end-tests-dir/build-test-ports.ps1 b/azure-pipelines/end-to-end-tests-dir/build-test-ports.ps1
new file mode 100644
index 0000000000..5b2ae81086
--- /dev/null
+++ b/azure-pipelines/end-to-end-tests-dir/build-test-ports.ps1
@@ -0,0 +1,5 @@
+. $PSScriptRoot/../end-to-end-tests-prelude.ps1
+
+$CurrentTest = "Build Test Ports"
+
+Run-Vcpkg --overlay-ports="$PSScriptRoot/../e2e_ports" install vcpkg-find-acquire-program
diff --git a/azure-pipelines/end-to-end-tests-dir/cli.ps1 b/azure-pipelines/end-to-end-tests-dir/cli.ps1
new file mode 100644
index 0000000000..47f624fa8f
--- /dev/null
+++ b/azure-pipelines/end-to-end-tests-dir/cli.ps1
@@ -0,0 +1,11 @@
+. $PSScriptRoot/../end-to-end-tests-prelude.ps1
+
+# Test bad command lines
+Run-Vcpkg -TestArgs ($commonArgs + @("install", "zlib", "--vcpkg-rootttttt", "C:\"))
+Throw-IfNotFailed
+
+Run-Vcpkg -TestArgs ($commonArgs + @("install", "zlib", "--vcpkg-rootttttt=C:\"))
+Throw-IfNotFailed
+
+Run-Vcpkg -TestArgs ($commonArgs + @("install", "zlib", "--fast")) # NB: --fast is not a switch
+Throw-IfNotFailed
diff --git a/azure-pipelines/end-to-end-tests-dir/create.ps1 b/azure-pipelines/end-to-end-tests-dir/create.ps1
new file mode 100644
index 0000000000..9d59da5396
--- /dev/null
+++ b/azure-pipelines/end-to-end-tests-dir/create.ps1
@@ -0,0 +1,10 @@
+. $PSScriptRoot/../end-to-end-tests-prelude.ps1
+
+# Test vcpkg create
+$Script:CurrentTest = "create zlib"
+Write-Host $Script:CurrentTest
+./vcpkg --x-builtin-ports-root=$TestingRoot/ports create zlib https://github.com/madler/zlib/archive/v1.2.11.tar.gz zlib-1.2.11.tar.gz
+Throw-IfFailed
+
+Require-FileExists "$TestingRoot/ports/zlib/portfile.cmake"
+Require-FileExists "$TestingRoot/ports/zlib/vcpkg.json"
diff --git a/azure-pipelines/end-to-end-tests-dir/disable-metrics.ps1 b/azure-pipelines/end-to-end-tests-dir/disable-metrics.ps1
new file mode 100644
index 0000000000..5ad7616b48
--- /dev/null
+++ b/azure-pipelines/end-to-end-tests-dir/disable-metrics.ps1
@@ -0,0 +1,67 @@
+. $PSScriptRoot/../end-to-end-tests-prelude.ps1
+
+# Test that metrics are on by default
+$metricsTagName = 'vcpkg.disable-metrics'
+$metricsAreDisabledMessage = 'Warning: passed --sendmetrics, but metrics are disabled.'
+
+function Test-Metrics-Enabled() {
+ Param(
+ [Parameter(ValueFromRemainingArguments)]
+ [string[]]$TestArgs
+ )
+
+ $actualArgs = @('version', '--sendmetrics')
+ if ($TestArgs.Length -ne 0) {
+ $actualArgs += $TestArgs
+ }
+
+ $vcpkgOutput = Run-Vcpkg $actualArgs
+ if ($vcpkgOutput -contains $metricsAreDisabledMessage) {
+ Write-Host 'Metrics are disabled'
+ return $false
+ }
+
+ Write-Host 'Metrics are enabled'
+ return $true
+}
+
+# By default, metrics are enabled.
+Require-FileNotExists $metricsTagName
+if (-Not (Test-Metrics-Enabled)) {
+ throw "Metrics were not on by default."
+}
+
+if (Test-Metrics-Enabled '--disable-metrics') {
+ throw "Metrics were not disabled by switch."
+}
+
+$env:VCPKG_DISABLE_METRICS = 'ON'
+try {
+ if (Test-Metrics-Enabled) {
+ throw "Environment variable did not disable metrics."
+ }
+
+ # Also test that you get no message without --sendmetrics
+ $vcpkgOutput = Run-Vcpkg list
+ if ($vcpkgOutput -contains $metricsAreDisabledMessage) {
+ throw "Disabled metrics emit message even without --sendmetrics"
+ }
+
+ if (-Not (Test-Metrics-Enabled '--no-disable-metrics')) {
+ throw "Environment variable to disable metrics could not be overridden by switch."
+ }
+} finally {
+ Remove-Item env:VCPKG_DISABLE_METRICS
+}
+
+# If the disable-metrics tag file exists, metrics are disabled even if attempted to be enabled on
+# the command line.
+Set-Content -Path $metricsTagName -Value ""
+try {
+ if (Test-Metrics-Enabled '--disable-metrics') {
+ throw "Metrics were not force-disabled by the disable-metrics tag file."
+ }
+}
+finally {
+ Remove-Item $metricsTagName
+}
diff --git a/azure-pipelines/end-to-end-tests-dir/env-passthrough.ps1 b/azure-pipelines/end-to-end-tests-dir/env-passthrough.ps1
new file mode 100644
index 0000000000..af31c2da77
--- /dev/null
+++ b/azure-pipelines/end-to-end-tests-dir/env-passthrough.ps1
@@ -0,0 +1,21 @@
+if (-not $IsLinux -and -not $IsMacOS) {
+ . $PSScriptRoot/../end-to-end-tests-prelude.ps1
+
+ $env:_VCPKG_TEST_TRACKED = "a"
+ $env:_VCPKG_TEST_UNTRACKED = "b"
+
+ $x = ./vcpkg "--overlay-triplets=$PSScriptRoot/../e2e_ports/env-passthrough" env "echo %_VCPKG_TEST_TRACKED% %_VCPKG_TEST_TRACKED2% %_VCPKG_TEST_UNTRACKED% %_VCPKG_TEST_UNTRACKED2%"
+ if ($x -ne "%_VCPKG_TEST_TRACKED% %_VCPKG_TEST_TRACKED2% %_VCPKG_TEST_UNTRACKED% %_VCPKG_TEST_UNTRACKED2%")
+ {
+ throw "env should have cleaned the environment ($x)"
+ }
+
+ $y = ./vcpkg "--overlay-triplets=$PSScriptRoot/../e2e_ports/env-passthrough" env --triplet passthrough "echo %_VCPKG_TEST_TRACKED% %_VCPKG_TEST_TRACKED2% %_VCPKG_TEST_UNTRACKED% %_VCPKG_TEST_UNTRACKED2%"
+ if ($y -ne "a %_VCPKG_TEST_TRACKED2% b %_VCPKG_TEST_UNTRACKED2%")
+ {
+ throw "env should have kept the environment ($y)"
+ }
+
+ rm env:_VCPKG_TEST_TRACKED
+ rm env:_VCPKG_TEST_UNTRACKED
+}
diff --git a/azure-pipelines/end-to-end-tests-dir/integrate-install.ps1 b/azure-pipelines/end-to-end-tests-dir/integrate-install.ps1
new file mode 100644
index 0000000000..38362ba8cb
--- /dev/null
+++ b/azure-pipelines/end-to-end-tests-dir/integrate-install.ps1
@@ -0,0 +1,28 @@
+if (-not $IsLinux -and -not $IsMacOS) {
+ . $PSScriptRoot/../end-to-end-tests-prelude.ps1
+
+ # Test msbuild props and targets
+ $Script:CurrentTest = "zlib:x86-windows-static msbuild scripts\testing\integrate-install\..."
+ Write-Host $Script:CurrentTest
+ ./vcpkg $commonArgs install zlib:x86-windows-static --x-binarysource=clear
+ Throw-IfFailed
+ foreach ($project in @("VcpkgTriplet", "VcpkgTriplet2", "VcpkgUseStatic", "VcpkgUseStatic2")) {
+ $Script:CurrentTest = "msbuild scripts\testing\integrate-install\$project.vcxproj"
+ ./vcpkg $commonArgs env "msbuild scripts\testing\integrate-install\$project.vcxproj /p:VcpkgRoot=$TestingRoot /p:IntDir=$TestingRoot\int\ /p:OutDir=$TestingRoot\out\ "
+ Throw-IfFailed
+ Remove-Item -Recurse -Force $TestingRoot\int
+ Remove-Item -Recurse -Force $TestingRoot\out
+ }
+ $Script:CurrentTest = "zlib:x86-windows msbuild scripts\testing\integrate-install\..."
+ Write-Host $Script:CurrentTest
+ ./vcpkg $commonArgs install zlib:x86-windows --x-binarysource=clear
+ Throw-IfFailed
+ foreach ($project in @("Project1", "NoProps")) {
+ $Script:CurrentTest = "msbuild scripts\testing\integrate-install\$project.vcxproj"
+ Write-Host $Script:CurrentTest
+ ./vcpkg $commonArgs env "msbuild scripts\testing\integrate-install\$project.vcxproj /p:VcpkgRoot=$TestingRoot /p:IntDir=$TestingRoot\int\ /p:OutDir=$TestingRoot\out\ "
+ Throw-IfFailed
+ Remove-Item -Recurse -Force $TestingRoot\int
+ Remove-Item -Recurse -Force $TestingRoot\out
+ }
+}
diff --git a/azure-pipelines/end-to-end-tests-dir/registries.ps1 b/azure-pipelines/end-to-end-tests-dir/registries.ps1
new file mode 100644
index 0000000000..db5b91b417
--- /dev/null
+++ b/azure-pipelines/end-to-end-tests-dir/registries.ps1
@@ -0,0 +1,192 @@
+. "$PSScriptRoot/../end-to-end-tests-prelude.ps1"
+
+
+$builtinRegistryArgs = $commonArgs + @("--x-builtin-registry-versions-dir=$PSScriptRoot/../e2e_ports/versions")
+
+Run-Vcpkg install @builtinRegistryArgs 'vcpkg-internal-e2e-test-port'
+Throw-IfNotFailed
+
+# We should not look into the versions directory unless we have a baseline,
+# even if we pass the registries feature flag
+Run-Vcpkg install @builtinRegistryArgs --feature-flags=registries 'vcpkg-internal-e2e-test-port'
+Throw-IfNotFailed
+
+Run-Vcpkg install @builtinRegistryArgs --feature-flags=registries 'zlib'
+Throw-IfFailed
+
+Write-Trace "Test git and filesystem registries"
+Refresh-TestRoot
+$filesystemRegistry = "$TestingRoot/filesystem-registry"
+$gitRegistryUpstream = "$TestingRoot/git-registry-upstream"
+
+# build a filesystem registry
+Write-Trace "build a filesystem registry"
+New-Item -Path $filesystemRegistry -ItemType Directory
+$filesystemRegistry = (Get-Item $filesystemRegistry).FullName
+
+Copy-Item -Recurse `
+ -LiteralPath "$PSScriptRoot/../e2e_ports/vcpkg-internal-e2e-test-port" `
+ -Destination "$filesystemRegistry"
+New-Item `
+ -Path "$filesystemRegistry/versions" `
+ -ItemType Directory
+Copy-Item `
+ -LiteralPath "$PSScriptRoot/../e2e_ports/versions/baseline.json" `
+ -Destination "$filesystemRegistry/versions/baseline.json"
+New-Item `
+ -Path "$filesystemRegistry/versions/v-" `
+ -ItemType Directory
+
+$vcpkgInternalE2eTestPortJson = @{
+ "versions" = @(
+ @{
+ "version-string" = "1.0.0";
+ "path" = "$/vcpkg-internal-e2e-test-port"
+ }
+ )
+}
+New-Item `
+ -Path "$filesystemRegistry/versions/v-/vcpkg-internal-e2e-test-port.json" `
+ -ItemType File `
+ -Value (ConvertTo-Json -Depth 5 -InputObject $vcpkgInternalE2eTestPortJson)
+
+
+# build a git registry
+Write-Trace "build a git registry"
+New-Item -Path $gitRegistryUpstream -ItemType Directory
+$gitRegistryUpstream = (Get-Item $gitRegistryUpstream).FullName
+
+Push-Location $gitRegistryUpstream
+try
+{
+ $gitConfigOptions = @(
+ '-c', 'user.name=Nobody',
+ '-c', 'user.email=nobody@example.com',
+ '-c', 'core.autocrlf=false'
+ )
+
+ $CurrentTest = 'git init .'
+ git @gitConfigOptions init .
+ Throw-IfFailed
+ Copy-Item -Recurse -LiteralPath "$PSScriptRoot/../e2e_ports/vcpkg-internal-e2e-test-port" -Destination .
+ New-Item -Path './vcpkg-internal-e2e-test-port/foobar' -Value 'this is just to get a distinct git tree'
+
+ $CurrentTest = 'git add -A'
+ git @gitConfigOptions add -A
+ Throw-IfFailed
+ $CurrentTest = 'git commit'
+ git @gitConfigOptions commit -m 'initial commit'
+ Throw-IfFailed
+
+ $vcpkgInternalE2eTestPortGitTree = git rev-parse 'HEAD:vcpkg-internal-e2e-test-port'
+ $vcpkgInternalE2eTestPortVersionsJson = @{
+ "versions" = @(
+ @{
+ "version-string" = "1.0.0";
+ "git-tree" = $vcpkgInternalE2eTestPortGitTree
+ }
+ )
+ }
+ $vcpkgBaseline = @{
+ "default" = @{
+ "vcpkg-internal-e2e-test-port" = @{
+ "baseline" = "1.0.0"
+ }
+ }
+ }
+
+ New-Item -Path './versions' -ItemType Directory
+ New-Item -Path './versions/v-' -ItemType Directory
+
+ New-Item -Path './versions/baseline.json' -Value (ConvertTo-Json -Depth 5 -InputObject $vcpkgBaseline)
+ New-Item -Path './versions/v-/vcpkg-internal-e2e-test-port.json' -Value (ConvertTo-Json -Depth 5 -InputObject $vcpkgInternalE2eTestPortVersionsJson)
+
+ $CurrentTest = 'git add -A'
+ git @gitConfigOptions add -A
+ Throw-IfFailed
+ $CurrentTest = 'git commit'
+ git @gitConfigOptions commit --amend --no-edit
+ Throw-IfFailed
+}
+finally
+{
+ Pop-Location
+}
+
+# actually test the registries
+Write-Trace "actually test the registries"
+$vcpkgJson = @{
+ "name" = "manifest-test";
+ "version-string" = "1.0.0";
+ "dependencies" = @(
+ "vcpkg-internal-e2e-test-port"
+ )
+}
+
+# test the filesystem registry
+Write-Trace "test the filesystem registry"
+$manifestDir = "$TestingRoot/filesystem-registry-test-manifest-dir"
+
+New-Item -Path $manifestDir -ItemType Directory
+$manifestDir = (Get-Item $manifestDir).FullName
+
+Push-Location $manifestDir
+try
+{
+ New-Item -Path 'vcpkg.json' -ItemType File `
+ -Value (ConvertTo-Json -Depth 5 -InputObject $vcpkgJson)
+
+ $vcpkgConfigurationJson = @{
+ "default-registry" = $null;
+ "registries" = @(
+ @{
+ "kind" = "filesystem";
+ "path" = $filesystemRegistry;
+ "packages" = @( "vcpkg-internal-e2e-test-port" )
+ }
+ )
+ }
+ New-Item -Path 'vcpkg-configuration.json' -ItemType File `
+ -Value (ConvertTo-Json -Depth 5 -InputObject $vcpkgConfigurationJson)
+
+ Run-Vcpkg install @builtinRegistryArgs '--feature-flags=registries,manifests'
+ Throw-IfFailed
+}
+finally
+{
+ Pop-Location
+}
+
+# test the git registry
+Write-Trace "test the git registry"
+$manifestDir = "$TestingRoot/git-registry-test-manifest-dir"
+
+New-Item -Path $manifestDir -ItemType Directory
+$manifestDir = (Get-Item $manifestDir).FullName
+
+Push-Location $manifestDir
+try
+{
+ New-Item -Path 'vcpkg.json' -ItemType File `
+ -Value (ConvertTo-Json -Depth 5 -InputObject $vcpkgJson)
+
+ $vcpkgConfigurationJson = @{
+ "default-registry" = $null;
+ "registries" = @(
+ @{
+ "kind" = "git";
+ "repository" = $gitRegistryUpstream;
+ "packages" = @( "vcpkg-internal-e2e-test-port" )
+ }
+ )
+ }
+ New-Item -Path 'vcpkg-configuration.json' -ItemType File `
+ -Value (ConvertTo-Json -Depth 5 -InputObject $vcpkgConfigurationJson)
+
+ Run-Vcpkg install @builtinRegistryArgs '--feature-flags=registries,manifests'
+ Throw-IfFailed
+}
+finally
+{
+ Pop-Location
+}
diff --git a/azure-pipelines/end-to-end-tests-dir/spaces.ps1 b/azure-pipelines/end-to-end-tests-dir/spaces.ps1
new file mode 100644
index 0000000000..b7aaf6462c
--- /dev/null
+++ b/azure-pipelines/end-to-end-tests-dir/spaces.ps1
@@ -0,0 +1,11 @@
+. $PSScriptRoot/../end-to-end-tests-prelude.ps1
+
+##### Test spaces in the path
+$Script:CurrentTest = "zlib with spaces in path"
+Write-Host $Script:CurrentTest
+./vcpkg install zlib "--triplet" $Triplet `
+ "--no-binarycaching" `
+ "--x-buildtrees-root=$TestingRoot/build Trees" `
+ "--x-install-root=$TestingRoot/instalL ed" `
+ "--x-packages-root=$TestingRoot/packaG es"
+Throw-IfFailed
diff --git a/azure-pipelines/end-to-end-tests-dir/vcpkg-minimum-required.ps1 b/azure-pipelines/end-to-end-tests-dir/vcpkg-minimum-required.ps1
new file mode 100644
index 0000000000..8f512ae7a8
--- /dev/null
+++ b/azure-pipelines/end-to-end-tests-dir/vcpkg-minimum-required.ps1
@@ -0,0 +1,22 @@
+. $PSScriptRoot/../end-to-end-tests-prelude.ps1
+
+$successCases = @('vcpkg-requires-current-date', 'vcpkg-requires-old-date')
+foreach ($successCase in $successCases) {
+ $CurrentTest = "Should succeeed: ./vcpkg install $successCase"
+ Write-Host $CurrentTest
+ Run-Vcpkg install $successCase @commonArgs
+ if ($LastExitCode -ne 0) {
+ throw $CurrentTest
+ } else {
+ Write-Host "... succeeded."
+ }
+}
+
+$CurrentTest = "Should fail: ./vcpkg install vcpkg-requires-future-date"
+Write-Host $CurrentTest
+Run-Vcpkg install vcpkg-requires-future-date @commonArgs
+if ($LastExitCode -ne 0) {
+ Write-Host "... failed (this is good!)."
+} else {
+ throw $CurrentTest
+}
diff --git a/azure-pipelines/end-to-end-tests-dir/versions.ps1 b/azure-pipelines/end-to-end-tests-dir/versions.ps1
new file mode 100644
index 0000000000..0499a2b40a
--- /dev/null
+++ b/azure-pipelines/end-to-end-tests-dir/versions.ps1
@@ -0,0 +1,100 @@
+. $PSScriptRoot/../end-to-end-tests-prelude.ps1
+
+$versionFilesPath = "$env:VCPKG_ROOT/scripts/testing/version-files"
+
+# Test verify versions
+mkdir $VersionFilesRoot
+Copy-Item -Recurse "$versionFilesPath/versions_incomplete" $VersionFilesRoot
+$portsRedirectArgsOK = @(
+ "--feature-flags=versions",
+ "--x-builtin-ports-root=$versionFilesPath/ports",
+ "--x-builtin-registry-versions-dir=$versionFilesPath/versions"
+)
+$portsRedirectArgsIncomplete = @(
+ "--feature-flags=versions",
+ "--x-builtin-ports-root=$versionFilesPath/ports_incomplete",
+ "--x-builtin-registry-versions-dir=$VersionFilesRoot/versions_incomplete"
+)
+$CurrentTest = "x-verify-ci-versions (All files OK)"
+Write-Host $CurrentTest
+./vcpkg $portsRedirectArgsOK x-ci-verify-versions --verbose
+Throw-IfFailed
+
+$CurrentTest = "x-verify-ci-versions (Incomplete)"
+./vcpkg $portsRedirectArgsIncomplete x-ci-verify-versions --verbose
+Throw-IfNotFailed
+
+$CurrentTest = "x-add-version cat"
+# Do not fail if there's nothing to update
+./vcpkg $portsRedirectArgsIncomplete x-add-version cat
+Throw-IfFailed
+
+$CurrentTest = "x-add-version dog"
+# Local version is not in baseline and versions file
+./vcpkg $portsRedirectArgsIncomplete x-add-version dog
+Throw-IfFailed
+
+$CurrentTest = "x-add-version duck"
+# Missing versions file
+./vcpkg $portsRedirectArgsIncomplete x-add-version duck
+Throw-IfFailed
+
+$CurrentTest = "x-add-version ferret"
+# Missing versions file and missing baseline entry
+./vcpkg $portsRedirectArgsIncomplete x-add-version ferret
+Throw-IfFailed
+
+$CurrentTest = "x-add-version fish (must fail)"
+# Discrepancy between local SHA and SHA in fish.json. Requires --overwrite-version.
+$out = ./vcpkg $portsRedirectArgsIncomplete x-add-version fish
+Throw-IfNotFailed
+$CurrentTest = "x-add-version fish --overwrite-version"
+./vcpkg $portsRedirectArgsIncomplete x-add-version fish --overwrite-version
+Throw-IfFailed
+
+$CurrentTest = "x-add-version mouse"
+# Missing baseline entry
+./vcpkg $portsRedirectArgsIncomplete x-add-version mouse
+Throw-IfFailed
+# Validate changes
+./vcpkg $portsRedirectArgsIncomplete x-ci-verify-versions --verbose
+Throw-IfFailed
+
+$CurrentTest = "default baseline"
+$out = ./vcpkg $commonArgs "--feature-flags=versions" install --x-manifest-root=$versionFilesPath/default-baseline-1 2>&1 | Out-String
+Throw-IfNotFailed
+if ($out -notmatch ".*Error: while checking out baseline.*")
+{
+ $out
+ throw "Expected to fail due to missing baseline"
+}
+
+git -C "$env:VCPKG_ROOT" fetch https://github.com/vicroms/test-registries
+foreach ($opt_registries in @("",",registries"))
+{
+ Write-Trace "testing baselines: $opt_registries"
+ Refresh-TestRoot
+ $CurrentTest = "without default baseline 2 -- enabling versions should not change behavior"
+ Remove-Item -Recurse $buildtreesRoot/versioning -ErrorAction SilentlyContinue
+ ./vcpkg $commonArgs "--feature-flags=versions$opt_registries" install `
+ "--dry-run" `
+ "--x-manifest-root=$versionFilesPath/without-default-baseline-2" `
+ "--x-builtin-registry-versions-dir=$versionFilesPath/default-baseline-2/versions"
+ Throw-IfFailed
+ Require-FileNotExists $buildtreesRoot/versioning
+
+ $CurrentTest = "default baseline 2"
+ ./vcpkg $commonArgs "--feature-flags=versions$opt_registries" install `
+ "--dry-run" `
+ "--x-manifest-root=$versionFilesPath/default-baseline-2" `
+ "--x-builtin-registry-versions-dir=$versionFilesPath/default-baseline-2/versions"
+ Throw-IfFailed
+ Require-FileExists $buildtreesRoot/versioning
+
+ $CurrentTest = "using version features fails without flag"
+ ./vcpkg $commonArgs "--feature-flags=-versions$opt_registries" install `
+ "--dry-run" `
+ "--x-manifest-root=$versionFilesPath/default-baseline-2" `
+ "--x-builtin-registry-versions-dir=$versionFilesPath/default-baseline-2/versions"
+ Throw-IfNotFailed
+}
diff --git a/azure-pipelines/end-to-end-tests-prelude.ps1 b/azure-pipelines/end-to-end-tests-prelude.ps1
new file mode 100644
index 0000000000..497f4fc941
--- /dev/null
+++ b/azure-pipelines/end-to-end-tests-prelude.ps1
@@ -0,0 +1,80 @@
+$TestingRoot = Join-Path $WorkingRoot 'testing'
+$buildtreesRoot = Join-Path $TestingRoot 'buildtrees'
+$installRoot = Join-Path $TestingRoot 'installed'
+$packagesRoot = Join-Path $TestingRoot 'packages'
+$NuGetRoot = Join-Path $TestingRoot 'nuget'
+$NuGetRoot2 = Join-Path $TestingRoot 'nuget2'
+$ArchiveRoot = Join-Path $TestingRoot 'archives'
+$VersionFilesRoot = Join-Path $env:VCPKG_ROOT 'version-test'
+$commonArgs = @(
+ "--triplet",
+ $Triplet,
+ "--x-buildtrees-root=$buildtreesRoot",
+ "--x-install-root=$installRoot",
+ "--x-packages-root=$packagesRoot",
+ "--overlay-ports=$PSScriptRoot/e2e_ports/overlays"
+)
+$Script:CurrentTest = 'unassigned'
+
+if ($IsWindows)
+{
+ $VcpkgExe = Get-Item './vcpkg.exe'
+}
+else
+{
+ $VcpkgExe = Get-Item './vcpkg'
+}
+
+function Refresh-TestRoot {
+ Remove-Item -Recurse -Force $TestingRoot -ErrorAction SilentlyContinue
+ mkdir $TestingRoot | Out-Null
+ mkdir $NuGetRoot | Out-Null
+}
+
+function Require-FileExists {
+ [CmdletBinding()]
+ Param(
+ [string]$File
+ )
+ if (-Not (Test-Path $File)) {
+ throw "'$Script:CurrentTest' failed to create file '$File'"
+ }
+}
+
+function Require-FileNotExists {
+ [CmdletBinding()]
+ Param(
+ [string]$File
+ )
+ if (Test-Path $File) {
+ throw "'$Script:CurrentTest' should not have created file '$File'"
+ }
+}
+
+function Throw-IfFailed {
+ if ($LASTEXITCODE -ne 0) {
+ throw "'$Script:CurrentTest' had a step with a nonzero exit code"
+ }
+}
+
+function Throw-IfNotFailed {
+ if ($LASTEXITCODE -eq 0) {
+ throw "'$Script:CurrentTest' had a step with an unexpectedly zero exit code"
+ }
+}
+
+function Write-Trace ([string]$text) {
+ Write-Host (@($MyInvocation.ScriptName, ":", $MyInvocation.ScriptLineNumber, ": ", $text) -join "")
+}
+
+function Run-Vcpkg {
+ Param(
+ [Parameter(ValueFromRemainingArguments)]
+ [string[]]$TestArgs
+ )
+ $Script:CurrentTest = "vcpkg $($testArgs -join ' ')"
+ Write-Host $Script:CurrentTest
+ & $VcpkgExe @testArgs
+}
+
+Refresh-TestRoot
diff --git a/azure-pipelines/end-to-end-tests.ps1 b/azure-pipelines/end-to-end-tests.ps1
new file mode 100644
index 0000000000..d25bc67ff1
--- /dev/null
+++ b/azure-pipelines/end-to-end-tests.ps1
@@ -0,0 +1,59 @@
+# Copyright (c) Microsoft Corporation.
+# SPDX-License-Identifier: MIT
+#
+<#
+.SYNOPSIS
+End-to-End tests for the vcpkg executable.
+
+.DESCRIPTION
+These tests cover the command line interface and broad functions of vcpkg, including `install`, `remove` and certain
+binary caching scenarios. They use the vcpkg executable in the current directory.
+
+.PARAMETER Triplet
+The triplet to use for testing purposes.
+
+.PARAMETER WorkingRoot
+The location used as scratch space for testing.
+
+#>
+
+[CmdletBinding()]
+Param(
+ [Parameter(Mandatory = $true)]
+ [ValidateNotNullOrEmpty()]
+ [string]$Triplet,
+ [Parameter(Mandatory = $true)]
+ [ValidateNotNullOrEmpty()]
+ [string]$WorkingRoot,
+ [Parameter(Mandatory = $true)]
+ [string]$VcpkgRoot,
+ [Parameter(Mandatory = $false)]
+ [ValidateNotNullOrEmpty()]
+ [string]$Filter
+)
+
+$ErrorActionPreference = "Stop"
+
+if (-Not (Test-Path $WorkingRoot)) {
+ New-Item -Path $WorkingRoot -ItemType Directory
+}
+
+$WorkingRoot = (Get-Item $WorkingRoot).FullName
+$VcpkgRoot = (Get-Item $VcpkgRoot).FullName
+$env:VCPKG_ROOT = $VcpkgRoot
+
+$AllTests = Get-ChildItem $PSScriptRoot/end-to-end-tests-dir/*.ps1
+if ($Filter -ne $Null) {
+ $AllTests = $AllTests | ? { $_.Name -match $Filter }
+}
+$n = 1
+$m = $AllTests.Count
+
+$AllTests | % {
+ Write-Host "[end-to-end-tests.ps1] [$n/$m] Running suite $_"
+ & $_
+ $n += 1
+}
+
+Write-Host "[end-to-end-tests.ps1] All tests passed."
+$LASTEXITCODE = 0
diff --git a/azure-pipelines/pipelines.yml b/azure-pipelines/pipelines.yml
new file mode 100644
index 0000000000..518894da4b
--- /dev/null
+++ b/azure-pipelines/pipelines.yml
@@ -0,0 +1,103 @@
+variables:
+ VCPKG_REPO_COMMIT_SHA: '401b26c9866a071f645ae57831caa419b2c48be1'
+jobs:
+- job: linux
+ displayName: 'Linux'
+ pool:
+ vmImage: 'ubuntu-latest'
+ variables:
+ - name: 'VCPKG_ROOT'
+ value: $(Build.SourcesDirectory)/vcpkg-root
+ steps:
+ - bash: |
+ git clone https://github.com/microsoft/vcpkg "$VCPKG_ROOT" -n
+ git -C "$VCPKG_ROOT" checkout $VCPKG_REPO_COMMIT_SHA
+ displayName: "Clone vcpkg repo to serve as root"
+ - bash: |
+ cmake -DCMAKE_BUILD_TYPE=Debug -DBUILD_TESTING=ON -DVCPKG_DEVELOPMENT_WARNINGS=ON -DVCPKG_WARNINGS_AS_ERRORS=ON -DVCPKG_BUILD_FUZZING=ON -B build.amd64.debug
+ make -j 2 -C build.amd64.debug
+ displayName: "Build vcpkg with CMake"
+ failOnStderr: true
+ - bash: build.amd64.debug/vcpkg-test
+ displayName: 'Run vcpkg tests'
+ - task: PowerShell@2
+ displayName: 'Run vcpkg end-to-end tests'
+ inputs:
+ filePath: 'azure-pipelines/end-to-end-tests.ps1'
+ arguments: '-Triplet x64-linux -WorkingRoot work -VcpkgRoot $(VCPKG_ROOT)'
+ workingDirectory: '$(Build.SourcesDirectory)/build.amd64.debug'
+ pwsh: true
+- job: osx
+ displayName: 'OSX'
+ pool:
+ vmImage: 'macos-latest'
+ variables:
+ - name: 'VCPKG_ROOT'
+ value: $(Build.SourcesDirectory)/vcpkg-root
+ steps:
+ - bash: |
+ git clone https://github.com/microsoft/vcpkg "$VCPKG_ROOT" -n
+ git -C "$VCPKG_ROOT" checkout $VCPKG_REPO_COMMIT_SHA
+ displayName: "Clone vcpkg repo to serve as root"
+ - bash: |
+ cmake -DCMAKE_BUILD_TYPE=Debug -DBUILD_TESTING=ON -DVCPKG_DEVELOPMENT_WARNINGS=ON -DVCPKG_WARNINGS_AS_ERRORS=ON -DVCPKG_BUILD_FUZZING=ON -B build.amd64.debug
+ make -j 2 -C build.amd64.debug
+ displayName: "Build vcpkg with CMake"
+ failOnStderr: true
+ - bash: build.amd64.debug/vcpkg-test
+ displayName: 'Run vcpkg tests'
+ - task: PowerShell@2
+ displayName: 'Run vcpkg end-to-end tests'
+ inputs:
+ filePath: 'azure-pipelines/end-to-end-tests.ps1'
+ arguments: '-Triplet x64-osx -WorkingRoot work -VcpkgRoot $(VCPKG_ROOT)'
+ workingDirectory: '$(Build.SourcesDirectory)/build.amd64.debug'
+ pwsh: true
+- job: windows
+ displayName: 'Windows'
+ pool:
+ vmImage: 'windows-latest'
+ variables:
+ - name: DiffFile
+ value: $(Build.ArtifactStagingDirectory)\format.diff
+ - name: 'VCPKG_ROOT'
+ value: $(Build.SourcesDirectory)\vcpkg-root
+ steps:
+ - task: Powershell@2
+ displayName: 'Format C++'
+ inputs:
+ filePath: 'azure-pipelines/Format-CxxCode.ps1'
+ pwsh: true
+ - task: Powershell@2
+ displayName: 'Create Diff'
+ inputs:
+ filePath: azure-pipelines/Create-PRDiff.ps1
+ arguments: '-DiffFile $(DiffFile)'
+ pwsh: true
+ - task: PublishBuildArtifacts@1
+ condition: failed()
+ displayName: 'Publish Format and Documentation Diff'
+ inputs:
+ PathtoPublish: '$(DiffFile)'
+ ArtifactName: 'format.diff'
+ - script: |
+ git clone https://github.com/microsoft/vcpkg "%VCPKG_ROOT%" -n
+ git -C "%VCPKG_ROOT%" checkout %VCPKG_REPO_COMMIT_SHA%
+ displayName: "Clone vcpkg repo to serve as root"
+ - task: CmdLine@2
+ displayName: "Build vcpkg with CMake, and Run Tests"
+ inputs:
+ script: |
+ call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\Tools\VsDevCmd.bat" -arch=x86 -host_arch=x86
+ rmdir /s /q build.x86.debug > nul 2> nul
+ cmake.exe -G Ninja -DCMAKE_BUILD_TYPE=Debug -DBUILD_TESTING=ON -DVCPKG_DEVELOPMENT_WARNINGS=ON -DVCPKG_WARNINGS_AS_ERRORS=ON -DVCPKG_BUILD_FUZZING=ON -B build.x86.debug
+ ninja.exe -C build.x86.debug
+ build.x86.debug\vcpkg-test.exe
+ failOnStderr: true
+ - task: PowerShell@2
+ displayName: 'Run vcpkg end-to-end tests'
+ inputs:
+ filePath: 'azure-pipelines/end-to-end-tests.ps1'
+ arguments: '-Triplet x86-windows -WorkingRoot work -VcpkgRoot "$(VCPKG_ROOT)"'
+ workingDirectory: '$(Build.SourcesDirectory)/build.x86.debug'
+ pwsh: true