-
Notifications
You must be signed in to change notification settings - Fork 59
Expand file tree
/
Copy pathartifact_tset.bzl
More file actions
115 lines (97 loc) · 3.43 KB
/
artifact_tset.bzl
File metadata and controls
115 lines (97 loc) · 3.43 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# This source code is dual-licensed under either the MIT license found in the
# LICENSE-MIT file in the root directory of this source tree or the Apache
# License, Version 2.0 found in the LICENSE-APACHE file in the root directory
# of this source tree. You may select, at your option, one of the
# above-listed licenses.
load("@prelude//utils:expect.bzl", "expect")
load("@prelude//utils:type_defs.bzl", "is_list")
load(
"@prelude//utils:utils.bzl",
"flatten",
)
# Generic tag to provide more information about the artifact
ArtifactInfoTag = enum(
# Describes artifacts required for debugging Swift code, including
# swiftmodule files, swiftinterface files, clang modules and modulemaps.
"swift_debug_info",
)
ArtifactInfo = record(
label = field(Label),
artifacts = field(list[Artifact]),
tags = field(list[ArtifactInfoTag]),
)
def stringify_artifact_label(value: Label | str) -> str:
if type(value) == "string":
return value
return str(value.raw_target())
def _get_artifacts(entries: list[ArtifactInfo]) -> list[Artifact]:
return flatten([entry.artifacts for entry in entries])
_ArtifactTSet = transitive_set(
args_projections = {
"artifacts": _get_artifacts,
},
)
ArtifactTSet = record(
_tset = field([_ArtifactTSet, None], None),
)
# Simple empty `ArtifactTSet` that is shared to reduce memory usage.
EmptyArtifactTSet = ArtifactTSet()
def make_artifact_tset(
actions: AnalysisActions,
# Must be non-`None` if artifacts are passed in to `artifacts`.
label: Label | None = None,
artifacts: list[Artifact] = [],
infos: list[ArtifactInfo] = [],
children: list[ArtifactTSet] = [],
tags: list[ArtifactInfoTag] = []) -> ArtifactTSet:
expect(
label != None or not artifacts,
"must pass in `label` to associate with artifacts",
)
single_child = None # type: ArtifactTSet | None
children_orig = children
children = [] # type: list[_ArtifactTSet]
for c in children_orig:
# As a convenience for our callers, filter our `None` children.
if c._tset != None:
children.append(c._tset)
single_child = c
has_values = artifacts or infos
if not has_values and not children:
return EmptyArtifactTSet
if not has_values and len(children) == 1:
# If we have a single child, just return it
# rather than allocating and retaining additional memory.
return single_child
# Build list of all non-child values.
values = []
if artifacts:
values.append(ArtifactInfo(label = label, artifacts = artifacts, tags = tags))
values.extend(infos)
# We only build a `_ArtifactTSet` if there's something to package.
kwargs = {}
if values:
kwargs["value"] = values
if children:
kwargs["children"] = children
return ArtifactTSet(
_tset = actions.tset(_ArtifactTSet, **kwargs),
)
def project_artifacts(
actions: AnalysisActions,
tsets: ArtifactTSet | list[ArtifactTSet] = []) -> list[TransitiveSetArgsProjection]:
"""
Helper to project a list of optional tsets.
"""
if is_list(tsets):
tset = make_artifact_tset(
actions = actions,
children = tsets,
)
else:
tset = tsets
if tset._tset == None:
return []
return [tset._tset.project_as_args("artifacts")]