Exclude + include filesets in war task

I have the following situation I’m struggling to solve:

In the war task, I’m using the default “from”, which includes every file in src/main/webapp.

I have the following directory structure underneath it:

src/main/webapp/A/
                              B/
                              C/
                              D/

I want to include everything in webapp, as well as webapp/A/B, but not any other folder under webapp/A/*.
I tried:

    war {
      exclude '**/A/**'
      include '**/A/B/**' 
    }

But it still did not include B, it looks like exclude has precedence over include. Anyone have any other suggestion to do this?

Thanks!

I personally hate this type of complicated config of includes and excludes. Do you have the authority to change the layout?

In my (opinionated) view, you should never need exclude. Instead, you should only put resources into src/main/webapp which are ALWAYS included. Anything optional or related to a specific case (flavour?) should be in a separate folder (eg src/xxx/webapp) and include it as required.

If you do it my way, things become much simpler to understand. The next developer maintaining the code will thank you :slight_smile:

I’m definitely on-board with that approach. I’m really struggling to achieve that in this case though, and I’ll tell you why.

The directory under src/main/webapp I’m referring to is our bower install directory, that’s where web dependencies go when the build process does a “bower install”. Technically, everything under that folder is ‘safe’ to include in the war (although again that could be argued…). The original developer thought it was simpler to put that folder under src/main/webapp then outside of it, so it gets bundled in the WAR. I have the authority to change that if I want to, but…

The problem comes when I want to allow developers to use “bower link”, which essentially creates a symlink from that dependency’s folder (src/main/webapp/bower/mydependency), to their local workspace’s version of it, so they can work locally on a dependency. In this case I’m trying to exclude some of the files from bloating the war (files that would only be present during development, like build files, etc…).

I’m not sure moving the folder outside of src/main/webapp would gain me much - I guess I would then have to include everything back in and filter using includes only?

Yeah, don’t do that. In my opinion src/main/webapp should contain static, hand written sources which live under source control. I’d make a directory under $buildDir for bower and include that in your war when you package it. Using $buildDir means you get clean for free :slight_smile:

I have a similar opinion for generated java files in that they shouldn’t go in src/main/java. Again I’d put under $buildDir (or maybe src/generated/java if you’re going to commit them).

This also simplifies your svn ignores, git ignores etc

For finer grained control, you might use a fileTree

def allTree = fileTree("src/main/webapp") 
def excludeTree = allTree.matching {
   include "**/A/**" 
} 
def includeTree = allTree.matching {
   include "**/A/B/**" 
}  
def resultTree = allTree.minus(excludeTree).plus(includeTree)
war {
   from resultTree
} 

May be this is working too:

war {
    
    from('src/main/webapp/') {
        include '**/*'
        exclude 'A'
        into ''
     }
     
     from('src/main/webapp/A') {
        include 'B/**/*'
        into 'A'
     }
}