Skip to content
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 v2-only goals, and replace list with a @console_rule #6880

Merged

Conversation

stuhood
Copy link
Member

@stuhood stuhood commented Dec 7, 2018

Problem

While @console_rule has existed for a while now, it has not yet been possible to install a @console_rule as the exclusive implementer of a goal like ./pants list (see #6918 and #6651). Additionally, replacing existing goals comes with a need to backwards-compatibly consume options.

Solution

Run goals that are unambiguously --v1 or --v2 without passing those flags: this means that passing the --v1 vs --v2 flags is only necessary in cases where both v1 and v2 goals are installed. Additionally, create an engine.goal.Goal class with an inner Optionable instance in order to claim a CLI scope (and have options), and require one for all @console_rules. Finally, add a ConsoleRuleTestBase class to easily unit test @console_rules.

Result

The list goal is now implemented as a @console_rule, and consequently: is faster. ./pants help list is unchanged due to a deprecated dependency on a CacheSetup subsystem, and an optional Goal-mixin for wrapping line-oriented output around a Console. Fixes #6918 and fixes #6651.

@stuhood

This comment has been minimized.

@benjyw
Copy link
Contributor

benjyw commented Dec 7, 2018

So how does option equality work here? Presumably we only want to invalidate on changes to options with fingerprint=True, right?

@stuhood
Copy link
Member Author

stuhood commented Dec 8, 2018

So how does option equality work here? Presumably we only want to invalidate on changes to options with fingerprint=True, right?

fingerprint=True is used for v1 caching, but v2 caching is intended to be 100% "arguments to a subprocess" based.

Option/value equality in the engine's graph is used for memoization in the in-memory graph only: so it's essentially only used to avoid re-running things with pantsd. And in that case, any changes to a @(console_)rules arguments are relevant, because otherwise it would not re-run at all.

@stuhood stuhood force-pushed the stuhood/console-rules-consume-options branch 2 times, most recently from 1081b02 to 29b22f9 Compare December 8, 2018 02:35
@benjyw
Copy link
Contributor

benjyw commented Dec 8, 2018

So any option change will trigger a rebuild of the graph, but if the option change didn't happen to cause any input changes to any subprocesses, they won't re-run?

Copy link
Contributor

@illicitonion illicitonion left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is super exciting, great to see!

My only major point which may need discussion is about the tight coupling/overloading of subsystem with v2 goal.

Otherwise a few broken corners, a few bits of boilerplate it would be nice to remove, but looks great!

src/python/pants/bin/goal_runner.py Outdated Show resolved Hide resolved
src/python/pants/core_tasks/register.py Show resolved Hide resolved
src/python/pants/engine/rules.py Show resolved Hide resolved
src/python/pants/rules/core/fastlist.py Outdated Show resolved Hide resolved
src/python/pants/rules/core/fastlist.py Outdated Show resolved Hide resolved
src/python/pants/rules/core/fastlist.py Outdated Show resolved Hide resolved
src/python/pants/rules/core/fastlist.py Outdated Show resolved Hide resolved
src/python/pants/rules/core/fastlist.py Outdated Show resolved Hide resolved
@stuhood
Copy link
Member Author

stuhood commented Dec 13, 2018

So any option change will trigger a rebuild of the graph, but if the option change didn't happen to cause any input changes to any subprocesses, they won't re-run?

Correct.

@stuhood

This comment has been minimized.

@stuhood stuhood force-pushed the stuhood/console-rules-consume-options branch from 29b22f9 to 512b64f Compare December 14, 2018 06:24
@stuhood

This comment has been minimized.

Copy link
Contributor

@illicitonion illicitonion left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is looking great! Thanks!

@classproperty
def options_scope(cls):
if not cls.name:
# TODO: Would it be unnecessarily magical to have `cls.__name__.lower()` always be the name?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We'd want snake_case, rather than lower, and probably want it to be overridable? Or maybe not overridable... It is a bit magical, but it's magic I kind of like...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that would be a fine default. It should probably be overridable though.
Devil's advocate: Should Goals necessarily be optionable at all? Do we want that coupling? Why not let authors define subsystems where needed?

@stuhood stuhood force-pushed the stuhood/console-rules-consume-options branch from 512b64f to b5c99a6 Compare December 18, 2018 22:58
@stuhood

This comment has been minimized.

@stuhood stuhood force-pushed the stuhood/console-rules-consume-options branch from d251819 to 7161ddd Compare April 12, 2019 06:53
@stuhood stuhood requested review from benjyw and jsirois April 12, 2019 07:11
@stuhood

This comment has been minimized.

Copy link
Contributor

@illicitonion illicitonion left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good :) I still have a handful of questions, but a much smaller handful!

src/python/pants/engine/goal.py Outdated Show resolved Hide resolved
src/python/pants/rules/core/filedeps.py Show resolved Hide resolved
src/python/pants/rules/core/list_targets.py Show resolved Hide resolved
tests/python/pants_test/console_rule_test_base.py Outdated Show resolved Hide resolved
src/python/pants/backend/project_info/register.py Outdated Show resolved Hide resolved
@stuhood
Copy link
Member Author

stuhood commented Apr 18, 2019

I've added one commit on top that resolves @illicitonion's last round of concerns, and (most significantly,) applies the syntax changes from #6880 (comment)

This unifies/replaces:

  1. the synthetic _GoalProduct class that we were creating under the covers to be the "actual" output type of a @console_rule
  2. GracefulTerminationException

...with having @console_rules yield a concrete instance of their Goal that contains an exit code.

I'm really, really happy with how that clarifies and simplifies the syntax... the one downside was that the inner Goal.Options class has a pretty awkward implementation. But it feels worth it to me assuming that usage is well documented and examples are clear.

Copy link
Contributor

@illicitonion illicitonion left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a really cute solution, very nice!

My only open question now is: Should exit_code be optional (i.e. None means "I was fine" and 0 means "Eagerly terminate with exit code 0"? I feel like allowing eager termination is probably a bad thing, but also, using exit_code to conditionally mean "exit with this code" or "ignore this because it's a magic value" feels a little odd.

"""

is_goal_cls = isinstance(output_type, type) and issubclass(output_type, Goal)
if is_goal_cls == cacheable:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we remove the cacheable arg, and define cacheability exactly based on whether a Goal is returned, rather than having this check?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, but I think that that would make @console_rule unnecessary, and that feels like something we should wait until #6598 to nail down.

src/python/pants/rules/core/filedeps.py Outdated Show resolved Hide resolved
@stuhood
Copy link
Member Author

stuhood commented Apr 18, 2019

My only open question now is: Should exit_code be optional (i.e. None means "I was fine" and 0 means "Eagerly terminate with exit code 0"? I feel like allowing eager termination is probably a bad thing, but also, using exit_code to conditionally mean "exit with this code" or "ignore this because it's a magic value" feels a little odd.

A default exit code would probably be fine, yea...

Alternatively, singletons for success and failure?

class Goal(..):
  @memoized_classproperty
  def Success(cls):
    return cls(exit_code=0)
  
  ...

...

yield MyGoal.Success

Copy link
Contributor

@benjyw benjyw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like how this turned out.

I'm of two minds on whether we need Goal.Options at all. We could just require rule authors to create whatever subsystems they need in order to provide options to their console_rules. OTOH I can see how it might be a useful idiom in practice to have an implicit options scope attached to every console_rule, and then making it easy to register options on that scope without having to explicitly define a separate subsystem with a matching scope, so I'm fine with this on balance.

Great stuff!

src/python/pants/engine/goal.py Outdated Show resolved Hide resolved
src/python/pants/engine/goal.py Outdated Show resolved Hide resolved
stuhood pushed a commit that referenced this pull request Apr 20, 2019
…and v2 (#7598)

### Problem

In #6880, there will be two types of Goals:
1. v1 `pants.goal.goal.Goal`s, registered on a singleton
2. v2 `pants.engine.goal.Goal`s, registered as a `ScopeInfo` category via `@console_rules`.

But `./pants goals` supports only the first form (via access to the singleton), and would need to dig deep into `self.context` in order to get access to the scope info (...like `./pants options` does: but that's a story for another day!).

### Solution

Convert `./pants goals` into a plugin to the arg splitter, similar to `./pants help`. While the arg-splitter method is not incredibly scalable, it seems like it should be sufficiently scalable to support most of our "meta-goals". 

### Result

v1 and v2 Goals are supported, we have one fewer v1 Task, and #6880 is unblocked.
@stuhood stuhood force-pushed the stuhood/console-rules-consume-options branch from 34c96b0 to 68165cd Compare April 20, 2019 21:41
@stuhood stuhood merged commit d064804 into pantsbuild:master Apr 21, 2019
@stuhood stuhood deleted the stuhood/console-rules-consume-options branch April 21, 2019 00:04
Eric-Arellano added a commit that referenced this pull request Nov 8, 2019
…iledeps` (#8184)

### Problem
We want to finish replacing V1 `filedeps` with V2 `fast-filedeps`. Keeping both goals around gives us added complexity, e.g. more time in CI for tests.

To finish the replacement, `fast-filedeps` must first get support for `--absolute` and `--globs`. 

### Solution
Add support for `--absolute` and `--globs`.

Also, fix and refactor the unit tests, which were skipped in #6880 and never restored. Update the integration test to mirror the V1 test.

We can't yet actually drop the V1 goal yet due to two features that need to be implemented for full feature parity: 1) handling `scala_library`'s `java_sources` and 2) supporting `jvm_app`s. This PR adds failing unit tests for both those cases. Once those tests can be un-skipped, then we can drop V1.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

./pants --no-v1 --v2 doesn't complain about no goals specified v2 goals must shadow names of v1 goals
5 participants