Skip to content

New mill.api.opt API for configuration data containing paths#6129

Closed
lefou wants to merge 85 commits intocom-lihaoyi:mainfrom
lefou:tr-poc-args-type
Closed

New mill.api.opt API for configuration data containing paths#6129
lefou wants to merge 85 commits intocom-lihaoyi:mainfrom
lefou:tr-poc-args-type

Conversation

@lefou
Copy link
Copy Markdown
Member

@lefou lefou commented Nov 5, 2025

Add new API classes with the purpose to represent configuration data that may contain paths. All paths, even when embedded in options or text, are represented as os.Path type and can be therefore handled in a type-safe manner. In case, paths need to be to relocated, no guessing or vague String.replace logic is needed. For example, PR #6031 contains a path mapping mechanism, with which all Opts would be automatically covered, too. That means if a Opts or it's companion types are used for javacOptions, scalacOptions and other configuration tasks, embedded paths are no longer an issue for relocatable Mill caches or remote caching in general.

In contrast to the initial proposal of this idea (#6057) the main classes are named Opt/Opts, not Arg/Args, since we already have a mill.api.Args class used for other purposes.

New API classes

Opt is a holder of configuration data. Opt can be constructed from one or multiple Strings or os.Paths. When rendered as string, all parts will be concatenated.

Opts is a Seq-like container to be used instead of Seq[String].

OptMap is a type alias to Map[String, Opt] to provide some convenience to be used instead of Map[String, String].

Both container types, Opts and OptMap can be easily converted to a String-based container with .toStringSeq or .toStringMap.

OptGroup is a group of Opts that are tightly coupled, and should never be split. This is useful to model semantically bound CLI args with multi-arity like --file <file> or -classpath jar2:jar2:...:jarN. It can help to communicate intent and eases post-processing of multi-part opts.

JSON serialization

The JSON structure is more complex than the previous Seq[String] equivalent, because it needs to support options, option groups and multi-parts options, which may itself consist of many strings and paths.

A rather complex Opts JSON serialization may look like this:

Opts(
  "-deprecated", 
  OptGroup("-classpath", Opt.mkPath(classpath, sep = ":"))
)
[
  "-deprecated",
  [
    "-classpath",
    [
      { "path": "/path/to/jar1.jar" },
      ":",
      { "path": "/path/to/jar2.jar" },
      ":",
      { "path": "/path/to/jar3.jar" }
    ]
  ]
]

Since the JSON serialization for paths re-use the respective upickle-serializers, the root path mapping of PR #6031 may also work here (Resulting is paths like $MILL_OUT/task/to/jar.dest/out.jar).

YAML convenience

In addition, the json reader supports reading of flat json arrays, which means, that all Seq[String] can easily be read as Opts. This was done to make working with Opts as convenient as Seq[String] not only in Scala code but also in YAML configuration code.

This means, build.mill YAML frontmatter and build.mill.yaml don't need any changes.

mill-build:
  scalacOptions: ["-verbose"]
  forkEnv: { "MY_CUSOTM_ENV": "my-env-value" }

Although the full encoding is also supported but seldomly required.

mill-build:
  forkArgs: [[["-javaagent:", {"path": "$WORKSPACE/agent.jar"}]]]
  forkEnv: { "MY_WORK_DIR": [{"path": "$HOME/workDir"}] }

Realistic example

In POC PR #6800, you can see a refactoring of Mill to use the new mill.api.opt API in all relevant tasks like javacOptions, scalacOptions, forkArgs, forkEnv and some more.

Caveats / Feedback wanted

In this current POC, we need to add import mill.api.opt.*. I'm looking for ideas, how to improve this and make it a single import.

Related issues and discussions

Pull request: #6129

@lefou
Copy link
Copy Markdown
Member Author

lefou commented Dec 10, 2025

Merged in latest changes from main branch, fixed conflicts and added a OptMap type alias to make working with maps containing config data more convenient.

@lefou lefou changed the title [WIP] POC Opts (Args) concept New container for configuration data Opt, Opts and OptMap Jan 4, 2026
@lefou lefou changed the title New container for configuration data Opt, Opts and OptMap New mill.api.opt API for configuration data containing paths Jan 4, 2026
@lefou lefou added the feedback wanted Additional feedback or testing is apreciated label Feb 6, 2026
@lefou
Copy link
Copy Markdown
Member Author

lefou commented Feb 7, 2026

Going to move the binary breaking refactoring into it's own PR to get this API into Mill.

I'm still interested into feedback, though.

@lefou lefou marked this pull request as ready for review February 7, 2026 16:26
@lefou lefou removed later The issue is still relevant, but has now high priority right now compat-breaker A PR breaks compatibility and needs to wait till we prepare a major release labels Feb 7, 2026
@lefou lefou requested a review from lihaoyi February 7, 2026 22:42
@lihaoyi
Copy link
Copy Markdown
Member

lihaoyi commented Feb 8, 2026

Overall not really convinced that this is a viable alternative to the symlink+relative-path approach prototyped in the other PR.

This PR adds special handling for option lists, and some limited data structures related to them, but it doesn't really handle all the other places where paths may be embedded in various data structures, text blobs, or .dest file contents. One way we can attempt to prove out this approach is to get the integration/dedicated/reproducibility tests passing using this approach. That would at least act as a smoketest that this API is sufficient to get the bare minimum reproducible builds working.

This PR is also opt-in, v.s. the other approach which is on-by-default for OS-Lib via global configuration, which means it would be much easier for users to forget and get it wrong. And in general seems to be solving a much narrower slice of the problem that I'm not convinced is enough to get us to the goal of reproducible builds

@lefou lefou closed this Feb 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feedback wanted Additional feedback or testing is apreciated

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants