Skip to content

Commit 900d539

Browse files
author
Stewart Miles
committed
Added UPM archive export build target.
* Added export_unity_package applications to the repo. * Integrated export_unity_package tests into build.gradle. * Moved .unitypackage packaging to use export_unity_package. * Added a build target to generate the UPM archive. * Fixed merging exisitng manifest metadata with an export_unity_package generated manifest. * Fixed generated folder metadata so that it does not result in Unity reporting errors when a UPM package is imported. Bug: 150471207 Change-Id: I6fbb9da338ee2c29782226e95c17c2e485d191e7
1 parent 3bd1362 commit 900d539

23 files changed

+7561
-27
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
/plugin/obj/
2020
/plugin/plugin.sln
2121
/plugin/plugin.userprefs
22+
/source/ExportUnityPackage/__pycache__/
2223

2324
/source/.idea/
2425
/unity_dlls/

build.gradle

Lines changed: 188 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,8 @@ project.ext {
176176
buildDir = new File(scriptDirectory, "build")
177177
// Directory for testing.
178178
testDir = new File(scriptDirectory, "test_output")
179+
// Version of the plugin (update this with CHANGELOG.md on each release).
180+
pluginVersion = "1.2.144"
179181
// Directory that contains the template plugin.
180182
// Files under this directory are copied into the staging area for the
181183
// plugin.
@@ -184,9 +186,14 @@ project.ext {
184186
pluginStagingAreaDir = new File(buildDir, "staging")
185187
// Directory where the build plugin is unpacked to.
186188
pluginExplodedDir = new File(scriptDirectory, "exploded")
189+
// Base filename of the released plugin.
190+
currentPluginBasename = "external-dependency-manager"
187191
// Where the exported plugin file is built before it's copied to the release
188192
// location.
189-
pluginExportFile = new File(buildDir, "plugin.unitypackage")
193+
pluginExportFile = new File(buildDir, currentPluginBasename + ".unitypackage")
194+
// Where the exported UPM plugin file is built.
195+
pluginUpmExportFile = new File(buildDir,
196+
currentPluginBasename + pluginVersion + ".tgz")
190197
// Directory within the plugin staging area that just contains the plugin.
191198
pluginAssetsDir = new File("Assets", "ExternalDependencyManager")
192199
// Directories within the staging area to export.
@@ -198,10 +205,6 @@ project.ext {
198205
pluginSourceDir = new File(scriptDirectory, "source")
199206
// Solution which references all projects used by the plugin.
200207
pluginSolutionFile = new File(pluginSourceDir, "ExternalDependencyManager.sln")
201-
// Version of the plugin (update this with CHANGELOG.md on each release).
202-
pluginVersion = "1.2.144"
203-
// Base filename of the released plugin.
204-
currentPluginBasename = "external-dependency-manager"
205208
// Versioned release plugin file.
206209
pluginReleaseFile = new File(scriptDirectory,
207210
sprintf("%s-%s.unitypackage",
@@ -212,6 +215,12 @@ project.ext {
212215
sprintf("%s-latest.unitypackage",
213216
currentPluginBasename))
214217

218+
// Location of the Unity asset uploader application.
219+
unityAssetUploaderDir = new File(pluginSourceDir, "UnityAssetUploader")
220+
221+
// Location of the export_unity_package application.
222+
exportUnityPackageDir = new File(pluginSourceDir, "ExportUnityPackage")
223+
215224
// Common arguments used to execute Unity in batch mode.
216225
unityBatchModeArguments = ["-batchmode", "-nographics"]
217226
// Extension for Unity asset metadata files.
@@ -221,9 +230,13 @@ project.ext {
221230
// Changelog file.
222231
changelog = new File(scriptDirectory, "CHANGELOG.md")
223232
pythonBootstrapDir = new File(buildDir, "python_bootstrap")
233+
pythonBinDir = new File(new File(pythonBootstrapDir, "python"), "bin")
224234
// Python binary after it has been bootstrapped.
225-
pythonExe = new File(new File(new File(pythonBootstrapDir, "python"), "bin"),
226-
"python3")
235+
pythonExe = new File(pythonBinDir, "python3")
236+
// Pip binary after it has been bootstrapped.
237+
pipExe = new File(pythonBinDir, "pip3")
238+
// Python packages required by export_unity_package.py
239+
exportUnityPackageRequirements = ["absl-py", "PyYAML"]
227240
}
228241

229242
// Configure com.jetbrains.python.envs to bootstrap a Python install.
@@ -405,26 +418,31 @@ List<String> splitFilenameExtension(File fileObj) {
405418

406419
/*
407420
* Construct the name of a versioned asset from the source filename and version
408-
* string. The encoded string takes the form
421+
* string. If fullVersionPrefix is true, the encoded string takes the form
422+
* ${filename}_version-${version}.${extension}
423+
* if fullVersionPrefix is false, the string takes the form
409424
* ${filename}_v${version}.${extension}
410425
* where extension is derived from the specified filename.
411426
*
412427
* @param fileObj File to add version to.
428+
* @param fullVersionPrefix if true uses the "_version-" otherwise uses "_v-".
429+
* @param postfix Optional string to add before the extensioon.
413430
*
414431
* @returns File which includes an encoded version.
415432
*/
416-
File versionedAssetFile(File fileObj) {
433+
File versionedAssetFile(File fileObj, Boolean fullVersionPrefix,
434+
String postfix) {
417435
String basename
418436
String extension
419437
(basename, extension) = splitFilenameExtension(fileObj)
420438
// Encode the DLL version and target names into the DLL in the form...
421-
// ${dllname}_v${version}.dll
439+
// ${dllname}_version-${version}.dll
422440
String targetName = basename
423441
String version = project.ext.pluginVersion
424442
if (!(version == null || version.isEmpty())) {
425-
targetName += "_v" + version
443+
targetName += (fullVersionPrefix ? "_version-" : "_v") + version
426444
}
427-
String filename = targetName + extension
445+
String filename = targetName + postfix + extension
428446
return fileObj.parent != null ? new File(fileObj.parent, filename) :
429447
new File(filename)
430448
}
@@ -440,10 +458,16 @@ File unversionedAssetFile(File fileObj) {
440458
String basename
441459
String extension
442460
(basename, extension) = splitFilenameExtension(fileObj)
443-
def versionRegEx = /^(.*)_(v[^v]+)$/
444-
def versionMatch = basename =~ versionRegEx
461+
def versionRegExFull = /^(.*)_(version-[^-]+)$/
462+
def versionRegExShort = /^(.*)_(v[^v]+)$/
463+
def versionMatch = basename =~ versionRegExShort
445464
if (versionMatch.matches()) {
446465
basename = versionMatch.group(1)
466+
} else {
467+
versionMatch = basename =~ versionRegExFull
468+
if (versionMatch.matches()) {
469+
basename = versionMatch.group(1)
470+
}
447471
}
448472
String filename = basename + extension
449473
return fileObj.parent != null ?
@@ -725,7 +749,7 @@ Task createBuildPluginDllTask(String componentName,
725749
return [
726750
unversionedFile.path,
727751
versionDll ?
728-
versionedAssetFile(unversionedOutputFile) :
752+
versionedAssetFile(unversionedOutputFile, false, "") :
729753
unversionedOutputFile]
730754
}
731755

@@ -1046,6 +1070,29 @@ Task compileResolverLibTests = createXbuildTask(
10461070
doFirst { checkNUnitDllPath() }
10471071
}
10481072

1073+
/*
1074+
* Install Python packages.
1075+
*
1076+
* @param taskName Name of the task to create.
1077+
* @param description Description of the task.
1078+
* @param dependsOn Dependencies of the new task.
1079+
* @param packages Packages to install.
1080+
*
1081+
* @returns Task which executes pip to install packages
1082+
*/
1083+
Task createInstallPythonPackageTask(String taskName, String description,
1084+
Iterable<Task> dependsOn,
1085+
Iterable<String> packages) {
1086+
Task installPythonPackageTask = tasks.create(
1087+
name: taskName,
1088+
description: sprintf("Run Pip to %s", description),
1089+
type: Exec,
1090+
dependsOn: dependsOn + ["build_envs"]).with {
1091+
executable project.ext.pipExe
1092+
args (["-q", "install"] + packages)
1093+
}
1094+
}
1095+
10491096
/*
10501097
* Create a task to execute Python.
10511098
*
@@ -1054,25 +1101,87 @@ Task compileResolverLibTests = createXbuildTask(
10541101
* @param dependsOn Dependencies of the new task.
10551102
* @param script Python script to run.
10561103
* @param arguments Command line arguments to pass to the Python script.
1057-
* @param inputFiles Files that are required by the script.
1058-
* @param outputFiles Files generated by the script.
1104+
* @param packages Optional Python packages to install.
10591105
*
10601106
* @returns Task which executes Python.
10611107
*/
10621108
Task createPythonTask(String taskName, String description,
10631109
Iterable<Task> dependsOn,
1064-
File script, Iterable<String> arguments) {
1110+
File script, Iterable<String> arguments,
1111+
Iterable<String> packages) {
1112+
List<Task> installPackagesTask = []
1113+
if (packages) {
1114+
installPackagesTask = [
1115+
createInstallPythonPackageTask(
1116+
taskName + "InstallPipPackages",
1117+
sprintf("install packages %s for %s", packages.toString(), taskName),
1118+
[],
1119+
packages)
1120+
]
1121+
}
10651122
Task pythonTask = tasks.create(
10661123
name: taskName,
10671124
description: sprintf("Run Python to %s", description),
10681125
type: Exec,
1069-
dependsOn: dependsOn + ["build_envs"]).with {
1126+
dependsOn: (dependsOn + installPackagesTask + ["build_envs"])).with {
10701127
executable project.ext.pythonExe
10711128
args ([script.absolutePath] + arguments)
10721129
}
10731130
return pythonTask
10741131
}
10751132

1133+
/*
1134+
* Creates a task that packages a Unity plugin with export_unity_package.py.
1135+
*
1136+
* @param taskName Name of the task to create.
1137+
* @param description Description of the task.
1138+
* @param dependsOn Dependencies of the new task.
1139+
* @param configFile Configuration file which specifies input files.
1140+
* @param guidsFile Optional GUIDs database file.
1141+
* @param assetsDir Input directory for assets referenced by the configFile.
1142+
* @param generateUnitypackage Whether to create a .unitypackage.
1143+
* @param generateUpmTarball Whether to create a UPM tarball.
1144+
* @param pluginsVersion Version to apply to exported plugins.
1145+
* @param outputDir Directory to write the the exported archives.
1146+
* @param arguments Additional arguments for export_unity_package.py
1147+
*/
1148+
Task createExportUnityPackageTask(String taskName,
1149+
String description,
1150+
Iterable<Task> dependsOn,
1151+
File configFile,
1152+
File guidsFile,
1153+
File assetsDir,
1154+
Boolean generateUnityPackage,
1155+
Boolean generateUpmTarball,
1156+
String pluginVersion,
1157+
File outputDir,
1158+
Iterable<String> arguments) {
1159+
File exportScript = new File(project.ext.exportUnityPackageDir,
1160+
"export_unity_package.py")
1161+
Task exportUnityPackageTask = createPythonTask(
1162+
taskName,
1163+
description,
1164+
dependsOn,
1165+
exportScript,
1166+
["--config_file", configFile,
1167+
"--assets_dir", assetsDir,
1168+
"--plugins_version", pluginVersion,
1169+
"--output_dir", outputDir] +
1170+
[generateUnityPackage ?
1171+
"--output_unitypackage" : "--nooutput_unitypackage"] +
1172+
[generateUpmTarball ? "--output_upm" : "--nooutput_upm"] +
1173+
(guidsFile ? ["--guids_file", guidsFile] : []) +
1174+
arguments,
1175+
exportUnityPackageRequirements)
1176+
exportUnityPackageTask.with {
1177+
inputs.files ([configFile] +
1178+
(guidsFile ? [guidsFile] : []) +
1179+
fileTree(assetsDir) +
1180+
[exportScript])
1181+
}
1182+
return exportUnityPackageTask
1183+
}
1184+
10761185
Task testResolverLibTests = createNUnitTask(
10771186
"testResolverLibTests",
10781187
"Runs the tests for the deprecated Jar Resolver library",
@@ -1094,9 +1203,26 @@ createPythonTask(
10941203
"testPackageUploader",
10951204
"Test the unity_asset_uploader.py application.",
10961205
[],
1097-
new File(project.ext.scriptDirectory, "source/UnityAssetUploader/unity_asset_uploader_test.py"),
1206+
new File(project.ext.unityAssetUploaderDir, "unity_asset_uploader_test.py"),
1207+
[],
10981208
[])
10991209

1210+
createPythonTask(
1211+
"testExportUnityPackage",
1212+
"Test the export_unity_package.py application",
1213+
[],
1214+
new File(project.ext.exportUnityPackageDir, "export_unity_package_test.py"),
1215+
[],
1216+
exportUnityPackageRequirements)
1217+
1218+
createPythonTask(
1219+
"testGenGuids",
1220+
"Test the gen_guids.py application",
1221+
[],
1222+
new File(project.ext.exportUnityPackageDir, "gen_guids_test.py"),
1223+
[],
1224+
["absl-py"])
1225+
11001226
task updateEmbeddedGradleWrapper(type: Zip) {
11011227
description "Update the gradle wrapper in gradle-template.zip"
11021228
from project.ext.scriptDirectory
@@ -1219,9 +1345,9 @@ task generatePluginManifest(dependsOn: [preparePluginStagingAreaDir,
12191345
project.ext.pluginEditorDllDir.path),
12201346
unversionedManifestName + project.ext.unityMetadataExtension)
12211347
File manifestFile = versionedAssetFile(
1222-
new File(outputDir, unversionedManifestName))
1348+
new File(outputDir, unversionedManifestName), true, "_manifest")
12231349
File manifestMetadataFile = versionedAssetFile(
1224-
new File(outputDir, manifestMetadataTemplateFile.name))
1350+
new File(outputDir, manifestMetadataTemplateFile.name), true, "_manifest")
12251351

12261352
description "Generate a manifest for the files in the plug-in."
12271353
inputs.files files(manifestMetadataTemplateFile)
@@ -1246,8 +1372,9 @@ task generatePluginManifest(dependsOn: [preparePluginStagingAreaDir,
12461372
}
12471373
}
12481374

1249-
Task buildPlugin = createUnityTask(
1250-
"buildPlugin", "build_plugin", [generatePluginManifest],
1375+
// Deprecated target for packaging the plugin.
1376+
Task buildPluginWithUnity = createUnityTask(
1377+
"buildPluginWithUnity", "build_plugin", [generatePluginManifest],
12511378
project.ext.pluginStagingAreaDir.name,
12521379
project.ext.buildDir,
12531380
["-g.building",
@@ -1256,13 +1383,46 @@ Task buildPlugin = createUnityTask(
12561383
[project.ext.pluginExportFile.absolutePath,
12571384
"-gvh_disable",
12581385
"-quit"], true, null)
1259-
buildPlugin.with {
1260-
description "Exports the plugin staging area directory as a Unity package."
1386+
buildPluginWithUnity.with {
1387+
description ("(Deprecated) Exports the plugin staging area directory as " +
1388+
"a Unity package.")
12611389
inputs.files files(copyPluginTemplateToStagingArea.outputs.files,
12621390
copyPluginComponentsToStagingArea.outputs.files)
12631391
outputs.files files(project.ext.pluginExportFile)
12641392
}
12651393

1394+
Task buildPlugin = createExportUnityPackageTask(
1395+
"buildPlugin",
1396+
"Package the .unitypackage with export_unity_package.py.",
1397+
[generatePluginManifest],
1398+
new File(project.ext.scriptDirectory, "export_unity_package_config.json"),
1399+
new File(project.ext.scriptDirectory, "export_unity_package_guids.json"),
1400+
new File(project.ext.pluginStagingAreaDir, "Assets"),
1401+
true, // Enable .unitypackage export.
1402+
false, // Disable UPM export.
1403+
project.ext.pluginVersion,
1404+
project.ext.pluginExportFile.parentFile,
1405+
["--enabled_sections", "unitypackage"])
1406+
buildPlugin.with {
1407+
outputs.files project.ext.pluginExportFile.absolutePath
1408+
}
1409+
1410+
Task buildUpmPlugin = createExportUnityPackageTask(
1411+
"buildUpmPlugin",
1412+
"Package the .unitypackage with export_unity_package.py.",
1413+
[generatePluginManifest],
1414+
new File(project.ext.scriptDirectory, "export_unity_package_config.json"),
1415+
new File(project.ext.scriptDirectory, "export_unity_package_guids.json"),
1416+
new File(project.ext.pluginStagingAreaDir, "Assets"),
1417+
false, // Disable .unitypackage export.
1418+
true, // Enable UPM export.
1419+
project.ext.pluginVersion,
1420+
project.ext.pluginUpmExportFile.parentFile,
1421+
[])
1422+
buildUpmPlugin.with {
1423+
outputs.files project.ext.pluginUpmExportFile.absolutePath
1424+
}
1425+
12661426
task releasePlugin(dependsOn: buildPlugin) {
12671427
Map<File, File> pluginTemplateFilesMap = files(
12681428
copyPluginTemplateToStagingArea.outputs.files,
@@ -1468,7 +1628,8 @@ createUnityTestBatchAndNonBatch(
14681628
"VersionHandlerImpl"),
14691629
"test"),
14701630
"webrequest_launcher.py"),
1471-
runnerArgs)
1631+
runnerArgs,
1632+
[])
14721633
})
14731634

14741635
createUnityTestBatchAndNonBatch(

0 commit comments

Comments
 (0)