-
Notifications
You must be signed in to change notification settings - Fork 2
/
setup.gradle
218 lines (193 loc) · 7.99 KB
/
setup.gradle
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
import org.gradle.util.GFileUtils
import java.nio.file.Path
import java.nio.file.Paths
// write operating system platform name to project property
switch (org.gradle.internal.os.OperatingSystem.current()) {
case org.gradle.internal.os.OperatingSystem.LINUX:
project.ext.osName = "Linux"
break
case org.gradle.internal.os.OperatingSystem.MAC_OS:
project.ext.osName = "macOS"
break
case org.gradle.internal.os.OperatingSystem.WINDOWS:
project.ext.osName = "Windows"
break
}
// This is where local project properties are stored
def propertiesFile = rootDir.toPath().resolve('local.properties').toFile()
project.ext.localProperties = new Properties()
/**
* Initialize and get project property from {@code local.properties} file with designated type.
*
* @param name property name to search for in local properties.
* @param type class to initialize the property as.
* @param env environment variable to use if property not found.
* @param required whether to throw an exception if property is not found.
* @param defaultValue value to be used if property was not found.
* @return found project property of type {@code T} or {@code null} if no property found.
*/
def <T> T getLocalProjectProperty(String name, Class<T> type, String env, boolean required, T defaultValue) {
Properties localProperties = project.ext.localProperties
String property = localProperties.getProperty(name, '')
if (property.isEmpty()) {
if (!System.hasProperty(name)) {
// when env parameter is not defined search for env variable with property name
def sEnv = env != null && !env.isEmpty() ? env : name
def envVariable = providers.environmentVariable(sEnv).forUseAtConfigurationTime()
if (envVariable.present) {
property = envVariable.get()
}
else if (required && defaultValue == null) {
throw new InvalidUserDataException("Unable to find local project property ${name}")
}
else return defaultValue
}
else property = System.getProperty(name)
}
if (type == Path) {
return Paths.get(property) as T
}
else return property as T
}
/**
* Initialize and register project property from {@code local.properties} file.
*
* @param name property name to search for in local properties.
* @param type class to initialize the property as.
* @param env environment variable to use if property not found.
* @param required whether to throw an exception if property is not found.
* @return found project property or {@code null} if no property found.
*/
def registerLocalProjectProperty(String name, Class<Object> type, String env, boolean required) {
project.ext.set(name, getLocalProjectProperty(name, type, env, required, null))
}
tasks.register('initLocalProperties') {
it.description 'Initialize local project properties.'
it.group 'build setup'
it.onlyIf {
!propertiesFile.exists()
}
it.doLast {
ArrayList<String> content = new ArrayList<String>()
content.add('# This file contains local properties used to configure project build.')
content.add('# Note: paths need to be Unix-style where segments need to be separated with forward-slashes (/)')
content.add('# this is for compatibility and stability purposes as backslashes don\'t play well.\n')
content.add('# Path to game installation directory')
ant.input(message: 'Enter path to game installation directory: ', addproperty: 'gameDir')
content.add("gameDir=${ant.properties.gameDir.toString().replace('\\', '/')}")
content.add('\n# Path to IntelliJ IDEA installation directory')
ant.input(message: '\nEnter path to IntelliJ IDEA installation directory: ', addproperty: 'ideaHome')
content.add("ideaHome=${ant.properties.ideaHome.toString().replace('\\', '/')}")
logger.info('Creating local.properties file...')
if (!propertiesFile.createNewFile()) {
throw new IOException('Unable to create local.properties file')
}
// noinspection GroovyAssignabilityCheck
GFileUtils.writeFile(content.join(System.lineSeparator()), propertiesFile)
}
}
// load and register all local properties
if (propertiesFile.exists()) {
// load properties from properties file
logger.info('Loading local properties...')
propertiesFile.withInputStream {
localProperties.load(it)
}
// path to Project Zomboid installation directory
registerLocalProjectProperty('gameDir', Path.class, 'PZ_DIR_PATH', true)
// path to IntelliJ IDEA installation directory
registerLocalProjectProperty('ideaHome', Path.class, 'IDEA_HOME', false)
// Github repository token used to generate changelog
registerLocalProjectProperty('cg.token', String.class, 'CHANGELOG_GITHUB_TOKEN', false)
}
else logger.warn('WARN: Unable to find local.properties file')
/**
* Create game launch run configuration.
*
* @param name run configuration name.
* @param debug if {@code true} launch game in debug mode.
* @param steam if {@code true} enable steam integration.
*/
void createRunConfig(String name, boolean debug, boolean steam) {
def runConfigFormat = [
'<component name="ProjectRunConfigurationManager">',
" <configuration default=\"false\" name=\"${name}\" type=\"Application\" factoryName=\"Application\">",
' <option name="MAIN_CLASS_NAME" value="zombie.gameStates.MainScreenState" />',
" <module name=\"${rootProject.name}.main\" />",
" <option name=\"VM_PARAMETERS\" value=\"-Ddebug=${debug ? 1 : 0} -Dzomboid.steam=${steam ? 1 : 0} " +
'-Dzomboid.znetlog=1 -XX:+UseConcMarkSweepGC -XX:-CreateMinidumpOnCrash ' +
'-XX:-OmitStackTraceInFastThrow -Xms1800m -Xmx2048m" />',
" <option name=\"WORKING_DIRECTORY\" value=\"${gameDir}\" />",
' <method v="2">',
' <option name="Gradle.BeforeRunTask" enabled="true" tasks="zomboidClasses" ' +
'externalProjectPath="\$PROJECT_DIR\$" vmOptions="" scriptParameters="" />',
' </method>',
' </configuration>',
'</component>',
]
// translate config name to filename (similar to what IDEA is doing)
def filename = name.replaceAll('\\s', '_').replaceAll('[^\\w_]', '').replaceAll("__", '_')
// write xml configuration to file
file("./.idea/runConfigurations/${filename}.xml").withWriter {
runConfigFormat.each { l -> it.writeLine(l) }
}
}
tasks.register('createLaunchRunConfigs') {
it.description 'Create game launch run configurations.'
it.group 'build setup'
it.onlyIf {
project.ext.has('gameDir')
}
it.doLast {
// debug configurations
createRunConfig('Debug Zomboid', true, true)
createRunConfig('Debug Zomboid (local)', true, false)
// run configurations
createRunConfig('Run Zomboid', false, true)
createRunConfig('Run Zomboid (local)', false, false)
}
}
tasks.register('createModSearchScopes') {
it.description 'Create IDEA search scopes for mod files.'
it.group 'build setup'
def modLuaScope = [
'<component name="DependencyValidationManager">',
"<scope name=\"mod-lua\" pattern=\"file[${rootProject.name}.media]:*.lua\" />",
'</component>'
]
def modMediaScope = [
'<component name="DependencyValidationManager">',
"<scope name=\"mod-media\" pattern=\"file[${rootProject.name}.media]:*.*\" />",
'</component>'
]
it.doLast {
file('./.idea/scopes/mod_lua.xml').withWriter {
modLuaScope.each { l -> it.writeLine(l) }
}
file('./.idea/scopes/mod_media.xml').withWriter {
modMediaScope.each { l -> it.writeLine(l) }
}
}
}
tasks.register('createDiscordIntegration') {
it.description 'Show IDEA project in Discord via rich presence.'
it.group 'build setup'
it.doLast {
def projectName = project.findProperty('mod.name') ?: 'PZ Mod'
def projectDescription = project.findProperty('mod.description') ?: 'Project Zomboid mod.'
def discordXmlFormat = [
'<?xml version="1.0" encoding="UTF-8"?>',
'<project version="4">',
' <component name="DiscordProjectSettings">',
' <option name="show" value="PROJECT" />',
' <option name="nameOverrideEnabled" value="true" />',
" <option name=\"nameOverrideText\" value=\"${projectName}\" />",
" <option name=\"description\" value=\"${projectDescription}\" />",
' </component>',
'</project>',
]
file('./.idea/discord.xml').withWriter {
discordXmlFormat.each { l -> it.writeLine(l) }
}
}
}