Dynamic Task inputs


#1

I have a custom task that compiles Sass stylesheets. These stylesheets can contain various “@import”-Statements, that usually point somewhere within a “node_modules” directory. “node_modules” in the parent directories will also be considered, as per NodeJS “require” semantics. There may also be transitive imports.

Therefore, it’s difficult for me to predict which files should be considered inputs for my task. I tried adding $projectDir/**/*.scss, but not unsurprisingly, that leads to some overhead, each Sass-Task then takes about 700ms to consider its inputs, even if it is UP-TO-DATE.
I can however easily hook into the Sass compiler and get notified about all imports, so I can provide the list of input files after the task has been run. But Gradle of course needs the information beforehand to decide if it should run the task at all. Is there a good way to hook this up with Gradle?


(uklance) #2

Disclaimer: I have only a vague understanding of sass

Perhaps you could write another task which “hooks into the sass compiler” and parses the sass files and writes the list of @import files to a text/json/xml file.

Your sass compile task could then use the text/json/xml file to calculate the task inputs for the second task.

Eg:

task parseImports {
    inputs.dir 'src/main/sass'
    outputs.file "$buildDir/sassImports.csv"
    doLast {
       List<String> imports = MySassCompiler.getImports("$projectDir/src/main/sass")
       file("$buildDir/sassImports.csv").text = imports.join(',')
    }
}
task sass(type: Sass) {
    dependsOn 'parseInputs' 
    inputs.dir 'src/main/sass' 
    inputs.files file("$buildDir/sassImports.csv").text.split(',')
}