cold-soccer-63228
05/17/2022, 3:12 PMInferDependenciesRequest
, what is the difference between from_sources
and infer_from
? The docstring description and example for https://github.com/pantsbuild/pants/blob/c73b9f68b7e05ac455057142ae50c75f2560d06b/src/python/pants/engine/target.py#L2529-L2559 seem to contradict each otherbitter-ability-32190
05/17/2022, 3:17 PMinfer_from
is the class variable you set to the field type.
soruces_field
is the instance variable you'll get which is an instance of the infer_from
type?cold-soccer-63228
05/17/2022, 3:20 PMFortranSources
is referenced. What does such a class look like? I want to be able to infer dependencies based on *.graphql
files, and want to write something for GraphQLSources
bitter-ability-32190
05/17/2022, 3:21 PMcold-soccer-63228
05/17/2022, 3:23 PMbitter-ability-32190
05/17/2022, 3:23 PMGraphQLSources
target type. See PythonSource
or ScalaSource
target types for example.
The target type will have a source
field of a similar name to your sources. So check out PythonSourceField
and ScalaSourceField
for reference.
... Then when you're ready, wire up the "plural" version ("sources")bitter-ability-32190
05/17/2022, 3:26 PMcold-soccer-63228
05/17/2022, 3:44 PMBUILD
files when I run ./pants tailor
.
Here's what I have so far.
class GraphQLSources(MultipleSourcesField):
expected_file_extensions: ClassVar = (".graphql",)
class GraphQLSourceField(SingleSourceField):
expected_file_extensions: ClassVar = (".graphql",)
class InferGraphQLDependencies(InferDependenciesRequest):
infer_from = GraphQLSources
def rules() -> List[UnionRule]:
return [
UnionRule(InferDependenciesRequest, InferGraphQLDependencies)
]
I need to add something to a register.py
, right?bitter-ability-32190
05/17/2022, 3:45 PMregister
needs to have a rules()
which returns all of the rules you've authored and target_types()
returning the target typesbitter-ability-32190
05/17/2022, 3:46 PMbitter-ability-32190
05/17/2022, 3:46 PMcold-soccer-63228
05/17/2022, 3:49 PMrules()
and target_types()
functions to register.py
, what else do I need to do to expect BUILD
files next to *.graphql
files to be updated with the proper dependencies after running ./pants tailor
?
I defined target_types()
as follows.
def target_types() -> List[SourcesField]:
return [GraphQLSourceField, GraphQLSources]
bitter-ability-32190
05/17/2022, 3:56 PMtailor
to work, there's work to be done to teach tailor
about your targets. This is beyond what I've done (we don't use tailor
quite yet)bitter-ability-32190
05/17/2022, 3:57 PMPutativeTargetsRequest
https://github.com/pantsbuild/pants/search?q=PutativeTargetsRequestbitter-ability-32190
05/17/2022, 3:58 PMfmt
or lint
tools on them?bitter-ability-32190
05/17/2022, 3:59 PMcold-soccer-63228
05/17/2022, 4:01 PMariadne.load_schema_from_path
, which attempts to load *.graphql
files from within Python code. If I don't declare my GraphQL dependencies, then this ends up not working š
https://pantsbuild.slack.com/archives/C046T6T9U/p1652796498287969?thread_ts=1652414328.320049&cid=C046T6T9Ubitter-ability-32190
05/17/2022, 4:01 PMresources
and then add the depcold-soccer-63228
05/17/2022, 4:01 PMbitter-ability-32190
05/17/2022, 4:02 PMresources
, and implement an InferDependencies
between your Python code and the GraphQL files whne necessary.
It's the least amount of code, and metadata šcold-soccer-63228
05/17/2022, 4:04 PMtailor
declare the resources for me? The GraphQL paths being imported are variables, not string literals. I would assume that --python-infer-assets
isn't smart enough to figure it out?bitter-ability-32190
05/17/2022, 4:04 PMHow do I haveYou'll have to grok thedeclare the resources for me?tailor
PutativeTargetsRequest
code in the Pants codebase on how that works. Or I can ping another maintainerbitter-ability-32190
05/17/2022, 4:05 PMThe GraphQL paths being imported are variables, not string literals. I would assume thatYeah the inference is very naive today (and likely will always be "naive" to some degree). I thinking writing your ownisn't smart enough to figure it out?--python-infer-assets
InferDependencies
plugin is likely the way forward for you.cold-soccer-63228
05/17/2022, 4:08 PMPutativeTargetsRequest
? How does it differ from InferDependenciesRequest
at a feature level?
⢠When you mention implementing an InferDependencies
between my Python code and the GraphQL files, are you referring to a subclass of InferDependenciesRequest
? In that subclass, I would look to see whenever I need ariadne.load_schema_from_path
, and then if I do, I add all GraphQL resources as dependencies?bitter-ability-32190
05/17/2022, 4:10 PMWhat exactly isIt's the type that powers? How does it differ fromPutativeTargetsRequest
at a feature level?InferDependenciesRequest
tailor
. InferDependenciesRequest
powers the magical Pants dependency inference for you.
To put it in more concrete terms:
⢠PutativeTargetsRequest
would be rules that allow tailor
to generate python_sources
/`python_tests` etc...
⢠InferDependenciesRequest
would be the rules which parse your source code to find imports, then infer the dependencies on your first- and third-party targetsbitter-ability-32190
05/17/2022, 4:14 PMWhen you mention implementing an InferDependencies between my Python code and the GraphQL files, are you referring to a subclass of InferDependenciesRequest? In that subclass, I would look to see whenever I need ariadne.load_schema_from_path, and then if I do, I add all GraphQL resources as dependencies?You can grok the codebase on other
InferDependencies
requests and how they're all plugged in. Ack that admittedly, Pants' own codebase is powerful, which also means complex too.
High-level:
⢠Subclass the class, declare a rule which takes it as a param (put all the juicy code in the rule) and then declare/register a UnionRule(...)
⢠You probably also want to have your rule take in AllAssetTargets
as a param. That instance contains all the assets in the repo (files and resources)
⢠The rule body should look for the relevant code (in this case ariadne.load_schema_from_path
) and try and match the argument(s) to declared resources
⦠Up to you whether to silently fail if none are found or error.bitter-ability-32190
05/17/2022, 4:15 PMAllAssetTargetsByPath
, which already has the assets mapped to their path!bitter-ability-32190
05/17/2022, 4:16 PMcold-soccer-63228
05/17/2022, 4:29 PMTypeError
when I run ./pants tailor
now...
TypeError: Every element of the entrypoint `target_types` must be a subclass of Target. Bad elements: [<class 'front_porch.modules.peach.internals.pants.graphql.target_types.GraphQLSourceField'>, <class 'front_porch.modules.peach.internals.pants.graphql.target_types.GraphQLSources'>]
Here's what my source looks like.
from typing import ClassVar
from pants.engine.target import MultipleSourcesField, SingleSourceField
class GraphQLSources(MultipleSourcesField):
expected_file_extensions: ClassVar = (".graphql",)
class GraphQLSourceField(SingleSourceField):
expected_file_extensions: ClassVar = (".graphql",)
Do you know what this is?bitter-ability-32190
05/17/2022, 4:30 PMTarget
bitter-ability-32190
05/17/2022, 4:31 PMGraphQLSources
should be renamed to GraphQLSourcesField
, and then you need to declare the types GraphQLSources
which uses the multiple sources field and also declare GraphQLSource
which uses the single source field. And then also declare the generator from ..Sources
to ..Source
.bitter-ability-32190
05/17/2022, 4:31 PMresources
is the way to go šbitter-ability-32190
05/17/2022, 4:31 PMcold-soccer-63228
05/17/2022, 4:34 PMpants-plugins/graphql/goals/tailor.py
that looks as follows.
@dataclass(frozen=True)
class PutativeGraphQLTargetsRequest(PutativeTargetsRequest):
pass
@rule(level=LogLevel.DEBUG, desc="Determine candidate GraphQL targets to create")
async def find_putative_targets(
req: PutativeGraphQLTargetsRequest, all_owned_sources: AllOwnedSources
) -> PutativeTargets:
all_graphql_files = await Get(Paths, PathGlobs, req.search_paths.path_globs("*.graphql"))
unowned_graphql_files = set(all_graphql_files.files) - set(all_owned_sources)
pts = [
PutativeTarget.for_target_type(GraphQLSources, path=dirname, name=None, triggering_sources=sorted(filenames))
for dirname, filenames in group_by_dir(unowned_graphql_files).items()
]
return PutativeTargets(pts)
def rules() -> Iterable[Rule]:
return [*collect_rules(), UnionRule(PutativeTargetsRequest, PutativeGraphQLTargetsRequest)]
Instead of the following:
pts = [
PutativeTarget.for_target_type(GraphQLSources, path=dirname, name=None, triggering_sources=sorted(filenames))
for dirname, filenames in group_by_dir(unowned_graphql_files).items()
]
I should be making it so that it defines a resource
for each filename, yes? What is the Pants API class for the target that generates a resource
?bitter-ability-32190
05/17/2022, 4:35 PMPutativeTarget.for_target_type(ResourceSources
I think.cold-soccer-63228
05/17/2022, 4:50 PMpants.core.target_types.ResourcesGeneratorTarget
bitter-ability-32190
05/17/2022, 4:51 PMbitter-ability-32190
05/17/2022, 4:51 PMcold-soccer-63228
05/17/2022, 4:59 PM@dataclass(frozen=True)
class PutativeGraphQLTargetsRequest(PutativeTargetsRequest):
pass
@rule(level=LogLevel.DEBUG, desc="Determine candidate GraphQL targets to create")
async def find_putative_targets(
req: PutativeGraphQLTargetsRequest, all_owned_sources: AllOwnedSources
) -> PutativeTargets:
all_graphql_files = await Get(Paths, PathGlobs, req.search_paths.path_globs("*.graphql"))
unowned_graphql_files = set(all_graphql_files.files) - set(all_owned_sources)
pts = [
PutativeTarget.for_target_type(
ResourcesGeneratorTarget, path=dirname, name=None, triggering_sources=sorted(filenames)
)
for dirname, filenames in group_by_dir(unowned_graphql_files).items()
]
return PutativeTargets(pts)
I'm running ./pants tailor
again, and seeing a different error.
12:55:04.61 [ERROR] Encountered 9 rule graph errors:
No installed rules return the type PutativePythonTargetsRequest, and it was not provided by potential callers of @rule(pants.backend.python.goals.tailor:88:find_putative_targets(PutativePythonTargetsRequest, AllOwnedSources, PythonSetup, GlobalOptions) -> PutativeTargets, gets=[Get(Paths, PathGlobs), Get(DigestContents, PathGlobs), Get(SourceRootsResult, SourceRootsRequest), Get(UnexpandedTargets, AddressSpecs), Get(ResolvedPexEntryPoint, ResolvePexEntryPointRequest)]).
If that type should be computed by a rule, ensure that that rule is installed.
If it should be provided by a caller, ensure that it is included in any relevant Query or Get.
No source of dependency AllOwnedSources for @rule(pants.backend.python.goals.tailor:88:find_putative_targets(PutativePythonTargetsRequest, AllOwnedSources, PythonSetup, GlobalOptions) -> PutativeTargets, gets=[Get(Paths, PathGlobs), Get(DigestContents, PathGlobs), Get(SourceRootsResult, SourceRootsRequest), Get(UnexpandedTargets, AddressSpecs), Get(ResolvedPexEntryPoint, ResolvePexEntryPointRequest)]). All potential sources were eliminated: []
No source of dependency Get(DigestContents, PathGlobs) for @rule(pants.backend.python.goals.tailor:88:find_putative_targets(PutativePythonTargetsRequest, AllOwnedSources, PythonSetup, GlobalOptions) -> PutativeTargets, gets=[Get(Paths, PathGlobs), Get(DigestContents, PathGlobs), Get(SourceRootsResult, SourceRootsRequest), Get(UnexpandedTargets, AddressSpecs), Get(ResolvedPexEntryPoint, ResolvePexEntryPointRequest)]). All potential sources were eliminated: []
No source of dependency Get(Paths, PathGlobs) for @rule(pants.backend.python.goals.tailor:88:find_putative_targets(PutativePythonTargetsRequest, AllOwnedSources, PythonSetup, GlobalOptions) -> PutativeTargets, gets=[Get(Paths, PathGlobs), Get(DigestContents, PathGlobs), Get(SourceRootsResult, SourceRootsRequest), Get(UnexpandedTargets, AddressSpecs), Get(ResolvedPexEntryPoint, ResolvePexEntryPointRequest)]). All potential sources were eliminated: []
No source of dependency Get(ResolvedPexEntryPoint, ResolvePexEntryPointRequest) for @rule(pants.backend.python.goals.tailor:88:find_putative_targets(PutativePythonTargetsRequest, AllOwnedSources, PythonSetup, GlobalOptions) -> PutativeTargets, gets=[Get(Paths, PathGlobs), Get(DigestContents, PathGlobs), Get(SourceRootsResult, SourceRootsRequest), Get(UnexpandedTargets, AddressSpecs), Get(ResolvedPexEntryPoint, ResolvePexEntryPointRequest)]). All potential sources were eliminated: []
No source of dependency Get(SourceRootsResult, SourceRootsRequest) for @rule(pants.backend.python.goals.tailor:88:find_putative_targets(PutativePythonTargetsRequest, AllOwnedSources, PythonSetup, GlobalOptions) -> PutativeTargets, gets=[Get(Paths, PathGlobs), Get(DigestContents, PathGlobs), Get(SourceRootsResult, SourceRootsRequest), Get(UnexpandedTargets, AddressSpecs), Get(ResolvedPexEntryPoint, ResolvePexEntryPointRequest)]). All potential sources were eliminated: []
No source of dependency Get(UnexpandedTargets, AddressSpecs) for @rule(pants.backend.python.goals.tailor:88:find_putative_targets(PutativePythonTargetsRequest, AllOwnedSources, PythonSetup, GlobalOptions) -> PutativeTargets, gets=[Get(Paths, PathGlobs), Get(DigestContents, PathGlobs), Get(SourceRootsResult, SourceRootsRequest), Get(UnexpandedTargets, AddressSpecs), Get(ResolvedPexEntryPoint, ResolvePexEntryPointRequest)]). All potential sources were eliminated: []
No source of dependency GlobalOptions for @rule(pants.backend.python.goals.tailor:88:find_putative_targets(PutativePythonTargetsRequest, AllOwnedSources, PythonSetup, GlobalOptions) -> PutativeTargets, gets=[Get(Paths, PathGlobs), Get(DigestContents, PathGlobs), Get(SourceRootsResult, SourceRootsRequest), Get(UnexpandedTargets, AddressSpecs), Get(ResolvedPexEntryPoint, ResolvePexEntryPointRequest)]). All potential sources were eliminated: []
No source of dependency PythonSetup for @rule(pants.backend.python.goals.tailor:88:find_putative_targets(PutativePythonTargetsRequest, AllOwnedSources, PythonSetup, GlobalOptions) -> PutativeTargets, gets=[Get(Paths, PathGlobs), Get(DigestContents, PathGlobs), Get(SourceRootsResult, SourceRootsRequest), Get(UnexpandedTargets, AddressSpecs), Get(ResolvedPexEntryPoint, ResolvePexEntryPointRequest)]). All potential sources were eliminated: []
Do I need to add my function definition to a list of rules somewhere? I was following https://github.com/pantsbuild/pants/blob/fda1838ced4b46346d0ee1a8154bbc0de076d7f7/src/python/pants/backend/codegen/protobuf/tailor.py as a reference, which doesn't seem to do that?...bitter-ability-32190
05/17/2022, 5:13 PMbitter-ability-32190
05/17/2022, 5:14 PMcold-soccer-63228
05/17/2022, 5:33 PMdef rules() -> Iterable[Rule]:
return [
*collect_rules(),
find_putative_targets,
UnionRule(
PutativeTargetsRequest,
PutativeGraphQLTargetsRequest,
),
]
This causes the following error:
13:28:32.30 [ERROR] 1 Exception encountered:
AssertionError: A target of type ResourcesGeneratorTarget was proposed at address front_porch/modules/delinquency/loss_mitigation/graphql:graphql with explicit sources loss_mitigation_schema.graphql, but this target type does not have a `sources` field.
I also tried removing the UnionRule
altogether, which made ./pants tailor
run, but I didn't see anything generated for GraphQL resources in the BUILD
files I wanted.
So I'm guessing I do want the UnionRule
there. The question then is: "what is this error telling me, and how do I fix it?"
Going a bit more high-level, how does UnionRule
work, exactly? I tried reading https://www.pantsbuild.org/docs/rules-api-unions but I don't think I quite understand...bitter-ability-32190
05/17/2022, 5:37 PMcold-soccer-63228
05/17/2022, 5:39 PMbitter-ability-32190
05/17/2022, 5:39 PMcollect_rules
magically finds all the @rule
functions in your file, so you shouldnt need to list them out.
---
So I'm guessing I do want theIt's Pants' way of "injecting" code into the engine. E.g. the engine will ask something "please give me all the implementations of things that consume athere. The question then is: "what is this error telling me, and how do I fix it?"UnionRule
PutativeTargetsRequest
. The engine hands the registered union rules over and they get calledcold-soccer-63228
05/17/2022, 5:40 PMsorted(filenames)
, and it seems that they're valid, and I'm passing them into the triggering_sources
parameter. So I'm surprised that it's telling me these targets don't have a sources
field, unless I populate that field differently?bitter-ability-32190
05/17/2022, 5:41 PMbitter-ability-32190
05/17/2022, 5:41 PMResourcesGeneratorTarget
is the wrong typebitter-ability-32190
05/17/2022, 5:42 PMtailor
, personally. let me sniff aroundcold-soccer-63228
05/17/2022, 5:45 PMResourceTarget
?ResourceTarget
also gives the same errorbitter-ability-32190
05/17/2022, 5:45 PMresource
. But if there's going to be multiple, use a glob + the generator target.bitter-ability-32190
05/17/2022, 5:45 PMcold-soccer-63228
05/17/2022, 5:46 PMcold-soccer-63228
05/17/2022, 5:47 PMdefault_sources = default_sources_for_target_type(target_type)
if (explicit_sources or triggering_sources) and not default_sources:
raise AssertionError(
f"A target of type {target_type.__name__} was proposed at "
f"address {path}:{name} with explicit sources {', '.join(explicit_sources or triggering_sources)}, "
"but this target type does not have a `sources` field."
)
cold-soccer-63228
05/17/2022, 5:47 PMcold-soccer-63228
05/17/2022, 5:48 PMdefault_sources_for_target_type(...)
is returning tuple()
?...bitter-ability-32190
05/17/2022, 5:48 PMif issubclass(field, MultipleSourcesField):
return field.default or tuple()
should be firingcold-soccer-63228
05/17/2022, 5:48 PMcold-soccer-63228
05/17/2022, 5:49 PMGraphQLResourceTarget(ResourceTarget)
, and then override the default fields or something?bitter-ability-32190
05/17/2022, 5:49 PMAssertionError: A target of type ResourcesGeneratorTarget was proposed at address front_porch/modules/delinquency/loss_mitigation/graphql:graphql with explicit sources loss_mitigation_schema.graphql, but this target type does not have a `sources` field.
Stemming from
PutativeTarget.for_target_type(
ResourcesGeneratorTarget, path=dirname, name=None, triggering_sources=sorted(filenames)
)
cold-soccer-63228
05/17/2022, 6:00 PMResourceSourceField
is one of the core_fields
in the ResourceTarget
class. And ResourceSourceField
is indeed a subclass of SourcesField
. But unfortunately, SourcesField.default = None
, and it is not overridden.
So I'm guessing I need to override ResourceTarget
with my own GraphQLResourceTarget
and perhaps do the following?
core_fields = (*COMMON_TARGET_FIELDS, Dependencies, GraphQLResourceSourceField)
Then, I would define GraphQLResourceSourceField.default
to be something that's not None
.
Does this sound right?bitter-ability-32190
05/17/2022, 6:01 PMif (explicit_sources or triggering_sources) and not default_sources
You are calling this somewhere with an empty triggering_sources
šbitter-ability-32190
05/17/2022, 6:01 PMcold-soccer-63228
05/17/2022, 6:01 PMcold-soccer-63228
05/17/2022, 6:02 PMowned_sources = explicit_sources or default_sources or tuple()
cold-soccer-63228
05/17/2022, 6:02 PMexplicit_sources
without necessarily having default_sources
definedbitter-ability-32190
05/17/2022, 6:02 PMif not (explicit_sources or triggering_sources or default_sources)
hmm?cold-soccer-63228
05/17/2022, 6:02 PMYou are calling this somewhere with an emptyI don't think so.triggering_sources
triggering_sources
is never emptybitter-ability-32190
05/17/2022, 6:03 PMcold-soccer-63228
05/17/2022, 6:03 PMbitter-ability-32190
05/17/2022, 6:03 PMhundreds-father-404
05/17/2022, 6:03 PMcold-soccer-63228
05/17/2022, 6:03 PMbitter-ability-32190
05/17/2022, 6:05 PMResourceSourceField
before calling that method? Or try as you said maybe?
Really since this is just to support tailor
, you can fudge the code a smidgenbitter-ability-32190
05/17/2022, 6:05 PMPutativeTarget
yourself, copying most of the code from PutativeTarget.for_target_type
bitter-ability-32190
05/17/2022, 6:06 PMcold-soccer-63228
05/17/2022, 6:11 PMtailor
implemented would be useful to have in the pants
repository itself?
All this would do is generate resources wherever *.graphql
files are found...bitter-ability-32190
05/17/2022, 6:22 PMcold-soccer-63228
05/17/2022, 7:55 PMPutativeTarget
š
TypeError: Invalid Get. The third argument `FixedPutativeTarget(path='front_porch/modules/activities/graphql', name='graphql0', type_alias='resource', triggering_sources=('activities_schema.graphql',), owned_sources=(), addressable=True, kwargs=FrozenDict({}), comments=())` must have the exact same type as the second argument, <class 'pants.core.goals.tailor.PutativeTarget'>, but had the type <class 'front_porch.modules.peach.internals.pants.graphql.goals.tailor.FixedPutativeTarget'>.
I think this is happening because of the code here: https://github.com/pantsbuild/pants/blob/41d4b82338cae0b54eb6e81d23dd0e9665fb2598/src/python/pants/core/goals/tailor.py#L586-L589bitter-ability-32190
05/17/2022, 7:57 PMcold-soccer-63228
05/17/2022, 7:57 PMclass FixedPutativeTarget(PutativeTarget):
@classmethod
def for_target_type(
cls,
target_type: type[Target],
path: str,
name: str | None,
triggering_sources: Iterable[str],
kwargs: Mapping[str, str | int | bool | tuple[str, ...]] | None = None,
comments: Iterable[str] = tuple(),
) -> PutativeTarget:
if name is None:
name = os.path.basename(path)
explicit_sources = (kwargs or {}).get("sources")
if explicit_sources is not None and not isinstance(explicit_sources, tuple):
raise TypeError("Explicit sources passed to PutativeTarget.for_target_type must be a Tuple[str].")
default_sources = default_sources_for_target_type(target_type)
if not (explicit_sources or triggering_sources or default_sources):
raise AssertionError(
f"A target of type {target_type.__name__} was proposed at "
f"address {path}:{name} with explicit sources {', '.join(explicit_sources or triggering_sources)}, "
"but this target type does not have a `sources` field."
)
owned_sources = explicit_sources or default_sources or tuple()
return cls(
path,
name,
target_type.alias,
triggering_sources,
owned_sources,
addressable=True, # "Real" targets are always addressable.
kwargs=kwargs,
comments=comments,
)
cold-soccer-63228
05/17/2022, 7:57 PMFixedPutativeTarget
where I previously used PutativeTarget
bitter-ability-32190
05/17/2022, 7:58 PMbitter-ability-32190
05/17/2022, 7:58 PMfor_target_type
instead just construct your PutativeTarget(...)
bitter-ability-32190
05/17/2022, 7:59 PMpts = [
PutativeTarget(<put the right values here>)
for dirname, filenames in group_by_dir(unowned_graphql_files).items()
]
cold-soccer-63228
05/17/2022, 7:59 PMcold-soccer-63228
05/17/2022, 7:59 PMcold-soccer-63228
05/17/2022, 7:59 PMcold-soccer-63228
05/17/2022, 8:00 PMtype_alias
and owned_sources
be?bitter-ability-32190
05/17/2022, 8:01 PMfor_target_type
and follow the code alongbitter-ability-32190
05/17/2022, 8:02 PMResourcesGeneratorTarget.alias
and maybe tuple()
?cold-soccer-63228
05/17/2022, 8:07 PMpts = [
PutativeTarget(
path=dirname,
name="graphql",
type_alias=ResourcesGeneratorTarget.alias,
owned_sources=tuple(),
triggering_sources=sorted(filenames),
)
for dirname, filenames in group_by_dir(unowned_graphql_files).items()
]
It generates the following.
resource(
name="graphql0",
)
Granted, this is generating something now, so it seems like a step in the right direction. I am wondering how I can get it to have something like follows.
resource(
name="graphql",
sources=[ <the sources I passed in> ]
)
cold-soccer-63228
05/17/2022, 8:07 PMbitter-ability-32190
05/17/2022, 8:10 PMowned_sources
to something like "*.graphql"
? Also super weird it is generating a resource
and not a resources
.bitter-ability-32190
05/17/2022, 8:10 PMcold-soccer-63228
05/17/2022, 8:16 PMowned_sources
to:
⢠sorted(filenames)
⢠("*.graphql",)
Also tried setting addressable=True
.
Perhaps I need to populate kwargs
?...bitter-ability-32190
05/17/2022, 8:18 PMtailor
did to your BUILD file before trying a new permutation?cold-soccer-63228
05/17/2022, 8:21 PMPutativeTarget.for_target_type
is ultimately invoking the what I am currently invoking...
Is there perhaps another rule I need to add besides find_putative_targets
that I've defined? This tells me how to find the targets, but does it tell it also how to add the sources as I would expect?bitter-ability-32190
05/17/2022, 8:21 PMbitter-ability-32190
05/17/2022, 8:22 PMkwargs
š¤·āāļøcold-soccer-63228
05/17/2022, 9:00 PMsources=[...]
not to be emitted.
As an experiment, I tried invoking both PutativeTarget.for_target_type(target_type=PythonSourcesGeneratorTarget, ...)
and PutativeTarget(type_alias=PythonSourcesGeneratorTarget.alias)
and inspecting what was generated.
If I don't pass in what the default sources of PythonSourcesGeneratorTarget
into the owned_sources
parameter of the PutativeTarget
constructor, the sources aren't generated. But if I pass in the exact same default sources into the owned_sources
parameter, they are generated... š¤bitter-ability-32190
05/17/2022, 9:01 PMbitter-ability-32190
05/17/2022, 9:01 PMkwargs
work around that or nah?cold-soccer-63228
05/17/2022, 9:02 PMkwargs
is primarily used for PutativeTarget.for_target_type
, and not the PutativeTarget
constructor itself, really...cold-soccer-63228
05/17/2022, 9:02 PMbitter-ability-32190
05/17/2022, 9:03 PMcold-soccer-63228
05/17/2022, 9:03 PMbitter-ability-32190
05/17/2022, 9:03 PMhundreds-father-404
05/17/2022, 9:03 PMhundreds-father-404
05/17/2022, 9:04 PMhundreds-father-404
05/17/2022, 9:04 PMcold-soccer-63228
05/17/2022, 9:11 PMcold-soccer-63228
05/17/2022, 9:21 PMpython_sources
correctly. (I'm trying to generate resources
, but am using python_sources
generation as an experiment, since invoking PutativeTarget.for_target_type
for ResourcesGeneratorTarget
seems broken:
PutativeTarget.for_target_type(
target_type=PythonSourcesGeneratorTarget,
path=dirname,
name="graphql_schema",
triggering_sources=sorted(filenames),
)
However, constructing PutativeTarget
directly causes the sources=[...]
to be missing in the generated files.
PutativeTarget(
path=dirname,
name="graphql_schema",
type_alias=PythonSourcesGeneratorTarget.alias,
owned_sources=("*.graphql",),
triggering_sources=sorted(filenames),
addressable=True,
)
When inspecting the underlying PutativeTarget
object, it seems that the only difference is the owned_sources
attribute.
@hundreds-father-404, I'm curious if you have any suspicions on why this causes sources=[...]
to not generate?hundreds-father-404
05/17/2022, 9:27 PMcold-soccer-63228
05/17/2022, 9:34 PM@dataclass(frozen=True)
class PutativeGraphQLTargetsRequest(PutativeTargetsRequest):
pass
@rule(level=LogLevel.DEBUG, desc="Determine candidate GraphQL resources to create")
async def find_putative_targets(
req: PutativeGraphQLTargetsRequest, all_owned_sources: AllOwnedSources
) -> PutativeTargets:
all_graphql_files = await Get(Paths, PathGlobs, req.search_paths.path_globs("*.graphql"))
unowned_graphql_files = set(all_graphql_files.files) - set(all_owned_sources)
return PutativeTargets(
[
PutativeTarget(
path=dirname,
name="graphql_schema",
type_alias=ResourcesGeneratorTarget.alias,
owned_sources=("*.graphql",),
triggering_sources=sorted(filenames),
addressable=True,
)
for dirname, filenames in group_by_dir(unowned_graphql_files).items()
]
)
Thanks for the help!cold-soccer-63228
05/17/2022, 9:57 PMowned_sources=tuple(...)
and kwargs={"sources": tuple(...)}
, then it works. But this feels like a bug?cold-soccer-63228
05/18/2022, 7:37 PMkwargs
.