blob: 5e3c795f6391ffa750c1b7c41042e469152a2a9d [file] [log] [blame]
#!/usr/bin/env python3
# Copyright 2019 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Update our pinned copy of node to match Chromium."""
import logging
import sys
import libdot
URI_BASE = "https://chromium.googlesource.com/chromium/src/+/HEAD"
# Where in Chromium's tree they maintain the version.
# Look for 'src/third_party/node/linux' here:
# https://chromium.googlesource.com/chromium/src/+/HEAD/DEPS
URI_VER = f"{URI_BASE}/DEPS"
def update_hash(
manifest: libdot.ArtifactManifest, var: str, deps: dict
) -> None:
"""Update |var| in |manifest| with data from |deps|."""
# The structure expected is:
# {
# ...
# 'dep_type': 'gcs',
# 'bucket': 'chromium-nodejs',
# 'objects': [ {
# 'object_name': 'fa98c6432de572206bc5519f85e9c96bd518b039',
# 'sha256sum': 'fb563633b5bfe2d4307075c54c6bb54664a3b5ec6bc811f5b1...',
# 'size_bytes': 50288755,
# 'generation': 1730835522207929,
# 'output_file': 'node-linux-x64.tar.gz',
# } ]
# }
if deps["dep_type"] != "gcs":
logging.error("Unknown dep type: %s", deps)
return
objects = deps["objects"]
if len(objects) != 1:
logging.error("Too many objects: %s", objects)
return
obj = objects[0]
artifact = manifest.files.get(var, libdot.Artifact())
artifact.size = obj["size_bytes"]
artifact.url = "/".join(
(
"https://storage.googleapis.com",
deps["bucket"],
obj["object_name"],
)
)
artifact.hashes = {"sha256": obj["sha256sum"]}
logging.info("Updating %s with hash %s", var, obj["object_name"])
def fetch_deps(uri: str) -> dict:
"""Fetch & parse Chromium DEPS file."""
data = fetch_data(uri)
# Very basic implementation of the format to get the data we care about.
context = {
"Str": str,
"Var": lambda x: x,
}
exec(compile(data, uri, "exec"), context) # pylint: disable=exec-used
return context["deps"]
def fetch_data(uri):
"""Read the gitiles base64 encoded data from |uri|."""
data = libdot.fetch_data(f"{uri}?format=TEXT", b64=True)
return data.getvalue().decode("utf-8").strip()
def get_parser():
"""Get a command line parser."""
parser = libdot.ArgumentParser(description=__doc__)
return parser
def main(argv):
"""The main func!"""
parser = get_parser()
_opts = parser.parse_args(argv)
deps = fetch_deps(URI_VER)
manifest_path = libdot.DIR / "fetch.json"
manifest = libdot.ArtifactManifest.from_file(manifest_path)
old_data = manifest.toJSON()
update_hash(manifest, "node/linux", deps["src/third_party/node/linux"])
update_hash(manifest, "node/mac", deps["src/third_party/node/mac"])
update_hash(manifest, "node/win", deps["src/third_party/node/win"])
new_data = manifest.toJSON()
if old_data != new_data:
logging.info("%s: saving updates", manifest_path)
manifest_path.write_text(new_data, encoding="utf-8")
else:
logging.info("%s: already up-to-date", manifest_path)
if __name__ == "__main__":
sys.exit(main(sys.argv[1:]))