Setting default task values based on new model feature


(Sten Roger Sandvik) #1

I am trying out the new model based configuration. I know that this is an incubating feature, but I am trying it out anyway. In my project I have a mix between new model based configuration and defining tasks the “old” way like this:

model {
  myconf {
     prop1 = 'a'
     prop2 = 'b'
  }
}

task mytask(type: MyCustomType) {
}

So, my questions:

  • How can I get hold of the model object’s inside a custom task?
  • Or how can I set default task values from a model?

BR,
Sten Roger


(Mark Vieira) #2

You can’t. The model can only be accessed via model rules or the model { } DSL.

I’m not sure what you mean here. You can modify tasks via model rules (or the DSL) but they won’t be “default” values in the sense that legacy configuration can overwrite them. Consider the following code, in this case the model rule wins and the value of description will be actually be ‘default’ since rules are evaluated after legacy configuration (however this is effectively an implementation detail).

task foo {
  description = 'custom'
}

model {
  tasks {
    foo {
      description = 'default'
    }
  }
}

In summary, interoperation between “legacy” and “new” configuration is still evolving.


(Sten Roger Sandvik) #3

Thanks for the explanation.


(remo) #4

is there a possiblity to realize/evaluate some model objects and their rules only if a given task is executed? That seems to be difficult if a task cannot access a model object? In my use case some model objects are quite expensive to compute (requires parsing various files in the project directory). Because of this, I would like to do this only if some given task is executed and deemed to be out-of-date. Otherwise it should skip the parsing.


(Mark Vieira) #5

Absolutely. This is one of the main driving factors behind the software model. It’s a bit messy to implement at the moment, but this will be improved. There’s no way to do this with the model DSL, but you can implement what you are describing with model rules. Basically, you want to specify the expensive model as an input to the dependent task. This means that model element will only be evaluated when the given task is required. Here’s a bit of a contrived example with just a String but this could be any object that could potentially be expensive to construct. You can observe that running expensiveTask causes the model element to be evaluated but cheapTask does not.

class Rules extends RuleSource {
    @Model
    String expensiveModel() { 
        println "Generating Expensive Model"
        return "expensive model" 
    }
    
    @Mutate
    void createTask(ModelMap<Task> tasks) {
        tasks.create("expensiveTask")
        tasks.create("cheapTask")
    }
    
    @Mutate
    void modifyTask(@Path("tasks.expensiveTask") Task myTask, @Path("expensiveModel") String model) {
        // update task with values from expensive model
    }
}

apply plugin: Rules

(remo) #6

works prefectly, thx, great stuff :slight_smile:

Maybe it would be a good thing if the model can be injected directly into a task (or action). Or this example could be useful addition to the documentation.