post call-by-name, is there any way to replace reg...
# development
f
post call-by-name, is there any way to replace registered rules via a plugin? I'm looking at upgrading to 2.28 but we have a few rules that relied on the ability to patch what pants ships with. Mostly this is changes to the nodejs backend, where we are working around some limitation in the existing code. We're slowly upstreaming these fixes but having the ability to do it via plugin was nice in that it unblocked us
h
Ha, no, there will not be. That was the feature we decided to jettison as it wasn’t worth the cost of the solver…
I wonder if monkeypatching might work
Sorry, this ability to patch in new rule implementations was rarely used (although you are apparently getting value from it) and deemed not worth the cost of the solver (both at runtime and in maintaining its complicated code)
f
Yeah I remember hearing that on the call and I think it makes sense to optimize for the common case. I need to dig through the rule graph code more to understand whats happening, but simple monkey patching does work prior to 2.28 but not after (the old rule is still invoked). Maybe a special api could be exposed to the plugins to allow explicit rule-replacement? In our case, I think we're replacing the implementation of a rule with the same method signature
f
Idea: Create a new
register.py
which calls the underlying backend’s registration methods but patches as you want and then returns those as the rules, target types, etc.
Don’t enable the underlying backend directly, just your facade backend.
Avoids any need for a special API.
f
thats actually what we're doing today, I'm going to see if I can put together a tiny reproduction that shows where it works / doesn't
f
That would be helpful. Because then might be fruitful to address why that doesn’t work.
h
Ah yes, that should work…
f
Ok heres a small repo showing it. Hopefully I'm just monkeypatching wrong or something https://github.com/chris-smith-zocdoc/pants-custom-plugin-rule-override
f
So calling
.rules()
get you
TaskRule
instances made by the
@rule
decorator. Maybe set
canonical_name
on your replacement rule to match the name of the underlying rule to be replaced?
Otherwise,
@rule
will infer the name based on the module in which the rule (your replacement) is defined.
f
I was able to get it working by swapping the callable on the original rule to the patched version. Let me try the
canonical_name
version to see if thats simpler https://github.com/chris-smith-zocdoc/pants-custom-plugin-rule-override/blob/5b7ab[…]8c8d9650d8318399780392ae93375/pants-plugins/plugin1/register.py