Tom Eyckmans wrote:
Hi,

During aSkype session on sunday (Hans & me) we thought of introducing a SourceDirectory concept to improve our compile/resource and test handling.


I think this is a fantastic idea.

some of my first ideas:

# Defining source & resource dirs:

sourceDir('main') {
   dir('src/main/java')
}
resourceDir('main') {
   dir('src/main/resources')
   replaceTokens ( prefix : '${', suffix : '}' ) ( [
      tokenOne: 'valueOne',
      tokenTwo: 'valueTwo'
   ])
}
testSourceDir('main') {
   dir('src/test/java')
}
testResourceDir('main' {
    dir('src/test/resources')
}

a more advanced example (with jdk version  specific code):

sourceDir('main') {    dir('src/main/java')      }
sourceDir('jdk14') {    dir('src/jdk14/java')      }
sourceDir('jdk15') {   dir('src/jdk15/java')      }

sourceDirGroup('jdk14'){    sourceDirs('main','jdk14')      }
sourceDirGroup('jdk15'){    sourceDirs('main','jdk15')      }

testSourceDir('main') {        dir('src/test/java')       }
testSourceDir('jdk14') {       dir('src/test-jdk14/java')      }
testSourceDir('jdk15') {       dir('src/test-jdk15/java')      }

testSourceDirGroup('jdk14') {      testSourceDirs('main','jdk14')      }
testSourceDirGroup('jdk15') {      testSourceDirs('main','jdk15')      }


Some comments/questions:

How would we deal with resources and source living in the same directory? production and test classes in the same directory? java 1.4 and java 1.5 classes in the same directory?

How would we deal with a multi-language project, which has both java and groovy source, or java and c source, or whatever?

Why do we need source dir groups?

I'm not sure about how we should define and reference these domain objects. This is another type of domain object with a name and type, which you can add to the project, configure, and refer to, just like tasks, projects, configurations, repositories, etc. We should make the DSL for source directories consistent with the DSL for other domain objects with a name and type.

Using http://docs.codehaus.org/display/GRADLE/Dependencies as a reference for what we want the DSL to look like, we should either put source directories in a context like repositories:

sourceDirectories {
   SourceDirectory(name: 'api') {
       dir('...')
   }
   SourceDirectory(name: 'main') {
       dir('...')
   }
   TestSourceDirectory(name: 'test') {
      dir('...')
   }
}

or we should treat them the same way as tasks, something like:

main(SourceDirectory) {
   dir('...')
}

or we should change the DSL shown on the wiki to match what you've got here.

Personally, I would really like a DSL where I can refer to the domain objects using a groovy identifier, rather than a string (or even worse, forcing me to sometimes use a string and sometimes an identifier, like we currently do with tasks).

Regardless, it might be a good idea if you added some of the stuff you've described here to the DSL wiki page, so we can see it in context with the other DSL stuff, which might help us figure out something consistent for all domain objects.

# Define how stuff should be compiled

// default by name and synhtetic
compile('main') {
   // options
}
// or compileMain {
   // options
}

// custom compiles (naming optional)
compile ( sourceDir('build/generated-java-sources') ) {
    // options
}
// or compile ('antlr-source-compile', sourceDir('build/generated-java-sources') ) {
    // options
}


What are these defining? compile tasks? some kind of domain object?


# Define how stuff should be tested:

// default by name and synhtetic
test('main') {
 // options
}
// or
testMain {
 // options
}

// custom compiles (naming optional but required when you want to be able to use it from the command line)
test (sourceDir('main'), testSourceDir('main') ) {
  dependsOn(...) ?
  // options
}
// with explicit name
test ('slow-test', sourceDir('main'), testSourceDir('main') ) {
  // options
}


what are these defining?

# Define how stuff should be javadoc-ed

javadoc('main') {
    // options
}
// or
javadocMain() {
  // options
}

// custom javadoc
javadoc('custom', sourceDirs('jdk14','antlr-sources') ) {
  // options
}


what are these defining?

# Define how stuff should be packaged

defaultJar(JarTask, name: project.name <http://project.name>) {
     mainCompile {  // include the result of main compile
         // additional options includes/excludes ?
     }
     mainResources // include the result of main resources
}
// or
defaultJar(JarTask, name: project.name <http://project.name>) {
      main // all of main compile + resources
}

defaultSourceJar(JarTask, name: project.name <http://project.name>, classifier: 'sources') {
    mainSources
}

defaultJavadocJar(JarTask, name: project.name <http://project.name>, classifier: 'javadoc' ) {
    javadocMain
}

defaultTestJar(JarTask, name: project.name <http://project.name>, classifier: 'tests') {
    mainTestCompile
    mainTestResources
}
// or
defaultTestJar(JarTask, name:project.name <http://project.name>, classifier: 'tests') {
    mainTest // all of mainTest test compile + test resources
}

defaultTestSourceJar(JarTask, name: project.name <http://project.name>, classifier: 'test-sources') {
     mainTestSources
}

 // this way it is very easy to define bundles:
gradleExternalJavadocBundle(JarTask, name: 'gradle-external-javadoc' ) {
main { package('org.gradle.external.javadoc')
      }
      manifest {
           // additional manifest instructions
      }
}


We will need some way to include the these things with a prefix, as not everything ends up in the root of an archive.

I think this is a very powerfull concept to use the task names to include the result of a compile/resources task in an artifact and I find it very natural but other views may differ.


I agree. In fact, we should generalise it: you should be able to add any domain object which implements FileCollection (say) to an archive. Given that Configuration, Dependency, SourceDirectory, Archive, and all file producing tasks implement FileCollection, this makes it very easy to assemble archives.


Adam

Reply via email to