blob: 99c8e4b310074a087a7d91eda4949374c49bf1ac [file]
# Copyright 2024 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Preprocesses version_history.json before including it in the IDK."""
import datetime
from typing import Any
def replace_special_abi_revisions(
version_history: Any,
daily_commit_hash: str,
daily_commit_timestamp: datetime.datetime,
) -> None:
"""Modifies `version_history`, assigning ABI revisions for the special API
levels. The format is the following:
0xFF0X_YYYY_ZZZZ_ZZZZ
X: 0 if the API level is NEXT or HEAD. 1 if the API level is PLATFORM.
YYYY: the first 16 bits of `daily_commit_hash`. This is largely to make
the ABI revision unpredictable.
ZZZZ_ZZZZ: 32 bit encoding of the proleptic Gregorian ordinal of the day
*after* `daily_commit_timestamp`. In most situations, this will
indicate "today". We'll need to revise this encoding sometime before
the year 11761200.
"""
# Embed the first 16 bits of the git hash in the ABI.
masked_git_hash = (0xFFFF & int(daily_commit_hash[:4], 16)) << 32
masked_day = 0xFFFF_FFFF & (daily_commit_timestamp.toordinal() + 1)
for level, value in version_history["data"]["special_api_levels"].items():
input_abi_revision = value["abi_revision"]
assert (
input_abi_revision == "GENERATED_BY_BUILD"
), f"ABI revision for special API level {level} was '{input_abi_revision}'; expected 'GENERATED_BY_BUILD'"
if level == "NEXT" or level == "HEAD":
# ABI revisions for unstable levels start with 0xFF00.
# All such levels share an ABI revision.
value["abi_revision"] = "0x{:X}".format(
0xFF00_0000_0000_0000 | masked_git_hash | masked_day
)
elif level == "PLATFORM":
# ABI revisions for PLATFORM start with 0xFF01.
value["abi_revision"] = "0x{:X}".format(
0xFF01_0000_0000_0000 | masked_git_hash | masked_day
)
else:
assert False, "Unknown special API level: %s" % level
def add_deprecated_status_field(version_history: Any) -> None:
"""Modifies `version_history` to add a `status` field to each API level and
special API level, based on the newer "phase" field.
TODO(https://fxbug.dev/383361369): Delete this once all clients have been
updated to use "phase".
"""
for value in version_history["data"]["api_levels"].values():
phase = value.get("phase")
if phase == "retired":
value["status"] = "unsupported"
elif phase == "sunset":
# Sunset doesn't have a precisely analogous "status" - we'll
# consider sunset levels "unsupported" in the old model, to be
# safe.
value["status"] = "unsupported"
elif phase == "supported":
value["status"] = "supported"
else:
assert False, f"Unknown phase: {phase}"
for value in version_history["data"]["special_api_levels"].values():
value["status"] = "in-development"