Gradle: getting the root project directory path when starting with a custom build file

The structure of my Gradle project is the following:

Project
├── app
     └── build.gradle
├── foo
     └── bar.txt
·
·
·
└── build.gradle

Normally to get the absolute path of the foo folder I can just simply do new File('foo').getAbsolutePath() in the root build.gradle file.

But this unfortunately doesn't work if you run the gradle script from outside the project directory, for example doing something like this:

$ trunk/gradlew -b trunk/build.gradle tasks

With the previous command gradle is looking for the foo directory in the parent of the Project, because I started the script from there.

Is there a way to get the absolute path of the Project where the build.gradle is, even if you start your script from another directory? Or is there any other way to get a reference of a directory in the same folder where the script is?

I've tried also with getClass().protectionDomain.codeSource.location.path but it is returning the path to the gradle cache directory.


Solution 1:

I got past this problem by ensuring Java userDir was set to the project directory (i.e. project.projectDir) at the top of my build.gradle file, as follows:

    System.setProperty( "user.dir", project.projectDir.toString() )
    println  "  project dir:  "+ System.getProperty("user.dir");

This can be checked by executing a separate (Groovy) code file such as:

    println "User Dir: ${System.getProperty( 'user.dir' )}"

You can output the Gradle project values before and after using these statements.

    println  "Root project:   ${project.rootProject}";
    println  "  rootDir:      ${project.rootDir}"
    println  "  projectDir:   ${project.projectDir}";
    println  "  project dir:  ${System.getProperty("user.dir")}";

If you have sub-projects, projectDir is not the same as rootDir.

This hasn't fixed my actual problem but it has ensured that I'm opening the correct file (relative to the location of build.gradle.

Solution 2:

new File('foo') by definition (look at its JavaDoc) makes a path relative to the current working directory, so depends on where you call the app from. If you want a path relative to the project folder, use project.file('foo'), or as project is the default for resolving the method just file('foo') and you get the relative path resolved against the project directory, not the working directory. So use file('foo').absolutePath and you will be fine.

Solution 3:

In the build.gradle file just use projectDir to get the absolute path of the build.gradle file. from there you can navigate your project's files. read this for more info:

https://www.tutorialspoint.com/gradle/gradle_build_script.htm