
|
task name changes
I have not been paying enough attention to the source set changes, but one item
caught my eye today that I really would like to see changed.
I fully support the concept of source sets where you have groups of source
divided by function: main, test, integTest, etc. This is great!
I don't, however, like the inclusion of the language as part of the task name.
I don't think that the user should have to know whether to call compileGroovy or
compile or compileScala. I have been bit several times now by calling
project:compile and nothing happens. There is a compile task, it just does
nothing. I didn't know to call project:compileGroovy.
Before we release 0.8, I think it would be good to use source sets in gradle's
own project for integration Tests. I think our own build.gradle is often used
as an example for others. It is actually a little sad how complicated it is now.
--
Steve Appling
Automated Logic Research Team
---------------------------------------------------------------------
To unsubscribe from this list, please visit:
http://xircles.codehaus.org/manage_email
|

|
Re: task name changes
Steve Appling wrote:
> I have not been paying enough attention to the source set changes, but
> one item caught my eye today that I really would like to see changed.
>
> I fully support the concept of source sets where you have groups of
> source divided by function: main, test, integTest, etc. This is great!
>
> I don't, however, like the inclusion of the language as part of the
> task name. I don't think that the user should have to know whether to
> call compileGroovy or compile or compileScala. I have been bit
> several times now by calling project:compile and nothing happens.
> There is a compile task, it just does nothing. I didn't know to call
> project:compileGroovy.
>
I'm curious why you're calling the compile task from the command-line?
Not that what you point out above isn't a problem, I think it is. If we
know what your use case is, we can come up with a solution.
> Before we release 0.8, I think it would be good to use source sets in
> gradle's own project for integration Tests. I think our own
> build.gradle is often used as an example for others. It is actually a
> little sad how complicated it is now.
>
Indeed. There's a few things we've discussed recently which will clean
it up, but I think they're post-0.8 things:
- A java application plugin
- An aggregating project plugin
- Moving documentation + samples into their own subproject
- Task dependency auto-wiring
Adam
---------------------------------------------------------------------
To unsubscribe from this list, please visit:
http://xircles.codehaus.org/manage_email
|

|
Re: task name changes
Adam Murdoch wrote:
>
>
> Steve Appling wrote:
>> I have not been paying enough attention to the source set changes, but
>> one item caught my eye today that I really would like to see changed.
>>
>> I fully support the concept of source sets where you have groups of
>> source divided by function: main, test, integTest, etc. This is great!
>>
>> I don't, however, like the inclusion of the language as part of the
>> task name. I don't think that the user should have to know whether to
>> call compileGroovy or compile or compileScala. I have been bit
>> several times now by calling project:compile and nothing happens.
>> There is a compile task, it just does nothing. I didn't know to call
>> project:compileGroovy.
>>
>
> I'm curious why you're calling the compile task from the command-line?
> Not that what you point out above isn't a problem, I think it is. If we
> know what your use case is, we can come up with a solution.
>
The first time I ran into this was a dependency problem in the gradle-ui
project. It has:
compileTest.dependsOn project( ':gradle-core' ).compileTest
This is now broken because "compileTest" doesn't do anything. It needs to now
be compileTestGroovy. I didn't know that and it took me a while to puzzle out.
Aside - Perhaps you could suggest a better way to do this. We needed to have
the tests in the gradle-ui project depend on the tests in the gradle-core
project. It seemed that this should be easier, but we solved it with the above
task dependency and a configuration of:
testCompile files(project( ':gradle-core'
).dependencyProject.source.test.classesDir)
Later I noted that the gradle-ui/src/main/groovy only contains java files and I
wanted to compare the compile speed for building this under groovy and under
java. I was running gradlew :gradle-ui:compile and comparing the performance
with a java directory and a groovy directory. Surprisingly the groovy one was
faster - but only because the compile task doesn't do anything when you have the
groovy directory. After comparing using the correct tasks I saw that it
compiled about 1.5 sec faster when under the java directory. I plan to check it
in this way. This isn't a common thing to do, but it pointed out an area of
confusion to me. I do think that people call compile (and certainly test)
directly and they shouldn't have to specify the language.
>> Before we release 0.8, I think it would be good to use source sets in
>> gradle's own project for integration Tests. I think our own
>> build.gradle is often used as an example for others. It is actually a
>> little sad how complicated it is now.
>>
>
> Indeed. There's a few things we've discussed recently which will clean
> it up, but I think they're post-0.8 things:
>
> - A java application plugin
> - An aggregating project plugin
> - Moving documentation + samples into their own subproject
> - Task dependency auto-wiring
>
>
> Adam
I think all of those post 0.8 items will help, but I would like to see at least
the integration tests use source sets in 0.8. That should be straightforward,
but I'm not sure I understand source sets well enough to do it now :(
--
Steve Appling
Automated Logic Research Team
---------------------------------------------------------------------
To unsubscribe from this list, please visit:
http://xircles.codehaus.org/manage_email
|

|
Re: task name changes
Steve Appling wrote:
>
>
> Adam Murdoch wrote:
>>
>>
>> Steve Appling wrote:
>>> I have not been paying enough attention to the source set changes,
>>> but one item caught my eye today that I really would like to see
>>> changed.
>>>
>>> I fully support the concept of source sets where you have groups of
>>> source divided by function: main, test, integTest, etc. This is great!
>>>
>>> I don't, however, like the inclusion of the language as part of the
>>> task name. I don't think that the user should have to know whether
>>> to call compileGroovy or compile or compileScala. I have been bit
>>> several times now by calling project:compile and nothing happens.
>>> There is a compile task, it just does nothing. I didn't know to
>>> call project:compileGroovy.
>>>
>>
>> I'm curious why you're calling the compile task from the
>> command-line? Not that what you point out above isn't a problem, I
>> think it is. If we know what your use case is, we can come up with a
>> solution.
>>
> The first time I ran into this was a dependency problem in the
> gradle-ui project. It has:
> compileTest.dependsOn project( ':gradle-core' ).compileTest
> This is now broken because "compileTest" doesn't do anything. It
> needs to now be compileTestGroovy. I didn't know that and it took me
> a while to puzzle out.
>
> Aside - Perhaps you could suggest a better way to do this. We needed
> to have the tests in the gradle-ui project depend on the tests in the
> gradle-core project. It seemed that this should be easier, but we
> solved it with the above task dependency and a configuration of:
> testCompile files(project( ':gradle-core'
> ).dependencyProject.source.test.classesDir)
>
I think the best option is for projects to consume gradle-core's test
classes using exactly the same mechanism as they do for gradle-core's
production classes. Currently, we publish a jar containing the
production classes to a configuration, and the other projects pick this
up using a project dependency. We should do the same for the tests,
though we might just publish the test classes dir, rather than bothering
to jar them up.
Then, the auto-wiring will pick up the correct dependencies, without
anyone needing to explicitly add dependOn compile or compileTestGroovy
or whatever.
Something like:
In gradle-core:
configurations {
testFixtures
testFixturesRuntime
}
dependencies {
testFixtures source.test.classes, source.test.compileClasspath
testFixturesRuntime source.test.runtimeClasspath
}
In gradle-*
dependencies {
testCompile project(path: ':gradle-core', configuration: ':testFixtures')
testRuntime project(path: ':gradle-core', configuration:
':testFixturesRuntime')
}
>
> Later I noted that the gradle-ui/src/main/groovy only contains java
> files and I wanted to compare the compile speed for building this
> under groovy and under java. I was running gradlew :gradle-ui:compile
> and comparing the performance with a java directory and a groovy
> directory. Surprisingly the groovy one was faster - but only because
> the compile task doesn't do anything when you have the groovy
> directory. After comparing using the correct tasks I saw that it
> compiled about 1.5 sec faster when under the java directory. I plan
> to check it in this way. This isn't a common thing to do, but it
> pointed out an area of confusion to me. I do think that people call
> compile (and certainly test) directly and they shouldn't have to
> specify the language.
>
Perhaps we should rename 'compile' to 'compileJava', and add a 'compile'
task which depends on {compileJava, compileGroovy, compileScala} as
appropriate?
This would also clean up the output of gradle -t, and let you do gradle
-x compile.
>>> Before we release 0.8, I think it would be good to use source sets
>>> in gradle's own project for integration Tests. I think our own
>>> build.gradle is often used as an example for others. It is actually
>>> a little sad how complicated it is now.
>>>
>>
>> Indeed. There's a few things we've discussed recently which will
>> clean it up, but I think they're post-0.8 things:
>>
>> - A java application plugin
>> - An aggregating project plugin
>> - Moving documentation + samples into their own subproject
>> - Task dependency auto-wiring
>>
>>
>> Adam
>
> I think all of those post 0.8 items will help, but I would like to see
> at least the integration tests use source sets in 0.8. That should be
> straightforward, but I'm not sure I understand source sets well enough
> to do it now :(
---------------------------------------------------------------------
To unsubscribe from this list, please visit:
http://xircles.codehaus.org/manage_email
|

|
Re: task name changes
2009/9/16 Adam Murdoch <a@...>
Steve Appling wrote:
Adam Murdoch wrote:
Steve Appling wrote:
I have not been paying enough attention to the source set changes, but one item caught my eye today that I really would like to see changed.
I fully support the concept of source sets where you have groups of source divided by function: main, test, integTest, etc. This is great!
I don't, however, like the inclusion of the language as part of the task name. I don't think that the user should have to know whether to call compileGroovy or compile or compileScala. I have been bit several times now by calling project:compile and nothing happens. There is a compile task, it just does nothing. I didn't know to call project:compileGroovy.
I'm curious why you're calling the compile task from the command-line? Not that what you point out above isn't a problem, I think it is. If we know what your use case is, we can come up with a solution.
The first time I ran into this was a dependency problem in the gradle-ui project. It has:
compileTest.dependsOn project( ':gradle-core' ).compileTest
This is now broken because "compileTest" doesn't do anything. It needs to now be compileTestGroovy. I didn't know that and it took me a while to puzzle out.
Aside - Perhaps you could suggest a better way to do this. We needed to have the tests in the gradle-ui project depend on the tests in the gradle-core project. It seemed that this should be easier, but we solved it with the above task dependency and a configuration of:
testCompile files(project( ':gradle-core' ).dependencyProject.source.test.classesDir)
I think the best option is for projects to consume gradle-core's test classes using exactly the same mechanism as they do for gradle-core's production classes. Currently, we publish a jar containing the production classes to a configuration, and the other projects pick this up using a project dependency. We should do the same for the tests, though we might just publish the test classes dir, rather than bothering to jar them up.
Then, the auto-wiring will pick up the correct dependencies, without anyone needing to explicitly add dependOn compile or compileTestGroovy or whatever.
Something like:
In gradle-core:
configurations {
testFixtures
testFixturesRuntime
}
dependencies {
testFixtures source.test.classes, source.test.compileClasspath
testFixturesRuntime source.test.runtimeClasspath
}
In gradle-*
dependencies {
testCompile project(path: ':gradle-core', configuration: ':testFixtures')
testRuntime project(path: ':gradle-core', configuration: ':testFixturesRuntime')
}
Later I noted that the gradle-ui/src/main/groovy only contains java files and I wanted to compare the compile speed for building this under groovy and under java. I was running gradlew :gradle-ui:compile and comparing the performance with a java directory and a groovy directory. Surprisingly the groovy one was faster - but only because the compile task doesn't do anything when you have the groovy directory. After comparing using the correct tasks I saw that it compiled about 1.5 sec faster when under the java directory. I plan to check it in this way. This isn't a common thing to do, but it pointed out an area of confusion to me. I do think that people call compile (and certainly test) directly and they shouldn't have to specify the language.
Perhaps we should rename 'compile' to 'compileJava', and add a 'compile' task which depends on {compileJava, compileGroovy, compileScala} as appropriate?
I also find it really ood to have to specify the language here, I thought we planned on having a distinction between main and test source sets and have the compile and compileTests as tasks that compile all main source sets and compileTests compile all test source sets.
To limit the gradle -t output we need to have a way to segment the output, like for synthetic tasks for source sets only show the global tasks that execute all of the main/test source set compiles/tests/....
And allow for example:
gradle -t main
with main being the main source set and show all the synthetic tasks for that source set when asked for like this.
This would also clean up the output of gradle -t, and let you do gradle -x compile.
Before we release 0.8, I think it would be good to use source sets in gradle's own project for integration Tests. I think our own build.gradle is often used as an example for others. It is actually a little sad how complicated it is now.
Indeed. There's a few things we've discussed recently which will clean it up, but I think they're post-0.8 things:
- A java application plugin
- An aggregating project plugin
- Moving documentation + samples into their own subproject
- Task dependency auto-wiring
Adam
I think all of those post 0.8 items will help, but I would like to see at least the integration tests use source sets in 0.8. That should be straightforward, but I'm not sure I understand source sets well enough to do it now :(
|

|
Re: task name changes
Tom Eyckmans wrote:
2009/9/16 Adam Murdoch <a@...>
Steve Appling wrote:
Adam Murdoch wrote:
Steve Appling wrote:
I have not been paying enough attention to the source set changes, but
one item caught my eye today that I really would like to see changed.
I fully support the concept of source sets where you have groups of
source divided by function: main, test, integTest, etc. This is great!
I don't, however, like the inclusion of the language as part of the
task name. I don't think that the user should have to know whether to
call compileGroovy or compile or compileScala. I have been bit several
times now by calling project:compile and nothing happens. There is a
compile task, it just does nothing. I didn't know to call
project:compileGroovy.
I'm curious why you're calling the compile task from the command-line?
Not that what you point out above isn't a problem, I think it is. If we
know what your use case is, we can come up with a solution.
The first time I ran into this was a dependency problem in the
gradle-ui project. It has:
compileTest.dependsOn project( ':gradle-core' ).compileTest
This is now broken because "compileTest" doesn't do anything. It needs
to now be compileTestGroovy. I didn't know that and it took me a while
to puzzle out.
Aside - Perhaps you could suggest a better way to do this. We needed
to have the tests in the gradle-ui project depend on the tests in the
gradle-core project. It seemed that this should be easier, but we
solved it with the above task dependency and a configuration of:
testCompile files(project( ':gradle-core'
).dependencyProject.source.test.classesDir)
I think the best option is for projects to consume gradle-core's test
classes using exactly the same mechanism as they do for gradle-core's
production classes. Currently, we publish a jar containing the
production classes to a configuration, and the other projects pick this
up using a project dependency. We should do the same for the tests,
though we might just publish the test classes dir, rather than
bothering to jar them up.
Then, the auto-wiring will pick up the correct dependencies, without
anyone needing to explicitly add dependOn compile or compileTestGroovy
or whatever.
Something like:
In gradle-core:
configurations {
testFixtures
testFixturesRuntime
}
dependencies {
testFixtures source.test.classes, source.test.compileClasspath
testFixturesRuntime source.test.runtimeClasspath
}
In gradle-*
dependencies {
testCompile project(path: ':gradle-core', configuration:
':testFixtures')
testRuntime project(path: ':gradle-core', configuration:
':testFixturesRuntime')
}
Later I noted that the gradle-ui/src/main/groovy only contains java
files and I wanted to compare the compile speed for building this under
groovy and under java. I was running gradlew :gradle-ui:compile and
comparing the performance with a java directory and a groovy directory.
Surprisingly the groovy one was faster - but only because the compile
task doesn't do anything when you have the groovy directory. After
comparing using the correct tasks I saw that it compiled about 1.5 sec
faster when under the java directory. I plan to check it in this way.
This isn't a common thing to do, but it pointed out an area of
confusion to me. I do think that people call compile (and certainly
test) directly and they shouldn't have to specify the language.
Perhaps we should rename 'compile' to 'compileJava', and add a
'compile' task which depends on {compileJava, compileGroovy,
compileScala} as appropriate?
I also find it really ood to have to specify the language here, I
thought we planned on having a distinction between main and test source
sets and have the compile and compileTests as tasks that compile all
main source sets and compileTests compile all test source sets.
I'm curious why you would want to do this? What use cases do you have
in mind?
Right now, source sets are untyped, so there is no distinction between
which are production source sets and which are test source sets. I
still think it is a good idea to type them somehow. My plan was to go
slowly at this, and leave them untyped for the 0.8 release. Then, we
can see how they are being used and what does and does not work, and
address that in later releases.
I'm not, for example, 100% convinced that 'main' and 'test' is the
right way to slice them. It feels to me we want a more descriptive
slicing, something like:
- library
- application
- web app
- unit tests
- integration tests
We might allow multiple of the 'roles' to be applied to a source set.
One option would be to allow plugins to be applied to a source set:
source {
main {
usePlugin 'java-application' // (1)
mainClass = 'org.gradle.BootstrapMain'
usePlugin 'library' // (2)
api {
exclude '**/internal/*
}
}
test {
usePlugin 'library' // (3)
}
integTest {
usePlugin 'integration-test' // (4)
}
}
Where
(1) might add a dist task which creates a Zip containing launcher
scripts, the runtime classpath, the main jar, plus anything from
src/dist. Similarly, it might also add sourceDist, distTar, distTarGz
and explodedDist tasks which do the same thing in different formats. It
might also add the dist archives to the 'dists' configuration.
(2) might add the javadoc task, and wire it up so it is included in the
dist image. It might also add an apiJar task, and include that Jar in
the 'api' configuration.
(3) might publish the test classes api to the 'testFixtures'
configuration, and the test classes impl to the 'testFixturesRuntime'
configuration.
(4) might add in an integTest task which runs against the main jar from
the dist image, rather than the main classes dir.
We might default to main { usePlugin 'library' } and test { usePlugin
'unit-test' }. Or maybe just test { usePlugin 'unit-test' }.
We still get the distinction between production and test source sets,
but we end up with a model that is much, much richer. We could also
then fix up some odd things like the fact that the war plugin disables
the jar task.
To limit the gradle -t output we need to have a way to segment
the output, like for synthetic tasks for source sets only show the
global tasks that execute all of the main/test source set
compiles/tests/....
This problem is independent of what we do with source sets, and affects
anyone with large builds regardless of how the tasks get added.
We really need some way to distinguish between the important tasks that
are intended for a user to run from the command-line, and all the
internal tasks. Personally, I like John's suggestion of having gradle
-t show only lifecycle tasks by default, and maybe having gradle -t
--all show all the tasks.
Additionally, gradle -t might take a set of task name patterns, eg
gradle -t compile*
Or perhaps we should get some HTML project reports happening, which
could potentially offer a better way of exploring and navigating the
tasks of the build.
Adam
|

|
Re: task name changes
2009/9/18 Adam Murdoch <a@...>
Tom Eyckmans wrote:
2009/9/16 Adam Murdoch <a@...>
Steve Appling wrote:
Adam Murdoch wrote:
Steve Appling wrote:
I have not been paying enough attention to the source set changes, but
one item caught my eye today that I really would like to see changed.
I fully support the concept of source sets where you have groups of
source divided by function: main, test, integTest, etc. This is great!
I don't, however, like the inclusion of the language as part of the
task name. I don't think that the user should have to know whether to
call compileGroovy or compile or compileScala. I have been bit several
times now by calling project:compile and nothing happens. There is a
compile task, it just does nothing. I didn't know to call
project:compileGroovy.
I'm curious why you're calling the compile task from the command-line?
Not that what you point out above isn't a problem, I think it is. If we
know what your use case is, we can come up with a solution.
The first time I ran into this was a dependency problem in the
gradle-ui project. It has:
compileTest.dependsOn project( ':gradle-core' ).compileTest
This is now broken because "compileTest" doesn't do anything. It needs
to now be compileTestGroovy. I didn't know that and it took me a while
to puzzle out.
Aside - Perhaps you could suggest a better way to do this. We needed
to have the tests in the gradle-ui project depend on the tests in the
gradle-core project. It seemed that this should be easier, but we
solved it with the above task dependency and a configuration of:
testCompile files(project( ':gradle-core'
).dependencyProject.source.test.classesDir)
I think the best option is for projects to consume gradle-core's test
classes using exactly the same mechanism as they do for gradle-core's
production classes. Currently, we publish a jar containing the
production classes to a configuration, and the other projects pick this
up using a project dependency. We should do the same for the tests,
though we might just publish the test classes dir, rather than
bothering to jar them up.
Then, the auto-wiring will pick up the correct dependencies, without
anyone needing to explicitly add dependOn compile or compileTestGroovy
or whatever.
Something like:
In gradle-core:
configurations {
testFixtures
testFixturesRuntime
}
dependencies {
testFixtures source.test.classes, source.test.compileClasspath
testFixturesRuntime source.test.runtimeClasspath
}
In gradle-*
dependencies {
testCompile project(path: ':gradle-core', configuration:
':testFixtures')
testRuntime project(path: ':gradle-core', configuration:
':testFixturesRuntime')
}
Later I noted that the gradle-ui/src/main/groovy only contains java
files and I wanted to compare the compile speed for building this under
groovy and under java. I was running gradlew :gradle-ui:compile and
comparing the performance with a java directory and a groovy directory.
Surprisingly the groovy one was faster - but only because the compile
task doesn't do anything when you have the groovy directory. After
comparing using the correct tasks I saw that it compiled about 1.5 sec
faster when under the java directory. I plan to check it in this way.
This isn't a common thing to do, but it pointed out an area of
confusion to me. I do think that people call compile (and certainly
test) directly and they shouldn't have to specify the language.
Perhaps we should rename 'compile' to 'compileJava', and add a
'compile' task which depends on {compileJava, compileGroovy,
compileScala} as appropriate?
I also find it really ood to have to specify the language here, I
thought we planned on having a distinction between main and test source
sets and have the compile and compileTests as tasks that compile all
main source sets and compileTests compile all test source sets.
I'm curious why you would want to do this? What use cases do you have
in mind? Exactly what you are suggesting below depending on the type of sources have different tasks.
Right now, source sets are untyped, so there is no distinction between
which are production source sets and which are test source sets. I
still think it is a good idea to type them somehow. My plan was to go
slowly at this, and leave them untyped for the 0.8 release. Then, we
can see how they are being used and what does and does not work, and
address that in later releases.
Good plan
I'm not, for example, 100% convinced that 'main' and 'test' is the
right way to slice them. It feels to me we want a more descriptive
slicing, something like:
- library
- application
- web app
- unit tests
- integration tests
Totally agree, main and test should not be the only slices possible.
We might allow multiple of the 'roles' to be applied to a source set.
One option would be to allow plugins to be applied to a source set:
source {
main {
usePlugin 'java-application' // (1)
mainClass = 'org.gradle.BootstrapMain'
usePlugin 'library' // (2)
api {
exclude '**/internal/*
}
}
test {
usePlugin 'library' // (3)
}
integTest {
usePlugin 'integration-test' // (4)
}
}
I really like this idea, not sure if we need a new concept for the 'usePlugin' part, usePlugin is fine by me but it might be confusing for starters to have usePlugin for sourcesets and toplevel in the build script (project-reports plugin ?).
Where
(1) might add a dist task which creates a Zip containing launcher
scripts, the runtime classpath, the main jar, plus anything from
src/dist. Similarly, it might also add sourceDist, distTar, distTarGz
and explodedDist tasks which do the same thing in different formats. It
might also add the dist archives to the 'dists' configuration.
(2) might add the javadoc task, and wire it up so it is included in the
dist image. It might also add an apiJar task, and include that Jar in
the 'api' configuration.
(3) might publish the test classes api to the 'testFixtures'
configuration, and the test classes impl to the 'testFixturesRuntime'
configuration.
(4) might add in an integTest task which runs against the main jar from
the dist image, rather than the main classes dir.
We might default to main { usePlugin 'library' } and test { usePlugin
'unit-test' }. Or maybe just test { usePlugin 'unit-test' }.
We still get the distinction between production and test source sets,
but we end up with a model that is much, much richer. We could also
then fix up some odd things like the fact that the war plugin disables
the jar task.
To limit the gradle -t output we need to have a way to segment
the output, like for synthetic tasks for source sets only show the
global tasks that execute all of the main/test source set
compiles/tests/....
This problem is independent of what we do with source sets, and affects
anyone with large builds regardless of how the tasks get added.
We really need some way to distinguish between the important tasks that
are intended for a user to run from the command-line, and all the
internal tasks. Personally, I like John's suggestion of having gradle
-t show only lifecycle tasks by default, and maybe having gradle -t
--all show all the tasks.
Additionally, gradle -t might take a set of task name patterns, eg
gradle -t compile*
I like both.
Or perhaps we should get some HTML project reports happening, which
could potentially offer a better way of exploring and navigating the
tasks of the build.
Perhaps a gradle console would be nice also
run 'gradle' to start the console
and be able to do:
cd gradle-core <enter> -t <enter>
show only tasks of the gradle-core subproject
Adam
|

|
Re: task name changes
Tom Eyckmans wrote:
2009/9/18 Adam Murdoch <a@...>
Tom Eyckmans wrote:
2009/9/16 Adam Murdoch <a@...>
Steve Appling wrote:
Adam Murdoch wrote:
Steve Appling wrote:
I
have not been paying enough attention to the source set changes, but
one item caught my eye today that I really would like to see changed.
I fully support the concept of source sets where you have groups of
source divided by function: main, test, integTest, etc. This is great!
I don't, however, like the inclusion of the language as part of the
task name. I don't think that the user should have to know whether to
call compileGroovy or compile or compileScala. I have been bit several
times now by calling project:compile and nothing happens. There is a
compile task, it just does nothing. I didn't know to call
project:compileGroovy.
I'm curious why you're calling the compile task from the command-line?
Not that what you point out above isn't a problem, I think it is. If we
know what your use case is, we can come up with a solution.
The first time I ran into this was a dependency problem in the
gradle-ui project. It has:
compileTest.dependsOn project( ':gradle-core' ).compileTest
This is now broken because "compileTest" doesn't do anything. It needs
to now be compileTestGroovy. I didn't know that and it took me a while
to puzzle out.
Aside - Perhaps you could suggest a better way to do this. We needed
to have the tests in the gradle-ui project depend on the tests in the
gradle-core project. It seemed that this should be easier, but we
solved it with the above task dependency and a configuration of:
testCompile files(project( ':gradle-core'
).dependencyProject.source.test.classesDir)
I think the best option is for projects to consume gradle-core's test
classes using exactly the same mechanism as they do for gradle-core's
production classes. Currently, we publish a jar containing the
production classes to a configuration, and the other projects pick this
up using a project dependency. We should do the same for the tests,
though we might just publish the test classes dir, rather than
bothering to jar them up.
Then, the auto-wiring will pick up the correct dependencies, without
anyone needing to explicitly add dependOn compile or compileTestGroovy
or whatever.
Something like:
In gradle-core:
configurations {
testFixtures
testFixturesRuntime
}
dependencies {
testFixtures source.test.classes, source.test.compileClasspath
testFixturesRuntime source.test.runtimeClasspath
}
In gradle-*
dependencies {
testCompile project(path: ':gradle-core', configuration:
':testFixtures')
testRuntime project(path: ':gradle-core', configuration:
':testFixturesRuntime')
}
Later I noted that the gradle-ui/src/main/groovy only contains java
files and I wanted to compare the compile speed for building this under
groovy and under java. I was running gradlew :gradle-ui:compile and
comparing the performance with a java directory and a groovy directory.
Surprisingly the groovy one was faster - but only because the compile
task doesn't do anything when you have the groovy directory. After
comparing using the correct tasks I saw that it compiled about 1.5 sec
faster when under the java directory. I plan to check it in this way.
This isn't a common thing to do, but it pointed out an area of
confusion to me. I do think that people call compile (and certainly
test) directly and they shouldn't have to specify the language.
Perhaps we should rename 'compile' to 'compileJava', and add a
'compile' task which depends on {compileJava, compileGroovy,
compileScala} as appropriate?
I also find it really ood to have to specify the language here, I
thought we planned on having a distinction between main and test source
sets and have the compile and compileTests as tasks that compile all
main source sets and compileTests compile all test source sets.
I'm curious why you would want to do this? What use cases do you have
in mind?
Exactly what you are suggesting below depending on the type of
sources have different tasks.
I'm still not sure why you would run gradle compile from the
command-line. What would you do with the results? You can't use the
classes for anything without running more tasks.
Right now, source sets are untyped, so there is no distinction between
which are production source sets and which are test source sets. I
still think it is a good idea to type them somehow. My plan was to go
slowly at this, and leave them untyped for the 0.8 release. Then, we
can see how they are being used and what does and does not work, and
address that in later releases.
Good plan
I'm not, for example, 100% convinced that 'main' and 'test' is the
right way to slice them. It feels to me we want a more descriptive
slicing, something like:
- library
- application
- web app
- unit tests
- integration tests
Totally agree, main and test should not be the only slices
possible.
We might allow multiple of the 'roles' to be applied to a source set.
One option would be to allow plugins to be applied to a source set:
source {
main {
usePlugin 'java-application' // (1)
mainClass = 'org.gradle.BootstrapMain'
usePlugin 'library' // (2)
api {
exclude '**/internal/*
}
}
test {
usePlugin 'library' // (3)
}
integTest {
usePlugin 'integration-test' // (4)
}
}
I really like this idea, not sure if we need a new concept for the
'usePlugin' part, usePlugin is fine by me but it might be confusing for
starters to have usePlugin for sourcesets and toplevel in the build
script (project-reports plugin ?).
I wonder this too. I'm leaning towards the above.
I suspect that source sets won't be the only domain objects that we
will want to extend at runtime using plugins, whether that's directly
via usePlugin() or indirectly with some kind of type or role property).
I can imagine builds, repository containers, configurations,
dependencies, and maybe even tasks should be extensible in this way.
The question is, do we apply plugins to projects only, and have some
other type-specific mechanism for other types, or do we generalise the
plugin concept to allow pretty much any type to be extended via
usePlugin(). In other words, what's so special about projects that they
are the only extensible things that are extended using usePlugin()?
Another option is to rename usePlugin() to something that fits a bit
more generally.
Where
(1) might add a dist task which creates a Zip containing launcher
scripts, the runtime classpath, the main jar, plus anything from
src/dist. Similarly, it might also add sourceDist, distTar, distTarGz
and explodedDist tasks which do the same thing in different formats. It
might also add the dist archives to the 'dists' configuration.
(2) might add the javadoc task, and wire it up so it is included in the
dist image. It might also add an apiJar task, and include that Jar in
the 'api' configuration.
(3) might publish the test classes api to the 'testFixtures'
configuration, and the test classes impl to the 'testFixturesRuntime'
configuration.
(4) might add in an integTest task which runs against the main jar from
the dist image, rather than the main classes dir.
We might default to main { usePlugin 'library' } and test { usePlugin
'unit-test' }. Or maybe just test { usePlugin 'unit-test' }.
We still get the distinction between production and test source sets,
but we end up with a model that is much, much richer. We could also
then fix up some odd things like the fact that the war plugin disables
the jar task.
To limit the gradle -t output we need to have a way to
segment
the output, like for synthetic tasks for source sets only show the
global tasks that execute all of the main/test source set
compiles/tests/....
This problem is independent of what we do with source sets, and affects
anyone with large builds regardless of how the tasks get added.
We really need some way to distinguish between the important tasks that
are intended for a user to run from the command-line, and all the
internal tasks. Personally, I like John's suggestion of having gradle
-t show only lifecycle tasks by default, and maybe having gradle -t
--all show all the tasks.
Additionally, gradle -t might take a set of task name patterns, eg
gradle -t compile*
I like both.
Or perhaps we should get some
HTML project reports happening, which
could potentially offer a better way of exploring and navigating the
tasks of the build.
Perhaps a gradle console would be nice also
run 'gradle' to start the console
and be able to do:
cd gradle-core <enter>
-t <enter>
show only tasks of the gradle-core subproject
I like this.
Adam
|

|
Re: task name changes
On Mon, Sep 21, 2009 at 5:30 PM, Adam Murdoch <a@...> wrote: <snip>
I wonder this too. I'm leaning towards the above.
I suspect that source sets won't be the only domain objects that we
will want to extend at runtime using plugins, whether that's directly
via usePlugin() or indirectly with some kind of type or role property).
I can imagine builds, repository containers, configurations,
dependencies, and maybe even tasks should be extensible in this way.
The question is, do we apply plugins to projects only, and have some
other type-specific mechanism for other types, or do we generalise the
plugin concept to allow pretty much any type to be extended via
usePlugin(). In other words, what's so special about projects that they
are the only extensible things that are extended using usePlugin()?
Another option is to rename usePlugin() to something that fits a bit
more generally.
Well, projects are special because they are the "main" concept of Gradle. However, I agree that other things might want to be extensible. I think useExtension() would be a better name than usePlugin() even if projects were the only extensible thing, but especially if they are not. If one thinks about it, a plugin right now is just a collection of extensions to things such as tasks, rules, and conventions. By breaking up a plugin into finer grained extensions you might enable better reuse of functionality, but I'm not sure. Right now, many of the things that plugins extend all build upon one another, so it might not be so easy to break apart...
-- John Murph Automated Logic Research Team
|