From 47832f1878e30446eebdafaf1f8b1ac5903bdca9 Mon Sep 17 00:00:00 2001 From: Jonathan Pryor Date: Mon, 13 Jun 2022 06:15:13 -0400 Subject: [PATCH] [Xamarin.Android.Tools.AndroidSdk] AndroidSdkInfo validation locator (#170) Context: https://github.com/xamarin/xamarin-android/pull/7073 Context: https://github.com/xamarin/xamarin-android/blob/fdfc4c44ba65fcff9caf809bcf2d1f1a6837b1e3/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/AndroidDependenciesTests.cs#L19-L50 I was trying to figure out how xamarin-android's `AndroidDependenciesTests.InstallAndroidDependenciesTest()` *passes*; the test creates an empty "SDK" directory, then builds with the `InstallAndroidDependencies` target, then builds the `Build` target, then asserts that the used SDK directory matches the "temp" directory. The cause of the confusion was twofold: 1. Two targets were run, but they both wrote to the same log file, and thus any output from the `InstallAndroidDependencies` target was *lost*, which meant 2. When reviewing the output of the `Build` target -- the *only* output for quite some time -- I started searching for "other possibilities" for why it would work, e.g. "it's not using the constructor parameter, but rather `monodroid-config.xml`", which needed to be separately investigated and discarded. The investigation is done -- the problems were that the log file needed to understand what was going wrong didn't exist, and that the `platform-tools` 32.0.0 package didn't exist in the GoogleV2 manifest, and thus `platform-tools` wasn't installed, and thus `adb` wasn't found, causing `ValidateAndroidSdkLocation()` to skip it -- but the additional contextual log information could be useful for future investigations. Expand the log messages provided by `AndroidSdkBase` & co. so that we also log "where" the `loc` parameter is coming from, via a new `locator` parameter (similar to the `locator` parameter in `JdkInfo`), and update the "file check" logic so that we log the path of the detected files. --- .../Sdks/AndroidSdkBase.cs | 50 ++++++++++++------- .../Sdks/AndroidSdkUnix.cs | 6 +-- .../Sdks/AndroidSdkWindows.cs | 2 +- 3 files changed, 37 insertions(+), 21 deletions(-) diff --git a/src/Xamarin.Android.Tools.AndroidSdk/Sdks/AndroidSdkBase.cs b/src/Xamarin.Android.Tools.AndroidSdk/Sdks/AndroidSdkBase.cs index 2f03b6e..04e98c6 100644 --- a/src/Xamarin.Android.Tools.AndroidSdk/Sdks/AndroidSdkBase.cs +++ b/src/Xamarin.Android.Tools.AndroidSdk/Sdks/AndroidSdkBase.cs @@ -26,7 +26,7 @@ public string[] AllAndroidSdks { var dirs = new List (); dirs.Add (AndroidSdkPath); dirs.AddRange (GetAllAvailableAndroidSdks ()); - allAndroidSdks = dirs.Where (d => ValidateAndroidSdkLocation (d)) + allAndroidSdks = dirs.Where (d => ValidateAndroidSdkLocation ("AllAndroidSdks", d)) .Select (d => d!) .Distinct () .ToArray (); @@ -102,15 +102,15 @@ public virtual void Initialize (string? androidSdkPath = null, string? androidNd NdkStack = GetExecutablePath (AndroidNdkPath, NdkStack); } - static string? GetValidPath (Func pathValidator, string? ctorParam, Func getPreferredPath, Func> getAllPaths) + static string? GetValidPath (Func pathValidator, string? ctorParam, Func getPreferredPath, Func> getAllPaths) { - if (pathValidator (ctorParam)) + if (pathValidator ("constructor param", ctorParam)) return ctorParam; ctorParam = getPreferredPath (); - if (pathValidator (ctorParam)) + if (pathValidator ("preferred path", ctorParam)) return ctorParam; foreach (var path in getAllPaths ()) { - if (pathValidator (path)) { + if (pathValidator ("all paths", path)) { return path; } } @@ -119,18 +119,18 @@ public virtual void Initialize (string? androidSdkPath = null, string? androidNd string? GetValidNdkPath (string? ctorParam) { - if (ValidateAndroidNdkLocation (ctorParam)) + if (ValidateAndroidNdkLocation ("constructor param", ctorParam)) return ctorParam; if (AndroidSdkPath != null) { string bundle = FindBestNDK (AndroidSdkPath); - if (Directory.Exists (bundle) && ValidateAndroidNdkLocation (bundle)) + if (Directory.Exists (bundle) && ValidateAndroidNdkLocation ("within Android SDK", bundle)) return bundle; } ctorParam = PreferedAndroidNdkPath; - if (ValidateAndroidNdkLocation (ctorParam)) + if (ValidateAndroidNdkLocation ("preferred path", ctorParam)) return ctorParam; foreach (var path in GetAllAvailableAndroidNdks ()) { - if (ValidateAndroidNdkLocation (path)) + if (ValidateAndroidNdkLocation ("all paths", path)) return path; } return null; @@ -255,31 +255,47 @@ IEnumerable GetJavaSdkPaths () /// /// Checks that a value is the location of an Android SDK. /// - public bool ValidateAndroidSdkLocation ([NotNullWhen (true)] string? loc) + public bool ValidateAndroidSdkLocation (string locator, [NotNullWhen (true)] string? loc) { - bool result = !string.IsNullOrEmpty (loc) && ProcessUtils.FindExecutablesInDirectory (Path.Combine (loc, "platform-tools"), Adb).Any (); - Logger (TraceLevel.Verbose, $"{nameof (ValidateAndroidSdkLocation)}: `{loc}`, result={result}"); + bool result = !string.IsNullOrEmpty (loc); + if (result) { + bool foundAdb = false; + foreach (var p in ProcessUtils.FindExecutablesInDirectory (Path.Combine (loc!, "platform-tools"), Adb)) { + Logger (TraceLevel.Verbose, $"{nameof (ValidateAndroidSdkLocation)}: for locator={locator}, path=`{loc}`, found adb `{p}`"); + foundAdb = true; + } + result = foundAdb; + } + Logger (TraceLevel.Verbose, $"{nameof (ValidateAndroidSdkLocation)}: for locator={locator}, path=`{loc}`, result={result}"); return result; } /// /// Checks that a value is the location of a Java SDK. /// - public virtual bool ValidateJavaSdkLocation ([NotNullWhen (true)] string? loc) + public virtual bool ValidateJavaSdkLocation (string locator, [NotNullWhen (true)] string? loc) { - bool result = !string.IsNullOrEmpty (loc) && ProcessUtils.FindExecutablesInDirectory (Path.Combine (loc, "bin"), JarSigner).Any (); - Logger (TraceLevel.Verbose, $"{nameof (ValidateJavaSdkLocation)}: `{loc}`, result={result}"); + bool result = !string.IsNullOrEmpty (loc); + if (result) { + bool foundSigner = false; + foreach (var p in ProcessUtils.FindExecutablesInDirectory (Path.Combine (loc!, "bin"), JarSigner)) { + Logger (TraceLevel.Verbose, $"{nameof (ValidateJavaSdkLocation)}: for locator={locator}, path=`{loc}`, found jarsigner `{p}`"); + foundSigner = true; + } + result = foundSigner; + } + Logger (TraceLevel.Verbose, $"{nameof (ValidateJavaSdkLocation)}: locator={locator}, path=`{loc}`, result={result}"); return result; } /// /// Checks that a value is the location of an Android SDK. /// - public bool ValidateAndroidNdkLocation ([NotNullWhen (true)] string? loc) + public bool ValidateAndroidNdkLocation (string locator, [NotNullWhen (true)] string? loc) { bool result = !string.IsNullOrEmpty (loc) && ProcessUtils.FindExecutablesInDirectory (loc!, NdkStack).Any (); - Logger (TraceLevel.Verbose, $"{nameof (ValidateAndroidNdkLocation)}: `{loc}`, result={result}"); + Logger (TraceLevel.Verbose, $"{nameof (ValidateAndroidNdkLocation)}: for locator={locator}, path=`{loc}`, result={result}"); return result; } diff --git a/src/Xamarin.Android.Tools.AndroidSdk/Sdks/AndroidSdkUnix.cs b/src/Xamarin.Android.Tools.AndroidSdk/Sdks/AndroidSdkUnix.cs index e3b8aba..f21bc65 100644 --- a/src/Xamarin.Android.Tools.AndroidSdk/Sdks/AndroidSdkUnix.cs +++ b/src/Xamarin.Android.Tools.AndroidSdk/Sdks/AndroidSdkUnix.cs @@ -51,7 +51,7 @@ public override string? PreferedAndroidSdkPath { if (androidEl != null) { var path = (string?)androidEl.Attribute ("path"); - if (ValidateAndroidSdkLocation (path)) + if (ValidateAndroidSdkLocation ("preferred path", path)) return path; } return null; @@ -66,7 +66,7 @@ public override string? PreferedAndroidNdkPath { if (androidEl != null) { var path = (string?)androidEl.Attribute ("path"); - if (ValidateAndroidNdkLocation (path)) + if (ValidateAndroidNdkLocation ("preferred path", path)) return path; } return null; @@ -81,7 +81,7 @@ public override string? PreferedJavaSdkPath { if (javaEl != null) { var path = (string?)javaEl.Attribute ("path"); - if (ValidateJavaSdkLocation (path)) + if (ValidateJavaSdkLocation ("preferred path", path)) return path; } return null; diff --git a/src/Xamarin.Android.Tools.AndroidSdk/Sdks/AndroidSdkWindows.cs b/src/Xamarin.Android.Tools.AndroidSdk/Sdks/AndroidSdkWindows.cs index c330984..e1d9404 100644 --- a/src/Xamarin.Android.Tools.AndroidSdk/Sdks/AndroidSdkWindows.cs +++ b/src/Xamarin.Android.Tools.AndroidSdk/Sdks/AndroidSdkWindows.cs @@ -145,7 +145,7 @@ protected override IEnumerable GetAllAvailableAndroidNdks () foreach (var basePath in new string [] {xamarin_private, android_default, vs_default, vs_default32bit, vs_2017_default, cdrive_default}) if (Directory.Exists (basePath)) foreach (var dir in Directory.GetDirectories (basePath, "android-ndk-r*")) - if (ValidateAndroidNdkLocation (dir)) + if (ValidateAndroidNdkLocation ("Windows known NDK path", dir)) yield return dir; foreach (var dir in base.GetAllAvailableAndroidNdks ()) {