-
-
Notifications
You must be signed in to change notification settings - Fork 627
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow going from Addresses -> Address
#9097
Allow going from Addresses -> Address
#9097
Conversation
This avoids an upcoming import cycle
This removes graph ambiguity issues.
Addresses -> Address
class MappingError(Exception): | ||
"""Indicates an error mapping addressable objects.""" | ||
|
||
|
||
class UnaddressableObjectError(MappingError): | ||
"""Indicates an un-addressable object was found at the top level.""" | ||
|
||
|
||
class DuplicateNameError(MappingError): | ||
"""Indicates more than one top-level object was found with the same name.""" | ||
|
||
|
||
class ResolveError(MappingError): | ||
"""Indicates an error resolving targets.""" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moved to avoid a cyclic import. These also arguably belonged here originally as they are used in multiple files.
@rule | ||
async def find_build_file(address: Address) -> BuildFileAddress: | ||
address_family = await Get[AddressFamily](Dir(address.spec_path)) | ||
# NB: `address_family.addressables` is a dictionary of `BuildFileAddress`es and we look it up | ||
# with an `Address`. This works because `BuildFileAddress` is a subclass, but MyPy warns that it | ||
# could be a bug. | ||
struct = address_family.addressables.get(address) # type: ignore[call-overload] | ||
addresses = address_family.addressables | ||
if not struct or address not in addresses: | ||
_raise_did_you_mean(address_family, address.target_name) | ||
return next(build_address for build_address in addresses if build_address == address) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is prework for the next step of the project: no longer storing BuildFileAddress
in HydratedTarget
. Once we make that change, we need this rule so that we have a way to go from Address -> BuildFileAddress
.
@@ -222,7 +227,7 @@ def _hydrate(item_type, spec_path, **kwargs): | |||
address_family_by_directory = {af.namespace: af for af in address_families} | |||
|
|||
matched_addresses = OrderedSet() | |||
addr_to_origin: Dict[BuildFileAddress, AddressSpec] = {} | |||
bfaddr_to_origin: Dict[BuildFileAddress, AddressSpec] = {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The below changes are only renames to make clear that this is a BFA
rather than Address
. Will make the follow up easier to understand.
def _inject_addresses(self, subjects): | ||
"""Injects targets into the graph for each of the given `Address` objects, and then yields them. | ||
|
||
TODO: See #5606 about undoing the split between `_inject_addresses` and `_inject_address_specs`. | ||
""" | ||
logger.debug('Injecting addresses to %s: %s', self, subjects) | ||
with self._resolve_context(): | ||
addresses = tuple(subjects) | ||
thts, = self._scheduler.product_request(TransitiveHydratedTargets, | ||
[BuildFileAddresses(addresses)]) | ||
|
||
self._index(thts.closure) | ||
|
||
yielded_addresses = set() | ||
for address in subjects: | ||
if address not in yielded_addresses: | ||
yielded_addresses.add(address) | ||
yield address | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was never used.
# NB: The HydratedTargets are not valid HydratedTargets, such as using a str instead of | ||
# Address for the .address field. This is okay because it makes the tests much easier to work | ||
# with and the topo_sort rule does not actually care about the HydratedTarget fields. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Leftover from prior PR.
@@ -39,31 +39,26 @@ class Filedeps(Goal): | |||
@goal_rule |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This file only has some light refactoring. We're going to need to change this file once HydratedTarget.address
is no longer a BFA so that we await Get[BuildFileAddress](Address)
.
a31f035
to
851653f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lovely: thanks!
@@ -80,6 +81,17 @@ def _raise_did_you_mean(address_family: AddressFamily, name: str, source=None) - | |||
raise resolve_error from source | |||
raise resolve_error | |||
|
|||
@rule | |||
async def find_build_file(address: Address) -> BuildFileAddress: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, this works, but we should take a look at how it is being used, and see whether it should be batched. The parsing will be memoized obviously, but each usage is O(N) in the number of targets in a directory.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good. For now, it adds no new complexity than what we had before. But, after we finish this project, we'll be able to see if we can improve this. Thanks!
Part of #9083.
This allows us to entirely use
Addresses
andAddress
in V2 rules, rather thanBuildFileAddresses
. Tangibly,run
andtest
can now requestAddresses
in their signature.The only remaining piece is changing
HydratedTarget
,TargetWithOrigin
, andTargetAdaptor
to storeAddress
rather thanBuildFileAddress
, which is saved for a followup due to issues with V1 still expectingBuildFileAddress
.