Skip to content

Commit 0849971

Browse files
grievejiameta-codesync[bot]
authored andcommitted
Extract rule handling logic into separate functions
Summary: extraction_movie Reviewed By: stroxler Differential Revision: D88773202 fbshipit-source-id: ed92e1e2c8aded05f84d7983231f82199f1ad637
1 parent f0459a0 commit 0849971

File tree

1 file changed

+134
-99
lines changed

1 file changed

+134
-99
lines changed

prelude/python/sourcedb/pyrefly.bxl

Lines changed: 134 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -73,11 +73,11 @@ def _clean_module(base_module: str, module: str) -> str:
7373
# Set common fields for a target entry.
7474
# NOTE: This function doesn't populate `srcs`. Instead return an empty `srcs` dict for downstream logic to populate.
7575
def _set_entry_common_fields(
76-
entry: dict[str, typing.Any],
76+
entry: dict,
7777
attrs: bxl.LazyAttrs,
7878
fs: bxl.Filesystem,
7979
target: bxl.ConfiguredTargetNode,
80-
known_targets: dict) -> dict[str, list[str | bxl.EnsuredArtifact]]:
80+
known_targets: dict[TargetLabel, bxl.ConfiguredTargetNode]) -> dict[str, list[str | bxl.EnsuredArtifact]]:
8181
srcs = {}
8282
deps = []
8383
entry["srcs"] = srcs
@@ -102,13 +102,136 @@ def _set_entry_common_fields(
102102

103103
return srcs
104104

105+
def _handle_alias(
106+
entry: dict,
107+
attrs: bxl.LazyAttrs,
108+
target: bxl.ConfiguredTargetNode) -> None:
109+
actual = attrs.get("actual")
110+
if actual != None and actual.value() != None:
111+
entry["alias"] = actual.value().raw_target()
112+
else:
113+
fail("Alias has no actual target".format(target.label))
114+
115+
def _handle_genrule(
116+
entry: dict,
117+
attrs: bxl.LazyAttrs,
118+
fs: bxl.Filesystem,
119+
target: bxl.ConfiguredTargetNode,
120+
known_targets: dict[TargetLabel, bxl.ConfiguredTargetNode],
121+
to_remove: dict[str, None],
122+
to_build: list,
123+
to_insert: list,
124+
genrule_to_insert: list) -> None:
125+
labels = attrs.get("labels")
126+
if "custom_rule_internal" in labels.value():
127+
# skip internal targets, since they will be materialized as part
128+
# of their including target
129+
to_remove[str(target.label.raw_target())] = None
130+
return
131+
132+
srcs = _set_entry_common_fields(entry, attrs, fs, target, known_targets)
133+
to_build.append(target)
134+
135+
# Only one of these will have a value, but get both of them now since
136+
# it's easy.
137+
out = attrs.get("out")
138+
outs = attrs.get("outs")
139+
if out != None and out.value() != None:
140+
items = {out.value(): out.value()}
141+
elif outs != None and outs.value() != None:
142+
items = outs.value()
143+
else:
144+
fail(target)
145+
146+
if len(items) == 1:
147+
module_path = list(items.keys())[0]
148+
for suffix in _MODULE_SUFFIXES:
149+
if module_path.endswith(suffix):
150+
to_build.append(target)
151+
to_insert.append((srcs, _clean_module("", module_path), target.label.with_sub_target()))
152+
break
153+
else:
154+
# we need to handle building the full genrule
155+
genrule_to_insert.append((target, entry))
156+
for (module_path, src_paths) in items.items():
157+
if len(src_paths) < 1:
158+
fail("Target src has no output path: {}".format(target.label))
159+
for suffix in _MODULE_SUFFIXES:
160+
if module_path.endswith(suffix):
161+
_append_or_default_if_module(srcs, _clean_module("", module_path), src_paths[0])
162+
break
163+
164+
def _handle_python_library(
165+
entry: dict,
166+
attrs: bxl.LazyAttrs,
167+
fs: bxl.Filesystem,
168+
target: bxl.ConfiguredTargetNode,
169+
known_targets: dict[TargetLabel, bxl.ConfiguredTargetNode],
170+
to_remove: dict[str, None],
171+
to_build: list,
172+
to_insert: list) -> None:
173+
base_module = attrs.get("base_module")
174+
if base_module != None and base_module.value() != None:
175+
base_module = base_module.value()
176+
else:
177+
base_module = target.label.package
178+
179+
srcs = _set_entry_common_fields(entry, attrs, fs, target, known_targets)
180+
181+
# add type stubs first, so that they're preferred by Pyrefly
182+
type_stubs = attrs.get("type_stubs")
183+
type_stubs = {} if type_stubs == None else type_stubs.value()
184+
_get_and_materialize_sources(
185+
type_stubs,
186+
to_remove,
187+
base_module,
188+
srcs,
189+
to_build,
190+
to_insert,
191+
fs,
192+
)
193+
194+
# python_binary might be the root target, which doesn't have `srcs`.
195+
attr_srcs = attrs.get("srcs")
196+
attr_srcs = {} if attr_srcs == None else attr_srcs.value()
197+
_get_and_materialize_sources(
198+
attr_srcs,
199+
to_remove,
200+
base_module,
201+
srcs,
202+
to_build,
203+
to_insert,
204+
fs,
205+
)
206+
207+
def _build_generated_files(
208+
ctx: bxl.Context,
209+
to_build: list,
210+
to_insert: list,
211+
genrule_to_insert: list) -> None:
212+
if not to_build:
213+
return
214+
215+
built = ctx.build(to_build)
216+
ensured = ctx.output.ensure_multiple(built)
217+
218+
# handle individual generated files
219+
for srcs, module_name, target in to_insert:
220+
_append_or_default_if_module(srcs, module_name, ensured[target][0].rel_path())
221+
222+
# handle genrules
223+
for target, entry in genrule_to_insert:
224+
label = target.label.with_sub_target()
225+
relative_to = ensured[label][0].rel_path()
226+
entry["relative_to"] = relative_to
227+
105228
def _get_and_materialize_sources(
106-
to_add: list[typing.Any] | dict[str, typing.Any],
107-
to_remove: dict[str, typing.Any],
229+
to_add: list | dict,
230+
to_remove: dict[str, None],
108231
base_module: str,
109232
srcs: dict[str, list[str | bxl.EnsuredArtifact]],
110-
to_build: list[typing.Any],
111-
to_insert: list[typing.Any],
233+
to_build: list,
234+
to_insert: list,
112235
fs: bxl.Filesystem):
113236
if type(to_add) == type([]):
114237
for v in to_add:
@@ -181,101 +304,13 @@ def _main(ctx: bxl.Context) -> None:
181304
entries[str(x.label.raw_target())] = entry
182305

183306
if x.rule_type == "prelude//rules.bzl:alias":
184-
actual = attrs.get("actual")
185-
if actual != None and actual.value() != None:
186-
entry["alias"] = actual.value().raw_target()
187-
else:
188-
fail("Alias has no actual target".format(x.label))
189-
307+
_handle_alias(entry, attrs, x)
190308
elif x.rule_type == "prelude//rules.bzl:genrule":
191-
labels = attrs.get("labels")
192-
if "custom_rule_internal" in labels.value():
193-
# skip internal targets, since they will be materialized as part
194-
# of their including target
195-
to_remove[str(x.label.raw_target())] = None
196-
continue
197-
198-
srcs = _set_entry_common_fields(entry, attrs, fs, x, known_targets)
199-
to_build.append(x)
200-
201-
# Only one of these will have a value, but get both of them now since
202-
# it's easy.
203-
out = attrs.get("out")
204-
outs = attrs.get("outs")
205-
if out != None and out.value() != None:
206-
items = {out.value(): out.value()}
207-
elif outs != None and outs.value() != None:
208-
items = outs.value()
209-
else:
210-
fail(x)
211-
212-
if len(items) == 1:
213-
module_path = list(items.keys())[0]
214-
for suffix in _MODULE_SUFFIXES:
215-
if module_path.endswith(suffix):
216-
to_build.append(x)
217-
to_insert.append((srcs, _clean_module("", module_path), x.label.with_sub_target()))
218-
break
219-
else:
220-
# we need to handle building the full genrule
221-
genrule_to_insert.append((x, entry))
222-
for (module_path, src_paths) in items.items():
223-
if len(src_paths) < 1:
224-
fail("Target src has no output path: {}".format(x.label))
225-
for suffix in _MODULE_SUFFIXES:
226-
if module_path.endswith(suffix):
227-
_append_or_default_if_module(srcs, _clean_module("", module_path), src_paths[0])
228-
break
229-
309+
_handle_genrule(entry, attrs, fs, x, known_targets, to_remove, to_build, to_insert, genrule_to_insert)
230310
else:
231-
# python_library and other rules
232-
base_module = attrs.get("base_module")
233-
if base_module != None and base_module.value() != None:
234-
base_module = base_module.value()
235-
else:
236-
base_module = x.label.package
237-
238-
srcs = _set_entry_common_fields(entry, attrs, fs, x, known_targets)
239-
240-
# add type stubs first, so that they're preferred by Pyrefly
241-
type_stubs = attrs.get("type_stubs")
242-
type_stubs = {} if type_stubs == None else type_stubs.value()
243-
_get_and_materialize_sources(
244-
type_stubs,
245-
to_remove,
246-
base_module,
247-
srcs,
248-
to_build,
249-
to_insert,
250-
fs,
251-
)
252-
253-
# python_binary might be the root target, which doesn't have `srcs`.
254-
attr_srcs = attrs.get("srcs")
255-
attr_srcs = {} if attr_srcs == None else attr_srcs.value()
256-
_get_and_materialize_sources(
257-
attr_srcs,
258-
to_remove,
259-
base_module,
260-
srcs,
261-
to_build,
262-
to_insert,
263-
fs,
264-
)
265-
266-
if to_build:
267-
built = ctx.build(to_build)
268-
ensured = ctx.output.ensure_multiple(built)
269-
270-
# handle individual generated files
271-
for srcs, module_name, target in to_insert:
272-
_append_or_default_if_module(srcs, module_name, ensured[target][0].rel_path())
273-
274-
# handle genrules
275-
for target, entry in genrule_to_insert:
276-
label = target.label.with_sub_target()
277-
relative_to = ensured[label][0].rel_path()
278-
entry["relative_to"] = relative_to
311+
_handle_python_library(entry, attrs, fs, x, known_targets, to_remove, to_build, to_insert)
312+
313+
_build_generated_files(ctx, to_build, to_insert, genrule_to_insert)
279314

280315
# remove any targets we decided we shouldn't output
281316
for remove in to_remove:

0 commit comments

Comments
 (0)