powerful-eye-58407
05/04/2023, 1:24 PMpython_distribution(
name="common_package",
dependencies=<DEPENDENCIES_LIST>,
provides=python_artifact(
name="common_package",
version="1.0.0",
author="Pantsbuild",
python_requires=">=3.8.0",
),
)
This is a "library" wheel, being a collection of various packages. This means there is no single entry point.
I still want to use pants dependency inference for 3rd party packages.
I could have just listed all subdirectories of the sources root as dependencies and have them all included in the wheel (exactly as I want) - but the problem is that there's over 100 of them, and they keep changing....
So, I thought I can create a plugin to tweak the python distribution target so that the dependencies list is automatically generated using some sort of mechanism described in the doc, for example by just using AllTargets
.
The problem is that I'm not sure how PythonDistribution target is used, it doesn't seem as easy as tweaking SetupKwargs for python artifacts, as described here 🙂
I'd appreciate any tips on how to get started on the plugin (or maybe if there's a simpler way that I might have missed). Thanks!powerful-eye-58407
05/04/2023, 1:27 PMInferPythonDistributionDependencies
request is a good way to start https://github.com/pantsbuild/pants/blob/main/src/python/pants/backend/python/target_types_rules.py#L446powerful-eye-58407
05/04/2023, 1:28 PMinfer_python_distribution_dependencies
curved-television-6568
05/04/2023, 2:02 PMtarget(name="library_deps", dependencies=[<DEP LIST>])
snippet that you put in a BUILD file and then have a dep from the python_distribution to that: dependencies=["libs:library_deps"]
2. as a plugin, setup a custom target type that picks up your targets as deps according to the logic in the custom script and use that custom target in the BULD file for the dist to depend uponpowerful-eye-58407
05/04/2023, 2:21 PMpowerful-eye-58407
05/04/2023, 2:22 PMpowerful-eye-58407
05/04/2023, 3:00 PMpython_distribution(
name="common_package",
dependencies=[":library_deps"]
provides=...
)
library_root( # this is a custom LibraryRoot target
root_dir="directory_name_goes_here",
name="library_deps",
# dependencies=... << this I want my plugin to automatically populate somehow
)
Then I need a rule to transform a target with root_dir field so that it becomes depended on all targets inside root_dir that make sense, right?
I'm not sure what rule signature do I need here, as I'm not sure what pants does to get dependencies for a target. Based on this I'd guess it would be sth like:
@rule
async def populate_deps(target: LibraryRoot, request: DependenciesRequest) -> Targets:
# extract library root dir from target
# create the list of targets and return them
powerful-eye-58407
05/04/2023, 3:02 PMcurved-television-6568
05/04/2023, 3:04 PMpowerful-eye-58407
05/04/2023, 3:05 PMcurved-television-6568
05/04/2023, 3:32 PMroot_dir
field as required rather than some dependencies field. then implement the rule returning InferredDependencies
as appropriatepowerful-eye-58407
05/04/2023, 3:46 PMpowerful-eye-58407
05/04/2023, 3:48 PMclass LibraryRootsField(StringSequenceField):
alias = "library_roots"
help = "Paths to directory containing source code to be packaged"
class PythonLibraryConfiguration(Target):
alias = "python_library_configuration"
core_fields = (*COMMON_TARGET_FIELDS, LibraryRootsField)
@dataclass(frozen=True)
class PythonLibraryDependenciesInferenceFieldSet(FieldSet):
required_fields = (LibraryRootsField,)
library_roots: LibraryRootsField
class InferPythonLibraryDependencies(InferDependenciesRequest):
infer_from = PythonLibraryDependenciesInferenceFieldSet
@rule
def infer_python_library_dependencies(
request: InferPythonLibraryDependencies,
) -> InferredDependencies:
<http://logger.info|logger.info>("infer_python_library_dependencies called")
# TODO logic goes here...
return InferredDependencies(...)
powerful-eye-58407
05/04/2023, 3:48 PMpowerful-eye-58407
05/04/2023, 3:50 PMcurved-television-6568
05/04/2023, 3:50 PMcurved-television-6568
05/04/2023, 3:56 PMcurved-television-6568
05/04/2023, 3:59 PMcurved-television-6568
05/04/2023, 3:59 PMhappy-kitchen-89482
05/04/2023, 6:13 PMsources=["**/*.py"]
(maybe excluding tests if you have tests in the same dirs as sources) and then have a single dep on that target?powerful-eye-58407
05/04/2023, 7:11 PMPossibly even simpler - could you replace your fine-grained per-directory python_sources with one at the source root, withThat would work without plugins, that's true. I already have the structure with one BUILD file per directory and some of them required extra changes to infer 3rd party dependencies, that's why I was wondering how to do it in a different way, without removing all existing BUILD files in subdirs.(maybe excluding tests if you have tests in the same dirs as sources) and then have a single dep on that target?sources=["**/*.py"]