# Generating multiple source files from a template

**URL:** <https://discuss.gradle.org/t/generating-multiple-source-files-from-a-template/14800>\
**Category:** Help/Discuss\
**Created:** [February 27, 2016, 10:42pm UTC](https://discuss.gradle.org/t/generating-multiple-source-files-from-a-template/14800 "2016-02-27T22:42:52Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![Schalk\_Cronje](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/schalk_cronje/32/6511_2.png) [@Schalk\_Cronje](https://discuss.gradle.org/u/Schalk_Cronje)\
**Post date:** [February 27, 2016, 10:42pm UTC](https://discuss.gradle.org/t/generating-multiple-source-files-from-a-template/14800/1 "2016-02-27T22:42:53Z")

</div>

Normally when a applying a filter in a `Copy` task one would just have like a template file and then copy it whilst substituting using `filter` or `expand`. I would want to do something slighlty different.

In a specific code generation use case I have N _source files_ and one template file. The _source files_ actually contain data that becomes one property in the expansion of the template file. Let’s say my template file contains

```gradle
${prop1}
${prop2}
${prop3}

```

The _source files_ will contain the content that goes into `prop1`.

What I got so far in my `Copy` task is

```groovy
task generator( type : Copy ) {
  from 'examples', {
   include '*.txt'
 }

 into "${buildDir}/fooDir"

 rename /\.txt$/, '.foo'

 eachFile { fcd ->
 }
}

```

I am stuck in the `eachFile` closure because somehow I need to figure out to open the source file and the template file and then substitute the content of the source file as a property for the template file.

---

<div class="post-metadata">

**Author:** ![Schalk\_Cronje](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/schalk_cronje/32/6511_2.png) [@Schalk\_Cronje](https://discuss.gradle.org/u/Schalk_Cronje)\
**Post date:** [February 29, 2016, 10:16am UTC](https://discuss.gradle.org/t/generating-multiple-source-files-from-a-template/14800/2 "2016-02-29T10:16:45Z")

</div>

To answer my one question, one can do the following:

```groovy
eachFile { fcd ->
  String sourceName = fcd.sourceName.replaceAll( /\.txt$/, '')
  String content = fcd.file.text
  fcd.filter {null}
  fcd.filter ConcatFilter, append : project.file('src/templates/my.template')
  fcd.filter ReplaceTokens, tokens : [
    token1 : content,
    token2 : sourceName
 ]
}

```

It is very importtant that no filters must have been added before `String content = fcd.file.text` is executed. This is due to [Combining eachFile & filter results in failure](https://discuss.gradle.org/t/combining-eachfile-filter-results-in-failure/14801/2). The only way of adding filters are within the `eachFile` and only after extracting the content of the data file.

---

<div class="post-metadata">

**Author:** ![Lance\_Java](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/lance_java/32/787_2.png) [@Lance\_Java](https://discuss.gradle.org/u/Lance_Java)\
**Post date:** [February 29, 2016, 1:01pm UTC](https://discuss.gradle.org/t/generating-multiple-source-files-from-a-template/14800/3 "2016-02-29T13:01:50Z")

</div>

I think it’d be easier to invoke `project.copy()` in a custom task rather than using the `Copy` task. Eg:

```gradle
task generator() {
   def inFiles = fileTree('examples').matching {
      include "*.txt"
   } 
   def template = file("src/templates/my.template") 
   inputs.files inFiles
   inputs.file template
   outputs.dir "$buildDir/fooDir" 
   doLast {
      inFiles.files.each { inFile ->
         copy { 
            from template 
            filter ... 
            into "$buildDir/fooDir/$inFile.name"
         } 
      } 
   } 
} 

```

---

<div class="post-metadata">

**Author:** ![Schalk\_Cronje](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/schalk_cronje/32/6511_2.png) [@Schalk\_Cronje](https://discuss.gradle.org/u/Schalk_Cronje)\
**Post date:** [February 29, 2016, 4:08pm UTC](https://discuss.gradle.org/t/generating-multiple-source-files-from-a-template/14800/4 "2016-02-29T16:08:15Z")

</div>

That would work too.
