14

We use some Gradle base scripts on an central point. This scripts are included with "apply from:" from a large count of scripts. This base scripts need access to files relative to the script. How can I find the location of the base scripts?

Sample for one build.gradle:

apply from: "../../gradlebase/base1.gradle"

Sample for base1.gradle

println getScriptLocation()
Horcrux7
  • 23,758
  • 21
  • 98
  • 156
  • 5
    Do you want the full path of `base1.gradle` in `base1.gradle`? you can just get it from `buildscript.sourceFile`. or do you want the relative path used by the calling script? if you know that the caller is a `build.gradle` file you can get it from `buildFile`. can you add sample output to your question – Aarjav Jan 22 '16 at 23:14
  • Yes, this is the right answer. – Horcrux7 Jan 25 '16 at 07:29
  • Also in this question/answer: https://stackoverflow.com/a/41446643/573389 – djKianoosh Jun 02 '20 at 15:04

8 Answers8

11

I'm not sure if this is considered an internal interface, but DefaultScriptHandler has a getSourceFile() method, and the current instance is accessible via the buildscript property, so you can just use buildscript.sourceFile. It's a File instance pointing at the current script

Michael Mrozek
  • 169,610
  • 28
  • 168
  • 175
  • It's in the API at https://docs.gradle.org/current/javadoc/org/gradle/api/initialization/dsl/ScriptHandler.html#getSourceFile-- , so I think this is safe to rely on. – Adrian Baker Jun 02 '18 at 18:38
5

I'm still not sure if I understood the question well but You can find path of current gradle script using following piece of code:

println project.buildscript.sourceFile

It gives the full path of the script that is currently running. Is that what You're looking for?

mkobit
  • 43,979
  • 12
  • 156
  • 150
Opal
  • 81,889
  • 28
  • 189
  • 210
  • 1
    This return the location of the project build script. In the sample from build.gradle. Also if I call it inside the base1.gradle. But I need the location of base1.gradle. This is also expected. It is the buildscript of the project. And not the current script. – Horcrux7 Jul 11 '14 at 11:00
  • You need the location of `base1.gradle` in `build.gradle`, yes? – Opal Jul 11 '14 at 11:02
  • No, I need the location of base1.gradle inside base1.gradle. build.gradle does know of course the location of base1.gradle. See my workaround. – Horcrux7 Jul 15 '14 at 11:59
  • No I understand. This is not possible. Gradle sets workingDir for every applied script equal to the one that is invoked. It's impossible without a workaround You made or any other. – Opal Jul 15 '14 at 16:22
  • 6
    The right answer is without 'project'. Only 'buildscript.sourceFile' return the right path. – Horcrux7 Jan 25 '16 at 07:32
2

I'm pulling it off the stack.

buildscript {
    def root = file('.').toString();
    // We have to seek through, since groovy/gradle introduces
    // a lot of abstraction that we see in the trace as extra frames.
    // Fortunately, the first frame in the build dir is always going
    // to be this script.
    buildscript.metaClass.__script__ = file(
        Thread.currentThread().stackTrace.find { ste -> 
            ste.fileName?.startsWith root 
        }.fileName
    )

    // later, still in buildscript

    def libDir = "${buildscript.__script__.parent}/lib"


    classpath files("${libDir}/custom-plugin.jar")
}
// This is important to do if you intend to use this path outside of 
//   buildscript{}, since everything else is pretty asynchronous, and
//   they all share the buildscript object.
def __buildscripts__ = buildscript.__script__.parent;

Compact version for those who don't like clutter:

    String r = file('.').toString();
buildscript.metaClass.__script__ = file(Thread.currentThread().stackTrace*.fileName?.find { it.startsWith r })
Fordi
  • 2,798
  • 25
  • 20
1

My current workaround is to inject the path from the calling script. This is ugly hack.

The caller script must know where the base script is located. I save this path in a property before calling:

ext.scriptPath = '../../gradlebase'
apply from: "${scriptPath}/base1.gradle"

In base1.gradle I can also access the property ${scriptPath}

Opal
  • 81,889
  • 28
  • 189
  • 210
Horcrux7
  • 23,758
  • 21
  • 98
  • 156
  • Have You worked out anything else? I may try but I feel that I don't understand the question well. Any minimal working example? – Opal Jul 07 '14 at 11:41
  • 1
    This answer is my current workaround. The question is how can I detect the location/path of the current script? The script is checkin in a repository and has a different location on any developer system. – Horcrux7 Jul 10 '14 at 08:15
  • Do You have any minimal working example? Just to know what exactly You need to achieve? – Opal Jul 10 '14 at 08:22
  • I have add a minimal sample. – Horcrux7 Jul 10 '14 at 09:31
1

Another solution is set a property for the location of A.gradle in your global gradle settings at: {userhome}/.gradle/gradle.properties

Bill Lin
  • 1,145
  • 1
  • 11
  • 12
  • This can be a solution if the script exists only one. If I have checkout the workspace multiple times for different branches this will not work. – Horcrux7 Jul 02 '14 at 13:21
0

You could search for this scripts in the relative path like:

if(new File(rootDir,'../path/A.gradle').exists ()){
    apply from: '../path/A.gradle'
}
Bill Lin
  • 1,145
  • 1
  • 11
  • 12
  • I does not understand your answer. From your sample. How find I inside the script the A.gradle the path to A.gradle. This need I to load A.gradle.properties. – Horcrux7 Jul 02 '14 at 11:19
  • You have to know possible location of A.gradle in order to use it. – Bill Lin Jul 02 '14 at 12:35
0

This solution has not been tested with 'apply from', but has been tested with settings.gradle

Gradle has a Script.file(String path) function. I solved my problem by doing

def outDir = file("out")
def releaseDir = new File(outDir, "release")

And the 'out' directory is always next to the build.gradle in which this line is called.

Nathan
  • 431
  • 5
  • 8
0

I am looking for gradle kotlin DSL file location as we do for shell scripts like this

export LNX_SPI_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"

Raja Nagendra Kumar
  • 427
  • 1
  • 5
  • 12