Skip to content

Instantly share code, notes, and snippets.

@freekh
Last active August 29, 2015 14:06
Show Gist options
  • Save freekh/246ea62bb4f7ea9e34f3 to your computer and use it in GitHub Desktop.
Save freekh/246ea62bb4f7ea9e34f3 to your computer and use it in GitHub Desktop.
New configuration model execution summary (according to me)

NOTE: This document was written the 16th September 2014 and are based on notes taken before that - it might be wrong, outdated or misleading.

The new configuration model introduces the concepts of rules and models. A rule may add or mutate the model, which defines data which a user can define. Rules, models and tasks all live in plugins. The model is loaded eagerly when the the plugin is applied to a project, while the rules are lazily (when needed) evaluated.

Rules

In practice, rules are annotations on methods and there are currently 3 types: immutable (@Model), mutable (@Mutate) and finalized (@Finalize). The parameters of the method (subjects) are the dependencies. For mutable rules, the first parameter indicates that it is the mutating subject (the object which we will mutate/change), while the rest are the dependencies of the rule. An immutable rule may produce the types used by other rules. An example of this is if an immutable 'rule1' maps a model to another type, a mutable (or immutable) 'rule2' might define a dependency of this type (which would be populated by 'rule1'). If the model contains N objects with the types specified in the parameters, the rules will fire N times. It is also possible to add a path annotation (@Path) to a parameter to avoid firing a rule too often (I am (REALLY) not sure but I think a Path is a view as described in the documents). As for finalized rules, they are mutating rules that are run after all mutating rules are finished (again, this is only what I think). See below for an example of a mutating rule:

@Mutate
public void createBinaries(BinaryContainer binaries, NamedDomainObjectCollection<JvmLibrarySpec> libraries, @Path("buildDir”) File buildDir)

This rule will fire for every combination of the binaries, libraries and buildDir (with the path “buildDir") present in the model. The intent indicated (it is not checked yet) is that every BinaryContainer will be mutated (in this example: we can imagine we want to add libraries to the binaries), with every combination of NamedDomainObjectCollection and File matching the path “buildDir”.

Rules and tasks

Tasks in Gradle have properties (fields/methods) defining inputs, output and an action method which defines the behaviour. As most know, tasks are what users actually end up executing. Properties are defined with a Task and sometimes we need a way to pass properties between them (I am assuming). For example: the input directory of one task is the output directory of another. The relationship (again: as I understand it) to tasks and rules is that rules are responsible for mapping the model to tasks, either by creating new tasks or by configuring existing tasks. This way, the model defining the user input can be coherently mapped to multiple different tasks. I have tried to create a diagram of the flow of plugins, models, rules and tasks here (sorry for my bad Google Apps presentation skillz): https://docs.google.com/presentation/d/13LKYNnpRJi7oD_QWYSW6L0AxfyDOIUIqhYGYjjsbdtU/edit?usp=sharing

Model

Models defines what properties a user can customize. As mentioned previously the models are loaded eagerly when a plugin is applied. This matters, because it means that we can safely execute our rules on top of the model. In practice defining a model, means to register a container in the modelRegistery (a plugin service). A simple example of model usage registery (and rules) is the LanguageBasePlugin found here: https://github.com/gradle/gradle/blob/946cdfa82264a63dfb3c09681d8d999a6456b573/subprojects/platform-base/src/main/java/org/gradle/language/base/plugins/LanguageBasePlugin.java#L74.

@freekh
Copy link
Author

freekh commented Sep 17, 2014

Ok, this makes sense.

PS: the error messages that you get on rules (say if a rule cannot be applied) are what inspired me to name them "immutable"/"mutable".

@radimk
Copy link

radimk commented Sep 17, 2014

My takeover is that according to Daz @model means CreateModel and @Mutate is UpdateModel (+ there is @finalize to finish/lock the model). I like that way of explaining how it works.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment