Let’s by example say that we have a model for creating multiple Docker containers and we wat to have a directory specified where all of the files are.
My build script might be something like the following
model {
dockerComponents {
// In this container we use the default source dir <- See question below
webserver(DockerContainer) {
}
// And in this one we override it <- Easy peasy
mysql(DockerContainer) {
dockerDir 'src/mysql'
}
}
}
class ModelMapExampleRules extends RuleSource{
@Model
void dockerComponents(ModelMap<DockerContainer> components) {
}
@Mutate
void defaultLocations(@Each DockerContainer component) {
// ... Need some code here ...
// Somehow set dockerDir = 'src/docker/${name}'
}
}
How can I in a @Mutate section know what the name of the element is, so that I can apply it in an assignment?
Should DockerContainer implement the Named interface?
(An alternative could be use a non-managed implementaton based upon NamedDomainObjectContainer as is the case for model.repositories, but that is not really the point of the exercise).
After banging my head on this a lot, I don’t think you can, at least, currently. The ModelMap<DockerComponent> is what actually knows the mapping of name -> each component.
Even with this, I was unable to find a way to use a component’s name to set any value on it. Changing defaultLocations to accept ModelMap<DockerComponent> components did not help, as apparently this is a write-only view, so you can’t actually use it to read the names. I tried various other approaches, such as having the first parameter be @Each DockerContainer component and the second be ModelMap<DockerContainer>, and trying to use ModelMap’s afterEach, but no luck.
If you do find a way, I’d be curious how you pulled it off.
(Funny enough, I’m also here, also trying to use the new software model to experiment with managing Docker containers, so I got very confused why I was reading my own code in your forum post before the coffee kicked in ;))
Thanks, at least it shows I’m not the only one trying this out.
I thought using Docker as an example would a relatively well understood metaphor. I’m actually using it in a couple of places in writing my new Gradle book. Anyhow if you make your code open-source, it would also be good to have a look.
Will do - right now it’s very much in the ‘can I even bend the @Managed types to model this’ phase, but if I get anything of value working from it, I’ll be sure to ship it your way.
A @Managed type can extend Named, which will allow you to get at the name. This is probably the simplest way to do this at the moment.
The plan (but this isn’t possible yet) is to add some ways to query the name, path, etc of any element - regardless of whether it’s managed or not, or whether the declared type of the element extends Named.
@rhencke, on a side note, If you are interested in building an open-source Docker plugin using the new model, it would be worthwhile getting together with @gesellix, whose existing Docker plugin is the most complete (and platform-independent) implementation.