Tom Eyckmans wrote:


2009/9/18 Adam Murdoch <[email protected] <mailto:[email protected]>>



    Tom Eyckmans wrote:


    2009/9/16 Adam Murdoch <[email protected]
    <mailto:[email protected]>>



        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

Reply via email to