Codebender
Codebender

Reputation: 14461

Include a file from a specific source folder in Gradle

I have a java project which I want to build in gradle and the source is in the following structure,

src
 |
 +-main
 |  |
 |  +-java
 |     |
 |     +-package
 |        |
 |        +- Utils.java
 |        +- Other.java
 |        +- Files.java 
 |        +- Folders.java
 +-awesome
    |
    +-java
       |
       +-package
          |
          +- Utils.java

Now, I would like to build the files from the sourceSet src/main/java but including the Utils.java in src/awesome/java instead of from the main sourceset.

I have tried the following options (unsuccessfully):

1. Giving the full file path in exclude:

sourceSets {
    main {
        java {
            srcDir "src/awesome/java"
            exclude "${projectDir}/src/main/java/package/Utils.java"
        }
    }
}

Output: error: duplicate class package.Utils

Looks like giving the full file path does not work in the exclude pattern.

2. Using 2 java closures:

sourceSets {
    main {
        java {
            exclude "package/Utils.java"
        }
        java {
            srcDir "src/awesome/java"
        }
    }
}

But this removes the Utils.java class from both the source locations.

Is it possible to provide a single source file from another location in gradle?

Note: I cannot compile the Utils.java class alone since it has dependencies with the other classes. (I know it's bad, no need to rub it in).

Also copying the file to the main/java/package location is not possible since it could pollute the SCM.

Upvotes: 2

Views: 3600

Answers (2)

Codebender
Codebender

Reputation: 14461

It looks like we can exclude specific files using the exclude(Closure) or exclude(Spec) methods instead of passing Strings.

Here's how I achieved it,

sourceSets {
    main {
        java {
            srcDir "src/awesome/java"
            exclude { fileTreeElement ->
                fileTreeElement.file.equals("${projectDir}/src/main/java/package/Utils.java" as File)
            }
        }
    }
}

This way, it includes the Utils.java from awesome subfolder and excludes the Utils.java from main subfolder.

Upvotes: 0

lance-java
lance-java

Reputation: 27952

I suggest you insert a task into the DAG to merge the sources and build the merged folder

Eg:

sourceSets.main.java {
   srcDirs = ["$buildDir/mergedSources"]
}
task mergeSources(Type:Copy) {
   from 'src/awesome/java'
   from 'src/main/java'
   duplicatesStrategy = DuplicatesStrategy.EXCLUDE // (see https://docs.gradle.org/current/javadoc/org/gradle/api/file/DuplicatesStrategy.html#EXCLUDE)
   into "$buildDir/mergedSources"
}
compileJava.dependsOn mergeSources

Also copying the file to the main/java/package location is not possible since it could pollute the SCM.

Assuming you are already excluding $buildDir from SCM this won't 'pollute' SCM

Upvotes: 2

Related Questions