-
-
Notifications
You must be signed in to change notification settings - Fork 638
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for consuming Subsystems from @rules #6993
Add support for consuming Subsystems from @rules #6993
Conversation
2b7cf9c
to
842ce46
Compare
842ce46
to
7838a88
Compare
This is now reviewable! Commits should be independently useful to review. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great, although it in some places exceeds the boundaries of my knowledge of this part of the code (which means it's good that I'm reviewing these, for my own benefit...)
def register_subsystems(self, subsystems): | ||
return self.register_optionables(subsystems) | ||
|
||
def register_optionables(self, optionables): | ||
"""Registers the given subsystem types. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Docstring should mention "optionable" now, not "subsystem"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, why is this bit necessary? What are the non-subsystem optionables we care about in this context?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Subsystem.scoped(cls)
results in a SubsystemDependency
, which implements OptionableFactory
in this PR. And in #6880, Goal
implements Optionable
rather than Subsystem
.
Eventually we might be able to shrink the Optionable
/Subsystem
split... but this PR widens that gap a bit.
|
||
|
||
@console_rule('list', [Select(Console), Select(ListOptions), Select(Specs)]) | ||
def fast_list(console, options, specs): | ||
"""A fast variant of `./pants list` with a reduced feature set.""" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you remove the "reduced feature set" caveat? I don't see anything missing here now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's missing some of the options that used to be inherited from ConsoleTask
: that will be resolved in #6880.
# Console rule can only have one subject. | ||
assert len(subjects) == 1 | ||
for goal in goals: | ||
try: | ||
goal_product = self.goal_map[goal] | ||
params = Params(subjects[0], options_bootstrapper, console) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is my ignorance of the new engine talking, but where are these params consumed? I.e., what is using the options_bootstrapper in the console rule?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When the engine is invoked with a request for some type (a synthetic type ListGoalExecution
in this case), the engine selects a root @rule
to execute that produces that type given a non-ambiguous subset of the input params.
In this case, ListGoalExecution
actually uses all 3 of these parameters to execute: a portion of the rendered rulegraph looks like:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That much I understood already :) What I'm missing is where in the code the bootstrapper param is used in the production of the type.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@benjyw : See the screenshot. It shows that:
fast_list
depends onconstruct_scope_fastlist
(a synthetic method generated by this patch), which depends onscope_options
, which depends onparse_options
which consumes theOptionsBootstrapper
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, the piece I was missing was the code already in src/pants/src/python/pants/engine/legacy/options_parsing.py
.
@@ -196,7 +196,7 @@ def _prefork_loop(self, session, options): | |||
continue | |||
return target_roots | |||
|
|||
def _prefork_body(self, session, options): | |||
def _prefork_body(self, session, options, options_bootstrapper): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's something a bit jarring about passing around an options
along with the options_bootstrapper
that created it, since, naively, the role of the latter is create the former, so one might wonder why you still need the bootstrapper around, or, if you do, why you can't generate options
from it. Can you clarify in a comment somewhere? Or at least on the review, for my own edification?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Getting Options
from an OptionsBootstrapper
requires (re-)running the OptionsInitializer
to collect known scopes and call get_full_options
... the in-engine options parsing current re-does that work if requested. But as we port more code to v2, we should be able to push TargetRoots
calculation and other options-consuming prerequisite code into the engine and make that the only instance of options parsing in a v2-only run.
I think that this options
instance is actually only the global options and could be renamed to make that more obvious, but assuming this CI run goes green, I'd rather do that followup in #6880 instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, that makes sense. Definitely don't rename it in this change.
7838a88
to
112ba46
Compare
…rules, and consume a ListOptions Subsystem in order to implement the rest of `list`.
112ba46
to
9f68fc6
Compare
One confirmed flake. Merging. |
# Console rule can only have one subject. | ||
assert len(subjects) == 1 | ||
for goal in goals: | ||
try: | ||
goal_product = self.goal_map[goal] | ||
params = Params(subjects[0], options_bootstrapper, console) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the story with Console
being a Param
rather than a Singleton
? I thought we wanted to minimise Params
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this case, the Console
being a Param
is:
- more semantically correct, because in the case of
pantsd
, each run has a "new" console (we mutate global variables to accomplish this elsewhere, but we wouldn't technically need to with appropriate use of injection like this) - it's easier to test, because we can inject a mock
Console
rather than using the mutation as above
### Problem When looking at @benjyw's [comment thread](#6993 (comment)) with @stuhood on #6993, it seemed like it was difficult to create effective screenshots of the rule graph. This seemed to be for two reasons: 1. The nodes of the drawn graph are exceedingly wide due to the text being written in a single line. 2. The context of each node isn't clear (root nodes are outlined in blue, which is hard to make out compared to black against a white background, especially as the HSV coloration that `dot` outputs or that the OSX Preview app displays seems to be a bit off compared to other HSV selectors). ### Solution - Insert some newlines in the formatting of nodes in the rule graph to make it skinnier. - Color many different types of nodes by printing the node name, then its attributes, before printing the node again within a pair of `{ ... }` in the `.dot` file. ### TODO - [x] Use `Display` impls as [noted by @stuhood below](#7024 (comment)), and/or make clear the difference between string representations for diagnostics and errors vs strings for graph drawing. - [x] Color intrinsics the way we now do with Params, Singletons, and root nodes. This would require modifying `entry_node_str_with_attrs()` in much the same way as is done with `entry_str()` and `entry_node_str_with_attrs()` here. - [x] Remove the stub `__str__()` implementations which currently have `???`s. - [ ] Consider using more formatting attributes, such as `height`, `width`, `fixed-size` -- see `dot(1)`. - [x] **(#9016)** Weight *edges* with `Get`s, as described in #7024 (comment). ### Result ![graph-thin](https://user-images.githubusercontent.com/1305167/73127432-270e4380-3fb8-11ea-880e-5104083c20c8.png) <img width="1425" alt="graph-wider" src="https://user-images.githubusercontent.com/1305167/73127433-270e4380-3fb8-11ea-9ebb-c319f1080abb.png"> <img width="1407" alt="graph-thicc" src="https://user-images.githubusercontent.com/1305167/73127431-270e4380-3fb8-11ea-8bf0-09c28f6c3229.png">
Problem
#6872 laid groundwork for consuming
(Scoped)Options
from@rules
, but did not actually expose a facility for a@(console_)rule
to consume aSubsystem
.Solution
Expose
ScopedOptions
parsing to@console_rules
, and add a helper method that creates an@rule
to construct aSubsystem
. Finally, use this facility to havev2
list
consume aSubsystem
that holds options that define (most) of the behaviour that would allow it to replace theTask
/v1
implementation of./pants list
.Result
@rules
and@console_rules
can consumeSubsystems
. This is a prerequisite for #6880, which will build atop this facility to fully supportv2
-only goals, and replacev1
list
withv2
list
.