On 25/06/2012, at 9:39 AM, Howard Lewis Ship <[email protected]> wrote:
> I've been working on a little script to assist with compiling CoffeeScript
> for my project. I have it partially working, but am seeking some help on
> making it completely correct.
>
> Here's the main code:
>
> coffeescript.gradle:
> import ro.isdc.wro.model.resource.*
> import ro.isdc.wro.extensions.processor.js.*
>
> buildscript {
> repositories { mavenCentral() }
> dependencies {
> classpath "ro.isdc.wro4j:wro4j-extensions:${versions.wro4j}"
> }
> }
>
> class CompileCoffeeScript extends DefaultTask {
> def srcDir = "src/main/coffeescript"
>
> def outputDir = "${project.buildDir}/compiled-coffeescript"
>
> @InputDirectory
> File getSrcDir() { project.file(srcDir) }
>
> @OutputDirectory
> File getOutputDir() { project.file(outputDir) }
>
> @TaskAction
> void doCompile() {
> logger.info "Compiling CoffeeScript sources from $srcDir into $outputDir"
>
> def tree = project.fileTree srcDir, {
> include '**/*.coffee'
> }
>
> tree.visit { visit ->
> if (visit.directory) return
>
> def inputFile = visit.file
> def inputPath = visit.path
> def outputPath = inputPath.replaceAll(/\.coffee$/, '.js')
> def outputFile = new File(outputDir, outputPath)
>
> logger.info "Compiling ${inputPath}"
>
> outputFile.parentFile.mkdirs()
>
> def resource = Resource.create(inputFile.absolutePath, ResourceType.JS)
>
> new CoffeeScriptProcessor().process(resource, inputFile.newReader(),
> outputFile.newWriter())
> }
> }
>
> }
>
> project.ext.CompileCoffeeScript = CompileCoffeeScript
>
> And here's what I've added to my main build script:
>
> apply from: "coffeescript.gradle"
>
> task compileCoffeeScript(type: CompileCoffeeScript)
>
> processResources {
> from compileCoffeeScript
> }
>
>
> This works partially: when I change a source .coffee file, or add a new
> .coffee file, then all of the .coffee files are recompiled to JavaScript and
> included in the output JAR file (that is, task jar depends on task
> processResources which now depends on task compileCoffeeScript).
>
> However, if I delete an input file, I'm only getting partial behavior:
>
> :tapestry-core:compileCoffeeScript
> Executing task ':tapestry-core:compileCoffeeScript' due to:
> Input file
> /Users/hlship/workspaces/tapestry/tapestry5/tapestry-core/src/main/coffeescript/proto/bye.coffee
> for task ':tapestry-core:compileCoffeeScript' removed.
> Compiling CoffeeScript sources from src/main/coffeescript into
> /Users/hlship/workspaces/tapestry/tapestry5/tapestry-core/build/compiled-coffeescript
> Compiling proto/hello.coffee
> :tapestry-core:processResources
>
>
> ... but I see the output .js file for the deleted input .coffee file still in
> the JAR (and in build/compiled-coffeescript). In other words, deleting a
> source file does not cause the previously generated output file to be deleted.
>
> Secondly, and perhaps this is related, when I change ANY .coffee file, then
> ALL .coffee files are recompiled. CoffeeScript is unlike Java, each file is
> pretty much independent of all others (it's all going to be very late bound
> inside the client browser).
>
> So ... should I simply delete the output directory inside my doCompile()
> method?
Yes, see the Compile task for example.
> Given the message in the console output above, it seems like there could be a
> notification to a task that an input file was deleted and it should ensure
> the corresponding output file(s) are deleted.
That would prevent the task doing any fine grained incrementalness and would be
too presumptuous.
> But if I want a more "incremental" style, am I expected to walk the output
> directory and delete anything that doesn't have a corresponding source file?
Yes, Gradle can't know the mapping here as it is specific to what the task is
doing.
In the future, Gradle will be able to give you info on what changed but you
will still have to do some work. For cases like this though that are one to one
it will probably be little.
> And, is there a base class to extend from that handles more of this for me?
> SourceTask doesn't seem to do quite what I want.
No, SourceTask is your best option right now.
FYI - the nightlies have coffee script compilation support and this will be
experimental in 1.1. There is no commitment at this stage on when this will be
non experimental.
>
> Thanks in advance for any guidance.
>
> $ gradle --version
>
> ------------------------------------------------------------
> Gradle 1.0
> ------------------------------------------------------------
>
> Gradle build time: Tuesday, June 12, 2012 12:56:21 AM UTC
> Groovy: 1.8.6
> Ant: Apache Ant(TM) version 1.8.2 compiled on December 20 2010
> Ivy: 2.2.0
> JVM: 1.7.0_04 (Oracle Corporation 23.0-b21)
> OS: Mac OS X 10.7.4 x86_64
>
>
> --
> Howard M. Lewis Ship
>
> Creator of Apache Tapestry
>
> The source for Tapestry training, mentoring and support. Contact me to learn
> how I can get you up and productive in Tapestry fast!
>
> (971) 678-5210
> http://howardlewisship.com