Last active
June 3, 2016 13:13
-
-
Save martinda/5c46f0da471a446c61cbeac8ef1180e6 to your computer and use it in GitHub Desktop.
Cannot access binary.args, why?
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@Managed interface JuiceComponent extends GeneralComponentSpec { } | |
@Managed interface FruitLanguage extends LanguageSourceSet {} | |
@Managed | |
interface JuiceBinarySpec extends BinarySpec { | |
List<String> getArgs() | |
void setArgs(List<String> args) | |
} | |
class JuicerTask extends SourceTask { | |
@Input | |
List<String> args | |
@TaskAction | |
void makeJuice() { | |
println('Juicy args: '+args) | |
} | |
} | |
class Juicer extends DefaultTask { | |
List<String> args | |
} | |
class JuicerRules extends RuleSource { | |
@ComponentType void registerComponent(TypeBuilder<JuiceComponent> builder) { } | |
@ComponentType void registerFruitLanguage(TypeBuilder<FruitLanguage> builder) { } | |
@ComponentType void registerJuiceBinarySpec(TypeBuilder<JuiceBinarySpec> builder) { } | |
@ComponentBinaries | |
void generateJuiceBinaries(ModelMap<JuiceBinarySpec> binaries, GeneralComponentSpec component) { | |
binaries.create("builtinJuicer"); | |
} | |
@BinaryTasks | |
void generateTasks(ModelMap<Task> tasks, final JuiceBinarySpec binary) { | |
// Skip the internal built-in binary, this avoid the non-mutable exception | |
if (binary.name == "builtinJuicer") return | |
tasks.create("${binary.name}Juicer", Juicer) { task -> | |
task.args = binary.getArgs() | |
} | |
} | |
} | |
apply plugin: JuicerRules | |
model { | |
components { | |
juiceComponent(JuiceComponent) { | |
binaries { | |
// Describe the distributions | |
source(JuiceBinarySpec) { | |
args = ['a', 'b'] | |
} | |
} | |
sources { | |
// Describe the sources | |
juice(FruitLanguage) { | |
source { | |
srcDirs 'src/main/fruit' | |
} | |
} | |
} | |
} | |
} | |
} |
This is discussed on the gradle forums.
The final answer is that the the @BinaryTasks generateTask(...)
method was being called TWICE. It is called a FIRST time for the binary defined internally:
@ComponentBinaries
void generateJuiceBinaries(ModelMap<JuiceBinarySpec> binaries, GeneralComponentSpec component) {
binaries.create("builtinJuicer");
}
And it is being called a SECOND time for by the binary defined in the DSL:
model {
components {
juiceComponent(JuiceComponent) {
binaries {
source(JuiceBinarySpec) { // Called due to this line
...
So to avoid the non-mutable exception, the generateTask(...)
method has to skip over the internal binary:
@BinaryTasks
void generateTasks(ModelMap<Task> tasks, final JuiceBinarySpec binary) {
if (binary.name == "builtinJuicer") return
tasks.create("${binary.name}Juicer", Juicer) { task ->
task.args = binary.getArgs()
}
}
It still feels strange to have an exception thrown when a non-mutable is only being read (reading it should not change it).
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Change the creation rule
source(JuiceBinarySpec)
to a mutation rule:juicer
And change the task creation to
tasks.create("${binary.name}Juicer", JuicerTask)
.Then it "works".