Hi everyone. Is there by any chance an updated ve...
# plugins
f
Hi everyone. Is there by any chance an updated version of https://www.pantsbuild.org/stable/docs/writing-plugins/common-plugin-tasks/add-codegen anywhere? I'm having some issues, and at least part of it seems to be outdated class names in the doc.
The class renaming issue that I know about is
Inject
->
Infer
for dependency detection. But I'm also having a problem that when I include my
UnionRule(GenerateSourcesRequest, <my class>)
the entire system seems to lose all of the rules for all of the union members and I get 48 rule graph errors about "No installed rules".
I have a similar problem for the dependency inference rules, so I'm speculating that something changed about the
UnionRule
call that needs to be updated in the documentation?
g
My general goto is to either reference one of my known good rules; or one of the built-in plugins, unfortunately. With that said, I haven't noticed any previously working code in my plugins stop working around codegen. As an example; this is how my union rule is set up:
Copy code
class GenerateKubernetesFromKustomizeRequest(GenerateSourcesRequest):
    input = KustomizeSourcesField
    output = KubernetesSourceField

def rules():
    return [
        *collect_rules(),
        UnionRule(GenerateSourcesRequest, GenerateKubernetesFromKustomizeRequest),
    ]
And then the rule itself is declared like this:
Copy code
@rule
async def generate_kubernetes_from_kustomize(
    request: GenerateKubernetesFromKustomizeRequest,
    kustomize: KustomizeTool,
    platform: Platform,
) -> GeneratedSources:
Which has also been unchanged for quite a while.
I'd wager that when you add the union rule your actual implementation rule gets included with the graph but contains some error -- I've had great luck finding the error by just commenting out and stubbing calls, using bisection. Comment out everything except the return; if it works then you know the error is introduced by the function and not elsewhere. Could still be in a "downstream" function, though.
f
hmm. I can make the error go away by changing the parameters (like removing the tool), but then it doesn't show up as a valid codegen target. I'll try stubbing out the rule and see what happens.
g
That is interesting. So if I understand correctly and using my code as an example; removing
KustomizeTool
and all uses thereof in the function makes Pants work but it's not detected as a codegenable-target?
f
correct. Using the term "work" lightly, since it doesn't actually build my code. But that makes it not give the graph errors.
g
It seems to me that something is wrong with your tool then, as a starting point. Or somewhere you use it. But that's likely not the cause of the build not working.
f
certainly possible. This is my introduction to pants, so I'm kind of coding by "guess & check". I tried using Cursor to help, but it got very confused.
ok, so I've been going through https://www.pantsbuild.org/stable/docs/writing-plugins/the-rules-api/installing-tools again. It doesn't describe how to install an in-repo tool. Do you know if that's documented anywhere or there is an example?
g
So e.g. you have f.ex. a Python package and you want that to be your tool?
f
a perl script in this case, but yes.
g
Ok. Is embedding the perl script into your plugin code an option? That'll make your life easier.
f
Not really. I guess I could copy it somewhere and make it a BinaryPath?
or, maybe I should ask for clarification... what do you mean by embedding it into the plugin code? Just in lining the text of it in a CreateDigest object?
g
Hmm. The general way I'd do something like this is just manifest the code as a file and add to the sandbox sources when I invoke it. This is how most Pants-embedded scripts do it as well. This is a bit uglier, but it's an example I know from the top of my head: https://github.com/pantsbuild/pants/blob/main/src/python/pants/backend/python/providers/python_build_standalone/rules.py#L563
Yes, exactly. The code I linked just passes the script on the command line, but creating a file is IMO easier and has less issues.
f
So I did get this to work as a new goal and then I just pulled the script in as if it were one of the source files and ran it with
Process
and that was fine, but I figured I need to switch over to a proper codegen setup to be able to chain my rules.
g
I'm not sure I know enough at this point to say whether that is a true assertion or not. In general, yes. Doing more with the "right tools" that Pants gives you will make it integrate better and make it easier to expand. But I don't know what your goal is... if it was related to getting the perl script somewhere it sounds like the wrong tool for the job.
f
The perl script is a code generator - it takes in human written source code and spits out code in a different language. My ultimate goal is to go from the human written code, through a chain of dynamically discovered dependencies, a few different code generators (depending on what dependencies were found), and ultimately into a compiler. The binary generated by the compiler is the actual build product that the users want.
Let me come at this question from a different direction... what arguments are rules that return GeneratedSources expected to take in? My reading of the documentation is that just a type that's subclassed from GenerateSourcesRequest and registered to it with UnionRule is enough. And any extras are just based on the individual rule's needs.
g
So that does sound like something you'd do with codegen rules, indeed. I think you should be fine with just that. You can see exactly what it looks for here: https://github.com/pantsbuild/pants/blob/b68fbe7784df3862d26835556284efdcbe8ae9b5/src/python/pants/backend/codegen/export_codegen_goal.py#L40 The
export-codegen
goal in general is a gods-end for testing codegen rules, since you can validate in vitro if your rule works
So as far as I can tell it goes through all things that are part of the Union with GenerateSourcesRequest, checks for each target we've asked to run against if it matches one or more of those input source fields, and then runs the rule
f
Yes, I've been using
export-codegen
. I was looking at that exact code yesterday... I wish there was a debug print of
all_generate_request_types
and
inputs_to_outputs
.
I was specifically wondering what's up with line 51's check for
req.exportable
. Is that something I need to set in my request class? Is it more involved than just adding
exportable = True
? Because that didn't work. 🙂
g
fd export_codegen_goal.py ~/.cache/nce/
- should be able to modify the code if you can figure out which file matches the pants you're using. Or just run pants from source.
Exportable is true by default; no idea about the use-case unfortunately.
f
ok. That gives me something to try.
ah! Got it! I registered the generator as for generating the target type, not the source field type.
Thank you very much for your help, Tom. I really appreciate it!
And, in case anyone else reads this thread, I was able to use my in-repo script just by pulling it in with PathGlobs.