88 lines
3.4 KiB
Python
88 lines
3.4 KiB
Python
# Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
#
|
|
# This source code is licensed under both the MIT license found in the
|
|
# LICENSE-MIT file in the root directory of this source tree and the Apache
|
|
# License, Version 2.0 found in the LICENSE-APACHE file in the root directory
|
|
# of this source tree.
|
|
|
|
# Manifests are files containing information how to map sources into a package.
|
|
# The files are JSON lists with an entry per source, where each source is 3-tuple
|
|
# of relative destination path, artifact path, and a short description of the
|
|
# origin of this source (used for error messages in tooling that uses these).
|
|
ManifestInfo = record(
|
|
# The actual manifest file (in the form of a JSON file).
|
|
manifest = field("artifact"),
|
|
# All artifacts that are referenced in the manifest.
|
|
artifacts = field(["artifact"]),
|
|
)
|
|
|
|
def _write_manifest(
|
|
ctx: "context",
|
|
name: str.type,
|
|
entries: [(str.type, "artifact", str.type)]) -> "artifact":
|
|
"""
|
|
Serialize the given source manifest entries to a JSON file.
|
|
"""
|
|
return ctx.actions.write_json(name + ".manifest", entries)
|
|
|
|
def create_manifest_for_entries(
|
|
ctx: "context",
|
|
name: str.type,
|
|
entries: [(str.type, "artifact", str.type)]) -> ManifestInfo.type:
|
|
"""
|
|
Generate a source manifest for the given list of sources.
|
|
"""
|
|
return ManifestInfo(
|
|
manifest = _write_manifest(ctx, name, entries),
|
|
artifacts = [a for _, a, _ in entries],
|
|
)
|
|
|
|
def create_manifest_for_source_map(
|
|
ctx: "context",
|
|
param: str.type,
|
|
srcs: {str.type: "artifact"}) -> ManifestInfo.type:
|
|
"""
|
|
Generate a source manifest for the given map of sources from the given rule.
|
|
"""
|
|
origin = "{} {}".format(ctx.label.raw_target(), param)
|
|
return create_manifest_for_entries(
|
|
ctx,
|
|
param,
|
|
[(dest, artifact, origin) for dest, artifact in srcs.items()],
|
|
)
|
|
|
|
def create_manifest_for_source_dir(
|
|
ctx: "context",
|
|
param: str.type,
|
|
extracted: "artifact") -> ManifestInfo.type:
|
|
"""
|
|
Generate a source manifest for the given directory of sources from the given
|
|
rule.
|
|
"""
|
|
manifest = ctx.actions.declare_output(param + ".manifest")
|
|
cmd = cmd_args(ctx.attrs._create_manifest_for_source_dir[RunInfo])
|
|
cmd.add("--origin={}".format(ctx.label.raw_target()))
|
|
cmd.add(cmd_args(manifest.as_output(), format = "--output={}"))
|
|
cmd.add(extracted)
|
|
ctx.actions.run(cmd, category = "py_source_manifest", identifier = param)
|
|
return ManifestInfo(manifest = manifest, artifacts = [extracted])
|
|
|
|
def create_manifest_for_extensions(
|
|
ctx: "context",
|
|
extensions: {str.type: ("_a", "label")},
|
|
# Whether to include DWP files.
|
|
dwp: bool.type = False) -> ManifestInfo.type:
|
|
entries = []
|
|
for dest, (lib, label) in extensions.items():
|
|
entries.append((dest, lib.output, str(label.raw_target())))
|
|
if dwp and lib.dwp != None:
|
|
entries.append((dest + ".dwp", lib.dwp, str(label.raw_target()) + ".dwp"))
|
|
manifest = create_manifest_for_entries(ctx, "extensions", entries)
|
|
|
|
# Include external debug paths, even though they're not explicitly listed
|
|
# in the manifest, as python packaging may also consume debug paths which
|
|
# were referenced in native code.
|
|
for (lib, _) in extensions.values():
|
|
manifest.artifacts.extend(lib.external_debug_info)
|
|
|
|
return manifest
|