Skip to content

Commit 138a575

Browse files
author
Stewart Miles
committed
Refactored Gradle wrapper interface into its own class.
Moved logic that unpacks and uses the Gradle wrapper from GradleResolver into a seperate class so that it can be reused by other modules. Bug: 135269831, 135273820 Change-Id: I5d71eea8af8a57dccba979d5151d0703cfbe5abf
1 parent 83ab07e commit 138a575

File tree

4 files changed

+273
-139
lines changed

4 files changed

+273
-139
lines changed

source/PlayServicesResolver/PlayServicesResolver.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
<Compile Include="src\EmbeddedResource.cs" />
6363
<Compile Include="src\GradleResolver.cs" />
6464
<Compile Include="src\GradleTemplateResolver.cs" />
65+
<Compile Include="src\GradleWrapper.cs" />
6566
<Compile Include="src\LocalMavenRepository.cs" />
6667
<Compile Include="src\JavaUtilities.cs" />
6768
<Compile Include="src\PlayServicesPreBuild.cs" />

source/PlayServicesResolver/src/GradleResolver.cs

Lines changed: 28 additions & 139 deletions
Original file line numberDiff line numberDiff line change
@@ -199,20 +199,10 @@ public override string ToString() {
199199
private string aarExplodeDataFile = Path.Combine(FileUtils.ProjectTemporaryDirectory,
200200
"GoogleAarExplodeCache.xml");
201201

202-
// Directory used to execute Gradle.
203-
private string gradleBuildDirectory = Path.Combine(FileUtils.ProjectTemporaryDirectory,
204-
"PlayServicesResolverGradle");
205-
206202
private const int MajorVersion = 1;
207203
private const int MinorVersion = 1;
208204
private const int PointVersion = 0;
209205

210-
// Characters that are parsed by Gradle / Java in property values.
211-
// These characters need to be escaped to be correctly interpreted in a property value.
212-
private static string[] GradlePropertySpecialCharacters = new string[] {
213-
" ", "\\", "#", "!", "=", ":"
214-
};
215-
216206
// Special characters that should not be escaped in URIs for Gradle property values.
217207
private static HashSet<string> GradleUriExcludeEscapeCharacters = new HashSet<string> {
218208
":"
@@ -469,51 +459,6 @@ private void LogMissingDependenciesError(List<string> missingArtifacts) {
469459
}
470460
}
471461

472-
/// <summary>
473-
/// Escape all special characters in a gradle property value.
474-
/// </summary>
475-
/// <param name="value">Value to escape.</param>
476-
/// <param name="escapeFunc">Function which generates an escaped character. By default
477-
/// this adds "\\" to each escaped character.</param>
478-
/// <param name="charactersToExclude">Characters to exclude from the escaping set.</param>
479-
/// <returns>Escaped value.</returns>
480-
private static string EscapeGradlePropertyValue(
481-
string value, Func<string, string> escapeFunc = null,
482-
HashSet<string> charactersToExclude = null) {
483-
if (escapeFunc == null) {
484-
escapeFunc = (characterToEscape) => { return "\\" + characterToEscape; };
485-
}
486-
foreach (var characterToEscape in GradlePropertySpecialCharacters) {
487-
if (charactersToExclude == null ||
488-
!(charactersToExclude.Contains(characterToEscape))) {
489-
value = value.Replace(characterToEscape, escapeFunc(characterToEscape));
490-
}
491-
}
492-
return value;
493-
}
494-
495-
/// <summary>
496-
/// Generates a Gradle (Java) properties string from a dictionary of key value pairs.
497-
/// Details of the format is documented in
498-
/// http://docs.oracle.com/javase/7/docs/api/java/util/Properties.html#\
499-
/// store%28java.io.Writer,%20java.lang.String%29
500-
/// </summary>
501-
/// <param name="properties">Properties to generate a string from. Each value must not
502-
/// contain a newline.</param>
503-
/// <returns>String with Gradle (Java) properties</returns>
504-
private string GenerateGradleProperties(Dictionary<string, string> properties) {
505-
var lines = new List<string>();
506-
foreach (var kv in properties) {
507-
var escapedKey = kv.Key.Replace(" ", "\\ ");
508-
var elementAfterLeadingWhitespace = kv.Value.TrimStart(new [] { ' ' });
509-
var escapedElement =
510-
kv.Value.Substring(elementAfterLeadingWhitespace.Length).Replace(" ", "\\ ") +
511-
EscapeGradlePropertyValue(elementAfterLeadingWhitespace);
512-
lines.Add(String.Format("{0}={1}", escapedKey, escapedElement));
513-
}
514-
return String.Join("\n", lines.ToArray());
515-
}
516-
517462
/// <summary>
518463
/// From a list of dependencies generate a list of Maven / Gradle / Ivy package spec
519464
/// strings.
@@ -589,9 +534,9 @@ internal static string RepoPathToUri(string repoPath, string sourceLocation=null
589534
}
590535
// Escape the URI to handle special characters like spaces and percent escape
591536
// all characters that are interpreted by gradle.
592-
return EscapeGradlePropertyValue(Uri.EscapeUriString(repoPath),
593-
escapeFunc: Uri.EscapeDataString,
594-
charactersToExclude: GradleUriExcludeEscapeCharacters);
537+
return GradleWrapper.EscapeGradlePropertyValue(
538+
Uri.EscapeUriString(repoPath), escapeFunc: Uri.EscapeDataString,
539+
charactersToExclude: GradleUriExcludeEscapeCharacters);
595540
}
596541

597542
/// <summary>
@@ -675,69 +620,26 @@ private void GradleResolution(
675620
var allDependencies = PlayServicesSupport.GetAllDependencies();
676621
var allDependenciesList = new List<Dependency>(allDependencies.Values);
677622

678-
// Namespace for resources under the src/scripts directory embedded within this
679-
// assembly.
680-
const string EMBEDDED_RESOURCES_NAMESPACE = "PlayServicesResolver.scripts.";
681-
var gradleWrapper = Path.GetFullPath(Path.Combine(
682-
gradleBuildDirectory,
683-
UnityEngine.RuntimePlatform.WindowsEditor == UnityEngine.Application.platform ?
684-
"gradlew.bat" : "gradlew"));
623+
var gradleWrapper = PlayServicesResolver.Gradle;
685624
var buildScript = Path.GetFullPath(Path.Combine(
686-
gradleBuildDirectory, EMBEDDED_RESOURCES_NAMESPACE + "download_artifacts.gradle"));
687-
var gradleTemplateZip = Path.Combine(
688-
gradleBuildDirectory, EMBEDDED_RESOURCES_NAMESPACE + "gradle-template.zip");
625+
gradleWrapper.BuildDirectory,
626+
PlayServicesResolver.EMBEDDED_RESOURCES_NAMESPACE + "download_artifacts.gradle"));
689627

690628
// Extract the gradle wrapper and build script.
691-
if (!EmbeddedResource.ExtractResources(
692-
typeof(GradleResolver).Assembly,
693-
new KeyValuePair<string, string>[] {
694-
new KeyValuePair<string, string>(null, gradleTemplateZip),
695-
new KeyValuePair<string, string>(null, buildScript),
696-
}, PlayServicesResolver.logger)) {
629+
if (!(gradleWrapper.Extract(PlayServicesResolver.logger) &&
630+
EmbeddedResource.ExtractResources(typeof(GradleResolver).Assembly,
631+
new KeyValuePair<string, string>[] {
632+
new KeyValuePair<string, string>(
633+
null, buildScript),
634+
}, PlayServicesResolver.logger))) {
697635
PlayServicesResolver.Log(String.Format(
698636
"Failed to extract {0} and {1} from assembly {2}",
699-
gradleTemplateZip, buildScript, typeof(GradleResolver).Assembly.FullName),
637+
gradleWrapper.Executable, buildScript,
638+
typeof(GradleResolver).Assembly.FullName),
700639
level: LogLevel.Error);
701640
resolutionComplete(allDependenciesList);
702641
return;
703642
}
704-
705-
// Extract Gradle wrapper and the build script to the build directory.
706-
if (PlayServicesResolver.ExtractZip(
707-
gradleTemplateZip, new [] {
708-
"gradle/wrapper/gradle-wrapper.jar",
709-
"gradle/wrapper/gradle-wrapper.properties",
710-
"gradlew",
711-
"gradlew.bat"},
712-
gradleBuildDirectory, true)) {
713-
// Files extracted from the zip file don't have the executable bit set on some
714-
// platforms, so set it here.
715-
// Unfortunately, File.GetAccessControl() isn't implemented, so we'll use
716-
// chmod (OSX / Linux) and on Windows extracted files are executable by default
717-
// so we do nothing.
718-
if (UnityEngine.RuntimePlatform.WindowsEditor !=
719-
UnityEngine.Application.platform) {
720-
var result = CommandLine.Run("chmod",
721-
String.Format("ug+x \"{0}\"", gradleWrapper));
722-
if (result.exitCode != 0) {
723-
PlayServicesResolver.Log(
724-
String.Format("Failed to make \"{0}\" executable.\n\n" +
725-
"Resolution failed.\n\n{1}", gradleWrapper,
726-
result.message),
727-
level: LogLevel.Error);
728-
resolutionComplete(allDependenciesList);
729-
return;
730-
}
731-
}
732-
} else {
733-
PlayServicesResolver.Log(
734-
String.Format("Unable to extract Gradle build component {0}\n\n" +
735-
"Resolution failed.", gradleTemplateZip),
736-
level: LogLevel.Error);
737-
resolutionComplete(allDependenciesList);
738-
return;
739-
}
740-
741643
// Build array of repos to search, they're interleaved across all dependencies as the
742644
// order matters.
743645
var repoList = new List<string>();
@@ -964,7 +866,6 @@ private void GradleResolution(
964866
if (String.IsNullOrEmpty(androidGradlePluginVersion)) {
965867
androidGradlePluginVersion = "2.3.0";
966868
}
967-
968869
var gradleProjectProperties = new Dictionary<string, string>() {
969870
{ "ANDROID_HOME", androidSdkPath },
970871
{ "TARGET_DIR", Path.GetFullPath(destinationDirectory) },
@@ -973,29 +874,6 @@ private void GradleResolution(
973874
{ "USE_JETIFIER", SettingsDialog.UseJetifier ? "1" : "0" },
974875
{ "DATA_BINDING_VERSION", androidGradlePluginVersion }
975876
};
976-
var gradleArguments = new List<string> {
977-
String.Format("-b \"{0}\"", buildScript),
978-
SettingsDialog.UseGradleDaemon ? "--daemon" : "--no-daemon",
979-
};
980-
foreach (var kv in gradleProjectProperties) {
981-
gradleArguments.Add(String.Format("\"-P{0}={1}\"", kv.Key, kv.Value));
982-
}
983-
var gradleArgumentsString = String.Join(" ", gradleArguments.ToArray());
984-
985-
// Generate gradle.properties to set properties in the script rather than using
986-
// the command line.
987-
// Some users of Windows 10 systems have had issues running the Gradle resolver
988-
// which is suspected to be caused by command line argument parsing.
989-
// Using both gradle.properties and properties specified via command line arguments
990-
// works fine.
991-
File.WriteAllText(Path.Combine(gradleBuildDirectory, "gradle.properties"),
992-
GenerateGradleProperties(gradleProjectProperties));
993-
994-
PlayServicesResolver.Log(String.Format("Running dependency fetching script\n" +
995-
"\n" +
996-
"{0} {1}\n",
997-
gradleWrapper, gradleArgumentsString),
998-
level: LogLevel.Verbose);
999877

1000878
// Run the build script to perform the resolution popping up a window in the editor.
1001879
window.summaryText = "Resolving Android Dependencies...";
@@ -1004,11 +882,22 @@ private void GradleResolution(
1004882
window.autoScrollToBottom = true;
1005883
window.logger = PlayServicesResolver.logger;
1006884
var maxProgressLines = (allDependenciesList.Count * 10) + 50;
1007-
window.RunAsync(gradleWrapper, gradleArgumentsString,
885+
886+
if (gradleWrapper.Run(
887+
SettingsDialog.UseGradleDaemon, buildScript, gradleProjectProperties,
888+
null, PlayServicesResolver.logger,
889+
(string toolPath, string arguments) => {
890+
window.RunAsync(
891+
toolPath, arguments,
1008892
(result) => { RunOnMainThread.Run(() => { gradleComplete(result); }); },
1009-
workingDirectory: gradleBuildDirectory,
893+
workingDirectory: gradleWrapper.BuildDirectory,
1010894
maxProgressLines: maxProgressLines);
1011-
window.Show();
895+
return true;
896+
})) {
897+
window.Show();
898+
} else {
899+
resolutionComplete(allDependenciesList);
900+
}
1012901
}
1013902

1014903
/// <summary>

0 commit comments

Comments
 (0)