Skip to content

Commit

Permalink
docs: provide example how to convert target addresses to source files…
Browse files Browse the repository at this point in the history
… in rules API (pantsbuild#20524)

A plugin may need to output a list of resources (e.g. source code files)
so that it can be fed to another program (outside of Pants). Pants
operates on targets, and they can won't be understood by anything
outside of Pants.

E.g. `some/config/folder/example1.cfg:../config` would need to be
trimmed to map to a file. This is similar to what `filedeps` goal would
do, but without including BUILD files which are often irrelevant.

This snippet shows how this is done.

---------

Co-authored-by: Andreas Stenius <[email protected]>
  • Loading branch information
AlexTereshenkov and kaos authored Feb 12, 2024
1 parent e9f4d5d commit 1740a4e
Showing 1 changed file with 25 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ class MyTarget(Target):
Then, to resolve the addresses, you can use `UnparsedAddressInputs`:

```python
from pants.engine.addresses import Address, Addresses, UnparsedAddressInputs
from pants.engine.addresses import Addresses, UnparsedAddressInputs
from pants.engine.target import Targets
from pants.engine.rules import Get, rule

Expand Down Expand Up @@ -291,6 +291,30 @@ async def demo(...) -> Foo:

`SourceFilesRequest` expects an iterable of `SourcesField` objects. `SourceFiles` has a field `snapshot: Snapshot` with the merged snapshot of all resolved input sources fields.

To convert a list of target addresses to existing source file names, you can request `HydratedSources` for every input target:

```python
from itertools import chain
from pants.engine.addresses import Addresses
from pants.engine.collection import DeduplicatedCollection
from pants.engine.rules import Get, MultiGet, rule
from pants.engine.target import (HydratedSources, HydrateSourcesRequest, SourcesField, UnexpandedTargets)


class ProjectSources(DeduplicatedCollection[str]):
pass


@rule
async def addresses_to_source_files(addresses: Addresses) -> ProjectSources:
targets = await Get(UnexpandedTargets, Addresses, addresses)
all_sources = await MultiGet(Get(HydratedSources, HydrateSourcesRequest(tgt.get(SourcesField))) for tgt in targets)
return ProjectSources(chain.from_iterable(sources.snapshot.files for sources in all_sources))
```

This is often useful when you need to pass target addresses to commands that are not Pants goals and would not
be able to interpret them properly.

### Enabling codegen

If you want your plugin to work with code generation, you must set the argument `enable_codegen=True`, along with `for_sources_types` with the types of `SourcesField` you're expecting.
Expand Down

0 comments on commit 1740a4e

Please sign in to comment.