Filter source file when copy from directory


(john dafis) #1

Hi,
I am looking for a help in filtering some source files from the source project before building the project.
The scenario is as follow: I have a list of files that I want to exclude from the build. Hence, I am looking for a solution where I can create a custom task within Gradle that takes as input the list of file that I want to filter. Afterward, the build task should use the filtered source directory to build the project. I want this custom task to be activated while copying the source project. Meaning, while copying the project from the SVN or any directory, the custom filtering command should be activated.

Can you please help me or advice on the possible direction to solve this issue.

John


(Pierre) #2

Hello,

I will assume you build a plain old java single project:

apply plugin: 'java'

def myJavaExclusions = file('java.exclusions').readLines()
def myResourcesExclusions = file('resources.exclusions').readLines()

sourceSets {
    main {
        java { j ->
             myJavaExclusions.each { j.exclude it }
        }
        resources { r ->
            myResourcesExclusions.each { r.exclude it }
        }
    }
}

And you define your filters - one per line - in the text files java.exclusions and resources.exclusions.
For example, to ignore every java file ending with Foo or starting with Bar regardless of the package:

**/*Foo.java **/Bar*.java

Meaning, while copying the project from the SVN or any directory, the custom filtering command should be activated

I am more skeptical about this part. The above will only work when Gradle is invoked to build the project. Either you script the call to Gradle (with server side SVN hooks, or client side hooks if using TortoiseSVN) or you call it manually.


(uklance) #3

I always use exclusions as a last resort. Is there a chance you can split the files into two root directories instead? ie you combine the two directories (FileTrees) when you need them and don’t combine when you want the exclusion.


Create custom plugin for my task
(john dafis) #5

Thank you very much for the reply.
This absolutely what I was looking for, and it works fine for me.
One other question related to packaging this task in a separate file, and call it in the main Gradle build script where it is needed. ?
any idea if this possible. I have looked to custom plugin approach, but I am not sure how to structure the script and use it in the main gradle build file.

John


(john dafis) #6

Hi Lance,
Thank you for your reply.
I dont want to change the structure of project directory by splitting the file, and that why I have the only option of using exclusions approach.


(john dafis) #7

Hi Pierre,
I have one concern regarding the exclusions of the files in gradle multiple project scenario.
sometime I have source files with the same names located in same package structure but in a different module (projectA, ProjectB).

my directory looks something like this:
-->MyRooTDir
   ---->Project-A
         --->main
               ----->java
                   ---->Test
                          ----> Foo.java
  -----> project-B
         --->main
               ----->java
                   ---->Test
                          ----> Foo.java
-->build.gradle
......
..
..

Now in Java.exclusions file, I specify the full package url for the source file (e.g.," Test/Foo.java").
However, Foo.java appears in project A and B, but with a different implementation.
The question is how to exclude Foo.java from projectA and not B.

I tried something with this but never seem to work:

sourceSets {
    Project-A{
     main {
        java { j ->
             myJavaExclusions.each { j.exclude it }
        }
}

(Pierre) #8

Hi john,

You can apply specific logic in subproject build.gradle file and keep common logic in the rootProject build.gradle.

rootDir/build.gradle:

subprojects {
    apply plugin: 'java'
}

Filtering is only needed in project-A, so, in the rootDit/project-A/build.gradle:

def myJavaExclusions = file('java.exclusions').readLines()
def myResourcesExclusions = file('resources.exclusions').readLines()

sourceSets {
    main {
        java { j ->
             myJavaExclusions.each { j.exclude it }
        }
        resources { r ->
            myResourcesExclusions.each { r.exclude it }
        }
    }
}

Your java…exclusions and resources.exclusions files must be located in rootDir/project-A/.

You can also keep exclusion mechanism in the root build.gradle thanks to the filtering by name feature

rootDir/build.gradle:

subprojects {
    aply plugin: 'java'
}

// Filter all subprojects matching a regexp filtered
configure(subprojects.findAll { it.name ==~ /.*filtered.*/ }) { p ->
    def myJavaExclusions = p.file('java.exclusions').readLines()
    def myResourcesExclusions = p.file('resources.exclusions').readLines()

    p.sourceSets {
        main {
            java { j ->
                 myJavaExclusions.each { j.exclude it }
            }
            resources { r ->
                myResourcesExclusions.each { r.exclude it }
            }
        }
    }
}

Which one is the best depends on your use case. Is it mostly filter only […] or filter all but […]. In the first case I’d pick the subproject build.gradle file, in the latter the filtering approach.