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

Allow Mill CLI to select the meta-build frame it operates on #2719

Merged
merged 19 commits into from
Sep 2, 2023
Merged

Conversation

lefou
Copy link
Member

@lefou lefou commented Aug 29, 2023

Add a new CLI option --meta-level accepting an Int. Default is 0 and means the root project, 1 is the parent meta-build, if defined, or the built-in bootstrap module, and so on.

This is a first draft, to get more familiar with the recursive but mutable nature of our meta-build support.
Don't hesitate to point out shortcomings.

Review by @lihaoyi

Example: Find version updates in the meta build

Here is some example output (applied to the mill repo):

$ mill --meta-level 1 mill.scalalib.Dependency/showUpdates
[1657/1657] dev.run 
Found 3 dependency update for 
  net.sourceforge.htmlcleaner:htmlcleaner : 2.25 -> 2.26 -> 2.27 -> 2.28 -> 2.29
  com.lihaoyi:mill-contrib-buildinfo_2.13 : 0.11.2-6-261437 -> 0.11.2
  com.github.lolgab:mill-mima_mill0.11_2.13 : 0.0.23 -> 0.0.24

Meta information about the build

I also added a new external module mill.runner.MillBuild to get some meta-information about the project, for now, the meta-module count or frame count.

Here on a project with one meta-build:

$ mill show mill.runner.MillBuild/levelCount
3

Pull request: #2719

Add a new CLI option `--frame` acception an `Int`.
Default in `0` and means the root project,
`1` is the parent meta-build, if defined, or the built-in bootstrap module,
and so on.

This is a first draft, to get more familiar with the recursive but mutable nature of our meta-build support.
Don't hessitate to point out shortcomings.

* Fixes #2658

Review by @lihaoyi
I applied one hack-ish way to avoid instantiating the higher level evaluators by just assigning `null`.
This should be refactored, e.g. by representing a skipped frame by it's own case class.
@lihaoyi
Copy link
Member

lihaoyi commented Aug 31, 2023

The approach looks reasonable. Maybe one quibble is with the naming --frame. "Frame" isn't a term we use anywhere else in the user-facing documentation. Maybe we can call it --meta-build-level or --mill-build-level or something similar to that, since "Meta Build" and mill-build/ are both things that the user would likely encounter in the course of working with Mill? We don't expect this to be support commonly used, so having the flag be a bit more verbose is not a problem

@lefou
Copy link
Member Author

lefou commented Aug 31, 2023

What about --meta or --meta-level?

@lihaoyi
Copy link
Member

lihaoyi commented Aug 31, 2023

Sure that works. But I'd err on the side of "more verbose" since we don't expect this flag to be commonly used

@lefou lefou linked an issue Aug 31, 2023 that may be closed by this pull request
@lolgab
Copy link
Member

lolgab commented Aug 31, 2023

In the context of #1751 what I want is a way to run a target on all the levels, meta and non-meta.

This:

mill --meta-level 1 mill.scalalib.scalafmt.ScalafmtModule/reformatAll sources

requires me to know how many meta levels I have and also to run the target n times (once for every level).

I'm thinking (and please let me know it has problems) on something like:

mill --include-build mill.scalalib.scalafmt.ScalafmtModule/reformatAll sources

or something along those lines which would run a command on all levels, from meta-build to non-meta.

@lefou
Copy link
Member Author

lefou commented Aug 31, 2023

@lolgab Yeah, I also want sometimes to be able to run something on all levels. This PR is a first step, to be able to request to run targets on any specific level, which was not possible before. Once, we have that working, we can add more features.

From a high level view, what you want should be rather simple to implement, as we just need to aggregate all runs of all levels. But devil is in the details. Currently, we have different evaluators for each level, and the logic to aggregate results is also in the evaluator. Also parallelization logic is in the evaluator. So, some more work and refactoring is necessary. Whereas explicitly selecting one level is a rather easy goal to achieve.

I'm even not sure if it is possible at all to run targets from all levels at the same time, as evaluation of meta-build can affect the effective module and target relations on dependent levels. So maybe, we will never be able to parallelize evaluation of different levels.

Level 0 is the normal project, level 1 the first meta-build, and so on.
The last level is the built-in synthetic meta-build which Mill uses to bootstrap the project."""
)
val metaLevel: Option[Int]
Copy link
Member

Choose a reason for hiding this comment

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

Is there a reason why we don't use default values here? val metaLevel: Int = 0 which should be supported by mainargs?

Copy link
Member Author

@lefou lefou Aug 31, 2023

Choose a reason for hiding this comment

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

Defaults are provided in the apply method.

metaLevel: Option[Int] = None

Using Option[Int] in contrast to Int is more explicit whether the user provided a value or not.

@lefou lefou marked this pull request as ready for review September 1, 2023 12:46
@lefou lefou requested review from lihaoyi and lolgab September 1, 2023 12:46
@lefou
Copy link
Member Author

lefou commented Sep 1, 2023

This PR is ready for review. @lihaoyi @lolgab

@lefou lefou merged commit c0823da into main Sep 2, 2023
37 checks passed
@lefou lefou deleted the eval-frame branch September 2, 2023 08:01
@lefou lefou added this to the 0.11.3 milestone Sep 2, 2023
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.

Suport running tasks on a bootstrap module (--meta-level) Support a way to run Scalafmt on the build files
3 participants