-
-
Notifications
You must be signed in to change notification settings - Fork 358
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
Make T
an alias for Task
instead of Target
, move T.*
operations to Task.*
#3356
base: main
Are you sure you want to change the base?
Conversation
T
to task
T.*
operations to Task.*
@@ -28,7 +28,7 @@ object ApplicativeTests extends TestSuite { | |||
value | |||
} | |||
} | |||
@compileTimeOnly("Target.ctx() can only be used with a T{...} block") | |||
@compileTimeOnly("Target.ctx() can only be used with a Task {...} block") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@compileTimeOnly("Target.ctx() can only be used with a Task {...} block") | |
@compileTimeOnly("Target.ctx() can only be used within a Task {...} block") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't work yet; need to make changes in the mill-moduledefs repo. TBH I feel like just in-sourcing it again, since even when in-sourced people can depend on the artifact separately if necessary, and it makes doing these changes in one PR a lot more convenient
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since it's a compiler module, it needs releases for every Scala version we want to use. That's the main reason we out-sourced it. We post-release for every new Scala 2.13 version.
It might be ok for a development version to use a in-sourced patched version, but I think the goal should be to push any changes back to the external project before we reach a stable version.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about we in-source it to the Mill repo but still keep the publishing separate? That would mean it's treated like the bridge
modules, and would keep everything in one place while still preserving the per-scala-version releases and separate publishing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That will work too, if it's well documented. We do these things only occasionally, there is no muscle memory for the process, so we need a good step-by-step documentation targeting the developer/publisher.
T.*
operations to Task.*
T
an alias for Task
instead of Target
, move T.*
operations to Task.*
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is all the mill-moduledefs meta info removed. It does still have a dedicated release cycle, so we should manage it via the build.sc
and generated BuildInfo
.
If we release it with every Mill release, we also need to post-release for newer Scala versions all those plugins. For example, external plugin authors need to build against older Mill versions to ensure they don't accidentally use newer API. But they sometimes want and sometimes must update the Scala version.
@Target({ ElementType.TYPE, ElementType.METHOD }) | ||
@Retention(RetentionPolicy.RUNTIME) | ||
@Documented | ||
public @interface NullaryMethod {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
API doc needed. What is @NullaryMethod
for?
I think I've come up with a way go avoid modifying the compiler plugims by moving the info tonthe discover macro. That will let us avoid having to republish them, and also avoid failure modes of people forgetting to include the plugins in their published mill plugins. Will see if i can make it work |
…3565) Essentially a minimized binary-compatible version of #3356, renaming all the factory methods for various tasks to follow more standard naming conventions: * `T {...}` -> `Task {...}` * `T.command {...}` -> `Task.Command {...}` * `T.input {...}` -> `Task.Input {...}` * `T.source {...}` -> `Task.Source {...}` * `T.sources {...}` -> `Task.Sources {...}` * `T.persistent {...}` -> `Task.Persistent {...}` * `T.task {...}` -> `Task.Anon {...}` The type `T[_]` remains an alias for `Target[_]`, and `Task{ ... }` returns a `T[_]`, to maintain binary compatibility. Not quite ideal but can probably be hand-waved away until Mill 0.13.0 when we are allowed to break binary compatibility. All the `T.*` operations have been duplicated to `Task.*` by sharing them via a `trait TargetBase`, except the factory methods which were copied over and upper-cased while the old version deprecated. I have updated all the code and examples to use `Task` instead of `T` where relevant. The only exceptions are the `implicit def apply`s which needed to be manually copied without the `implicit` (otherwise the multiple implicits cause ambiguity). This gets us most of the user-facing benefits of #3356 without the bin-compat breakage: users no longer see an odd `T { ... }` syntax in the docs and in their build files, and now see `Task { ... }` which should be much more familiar. Although it does not allow us to do the type-hierarchy cleanups that the other PR provides, it's still worth doing so we can get it in in 0.12.0 The old `T { ... }` and `T.*` syntaxes should continue to work, and are exercised via the bootstrap tests as they continue to be used in Mill's own build. This PR should be source compatible to avoid migration pains, and given the prevalence of `T` everywhere we probably should just support it forever
This PR attempts to fix #3338:
T
is now an alias forTask
instead ofTarget
. We expect to usefoo: Task[V]
,Task { ... }
,Task.dest
, etc. APIs going forward, but all existing APIs remain on theT
aliases for backwards source compatibilityTask.apply
orTask { ... }
continues to return aTarget
instance, but now is typed as returning the supertypeTask
. This allows people to writedef foo: Task[T] = Task { ... }
and have it do the right thing, rather than the otherwise necessarydef foo: Target[T] = Task { ... }
which is pretty awkwardIn order to support using
Task[T]
everywhere as types, I flattened out the type hierarchy further: now, most APIs work directly withTask
instead ofTarget
orNamedTask
Task
now supports.ctx
, which throws anUnsupportedOperationException
by default.NamedTask
overrides it with an implementation.Target[_]
for resolution, we now rely on methods returningTask[_]
with zero argument lists. As the number of argument lists is not available through Java reflect (we can only see the total number of arguments), I rely on information collected by theDiscover[T]
macro.I made
Input[_]
,Source[_]
,Target[_]
, etc. type aliases ofTask[_]
. This avoids issues where people might accidentally declaredef foo: Target[V]
and find themselves unable to override it later as typedef foo: Task[V] = Task { ... }
. This is similar to how MakeTarget
type abstract to allow overriding by different concrete implementations #2402 earlier madeInput
Source
etc. type aliases ofTarget[_]
, and serves a similar purpose.Distinguishing of cached targets (zero argument lists) with uncached other things (1 or more argument lists) is done via the information we already collect in the
Discover
macro. For safety, I made thedef millDiscover
abstract, because it cannot really be implemented in abstract superclasses or traits (due to is macro implementation) so it really needs to be implemented in every concreteobject
. This should avoid a common issue where we forget to override it in the test suite and command resolution wouldn't work.The flattening out of the
Task[_]
type hierarchy is a compromise.def ctx: Ctx = throws
on theTask
trait is gross. We lost the ability to distinguish between various subtypes ofTask
based on method return types, and instead have to go through other ad-hoc mechanisms like number-of-argument-lists. But in exchange for a bit of sloppiness in the type signatures, users can now useTask{ ... }
to construct their most common tasks (targets),: Task[V]
to annotate their types, andTask.sources
andTask.dest
for most common task APIsThis is a binary incompatible change and will have to go into 0.13.0. I tried to leave the existing
T
/Target
/Input
/etc. aliases in place, so hopefully it's mostly source compatible (though probably not 100%)This PR is a bit messy, but important files to review include:
main/src/mill/package.scala
, which re-writes the varioustype
andval
aliasesmain/define/src/mill/define/Task.scala
, which moves the variousT.*
operations fromobject Target
onto a sharedtrait TaskCompanion
that can be shared withobject Task
, and makes them all returnTask[_]
instead of a more specific subtypemain/define/src/mill/define/Discover.scala
, which tweaks the class-task-name-discovery logic to make it look forTask
instead ofTarget
, and make it precise enough to work as the primary resolution mechanism (previously there were some bugs, that didn't matter when it was just used for error message reporting, but weren't acceptable now that it is becoming the primary way we find tasks in a module)main/resolve/src/mill/resolve/ResolveCore.scala
, which converts the task resolution logic to use the information already collected by the updatedDiscover
macromain/define/src/mill/define/BaseModuleTree.scala
, which pre-computes a bunch of values used throughout the task resolution logicmain/resolve/src/mill/resolve/Resolve.scala
has more changes to useBaseModuleTree
pre-computed values