Skip to content
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ BeforeAll {
'export', 'fetch', 'find', 'format-feature-baseline', 'format-manifest', 'hash', 'help', 'install', 'integrate',
'license-report', 'list', 'new', 'owns', 'portsdiff', 'remove', 'search', 'update', 'upgrade', 'use', 'version',
'x-add-version', 'x-check-support', 'x-init-registry', 'x-package-info', 'x-regenerate', 'x-set-installed',
'x-test-features', 'x-update-baseline', 'x-update-registry', 'x-vsinstances'
'x-test-features', 'x-update-baseline', 'x-update-registry', 'x-vsinstances', 'x-baseline-diff'
)
CommonParameterList = @()
CommandOptionList = @{
Expand Down
250 changes: 250 additions & 0 deletions azure-pipelines/end-to-end-tests-dir/baseline-diff.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,250 @@
. $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

# =====================================================================
# Helper: write a minimal empty test port
# =====================================================================
function New-TestPort {
param(
[string]$PortsRoot,
[string]$Name,
[string]$Version
)
$portDir = Join-Path $PortsRoot $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
Set-Content -LiteralPath (Join-Path $portDir 'vcpkg.json') `
-Value "{`"name`": `"$Name`", `"version`": `"$Version`"}" -Encoding Ascii
}

# =====================================================================
# Builtin registry tests use two real vcpkg release tags so that:
# - ref resolution is exercised against real tags in VCPKG_ROOT
# - the expected version change is stable and documented
#
# curl changed 8.11.0 -> 8.11.1 between the 2024.11.16 and 2024.12.16
# releases (https://github.com/microsoft/vcpkg/releases).
# =====================================================================
Write-Trace "Resolve vcpkg release tags to SHAs"
$oldTag = '2024.11.16'
$newTag = '2024.12.16'
# builtin-baseline in vcpkg.json must be a full 40-char SHA.
$oldSha = git -C $env:VCPKG_ROOT rev-parse $oldTag
Throw-IfFailed
$newSha = git -C $env:VCPKG_ROOT rev-parse $newTag
Throw-IfFailed

# Feature flag needed because the manifest carries builtin-baseline.
$builtinArgs = @('--feature-flags=versions')

# Manifest: depends on curl, whose version changed between the two releases.
$manifestDir = "$TestingRoot/manifest-builtin"
New-Item -Path $manifestDir -ItemType Directory | Out-Null
$manifestDir = (Get-Item $manifestDir).FullName
Set-Content -LiteralPath "$manifestDir/vcpkg.json" -Encoding Ascii -Value @"
{
"name": "baseline-diff-test",
"version-string": "0",
"builtin-baseline": "$oldSha",
"dependencies": [ "curl" ]
}
"@

# =====================================================================
# Test 1: Builtin registry — two explicit SHAs, expect known curl update
# =====================================================================
Write-Trace "Test: builtin registry with two explicit SHAs"
$CurrentTest = 'x-baseline-diff builtin two SHAs'
$Output = Run-VcpkgAndCaptureOutput x-baseline-diff @commonArgs @builtinArgs `
"--x-manifest-root=$manifestDir" $oldSha $newSha
Throw-IfFailed
Throw-IfNonContains -Actual $Output -Expected 'curl'
Throw-IfNonContains -Actual $Output -Expected '8.11.0'
Throw-IfNonContains -Actual $Output -Expected '8.11.1'

# =====================================================================
# Test 2: Builtin registry — one SHA, manifest builtin-baseline as old
# =====================================================================
Write-Trace "Test: builtin registry with one SHA (manifest provides old baseline)"
$CurrentTest = 'x-baseline-diff builtin one SHA'
$Output = Run-VcpkgAndCaptureOutput x-baseline-diff @commonArgs @builtinArgs `
"--x-manifest-root=$manifestDir" $newSha
Throw-IfFailed
Throw-IfNonContains -Actual $Output -Expected 'curl'
Throw-IfNonContains -Actual $Output -Expected '8.11.0'
Throw-IfNonContains -Actual $Output -Expected '8.11.1'

# =====================================================================
# Test 3: Builtin registry — real release tags as arguments (ref resolution)
# No temporary tags needed; the release tags already exist in VCPKG_ROOT.
# =====================================================================
Write-Trace "Test: builtin registry with release tags (ref resolution)"
$CurrentTest = 'x-baseline-diff builtin with tags'
$Output = Run-VcpkgAndCaptureOutput x-baseline-diff @commonArgs @builtinArgs `
"--x-manifest-root=$manifestDir" $oldTag $newTag
Throw-IfFailed
Throw-IfNonContains -Actual $Output -Expected 'curl'
Throw-IfNonContains -Actual $Output -Expected '8.11.0'
Throw-IfNonContains -Actual $Output -Expected '8.11.1'

# =====================================================================
# Test 4: Builtin registry — same tag twice, expect no changes
# =====================================================================
Write-Trace "Test: builtin registry — same baseline, no changes"
$CurrentTest = 'x-baseline-diff builtin no change'
$Output = Run-VcpkgAndCaptureOutput x-baseline-diff @commonArgs @builtinArgs `
"--x-manifest-root=$manifestDir" $newTag $newTag
Throw-IfFailed
Throw-IfContains -Actual $Output -Expected ' -> '
Comment thread
autoantwort marked this conversation as resolved.
Throw-IfNonContains -Actual $Output -Expected 'No changes to installed packages between baselines'

# =====================================================================
# Test 5: Missing manifest — must fail
# =====================================================================
Write-Trace "Test: x-baseline-diff fails without a manifest"
$CurrentTest = 'x-baseline-diff no manifest'
$noManifestDir = "$TestingRoot/no-manifest-dir"
New-Item -Path $noManifestDir -ItemType Directory | Out-Null
Run-Vcpkg x-baseline-diff @commonArgs @builtinArgs "--x-manifest-root=$noManifestDir" $oldSha $newSha
Throw-IfNotFailed

# =====================================================================
# Test 6: One-arg mode fails when manifest has no builtin-baseline
# =====================================================================
Write-Trace "Test: one-arg mode fails when manifest has no builtin-baseline"
$manifestDirNoBaseline = "$TestingRoot/manifest-no-baseline"
New-Item -Path $manifestDirNoBaseline -ItemType Directory | Out-Null
Set-Content -LiteralPath "$manifestDirNoBaseline/vcpkg.json" -Encoding Ascii -Value @"
{
"name": "baseline-diff-test",
"version-string": "0",
"dependencies": [ "zlib" ]
}
"@
$CurrentTest = 'x-baseline-diff one arg no manifest baseline'
Run-Vcpkg x-baseline-diff @commonArgs @builtinArgs `
"--x-manifest-root=$manifestDirNoBaseline" $newSha
Throw-IfNotFailed

# =====================================================================
# Build a filesystem registry used as the DEFAULT registry.
# It carries two named baselines ("v1", "v2") with different versions
# of the same port — a supported but uncommon filesystem-registry
# feature (https://learn.microsoft.com/vcpkg/maintainers/registries
# #filesystem-registries).
#
# Port files live in versioned subdirectories so both versions are
# accessible simultaneously via the "path" entries.
# =====================================================================
Write-Trace "Build filesystem registry with two named baselines"
$filesystemRegistryRoot = "$TestingRoot/filesystem-registry"
New-Item -Path $filesystemRegistryRoot -ItemType Directory | Out-Null
$filesystemRegistryRoot = (Get-Item $filesystemRegistryRoot).FullName

New-TestPort -PortsRoot "$filesystemRegistryRoot/v1" -Name 'vcpkg-baseline-diff-test-a' -Version '1.0.0'
New-TestPort -PortsRoot "$filesystemRegistryRoot/v2" -Name 'vcpkg-baseline-diff-test-a' -Version '2.0.0'
New-Item -Path "$filesystemRegistryRoot/versions/v-" -ItemType Directory -Force | Out-Null
Set-Content -LiteralPath "$filesystemRegistryRoot/versions/baseline.json" -Encoding Ascii -Value @"
{
"v1": {
"vcpkg-baseline-diff-test-a": { "baseline": "1.0.0", "port-version": 0 }
},
"v2": {
"vcpkg-baseline-diff-test-a": { "baseline": "2.0.0", "port-version": 0 }
}
}
"@
Set-Content -LiteralPath "$filesystemRegistryRoot/versions/v-/vcpkg-baseline-diff-test-a.json" -Encoding Ascii -Value @"
{
"versions": [
{ "version": "2.0.0", "port-version": 0, "path": "$/v2/vcpkg-baseline-diff-test-a" },
{ "version": "1.0.0", "port-version": 0, "path": "$/v1/vcpkg-baseline-diff-test-a" }
]
}
"@

# Manifest: plain dependency, no builtin-baseline needed.
# vcpkg-configuration.json sets the filesystem registry as default with
# "baseline": "v1" so that the 1-arg test can use it as the old baseline.
$manifestDirFs = "$TestingRoot/manifest-filesystem"
New-Item -Path $manifestDirFs -ItemType Directory | Out-Null
$manifestDirFs = (Get-Item $manifestDirFs).FullName

Set-Content -LiteralPath "$manifestDirFs/vcpkg.json" -Encoding Ascii -Value @"
{
"name": "baseline-diff-test",
"version-string": "0",
"dependencies": [ "vcpkg-baseline-diff-test-a" ]
}
"@
Set-Content -LiteralPath "$manifestDirFs/vcpkg-configuration.json" -Encoding Ascii `
-Value (ConvertTo-Json -Depth 5 @{
"default-registry" = @{
"kind" = "filesystem"
"path" = $filesystemRegistryRoot
"baseline" = "v1"
}
})

# =====================================================================
# Test 7: Filesystem registry as default — two named baselines
# =====================================================================
Write-Trace "Test: filesystem registry as default registry, two named baselines"
$CurrentTest = 'x-baseline-diff filesystem two baselines'
$Output = Run-VcpkgAndCaptureOutput x-baseline-diff @commonArgs '--feature-flags=registries' `
"--x-manifest-root=$manifestDirFs" 'v1' 'v2'
Throw-IfFailed
Throw-IfNonContains -Actual $Output -Expected 'vcpkg-baseline-diff-test-a'
Throw-IfNonContains -Actual $Output -Expected '1.0.0'
Throw-IfNonContains -Actual $Output -Expected '2.0.0'

# =====================================================================
# Test 7b: Filesystem registry — one baseline arg, registry config
# baseline used as old
# =====================================================================
Write-Trace "Test: filesystem registry, one arg (registry config baseline as old)"
$CurrentTest = 'x-baseline-diff filesystem one baseline'
$Output = Run-VcpkgAndCaptureOutput x-baseline-diff @commonArgs '--feature-flags=registries' `
"--x-manifest-root=$manifestDirFs" 'v2'
Throw-IfFailed
Throw-IfNonContains -Actual $Output -Expected 'vcpkg-baseline-diff-test-a'
Throw-IfNonContains -Actual $Output -Expected '1.0.0'
Throw-IfNonContains -Actual $Output -Expected '2.0.0'

# =====================================================================
# Test 8: Git registry pointing at https://github.com/microsoft/vcpkg
# as the default registry — same SHAs as the builtin tests above since
# VCPKG_ROOT is a clone of that repo. Also exercises the
# is_builtin_git_registry ref-resolution code path.
# =====================================================================
Write-Trace "Test: git registry (github.com/microsoft/vcpkg) as default registry"
$manifestDirGit = "$TestingRoot/manifest-git-registry"
New-Item -Path $manifestDirGit -ItemType Directory | Out-Null
$manifestDirGit = (Get-Item $manifestDirGit).FullName

Set-Content -LiteralPath "$manifestDirGit/vcpkg.json" -Encoding Ascii -Value @"
{
"name": "baseline-diff-test",
"version-string": "0",
"dependencies": [ "curl" ]
}
"@
Set-Content -LiteralPath "$manifestDirGit/vcpkg-configuration.json" -Encoding Ascii `
-Value (ConvertTo-Json -Depth 5 @{
"default-registry" = @{
"kind" = "git"
"repository" = "https://github.com/microsoft/vcpkg"
"baseline" = $oldSha
}
})

$CurrentTest = 'x-baseline-diff git registry two SHAs'
$Output = Run-VcpkgAndCaptureOutput x-baseline-diff @commonArgs '--feature-flags=registries' `
"--x-manifest-root=$manifestDirGit" $oldSha $newSha
Throw-IfFailed
Throw-IfNonContains -Actual $Output -Expected 'curl'
Throw-IfNonContains -Actual $Output -Expected '8.11.0'
Throw-IfNonContains -Actual $Output -Expected '8.11.1'
7 changes: 7 additions & 0 deletions include/vcpkg/base/git.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,4 +112,11 @@ namespace vcpkg
const Path& git_exe,
const Path& builtin_ports_dir,
StringView git_commit_id);

// Resolves a git ref (tag, branch, or commit-ish) to a full 40-character SHA using `git rev-parse`.
// Returns nullopt and reports an error if the ref cannot be resolved.
Optional<std::string> git_resolve_to_full_sha(DiagnosticContext& context,
const Path& git_exe,
GitRepoLocator locator,
StringView ref);
}
35 changes: 34 additions & 1 deletion include/vcpkg/base/message-data.inc.h
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,10 @@ DECLARE_MESSAGE(BaselineConflict,
"",
"Specifying vcpkg-configuration.default-registry in a manifest file conflicts with built-in "
"baseline.\nPlease remove one of these conflicting settings.")
DECLARE_MESSAGE(BaselineDiffNoChange,
(),
"Theoretically it is wrong to say installed, but this is probably the case most of the time",
"No changes to installed packages between baselines")
DECLARE_MESSAGE(BaselineGitShowFailed,
(msg::commit_sha),
"",
Expand Down Expand Up @@ -589,6 +593,21 @@ DECLARE_MESSAGE(CmdAddVersionOptOverwriteVersion, (), "", "Overwrites git-tree o
DECLARE_MESSAGE(CmdAddVersionOptSkipFormatChk, (), "", "Skips the formatting check of vcpkg.json files")
DECLARE_MESSAGE(CmdAddVersionOptSkipVersionFormatChk, (), "", "Skips the version format check")
DECLARE_MESSAGE(CmdAddVersionOptVerbose, (), "", "Prints success messages rather than only errors")
DECLARE_MESSAGE(CmdBaselineDiffExample1,
(),
"This is a command line, only the <old commit sha> and <newer commit sha> parts should be localized.",
"vcpkg x-baseline-diff <old commit sha> <newer commit sha>")
DECLARE_MESSAGE(CmdBaselineDiffMissingBuiltinBaseline,
(),
"",
"Only one commit was provided but the manifest does not have a 'builtin-baseline'. "
"Please specify two commits or add a 'builtin-baseline' to vcpkg.json.")
DECLARE_MESSAGE(CmdBaselineDiffMissingRegistryBaseline,
(),
"",
"Only one commit was provided but the default registry in vcpkg-configuration.json does not "
"have a 'baseline'. Please specify two commits or add a 'baseline' to the default registry.")
DECLARE_MESSAGE(CmdBaselineDiffSynopsis, (), "", "Computes version changes to installable packages between baselines")
DECLARE_MESSAGE(CmdBootstrapStandaloneSynopsis, (), "", "Bootstraps a vcpkg root from only a vcpkg binary")
DECLARE_MESSAGE(CmdBuildExternalExample1,
(),
Expand Down Expand Up @@ -1056,6 +1075,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 @@ -1972,7 +1992,10 @@ DECLARE_MESSAGE(InvalidCommentStyle,
"",
"vcpkg does not support c-style comments, however most objects allow $-prefixed fields to be used as "
"comments.")
DECLARE_MESSAGE(InvalidCommitId, (msg::commit_sha), "", "Invalid commit id: {commit_sha}")
DECLARE_MESSAGE(InvalidCommitId,
(msg::commit_sha),
"",
"Invalid commit id (expected lowercase 40 hexadecimal characters): {commit_sha}")
DECLARE_MESSAGE(InvalidDefaultFeatureName, (), "", "'default' is a reserved feature name")
DECLARE_MESSAGE(InvalidFeature,
(),
Expand All @@ -1988,6 +2011,10 @@ DECLARE_MESSAGE(InvalidFormatString,
(msg::actual),
"{actual} is the provided format string",
"invalid format string: {actual}")
DECLARE_MESSAGE(InvalidGitRef,
(msg::value),
"{value} is a git branch, tag or short git sha",
"Could not resolve git ref '{value}'")
DECLARE_MESSAGE(InvalidHexDigit, (), "", "Invalid hex digit in unicode escape")
DECLARE_MESSAGE(InvalidIntegerConst, (msg::count), "", "Invalid integer constant: {count}")
DECLARE_MESSAGE(InvalidLibraryMissingLinkerMembers, (), "", "Library was invalid: could not find a linker member.")
Expand Down Expand Up @@ -2173,6 +2200,7 @@ DECLARE_MESSAGE(MissingDependency,
(msg::spec, msg::package_name),
"",
"Package {spec} is installed, but dependency {package_name} is not.")
DECLARE_MESSAGE(MissingManifestFile, (), "", "Couldn't find a manifest file (vcpkg.json file)")
DECLARE_MESSAGE(MissingOption, (msg::option), "", "This command requires --{option}")
DECLARE_MESSAGE(MissingOrInvalidIdentifer, (), "", "missing or invalid identifier")
DECLARE_MESSAGE(MissingPortSuggestPullRequest,
Expand Down Expand Up @@ -2867,6 +2895,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 @@ -3119,6 +3148,10 @@ DECLARE_MESSAGE(UpdateBaselineNoUpdate,
"example of {value} is '5507daa796359fe8d45418e694328e878ac2b82f'",
"registry '{url}' not updated: '{value}'")
DECLARE_MESSAGE(UpdateBaselineRemoteGitError, (msg::url), "", "git failed to fetch remote repository '{url}'")
DECLARE_MESSAGE(UpdateBaselineSuggestBaselineDiff,
(msg::old_value, msg::new_value),
"example of {old_value}, {new_value} is '5507daa796359fe8d45418e694328e878ac2b82f'",
"To see what packages changed run: vcpkg x-baseline-diff {old_value} {new_value}")
DECLARE_MESSAGE(UpdateBaselineUpdatedBaseline,
(msg::url, msg::old_value, msg::new_value),
"example of {old_value}, {new_value} is '5507daa796359fe8d45418e694328e878ac2b82f'",
Expand Down
14 changes: 14 additions & 0 deletions include/vcpkg/commands.baseline-diff.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#pragma once

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

namespace vcpkg
Comment thread
autoantwort marked this conversation as resolved.
{
Comment thread
autoantwort marked this conversation as resolved.
extern const CommandMetadata CommandBaselineDiffMetadata;
void command_baseline_diff_and_exit(const VcpkgCmdArguments& args,
const VcpkgPaths& paths,
vcpkg::Triplet default_triplet,
vcpkg::Triplet host_triplet);
}
2 changes: 1 addition & 1 deletion include/vcpkg/commands.install.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ namespace vcpkg

std::unique_ptr<SourceControlFile> parse_manifest_scf_or_exit(const ManifestAndPath& manifest,
const VcpkgPaths& paths,
bool is_default_builtin_registry);
bool is_default_builtin_files_registry);

std::vector<std::string> get_manifest_features(const ParsedArguments& options,
const SourceParagraph& manifest_core,
Expand Down
Loading
Loading