Skip to content

Instantly share code, notes, and snippets.

@JamieMagee
Created May 23, 2025 15:49
Show Gist options
  • Save JamieMagee/faada6e6885aaaa700b964b4e5f71dc6 to your computer and use it in GitHub Desktop.
Save JamieMagee/faada6e6885aaaa700b964b4e5f71dc6 to your computer and use it in GitHub Desktop.
VCPKG updater
#!/usr/bin/env bash
set -euo pipefail
DEFAULT_REGISTRY="https://github.com/microsoft/vcpkg"
VCPKG_JSON="vcpkg.json"
GITHUB_API_BASE="https://api.github.com"
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# Function to print colored output
print_info() {
echo -e "${GREEN}[INFO]${NC} $1"
}
print_warning() {
echo -e "${YELLOW}[WARNING]${NC} $1"
}
print_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# Check if required tools are available
check_dependencies() {
local missing_deps=()
if ! command -v jq &> /dev/null; then
missing_deps+=("jq")
fi
if ! command -v curl &> /dev/null; then
missing_deps+=("curl")
fi
if [ ${#missing_deps[@]} -ne 0 ]; then
print_error "Missing required dependencies: ${missing_deps[*]}"
print_error "Please install them before running this script"
exit 1
fi
}
# Extract current builtin-baseline from vcpkg.json
get_current_baseline() {
if [ ! -f "$VCPKG_JSON" ]; then
print_error "vcpkg.json not found in current directory"
exit 1
fi
local baseline
baseline=$(jq -r '.["builtin-baseline"]' "$VCPKG_JSON")
if [ "$baseline" = "null" ] || [ -z "$baseline" ]; then
print_error "No builtin-baseline found in vcpkg.json"
exit 1
fi
echo "$baseline"
}
# Get the latest tag from GitHub
get_latest_tag() {
local repo_url="$1"
local repo_path
# Extract owner/repo from GitHub URL
repo_path=$(echo "$repo_url" | sed 's|https://github.com/||' | sed 's|\.git$||')
print_info "Fetching latest tag from $repo_path..." >&2
local latest_tag
latest_tag=$(curl -s "$GITHUB_API_BASE/repos/$repo_path/tags" | jq -r '.[0].name')
if [ "$latest_tag" = "null" ] || [ -z "$latest_tag" ]; then
print_error "Failed to fetch latest tag from GitHub" >&2
exit 1
fi
echo "$latest_tag"
}
# Get commit SHA for a specific tag
get_tag_commit_sha() {
local repo_url="$1"
local tag="$2"
local repo_path
# Extract owner/repo from GitHub URL
repo_path=$(echo "$repo_url" | sed 's|https://github.com/||' | sed 's|\.git$||')
print_info "Getting commit SHA for tag $tag..." >&2
local commit_sha
commit_sha=$(curl -s "$GITHUB_API_BASE/repos/$repo_path/git/refs/tags/$tag" | jq -r '.object.sha')
if [ "$commit_sha" = "null" ] || [ -z "$commit_sha" ]; then
# Try getting it from the tag object (annotated tags)
commit_sha=$(curl -s "$GITHUB_API_BASE/repos/$repo_path/tags" | jq -r ".[] | select(.name == \"$tag\") | .commit.sha")
fi
if [ "$commit_sha" = "null" ] || [ -z "$commit_sha" ]; then
print_error "Failed to get commit SHA for tag $tag" >&2
exit 1
fi
echo "$commit_sha"
}
# Compare two commit SHAs to see if one is ahead of the other
is_commit_ahead() {
local repo_url="$1"
local base_commit="$2"
local head_commit="$3"
local repo_path
# If commits are the same, head is not ahead
if [ "$base_commit" = "$head_commit" ]; then
return 1
fi
# Extract owner/repo from GitHub URL
repo_path=$(echo "$repo_url" | sed 's|https://github.com/||' | sed 's|\.git$||')
print_info "Checking if $head_commit is ahead of $base_commit..." >&2
# Use GitHub's compare API
local comparison
comparison=$(curl -s "$GITHUB_API_BASE/repos/$repo_path/compare/$base_commit...$head_commit")
local status
status=$(echo "$comparison" | jq -r '.status')
case "$status" in
"ahead")
return 0 # head is ahead of base
;;
"behind")
return 1 # head is behind base
;;
"identical")
return 1 # commits are identical
;;
"diverged")
print_warning "Commits have diverged. Latest tag might be on a different branch." >&2
return 0 # Assume we want to update anyway
;;
*)
print_warning "Unable to determine commit relationship. Status: $status" >&2
return 0 # Assume we want to update anyway
;;
esac
}
# Update the builtin-baseline in vcpkg.json
update_baseline() {
local new_baseline="$1"
print_info "Updating builtin-baseline to $new_baseline..."
# Update the baseline using jq
local temp_file
temp_file=$(mktemp)
jq --arg baseline "$new_baseline" '.["builtin-baseline"] = $baseline' "$VCPKG_JSON" > "$temp_file"
if [ $? -eq 0 ]; then
mv "$temp_file" "$VCPKG_JSON"
print_info "Successfully updated builtin-baseline in $VCPKG_JSON"
else
print_error "Failed to update vcpkg.json"
rm -f "$temp_file"
exit 1
fi
}
# Main function
main() {
print_info "Starting vcpkg builtin-baseline updater..."
# Check dependencies
check_dependencies
# Get current baseline
local current_baseline
current_baseline=$(get_current_baseline)
print_info "Current builtin-baseline: $current_baseline"
# Get latest tag
local latest_tag
latest_tag=$(get_latest_tag "$DEFAULT_REGISTRY")
print_info "Latest tag: $latest_tag"
# Get commit SHA for the latest tag
local latest_commit_sha
latest_commit_sha=$(get_tag_commit_sha "$DEFAULT_REGISTRY" "$latest_tag")
print_info "Latest tag commit SHA: $latest_commit_sha"
# Check if latest tag is ahead of current baseline
if is_commit_ahead "$DEFAULT_REGISTRY" "$current_baseline" "$latest_commit_sha"; then
print_info "Latest tag is ahead of current baseline. Updating..."
update_baseline "$latest_commit_sha"
print_info "Update completed successfully!"
else
print_info "Current baseline is up to date or ahead of latest tag. No update needed."
fi
}
# Run main function
main "$@"
{
"$schema": "https://raw.githubusercontent.com/microsoft/vcpkg-tool/main/docs/vcpkg.schema.json",
"name": "test-package",
"version": "0.0.0",
"dependencies": [
"zlib"
],
"builtin-baseline": "b02e341c927f16d991edbd915d8ea43eac52096c"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment