How to include a complete directory of subprojects

I am building a library which has a few demo projects, and will have a huge load of examples projects. I am currently including them manually one by one in the settings.gradle file, but I expect to have over 100 examples.

  1. So I am wondering if there was a way to include all subprojects under the example folders without manually specifying them one by one in the settings.gradle.

  2. Another side effect is that the example folder itself gets built even if there is no code inside. Is there a way to exclude that folder or it does not really matter if it does get built?

Here is the directory structure of the project (2 level depth):

.
β”œβ”€β”€ blackbook_demo
β”‚   β”œβ”€β”€ build
β”‚   └── src
β”œβ”€β”€ blackbook_terminal
β”‚   β”œβ”€β”€ build
β”‚   └── src
β”œβ”€β”€ build
β”‚   β”œβ”€β”€ classes
β”‚   β”œβ”€β”€ dependency-cache
β”‚   β”œβ”€β”€ libs
β”‚   └── tmp
β”œβ”€β”€ examples
β”‚   β”œβ”€β”€ build
β”‚   β”œβ”€β”€ poker_dice
β”‚   β”œβ”€β”€ stock_ticker
β”‚   └── template
β”œβ”€β”€ gradle
β”‚   └── wrapper
└── src
    β”œβ”€β”€ main
    β”œβ”€β”€ obsolete
    └── test

There is currently 2 example sub projects: stock_ticker and poker_dice.

settings.gradle goes as follow:

rootProject.name = 'javalib_blackbook'
include ":blackbook_terminal", ":blackbook_demo", ":examples:stock_ticker", ":examples:poker_dice"

the root build.gradle goes as follow:

allprojects 
{
  apply plugin: 'java'
  sourceCompatibility = '1.8'
  [compileJava, compileTestJava]*.options*.encoding = 'UTF-8'

  repositories 
  {
    mavenCentral()
  }

  dependencies 
  {
    testCompile group: 'junit', name: 'junit', version: '4.10'
  }

}

subprojects 
{
  dependencies 
  {
    compile rootProject 
  }
}

an example sub project will use this build.gradle file

apply plugin: "application"
mainClassName = 'com.lariennalibrary.blackbook.examples.Launcher'

dependencies 
{
  compile project(':blackbook_terminal')
}

jar 
{
  manifest 
  {
    attributes (
      'Class-Path': configurations.compile.collect { it.getName() }.join(' '),
      'Main-Class': 'com.lariennalibrary.blackbook.examples.Launcher'
    )
  }
}
1 Like

settings.gradle

new File(.).listFiles().each {
   if (it.directory && new File(it, 'build.gradle').exists()) {
      include(it)
   }
}

I get your logic but unfortunately even after reading a bit about collections, I cannot make it works. If I add the code β€œas is” and remove any include in my settings.gradle file, I get the following error.

* What went wrong:
Could not compile settings file '/mnt/data/git/javalib_blackbook/settings.gradle'.
> startup failed:
  settings file '/mnt/data/git/javalib_blackbook/settings.gradle': 2: unexpected token: . @ line     2, column 10.
new File(.).listFiles().each 
              ^

So the problem was the dot in the parenthesis, so I thought maybe it was lacking apostrophes around the dot since it should be a directory path expressed as a string. So I replaced it with File(’.’) and now I got the following message:

* What went wrong:
A problem occurred evaluating settings 'javalib_blackbook'.
> Could not find method include() for arguments [./blackbook_demo] on settings 'javalib_blackbook' of type org.gradle.initialization.DefaultSettings.

From what I can see, it tries to include β€œ./blackbook_demo” instead of β€œ:blackbook_demo”. Maybe that is the problem, I need to substitute the β€œ./” for β€œ:”.

Try

rootDir.listFiles().each {
   if (it.directory && new File(it, 'build.gradle').exists()) {
      include ":${it.name}" 
   }
}

I had an issue where the demo was dependent on the terminal. Since the the terminal appears alphabetically afterwards, it could not find the dependency. So I used portions of your code to create new code that will only explore the examples folder instead. Here is the new settings file which seems to work so far.

rootProject.name = 'javalib_blackbook'
include ":blackbook_terminal", ":blackbook_demo"

new File("examples/").listFiles().each
{
   if (it.directory && new File(it, 'build.gradle').exists())
   {
      include ":${it.name}"
   }
}

Thanks again

I had to make a quick fix to the code above as it created folders for each example in the root directory. So I replaced the include line with

  include ":examples:${it.name}"

the root folder β€œexample” still get built, but at least I don’t need to enter project name manually.

Better to do the following so it’s agnostic of the directory you’re running gradle from

new File(rootDir, "examples").listFiles().each {...} 

Thanks, that seems to have indirectly solved the issue I had with netbeans when trying to run my example projects from netbeans.