scalaammonitemill

How to iterate all mill targets in build.sc, how to get target.dest from outside the target?


I would like to write a mill utility tool (maybe a function or Module inside build.sc) for summarizing and post processing results of various targets. Instead of hard coding all processed targets I prefer a solution that could somehow iterate the build.sc contents and produce a list of found targets from which I could then filter out e.g. other than ScalaModules etc.

What is the most elegant way to implement this kind of iterator?

That utility tool also needs to locate the dest directory of each target. Inside the target I can use T.dest but how the get the destination directory from "outside" (not running the target)?

One way to accomplish this kind of functionality is to browse recursively the directory structure under ./out but that information lacks the target type information and also target out directory is missing if it is cleaned or not yet run at all. So it is not possible to report that target Foo exists but has currently no results.


Solution

  • If you are just interested in the list of modules and targets, you can simple use the resolve command.

    $ mill resolve __
    

    To apply advanced filtering, you need to do it in Scala. Mill already provides various support to access modules and targets. Just have a look at the class mill.define.Module, which is inherited from all Mill modules. As an example: to access direct sub modules of a module foo, use foo.millModuleDirectChildren. You can find more in foo.millInternal, e.g. modules to find all sub modules, or targets to find all targets.

    You can also look at the implementation of the various built-in commands in mill.main.MainModule. There you find various resolvers. You could even write your own to filter whatever you want. But be warned, it's far from trivial.

    About the dest directory. In general, you shouldn't even want to access this directory. It is considered an implementation detail of a target. If you have the current mill.eval.Evaluator at hand (e.g. within an evaluator command) to retrieve the actual used out directory, you can get the actual path used for T.dest of a target with mill.eval.EvaluatorPaths.resolveDestPaths.

    But instead of using this, you should just use whatever a target returns. There is no necessity e.g. for a compile target, that the actual compile result is located in its T.dest directory. Also, beware to not modify the dest directory or it's contents from outside, as that may break the caching mechanism.

    I'm referring to the latest released Mill version 0.10.5.