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

Calling an exclusive command from a non-interactive command results in a NoSuchElementException #3875

Open
lefou opened this issue Oct 30, 2024 · 4 comments

Comments

@lefou
Copy link
Member

lefou commented Oct 30, 2024

When running the following command:

def cleanClient(ev: Evaluator) = Task.Command {
  clean(ev, "appClient")()
}

Mill errors out with the following error:

> mill cleanClient
...
An unexpected error occurred
Exception in thread "MillServerActionRunner" java.util.NoSuchElementException: key not found: Labelled(clean,Segments(List(Label(clean))))

If the cleanClient command interactive = true, the error goes away.

def cleanClient(ev: Evaluator) = Task.Command(exclusive = true) {
  clean(ev, "appClient")()
}
> arturaz@razor:~/work/chqmate> ./mill cleanClient
[build.mill-57/61] compile
[build.mill-57] [info] compiling 1 Scala source to /home/arturaz/work/chqmate/out/mill-build/compile.dest/classes ...
[build.mill-57] [info] done compiling
[build.mill-57] [info] compiling 3 Scala sources to /home/arturaz/work/chqmate/out/mill-build/compile.dest/classes ...
[build.mill-57] [info] done compiling
[1/2] clean
[2/2] cleanClient
[2/2] =================================================================================== cleanClient ================================================================================= 7s
@lihaoyi lihaoyi changed the title Calling an interactive command from a non-interactive command results in a NoSuchElementException Calling an exclusive command from a non-interactive command results in a NoSuchElementException Oct 30, 2024
@lihaoyi
Copy link
Member

lihaoyi commented Oct 30, 2024

I guess this makes sense; the evaluator hardcodes the assumption that all exclusive commands run after the non-exclusive stuff, and so when the non-exclusive command tries to look up the exclusive upstream task in the list of non-exclusive upstream task it fails to find it.

It feels like the correct thing to do here is to raise a proper error when a non-exclusive task depends on an exclusive task

@lefou
Copy link
Member Author

lefou commented Oct 30, 2024

Another resolution could be to not necessarily run exclusive tasks at the end but only isolated (non-parallel to any other) but still before all its dependencies.

@lefou
Copy link
Member Author

lefou commented Oct 30, 2024

As a side note, in sbuild (my previous attempt to write a Scala build system), I had two different ways to concat task dependencies, a ~ b to have two dependencies that can resolve in parallel and a ~~ b which meant that aneeds to finish before b. This is only necessary in the context of destructive commands, e.g. when I want to have a clean build in a single CLI invocation, I need to be able to express, that the clean command needs to be run before I even start to fulfill dependencies of the actual build.

If we could have isolated commands not only in the end but also anywhere in the middle of the execution plan we could also run clean builds in Mill with a single run. E.g. mill clean ++ __.compile which could guarantee that clean is run before any other dependency of __.compile.

@lihaoyi
Copy link
Member

lihaoyi commented Oct 30, 2024

Yeah having some way to order commands would be nice, so clean can run first rather than in some random order

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

No branches or pull requests

2 participants