How to write an extension object property that does implicit conversion to FileCollection

I’d like to achieve what is documented in Understanding implicit conversion to file collections
for my own DSL.
I tried to look at the mentioned JavaCompile task and came up with this solution:

class ModelBeansExtension {
	final ConfigurableFileCollection modelDirs

	final Project project

	ModelBeansExtension(Project project) {
		modelDirs = project.layout.configurableFiles()
		this.project = project
	}

	void setModelDirs(FileCollection dirs) {
		this.modelDirs.setFrom(dirs)
	}
	void setModelDirs(Object dir) {
		this.modelDirs.setFrom(project.file(dir))
	}
	void setModelDirs(Object... dirs) {
		this.modelDirs.setFrom(project.files(dirs))
	}
}

This kind of works. I can use

modelBeans {
   modelDirs = 'some-path'
}

in my build script and could also supply a file or file collection to the “modelDirs” property.
However it feels wrong to store the project in the extension object. Isn’t a “project” property now also a part of my DSL?

Is there a better way?

You are having a rough idea of what to do, but you are evaluating too early. You might want to do the following instead.


void setModelDirs( Object dirs ) {
  this.modelDirs.clear()
  this.modelDirs.add(dirs)
}

void setModelDirs( Iterable<Object> dirs ) {
  this.modelDirs.clear()
  this.modelDirs.addAll(dirs)
}

void modelDirs( Iterable<Object> dirs ) {
  this.modelDirs.addAll(dirs)
}

void modelDirs( Object... dirs ) {
  this,.modelDirs.addAll( dirs as List )
}

FileCollection getModelDirs() {
   project.files( this.modelDirs ) 
}

private final List<Object> modelDirs = []
private final Project project

In this form you keep everything as Objects until the latest possible momemtn in time and they convert it to a FileCollection when needed.

Keep the Project instance private and iassign it only in the constructor. Now it is out of the way of the DSL.

1 Like

Thanks a lot for the answer. That really helps!