Skip to content
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
299 changes: 299 additions & 0 deletions azure-pipelines/end-to-end-tests-dir/update-baseline.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,299 @@
. $PSScriptRoot/../end-to-end-tests-prelude.ps1

$env:X_VCPKG_REGISTRIES_CACHE = Join-Path $TestingRoot 'registries'
New-Item -ItemType Directory -Force $env:X_VCPKG_REGISTRIES_CACHE | Out-Null

function New-TestRegistry {
Param(
[Parameter(Mandatory = $true)]
[string]$Path
)

New-Item -Path $Path -ItemType Directory -Force | Out-Null
$Path = (Get-Item $Path).FullName

git -C $Path @gitConfigOptions init . | Out-Null
Throw-IfFailed

return [pscustomobject]@{
Path = $Path
Current = @{}
Versions = @{}
}
}

function Set-TestRegistryPort {
Param(
[Parameter(Mandatory = $true)]
[string]$RegistryPath,
[Parameter(Mandatory = $true)]
[string]$Name,
[Parameter(Mandatory = $true)]
[string]$Version,
[string[]]$Dependencies = @()
)

$portDir = Join-Path $RegistryPath "ports/$Name"
New-Item -Path $portDir -ItemType Directory -Force | Out-Null
Set-Content -LiteralPath (Join-Path $portDir 'portfile.cmake') `
-Value 'set(VCPKG_POLICY_EMPTY_PACKAGE enabled)' `
-Encoding Ascii

$manifest = [ordered]@{
name = $Name
version = $Version
}

if ($Dependencies.Count -ne 0) {
$manifest.dependencies = $Dependencies
}

Set-Content -LiteralPath (Join-Path $portDir 'vcpkg.json') `
-Value (ConvertTo-Json -Depth 10 -InputObject $manifest) `
-Encoding Ascii `
-NoNewline
}

function Add-TestRegistryCommit {
Param(
[Parameter(Mandatory = $true)]
$Registry,
[Parameter(Mandatory = $true)]
[hashtable[]]$Ports,
[Parameter(Mandatory = $true)]
[string]$Message
)

foreach ($port in $Ports) {
$previousVersion = $null
if ($Registry.Current.ContainsKey($port.Name)) {
$previousVersion = $Registry.Current[$port.Name]
}

if ($previousVersion -ne $port.Version) {
if ($port.ContainsKey('Dependencies')) {
Set-TestRegistryPort -RegistryPath $Registry.Path -Name $port.Name -Version $port.Version -Dependencies $port.Dependencies
} else {
Set-TestRegistryPort -RegistryPath $Registry.Path -Name $port.Name -Version $port.Version
}
}

$Registry.Current[$port.Name] = $port.Version
}

git -C $Registry.Path @gitConfigOptions add ports | Out-Null
Throw-IfFailed
git -C $Registry.Path @gitConfigOptions commit --allow-empty -m $Message | Out-Null
Throw-IfFailed

foreach ($port in $Ports) {
if (@($Registry.Versions[$port.Name])[0].version -eq $port.Version) {
continue
}

$gitTree = git -C $Registry.Path rev-parse "HEAD:ports/$($port.Name)"
Throw-IfFailed

$versionEntry = [ordered]@{
'git-tree' = $gitTree
version = $port.Version
}

$previousVersions = @()
if ($Registry.Versions.ContainsKey($port.Name)) {
$previousVersions = @($Registry.Versions[$port.Name])
}

$Registry.Versions[$port.Name] = @($versionEntry) + $previousVersions
}

$baseline = [ordered]@{ default = [ordered]@{} }
foreach ($portName in ($Registry.Current.Keys | Sort-Object)) {
$baseline.default[$portName] = [ordered]@{ baseline = $Registry.Current[$portName] }
}

New-Item -Path (Join-Path $Registry.Path 'versions') -ItemType Directory -Force | Out-Null
Set-Content -LiteralPath (Join-Path $Registry.Path 'versions/baseline.json') `
-Value (ConvertTo-Json -Depth 10 -InputObject $baseline) `
-Encoding Ascii `
-NoNewline

foreach ($portName in $Registry.Versions.Keys) {
$versionDir = Join-Path $Registry.Path "versions/$($portName[0])-"
New-Item -Path $versionDir -ItemType Directory -Force | Out-Null
$versionFile = [ordered]@{ versions = @($Registry.Versions[$portName]) }
Set-Content -LiteralPath (Join-Path $versionDir "$portName.json") `
-Value (ConvertTo-Json -Depth 10 -InputObject $versionFile) `
-Encoding Ascii `
-NoNewline
}

git -C $Registry.Path @gitConfigOptions add -A | Out-Null
Throw-IfFailed
git -C $Registry.Path @gitConfigOptions commit --amend --no-edit --allow-empty | Out-Null
Throw-IfFailed

$baselineCommit = git -C $Registry.Path rev-parse HEAD
Throw-IfFailed
return $baselineCommit
}

function New-TestManifest {
Param(
[Parameter(Mandatory = $true)]
[string]$Path,
[Parameter(Mandatory = $true)]
[string[]]$Dependencies,
[Parameter(Mandatory = $true)]
[hashtable]$Configuration
)

New-Item -Path $Path -ItemType Directory -Force | Out-Null
Set-Content -LiteralPath (Join-Path $Path 'vcpkg.json') `
-Value (ConvertTo-Json -Depth 10 -InputObject ([ordered]@{
name = 'update-baseline-test'
version = '1.0.0'
dependencies = $Dependencies
})) `
-Encoding Ascii `
-NoNewline
Set-Content -LiteralPath (Join-Path $Path 'vcpkg-configuration.json') `
-Value (ConvertTo-Json -Depth 10 -InputObject $Configuration) `
-Encoding Ascii `
-NoNewline
}

function Invoke-UpdateBaselineDryRun {
Param(
[Parameter(Mandatory = $true)]
[string]$ManifestRoot,
[switch]$Quiet
)

$args = @('x-update-baseline') + $commonArgs + @('--dry-run', "--x-manifest-root=$ManifestRoot")
if ($Quiet) {
$args += '--quiet'
}

$out = Run-VcpkgAndCaptureOutput @args
Throw-IfFailed
return $out
}

function New-GitRegistryConfiguration {
Param(
[Parameter(Mandatory = $true)]
[string]$Repository,
[Parameter(Mandatory = $true)]
[string]$Baseline,
[Parameter(Mandatory = $true)]
[string[]]$Packages
)

return [ordered]@{
kind = 'git'
repository = $Repository
baseline = $Baseline
packages = $Packages
}
}

function New-DefaultGitRegistryConfiguration {
Param(
[Parameter(Mandatory = $true)]
[string]$Repository,
[Parameter(Mandatory = $true)]
[string]$Baseline
)

return [ordered]@{
kind = 'git'
repository = $Repository
baseline = $Baseline
}
}

Write-Trace 'build update-baseline registries'
$primaryRegistry = New-TestRegistry (Join-Path $TestingRoot 'primary-registry')
$primaryOldBaseline = Add-TestRegistryCommit -Registry $primaryRegistry -Message 'primary 1.0.0' -Ports @(
@{ Name = 'direct-port'; Version = '1.0.0'; Dependencies = @('transitive-port') },
@{ Name = 'transitive-port'; Version = '1.0.0' }
)
$primaryNewBaseline = Add-TestRegistryCommit -Registry $primaryRegistry -Message 'primary 2.0.0' -Ports @(
@{ Name = 'direct-port'; Version = '2.0.0'; Dependencies = @('transitive-port') },
@{ Name = 'transitive-port'; Version = '1.1.0' }
)

$unchangedSharedRegistry = New-TestRegistry (Join-Path $TestingRoot 'unchanged-shared-registry')
$unchangedSharedOldBaseline = Add-TestRegistryCommit -Registry $unchangedSharedRegistry -Message 'shared unchanged 1.0.0' -Ports @(
@{ Name = 'shared-port'; Version = '1.0.0' }
)
$unchangedSharedNewBaseline = Add-TestRegistryCommit -Registry $unchangedSharedRegistry -Message 'shared unchanged still 1.0.0' -Ports @(
@{ Name = 'shared-port'; Version = '1.0.0' }
)

$updatedSharedRegistry = New-TestRegistry (Join-Path $TestingRoot 'updated-shared-registry')
$updatedSharedOldBaseline = Add-TestRegistryCommit -Registry $updatedSharedRegistry -Message 'shared updated 1.0.0' -Ports @(
@{ Name = 'shared-port'; Version = '1.0.0' }
)
$updatedSharedNewBaseline = Add-TestRegistryCommit -Registry $updatedSharedRegistry -Message 'shared updated 2.0.0' -Ports @(
@{ Name = 'shared-port'; Version = '2.0.0' }
)

Write-Trace 'test direct and transitive dependency diff output'
$manifestDir = Join-Path $TestingRoot 'direct-and-transitive'
New-TestManifest -Path $manifestDir -Dependencies @('direct-port') -Configuration ([ordered]@{
'default-registry' = New-DefaultGitRegistryConfiguration -Repository $primaryRegistry.Path -Baseline $primaryOldBaseline
})

$out = Invoke-UpdateBaselineDryRun -ManifestRoot $manifestDir
Throw-IfNonContains -Actual $out -Expected @"
Updating baselines has resulted in the following version updates:

Direct dependencies:
direct-port: 1.0.0 -> 2.0.0

Transitive dependencies:
transitive-port: 1.0.0 -> 1.1.0
"@

Write-Trace 'test quiet suppresses dependency diff output'
$out = Invoke-UpdateBaselineDryRun -ManifestRoot $manifestDir -Quiet
Throw-IfContains -Actual $out -Expected 'Updating baselines has resulted in the following version updates:'
Throw-IfContains -Actual $out -Expected 'direct-port: 1.0.0 -> 2.0.0'
Throw-IfContains -Actual $out -Expected 'transitive-port: 1.0.0 -> 1.1.0'

Write-Trace 'test no dependency diff output when baseline is already current'
$manifestDir = Join-Path $TestingRoot 'no-port-changes'
New-TestManifest -Path $manifestDir -Dependencies @('direct-port') -Configuration ([ordered]@{
'default-registry' = New-DefaultGitRegistryConfiguration -Repository $primaryRegistry.Path -Baseline $primaryNewBaseline
})

$out = Invoke-UpdateBaselineDryRun -ManifestRoot $manifestDir
Throw-IfNonContains -Actual $out -Expected 'There were no changes in the ports.'
Throw-IfContains -Actual $out -Expected 'direct-port: 1.0.0 -> 2.0.0'

Write-Trace 'test shared port selected from updated registry is included in diff'
$manifestDir = Join-Path $TestingRoot 'shared-port-updated-registry-selected'
New-TestManifest -Path $manifestDir -Dependencies @('shared-port') -Configuration ([ordered]@{
'default-registry' = New-DefaultGitRegistryConfiguration -Repository $unchangedSharedRegistry.Path -Baseline $unchangedSharedOldBaseline
registries = @(
(New-GitRegistryConfiguration -Repository $updatedSharedRegistry.Path -Baseline $updatedSharedOldBaseline -Packages @('shared-port'))
)
})

$out = Invoke-UpdateBaselineDryRun -ManifestRoot $manifestDir
Throw-IfNonContains -Actual $out -Expected 'shared-port: 1.0.0 -> 2.0.0'

Write-Trace 'test shared port selected from unchanged registry is excluded from diff'
$manifestDir = Join-Path $TestingRoot 'shared-port-unchanged-registry-selected'
New-TestManifest -Path $manifestDir -Dependencies @('shared-port') -Configuration ([ordered]@{
'default-registry' = New-DefaultGitRegistryConfiguration -Repository $updatedSharedRegistry.Path -Baseline $updatedSharedOldBaseline
registries = @(
(New-GitRegistryConfiguration -Repository $unchangedSharedRegistry.Path -Baseline $unchangedSharedOldBaseline -Packages @('shared-port'))
)
})

$out = Invoke-UpdateBaselineDryRun -ManifestRoot $manifestDir
Throw-IfContains -Actual $out -Expected 'shared-port: 1.0.0 -> 2.0.0'
Throw-IfNonContains -Actual $out -Expected 'There were no changes in the ports.'
1 change: 1 addition & 0 deletions include/vcpkg/base/contractual-constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,7 @@ namespace vcpkg
inline constexpr StringLiteral SwitchPrintmetrics = "printmetrics";
inline constexpr StringLiteral SwitchPurge = "purge";
inline constexpr StringLiteral SwitchPython = "python";
inline constexpr StringLiteral SwitchQuiet = "quiet";
inline constexpr StringLiteral SwitchRaw = "raw";
inline constexpr StringLiteral SwitchRecurse = "recurse";
inline constexpr StringLiteral SwitchRegistriesCache = "registries-cache";
Expand Down
22 changes: 18 additions & 4 deletions include/vcpkg/base/message-data.inc.h
Original file line number Diff line number Diff line change
Expand Up @@ -874,6 +874,7 @@ DECLARE_MESSAGE(CmdUpdateBaselineOptInitial,
(),
"",
"Adds a `builtin-baseline` to a vcpkg.json that doesn't already have it")
DECLARE_MESSAGE(CmdUpdateBaselineOptQuiet, (), "", "Does not print the port version diff after updating baselines")
DECLARE_MESSAGE(CmdUpdateBaselineSynopsis,
(),
"",
Expand Down Expand Up @@ -1056,6 +1057,7 @@ DECLARE_MESSAGE(DependencyWillFail,
"'cascade' is a keyword and should not be translated",
"Dependency {feature_spec} will not build => cascade")
DECLARE_MESSAGE(DetectCompilerHash, (msg::triplet), "", "Detecting compiler hash for triplet {triplet}...")
DECLARE_MESSAGE(DirectDependencies, (), "", "Direct dependencies")
DECLARE_MESSAGE(DirectoriesRelativeToThePackageDirectoryHere,
(),
"",
Expand Down Expand Up @@ -2666,7 +2668,7 @@ DECLARE_MESSAGE(PortMissingManifest2,
"",
"{package_name} port manifest missing (no vcpkg.json or CONTROL file)")
DECLARE_MESSAGE(PortNotSupported, (msg::package_name, msg::triplet), "", "{package_name} is not supported on {triplet}")
DECLARE_MESSAGE(PortsNoDiff, (), "", "There were no changes in the ports between the two commits.")
DECLARE_MESSAGE(PortsNoDiff, (), "", "There were no changes in the ports.")

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

It was actually wrong for portsdiff because sometimes the user only specifies one commit there

DECLARE_MESSAGE(PortsRemoved, (msg::count), "", "The following {count} ports were removed:")
DECLARE_MESSAGE(PortsUpdated, (msg::count), "", "The following {count} ports were updated:")
DECLARE_MESSAGE(PortSupportsField, (msg::supports_expression), "", "(supports: \"{supports_expression}\")")
Expand Down Expand Up @@ -2867,6 +2869,7 @@ DECLARE_MESSAGE(ToUpdatePackages,
"To update these packages and all dependencies, run\n{command_name} upgrade'")
DECLARE_MESSAGE(TrailingCommaInArray, (), "", "Trailing comma in array")
DECLARE_MESSAGE(TrailingCommaInObj, (), "", "Trailing comma in an object")
DECLARE_MESSAGE(TransitiveDependencies, (), "", "Transitive dependencies")
DECLARE_MESSAGE(TripletLabel, (), "", "Triplet:")
DECLARE_MESSAGE(TripletFileNotFound, (msg::triplet), "", "Triplet file {triplet}.cmake not found")
DECLARE_MESSAGE(TwoFeatureFlagsSpecified,
Expand Down Expand Up @@ -3114,15 +3117,26 @@ DECLARE_MESSAGE(UpdateBaselineNoExistingBuiltinBaseline,
"",
"the manifest file currently does not contain a `builtin-baseline` field; in order to "
"add one, pass the --{option} switch.")
DECLARE_MESSAGE(UpdateBaselineNewDependencyVersion,
(msg::package_name, msg::version),
"example of {package_name} is zlib. example of {version} is 1.3.2#1",
"{package_name}: new: {version}")
DECLARE_MESSAGE(UpdateBaselineNoUpdate,
(msg::url, msg::value),
"example of {value} is '5507daa796359fe8d45418e694328e878ac2b82f'",
"registry '{url}' not updated: '{value}'")
DECLARE_MESSAGE(UpdateBaselineRemoteGitError, (msg::url), "", "git failed to fetch remote repository '{url}'")
"registry '{url}' not updated: {value}")
DECLARE_MESSAGE(UpdateBaselineRemovedDependencyVersion,
(msg::package_name, msg::version),
"example of {package_name} is zlib. example of {version} is 1.3.2#1",
"{package_name}: removed: {version}")
DECLARE_MESSAGE(UpdateBaselineVersionUpdates,
(),
"",
"Updating baselines has resulted in the following version updates:")
DECLARE_MESSAGE(UpdateBaselineUpdatedBaseline,
(msg::url, msg::old_value, msg::new_value),
"example of {old_value}, {new_value} is '5507daa796359fe8d45418e694328e878ac2b82f'",
"updated registry '{url}': baseline '{old_value}' -> '{new_value}'")
"updated registry '{url}': {old_value} -> {new_value}")
DECLARE_MESSAGE(
UpgradeInManifest,
(),
Expand Down
6 changes: 5 additions & 1 deletion include/vcpkg/commands.update-baseline.h
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
#pragma once

#include <vcpkg/fwd/triplet.h>
#include <vcpkg/fwd/vcpkgcmdarguments.h>
#include <vcpkg/fwd/vcpkgpaths.h>

namespace vcpkg
{
extern const CommandMetadata CommandUpdateBaselineMetadata;
void command_update_baseline_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths);
void command_update_baseline_and_exit(const VcpkgCmdArguments& args,
const VcpkgPaths& paths,
Triplet default_triplet,
Triplet host_triplet);
}
Loading
Loading