2021-12-21 08:23:33 -06:00
//version: 8fa7883b6196c1765266f4e6ddf3118d5043aafb
2021-11-20 13:55:05 +01:00
/*
DO NOT CHANGE THIS FILE!
Also, you may replace this file at any time if there is an update available.
Please check https://github.com/SinTh0r4s/ExampleMod1.7.10/blob/main/build.gradle for updates.
*/
import com.github.jengelman.gradle.plugins.shadow.tasks.ConfigureShadowRelocation
2021-11-30 10:01:34 +01:00
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
2021-11-20 13:55:05 +01:00
import java.util.concurrent.TimeUnit
buildscript {
repositories {
maven {
name = "forge"
url = "https://maven.minecraftforge.net"
}
maven {
name = "sonatype"
url = "https://oss.sonatype.org/content/repositories/snapshots/"
}
maven {
name = "Scala CI dependencies"
url = "https://repo1.maven.org/maven2/"
}
2021-11-30 10:01:34 +01:00
maven {
name = "jitpack"
url = "https://jitpack.io"
}
2021-11-20 13:55:05 +01:00
}
dependencies {
2021-11-30 10:01:34 +01:00
classpath 'com.github.GTNewHorizons:ForgeGradle:1.2.4'
2021-11-20 13:55:05 +01:00
}
}
plugins {
2021-11-30 10:01:34 +01:00
id 'idea'
id 'scala'
2021-11-20 13:55:05 +01:00
id ( "org.ajoberstar.grgit" ) version ( "3.1.1" )
id ( "com.github.johnrengelman.shadow" ) version ( "4.0.4" )
id ( "com.palantir.git-version" ) version ( "0.12.3" )
2021-12-21 08:23:33 -06:00
id ( "maven-publish" )
2021-11-20 13:55:05 +01:00
}
apply plugin: 'forge'
2021-11-30 10:01:34 +01:00
def projectJavaVersion = JavaLanguageVersion . of ( 8 )
2021-11-20 13:55:05 +01:00
java {
toolchain {
2021-11-30 10:01:34 +01:00
languageVersion . set ( projectJavaVersion )
2021-11-20 13:55:05 +01:00
}
}
idea {
module {
inheritOutputDirs = true
downloadJavadoc = true
downloadSources = true
}
}
2021-11-30 10:01:34 +01:00
if ( JavaVersion . current () != JavaVersion . VERSION_1_8 ) {
throw new GradleException ( "This project requires Java 8, but it's running on " + JavaVersion . current ())
}
2021-11-20 13:55:05 +01:00
checkPropertyExists ( "modName" )
checkPropertyExists ( "modId" )
checkPropertyExists ( "modGroup" )
checkPropertyExists ( "autoUpdateBuildScript" )
checkPropertyExists ( "minecraftVersion" )
checkPropertyExists ( "forgeVersion" )
checkPropertyExists ( "replaceGradleTokenInFile" )
checkPropertyExists ( "gradleTokenModId" )
checkPropertyExists ( "gradleTokenModName" )
checkPropertyExists ( "gradleTokenVersion" )
checkPropertyExists ( "gradleTokenGroupName" )
checkPropertyExists ( "apiPackage" )
checkPropertyExists ( "accessTransformersFile" )
checkPropertyExists ( "usesMixins" )
checkPropertyExists ( "mixinPlugin" )
checkPropertyExists ( "mixinsPackage" )
checkPropertyExists ( "coreModClass" )
checkPropertyExists ( "containsMixinsAndOrCoreModOnly" )
checkPropertyExists ( "usesShadowedDependencies" )
checkPropertyExists ( "developmentEnvironmentUserName" )
String javaSourceDir = "src/main/java/"
String scalaSourceDir = "src/main/scala/"
String targetPackageJava = javaSourceDir + modGroup . toString (). replaceAll ( "\\." , "/" )
String targetPackageScala = scalaSourceDir + modGroup . toString (). replaceAll ( "\\." , "/" )
2021-12-21 08:23:33 -06:00
if (( getFile ( targetPackageJava ). exists () || getFile ( targetPackageScala ). exists ()) == false ) {
2021-11-20 13:55:05 +01:00
throw new GradleException ( "Could not resolve \"modGroup\"! Could not find " + targetPackageJava + " or " + targetPackageScala )
}
if ( apiPackage ) {
targetPackageJava = javaSourceDir + modGroup . toString (). replaceAll ( "\\." , "/" ) + "/" + apiPackage . toString (). replaceAll ( "\\." , "/" )
targetPackageScala = scalaSourceDir + modGroup . toString (). replaceAll ( "\\." , "/" ) + "/" + apiPackage . toString (). replaceAll ( "\\." , "/" )
2021-12-21 08:23:33 -06:00
if (( getFile ( targetPackageJava ). exists () || getFile ( targetPackageScala ). exists ()) == false ) {
2021-11-20 13:55:05 +01:00
throw new GradleException ( "Could not resolve \"apiPackage\"! Could not find " + targetPackageJava + " or " + targetPackageScala )
}
}
if ( accessTransformersFile ) {
String targetFile = "src/main/resources/META-INF/" + accessTransformersFile
2021-12-21 08:23:33 -06:00
if ( getFile ( targetFile ). exists () == false ) {
2021-11-20 13:55:05 +01:00
throw new GradleException ( "Could not resolve \"accessTransformersFile\"! Could not find " + targetFile )
}
}
if ( usesMixins . toBoolean ()) {
if ( mixinsPackage . isEmpty () || mixinPlugin . isEmpty ()) {
throw new GradleException ( "\"mixinPlugin\" requires \"mixinsPackage\" and \"mixinPlugin\" to be set!" )
}
targetPackageJava = javaSourceDir + modGroup . toString (). replaceAll ( "\\." , "/" ) + "/" + mixinsPackage . toString (). replaceAll ( "\\." , "/" )
targetPackageScala = scalaSourceDir + modGroup . toString (). replaceAll ( "\\." , "/" ) + "/" + mixinsPackage . toString (). replaceAll ( "\\." , "/" )
2021-12-21 08:23:33 -06:00
if (( getFile ( targetPackageJava ). exists () || getFile ( targetPackageScala ). exists ()) == false ) {
2021-11-20 13:55:05 +01:00
throw new GradleException ( "Could not resolve \"mixinsPackage\"! Could not find " + targetPackageJava + " or " + targetPackageScala )
}
String targetFileJava = javaSourceDir + modGroup . toString (). replaceAll ( "\\." , "/" ) + "/" + mixinPlugin . toString (). replaceAll ( "\\." , "/" ) + ".java"
String targetFileScala = scalaSourceDir + modGroup . toString (). replaceAll ( "\\." , "/" ) + "/" + mixinPlugin . toString (). replaceAll ( "\\." , "/" ) + ".scala"
String targetFileScalaJava = scalaSourceDir + modGroup . toString (). replaceAll ( "\\." , "/" ) + "/" + mixinPlugin . toString (). replaceAll ( "\\." , "/" ) + ".java"
2021-12-21 08:23:33 -06:00
if (( getFile ( targetFileJava ). exists () || getFile ( targetFileScala ). exists () || getFile ( targetFileScalaJava ). exists ()) == false ) {
2021-11-20 13:55:05 +01:00
throw new GradleException ( "Could not resolve \"mixinPlugin\"! Could not find " + targetFileJava + " or " + targetFileScala + " or " + targetFileScalaJava )
}
}
if ( coreModClass ) {
String targetFileJava = javaSourceDir + modGroup . toString (). replaceAll ( "\\." , "/" ) + "/" + coreModClass . toString (). replaceAll ( "\\." , "/" ) + ".java"
String targetFileScala = scalaSourceDir + modGroup . toString (). replaceAll ( "\\." , "/" ) + "/" + coreModClass . toString (). replaceAll ( "\\." , "/" ) + ".scala"
String targetFileScalaJava = scalaSourceDir + modGroup . toString (). replaceAll ( "\\." , "/" ) + "/" + coreModClass . toString (). replaceAll ( "\\." , "/" ) + ".java"
2021-12-21 08:23:33 -06:00
if (( getFile ( targetFileJava ). exists () || getFile ( targetFileScala ). exists () || getFile ( targetFileScalaJava ). exists ()) == false ) {
2021-11-20 13:55:05 +01:00
throw new GradleException ( "Could not resolve \"coreModClass\"! Could not find " + targetFileJava + " or " + targetFileScala + " or " + targetFileScalaJava )
}
}
configurations . all {
resolutionStrategy . cacheChangingModulesFor ( 0 , TimeUnit . SECONDS )
// Make sure GregTech build won't time out
System . setProperty ( "org.gradle.internal.http.connectionTimeout" , 120000 as String )
System . setProperty ( "org.gradle.internal.http.socketTimeout" , 120000 as String )
}
// Fix Jenkins' Git: chmod a file should not be detected as a change and append a '.dirty' to the version
'git config core.fileMode false' . execute ()
// Pulls version from git tag
2021-11-30 10:01:34 +01:00
try {
version = minecraftVersion + "-" + gitVersion ()
}
catch ( Exception e ) {
throw new IllegalStateException ( "This mod must be version controlled by Git AND the repository must provide at least one tag!" );
}
2021-12-21 08:23:33 -06:00
2021-11-20 13:55:05 +01:00
group = modGroup
2021-12-21 08:23:33 -06:00
if ( project . hasProperty ( "customArchiveBaseName" ) && customArchiveBaseName ) {
archivesBaseName = customArchiveBaseName
}
else {
archivesBaseName = modId
}
2021-11-20 13:55:05 +01:00
minecraft {
version = minecraftVersion + "-" + forgeVersion + "-" + minecraftVersion
runDir = "run"
if ( replaceGradleTokenInFile ) {
replaceIn replaceGradleTokenInFile
if ( gradleTokenModId ) {
replace gradleTokenModId , modId
}
if ( gradleTokenModName ) {
replace gradleTokenModName , modName
}
2021-11-30 10:01:34 +01:00
if ( gradleTokenVersion ) {
2021-11-20 13:55:05 +01:00
replace gradleTokenVersion , versionDetails (). lastTag
}
if ( gradleTokenGroupName ) {
replace gradleTokenGroupName , modGroup
}
}
}
if ( file ( "addon.gradle" ). exists ()) {
apply from: "addon.gradle"
}
apply from: 'repositories.gradle'
configurations {
2021-12-21 08:23:33 -06:00
implementation . extendsFrom ( shadowImplementation ) // TODO: remove after all uses are refactored
implementation . extendsFrom ( shadowCompile )
implementation . extendsFrom ( shadeCompile )
2021-11-20 13:55:05 +01:00
}
repositories {
2021-11-30 10:01:34 +01:00
maven {
name = "Overmind forge repo mirror"
url = "https://gregtech.overminddl1.com/"
}
2021-11-20 13:55:05 +01:00
if ( usesMixins . toBoolean ()) {
maven {
name = "sponge"
url = "https://repo.spongepowered.org/repository/maven-public"
}
maven {
url = "https://jitpack.io"
}
}
}
dependencies {
if ( usesMixins . toBoolean ()) {
annotationProcessor ( "org.ow2.asm:asm-debug-all:5.0.3" )
annotationProcessor ( "com.google.guava:guava:24.1.1-jre" )
annotationProcessor ( "com.google.code.gson:gson:2.8.6" )
annotationProcessor ( "org.spongepowered:mixin:0.8-SNAPSHOT" )
// using 0.8 to workaround a issue in 0.7 which fails mixin application
compile ( "org.spongepowered:mixin:0.7.11-SNAPSHOT" ) {
// Mixin includes a lot of dependencies that are too up-to-date
exclude module: "launchwrapper"
exclude module: "guava"
exclude module: "gson"
exclude module: "commons-io"
exclude module: "log4j-core"
}
compile ( "com.github.GTNewHorizons:SpongeMixins:1.3.3:dev" )
}
}
apply from: 'dependencies.gradle'
def mixingConfigRefMap = "mixins." + modId + ".refmap.json"
def refMap = "${tasks.compileJava.temporaryDir}" + File . separator + mixingConfigRefMap
def mixinSrg = "${tasks.reobf.temporaryDir}" + File . separator + "mixins.srg"
task generateAssets {
if ( usesMixins . toBoolean ()) {
2021-12-21 08:23:33 -06:00
getFile ( "/src/main/resources/mixins." + modId + ".json" ). text = """{
2021-11-20 13:55:05 +01:00
"required": true,
"minVersion": "0.7.11",
"package": "${modGroup}.${mixinsPackage}",
"plugin": "${modGroup}.${mixinPlugin}",
"refmap": "${mixingConfigRefMap}",
"target": "@env(DEFAULT)",
"compatibilityLevel": "JAVA_8"
}
"""
}
}
2021-11-30 10:01:34 +01:00
task relocateShadowJar ( type: ConfigureShadowRelocation ) {
target = tasks . shadowJar
prefix = modGroup + ".shadow"
}
2021-11-20 13:55:05 +01:00
2021-11-30 10:01:34 +01:00
shadowJar {
2021-12-21 08:23:33 -06:00
project . configurations . shadeCompile . each { dep ->
from ( project . zipTree ( dep )) {
exclude 'META-INF' , 'META-INF/**'
}
}
2021-11-20 13:55:05 +01:00
manifest {
2021-11-30 10:01:34 +01:00
attributes ( getManifestAttributes ())
2021-11-20 13:55:05 +01:00
}
2021-11-30 10:01:34 +01:00
minimize () // This will only allow shading for actually used classes
2021-12-21 08:23:33 -06:00
configurations = [ project . configurations . shadowImplementation , project . configurations . shadowCompile ]
2021-11-20 13:55:05 +01:00
dependsOn ( relocateShadowJar )
}
jar {
2021-12-21 08:23:33 -06:00
project . configurations . shadeCompile . each { dep ->
from ( project . zipTree ( dep )) {
exclude 'META-INF' , 'META-INF/**'
}
}
2021-11-20 13:55:05 +01:00
manifest {
2021-11-30 10:01:34 +01:00
attributes ( getManifestAttributes ())
2021-11-20 13:55:05 +01:00
}
if ( usesShadowedDependencies . toBoolean ()) {
dependsOn ( shadowJar )
enabled = false
}
}
reobf {
if ( usesMixins . toBoolean ()) {
addExtraSrgFile mixinSrg
}
}
afterEvaluate {
if ( usesMixins . toBoolean ()) {
tasks . compileJava {
options . compilerArgs += [
"-AreobfSrgFile=${tasks.reobf.srg}" ,
"-AoutSrgFile=${mixinSrg}" ,
"-AoutRefMapFile=${refMap}" ,
// Elan: from what I understand they are just some linter configs so you get some warning on how to properly code
"-XDenableSunApiLintControl" ,
"-XDignore.symbol.file"
]
}
}
}
runClient {
def arguments = []
if ( usesMixins . toBoolean ()) {
arguments += [
"--mods=../build/libs/$modId-${version}.jar" ,
"--tweakClass org.spongepowered.asm.launch.MixinTweaker"
]
}
if ( developmentEnvironmentUserName ) {
arguments += [
"--username" ,
developmentEnvironmentUserName
]
}
args ( arguments )
}
runServer {
def arguments = []
2021-11-30 10:01:34 +01:00
if ( usesMixins . toBoolean ()) {
2021-11-20 13:55:05 +01:00
arguments += [
"--mods=../build/libs/$modId-${version}.jar" ,
"--tweakClass org.spongepowered.asm.launch.MixinTweaker"
]
}
args ( arguments )
}
2021-11-30 10:01:34 +01:00
tasks . withType ( JavaExec ). configureEach {
javaLauncher . set (
javaToolchains . launcherFor {
languageVersion = projectJavaVersion
}
)
2021-11-20 13:55:05 +01:00
}
2021-11-30 10:01:34 +01:00
processResources
2021-12-21 08:23:33 -06:00
{
// this will ensure that this task is redone when the versions change.
inputs . property "version" , project . version
inputs . property "mcversion" , project . minecraft . version
2021-11-30 10:01:34 +01:00
2021-12-21 08:23:33 -06:00
// replace stuff in mcmod.info, nothing else
from ( sourceSets . main . resources . srcDirs ) {
include 'mcmod.info'
2021-11-30 10:01:34 +01:00
2021-12-21 08:23:33 -06:00
// replace version and mcversion
expand "minecraftVersion" : project . minecraft . version ,
"modVersion" : versionDetails (). lastTag ,
"modId" : modId ,
"modName" : modName
}
if ( usesMixins . toBoolean ()) {
from refMap
}
// copy everything else, thats not the mcmod.info
from ( sourceSets . main . resources . srcDirs ) {
exclude 'mcmod.info'
}
}
2021-11-20 13:55:05 +01:00
2021-11-30 10:01:34 +01:00
def getManifestAttributes () {
2021-11-20 13:55:05 +01:00
def manifestAttributes = [:]
2021-11-30 10:01:34 +01:00
if ( containsMixinsAndOrCoreModOnly . toBoolean () == false && ( usesMixins . toBoolean () || coreModClass )) {
2021-11-20 13:55:05 +01:00
manifestAttributes += [ "FMLCorePluginContainsFMLMod" : true ]
}
if ( accessTransformersFile ) {
manifestAttributes += [ "FMLAT" : accessTransformersFile . toString ()]
}
if ( coreModClass ) {
manifestAttributes += [ "FMLCorePlugin" : modGroup + "." + coreModClass ]
}
if ( usesMixins . toBoolean ()) {
manifestAttributes += [
"TweakClass" : "org.spongepowered.asm.launch.MixinTweaker" ,
2021-11-30 10:01:34 +01:00
"MixinConfigs" : "mixins." + modId + ".json" ,
2021-11-20 13:55:05 +01:00
"ForceLoadAsMod" : containsMixinsAndOrCoreModOnly . toBoolean () == false
]
}
2021-11-30 10:01:34 +01:00
return manifestAttributes
2021-11-20 13:55:05 +01:00
}
2021-11-30 10:01:34 +01:00
task sourcesJar ( type: Jar ) {
from ( sourceSets . main . allJava )
from ( file ( "$projectDir/LICENSE" ))
getArchiveClassifier (). set ( 'sources' )
}
task shadowDevJar ( type: ShadowJar ) {
2021-12-21 08:23:33 -06:00
project . configurations . shadeCompile . each { dep ->
from ( project . zipTree ( dep )) {
exclude 'META-INF' , 'META-INF/**'
}
}
2021-11-20 13:55:05 +01:00
from sourceSets . main . output
getArchiveClassifier (). set ( "dev" )
2021-11-30 10:01:34 +01:00
manifest {
attributes ( getManifestAttributes ())
2021-11-20 13:55:05 +01:00
}
2021-11-30 10:01:34 +01:00
minimize () // This will only allow shading for actually used classes
2021-12-21 08:23:33 -06:00
configurations = [ project . configurations . shadowImplementation , project . configurations . shadowCompile ]
2021-11-30 10:01:34 +01:00
}
2021-11-20 13:55:05 +01:00
2021-11-30 10:01:34 +01:00
task relocateShadowDevJar ( type: ConfigureShadowRelocation ) {
target = tasks . shadowDevJar
prefix = modGroup + ".shadow"
}
task circularResolverJar ( type: Jar ) {
dependsOn ( relocateShadowDevJar )
dependsOn ( shadowDevJar )
enabled = false
}
task devJar ( type: Jar ) {
2021-12-21 08:23:33 -06:00
project . configurations . shadeCompile . each { dep ->
from ( project . zipTree ( dep )) {
exclude 'META-INF' , 'META-INF/**'
}
}
2021-11-30 10:01:34 +01:00
from sourceSets . main . output
getArchiveClassifier (). set ( "dev" )
2021-11-20 13:55:05 +01:00
manifest {
2021-11-30 10:01:34 +01:00
attributes ( getManifestAttributes ())
}
if ( usesShadowedDependencies . toBoolean ()) {
dependsOn ( circularResolverJar )
enabled = false
2021-11-20 13:55:05 +01:00
}
}
task apiJar ( type: Jar ) {
from ( sourceSets . main . allJava ) {
2021-12-21 08:23:33 -06:00
include modGroup . toString (). replaceAll ( "\\." , "/" ) + "/" + apiPackage . toString (). replaceAll ( "\\." , "/" ) + '/**'
2021-11-20 13:55:05 +01:00
}
from ( sourceSets . main . output ) {
2021-12-21 08:23:33 -06:00
include modGroup . toString (). replaceAll ( "\\." , "/" ) + "/" + apiPackage . toString (). replaceAll ( "\\." , "/" ) + '/**'
2021-11-20 13:55:05 +01:00
}
from ( sourceSets . main . resources . srcDirs ) {
include ( "LICENSE" )
}
getArchiveClassifier (). set ( 'api' )
}
artifacts {
archives sourcesJar
archives devJar
if ( apiPackage ) {
archives apiJar
}
}
2021-12-21 08:23:33 -06:00
// publishing
publishing {
publications {
maven ( MavenPublication ) {
artifact source: jar
artifact source: sourcesJar , classifier: "src"
artifact source: devJar , classifier: "dev"
if ( apiPackage ) {
artifact source: apiJar , classifier: "api"
}
groupId = System . getenv ( "ARTIFACT_GROUP_ID" ) ?: group
artifactId = System . getenv ( "ARTIFACT_ID" ) ?: project . name
version = System . getenv ( "ARTIFACT_VERSION" ) ?: project . version
}
}
repositories {
maven {
String owner = System . getenv ( "REPOSITORY_OWNER" ) ?: "Unknown"
String repositoryName = System . getenv ( "REPOSITORY_NAME" ) ?: "Unknown"
String githubRepositoryUrl = "https://maven.pkg.github.com/$owner/$repositoryName"
name = "GitHubPackages"
url = githubRepositoryUrl
credentials {
username = System . getenv ( "GITHUB_ACTOR" ) ?: "NONE"
password = System . getenv ( "GITHUB_TOKEN" ) ?: "NONE"
}
}
}
}
2021-11-20 13:55:05 +01:00
// Updating
task updateBuildScript {
doLast {
2021-12-21 08:23:33 -06:00
if ( performBuildScriptUpdate ( projectDir . toString ())) return
2021-11-20 13:55:05 +01:00
print ( "Build script already up-to-date!" )
}
}
2021-12-21 08:23:33 -06:00
if ( isNewBuildScriptVersionAvailable ( projectDir . toString ())) {
2021-11-20 13:55:05 +01:00
if ( autoUpdateBuildScript . toBoolean ()) {
2021-12-21 08:23:33 -06:00
performBuildScriptUpdate ( projectDir . toString ())
2021-11-20 13:55:05 +01:00
} else {
println ( "Build script update available! Run 'gradle updateBuildScript'" )
}
}
static URL availableBuildScriptUrl () {
new URL ( "https://raw.githubusercontent.com/SinTh0r4s/ExampleMod1.7.10/main/build.gradle" )
}
2021-12-21 08:23:33 -06:00
boolean performBuildScriptUpdate ( String projectDir ) {
if ( isNewBuildScriptVersionAvailable ( projectDir )) {
def buildscriptFile = getFile ( "build.gradle" )
2021-11-20 13:55:05 +01:00
availableBuildScriptUrl (). withInputStream { i -> buildscriptFile . withOutputStream { it << i } }
print ( "Build script updated. Please REIMPORT the project or RESTART your IDE!" )
return true
}
return false
}
2021-12-21 08:23:33 -06:00
boolean isNewBuildScriptVersionAvailable ( String projectDir ) {
2021-11-20 13:55:05 +01:00
Map parameters = [ "connectTimeout" : 2000 , "readTimeout" : 2000 ]
2021-12-21 08:23:33 -06:00
String currentBuildScript = getFile ( "build.gradle" ). getText ()
2021-11-20 13:55:05 +01:00
String currentBuildScriptHash = getVersionHash ( currentBuildScript )
String availableBuildScript = availableBuildScriptUrl (). newInputStream ( parameters ). getText ()
String availableBuildScriptHash = getVersionHash ( availableBuildScript )
boolean isUpToDate = currentBuildScriptHash . empty || availableBuildScriptHash . empty || currentBuildScriptHash == availableBuildScriptHash
return ! isUpToDate
}
static String getVersionHash ( String buildScriptContent ) {
String versionLine = buildScriptContent . find ( "^//version: [a-z0-9]*" )
if ( versionLine != null ) {
return versionLine . split ( ": " ). last ()
}
return ""
}
configure ( updateBuildScript ) {
group = 'forgegradle'
description = 'Updates the build script to the latest version'
}
2021-12-21 08:23:33 -06:00
// Helper methods
def checkPropertyExists ( String propertyName ) {
if ( project . hasProperty ( propertyName ) == false ) {
throw new GradleException ( "This project requires a property \"" + propertyName + "\"! Please add it your \"gradle.properties\". You can find all properties and their description here: https://github.com/SinTh0r4s/ExampleMod1.7.10/blob/main/gradle.properties" )
}
}
def getFile ( String relativePath ) {
return new File ( projectDir , relativePath )
}