diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b0309d39..078c3baa 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -156,14 +156,14 @@ jobs: - manifest: 'manifests/uno.ui.manifest.json' manifest_name: Stable Upgrade - previous_tool_version: 1.4.2 + previous_tool_version: 1.17.0 previous_tool_params: '' os: macos-11 dotnet_version: 7.0.403 - manifest: 'manifests/uno.ui-preview.manifest.json' manifest_name: Preview Upgrade - previous_tool_version: 1.4.2 + previous_tool_version: 1.17.0 previous_tool_params: '--pre' os: macos-11 dotnet_version: 7.0.403 @@ -196,14 +196,14 @@ jobs: - manifest: 'manifests/uno.ui.manifest.json' manifest_name: Stable Upgrade - previous_tool_version: 1.4.2 + previous_tool_version: 1.17.0 previous_tool_params: '' os: macos-12 dotnet_version: 7.0.403 - manifest: 'manifests/uno.ui-preview.manifest.json' manifest_name: Preview Upgrade - previous_tool_version: 1.4.2 + previous_tool_version: 1.17.0 previous_tool_params: '--pre' os: macos-12 dotnet_version: 7.0.403 @@ -215,6 +215,12 @@ jobs: # os: macos-12 # dotnet_version: 8.0.100 + # Disabled for android emulator setup issues + # - manifest: 'manifests/uno.ui.manifest.json' + # manifest_name: Stable + # os: macos-13 + # dotnet_version: 7.0.403 + runs-on: ${{ matrix.os }} steps: @@ -337,6 +343,11 @@ jobs: useConfigFile: true configFilePath: gitversion.yml + - uses: actions/setup-java@v3 + with: + distribution: 'microsoft' # See 'Supported distributions' for available options + java-version: '11' + - name: Install GTK+3 shell: pwsh run: | diff --git a/UnoCheck/CheckCommand.cs b/UnoCheck/CheckCommand.cs index 987ebfcc..cd834af2 100644 --- a/UnoCheck/CheckCommand.cs +++ b/UnoCheck/CheckCommand.cs @@ -314,7 +314,7 @@ public override async Task ExecuteAsync(CommandContext context, CheckSettin private async Task NeedsToolUpdateAsync(CheckSettings settings) { - if (settings.Manifest is not null && !settings.CI) + if ( (settings.Manifest is not null && !settings.CI) || Debugger.IsAttached) { return false; } diff --git a/UnoCheck/Checkups/AndroidEmulatorCheckup.cs b/UnoCheck/Checkups/AndroidEmulatorCheckup.cs index 99c07c8c..10d73d74 100644 --- a/UnoCheck/Checkups/AndroidEmulatorCheckup.cs +++ b/UnoCheck/Checkups/AndroidEmulatorCheckup.cs @@ -22,7 +22,7 @@ public IEnumerable RequiredEmulators => Manifest?.Check?.Android?.Emulators; public override bool IsPlatformSupported(Platform platform) - => platform == Platform.OSX || platform == Platform.Windows; + => platform == Platform.OSX || platform == Platform.Windows || platform == Platform.Linux; public override string Id => "androidemulator"; @@ -57,6 +57,11 @@ public override Task Examine(SharedState history) history.GetEnvironmentVariable("ANDROID_SDK_ROOT") ?? history.GetEnvironmentVariable("ANDROID_HOME")); avds.AddRange(avdManager.ListAvds()); } + else + { + return Task.FromResult( + new DiagnosticResult(Status.Error, this, $"Unable to find Java {java}")); + } // Fallback to manually reading the avd files if (!avds.Any()) @@ -87,6 +92,10 @@ public override Task Examine(SharedState history) preferredDevice = devices.FirstOrDefault(d => d.Name.Contains("pixel", StringComparison.OrdinalIgnoreCase)); } + else + { + ReportStatus($"Unable to find AVD manager", Status.Ok); + } } catch (Exception ex) { diff --git a/UnoCheck/Checkups/AndroidSdkCheckup.cs b/UnoCheck/Checkups/AndroidSdkCheckup.cs index ef0f242c..d747922d 100644 --- a/UnoCheck/Checkups/AndroidSdkCheckup.cs +++ b/UnoCheck/Checkups/AndroidSdkCheckup.cs @@ -27,7 +27,7 @@ public IEnumerable RequiredPackages List temporaryFiles = new List(); public override bool IsPlatformSupported(Platform platform) - => platform == Platform.OSX || platform == Platform.Windows; + => platform == Platform.OSX || platform == Platform.Windows || platform == Platform.Linux; public override bool ShouldExamine(SharedState history) => RequiredPackages?.Any() ?? false; diff --git a/UnoCheck/Checkups/DotNetSdkCheckupContributor.cs b/UnoCheck/Checkups/DotNetSdkCheckupContributor.cs index 9866b886..d2a2f36e 100644 --- a/UnoCheck/Checkups/DotNetSdkCheckupContributor.cs +++ b/UnoCheck/Checkups/DotNetSdkCheckupContributor.cs @@ -27,10 +27,7 @@ public override IEnumerable Contribute(Manifest.Manifest manifest, Shar if (sdk.Workloads?.Any() ?? false) { - if (NuGetVersion.Parse(sdkVersion) >= Manifest.DotNetSdk.Version6Preview7) - yield return new DotNetWorkloadsCheckup(sharedState, sdkVersion, workloads, pkgSrcs); - else - yield return new DotNetWorkloadsCheckupLegacy(sharedState, sdkVersion, workloads, pkgSrcs); + yield return new DotNetWorkloadsCheckup(sharedState, sdkVersion, workloads, pkgSrcs); } } } diff --git a/UnoCheck/Checkups/DotNetWorkloadsCheckup.cs b/UnoCheck/Checkups/DotNetWorkloadsCheckup.cs index e54bb9b4..bd26f537 100644 --- a/UnoCheck/Checkups/DotNetWorkloadsCheckup.cs +++ b/UnoCheck/Checkups/DotNetWorkloadsCheckup.cs @@ -24,7 +24,7 @@ public DotNetWorkloadsCheckup(SharedState sharedState, string sdkVersion, Manife SdkRoot = dotnet.DotNetSdkLocation.FullName; SdkVersion = sdkVersion; - RequiredWorkloads = requiredWorkloads; + RequiredWorkloads = requiredWorkloads.Where(w => w.SupportedPlatforms?.Contains(Util.Platform) ?? false).ToArray(); NuGetPackageSources = nugetPackageSources; } @@ -68,7 +68,7 @@ public override async Task Examine(SharedState history) var missingWorkloads = new List(); - foreach (var rp in RequiredWorkloads.Where(w => w.SupportedPlatforms?.Contains(Util.Platform) ?? false)) + foreach (var rp in RequiredWorkloads) { var versionParts = rp.Version.Split("/", StringSplitOptions.None); var workloadVersion = versionParts.First(); diff --git a/UnoCheck/Checkups/DotNetWorkloadsCheckupLegacy.cs b/UnoCheck/Checkups/DotNetWorkloadsCheckupLegacy.cs deleted file mode 100644 index 2baa2d17..00000000 --- a/UnoCheck/Checkups/DotNetWorkloadsCheckupLegacy.cs +++ /dev/null @@ -1,89 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using DotNetCheck.DotNet; -using DotNetCheck.Models; -using DotNetCheck.Solutions; -using Microsoft.NET.Sdk.WorkloadManifestReader; -using NuGet.Versioning; - -namespace DotNetCheck.Checkups -{ - public class DotNetWorkloadsCheckupLegacy : Checkup - { - public DotNetWorkloadsCheckupLegacy() : base() - { - throw new Exception("Do not IOC this type directly"); - } - - public DotNetWorkloadsCheckupLegacy(SharedState sharedState, string sdkVersion, Manifest.DotNetWorkload[] requiredWorkloads, params string[] nugetPackageSources) : base() - { - var dotnet = new DotNetSdk(sharedState); - - SdkRoot = dotnet.DotNetSdkLocation.FullName; - SdkVersion = sdkVersion; - RequiredWorkloads = requiredWorkloads; - NuGetPackageSources = nugetPackageSources; - } - - public readonly string SdkRoot; - public readonly string SdkVersion; - public readonly string[] NuGetPackageSources; - public readonly Manifest.DotNetWorkload[] RequiredWorkloads; - - public override IEnumerable DeclareDependencies(IEnumerable checkupIds) - => new [] { new CheckupDependency("dotnet") }; - - public override string Id => "dotnetworkloads-" + SdkVersion; - - public override string Title => $".NET SDK - Workloads ({SdkVersion})"; - - public override Task Examine(SharedState history) - { - if (!history.TryGetEnvironmentVariable("DOTNET_SDK_VERSION", out var sdkVersion)) - sdkVersion = SdkVersion; - - var workloadManager = new DotNetWorkloadManagerLegacy(SdkRoot, sdkVersion, NuGetPackageSources); - - //var installedWorkloads = workloadManager.GetInstalledWorkloads(); - - // This is a bit of a hack where we manually check the sdk-manifests/{SDK_VERSION}/* folders - // for installed workloads, and then go manually parse the manifest json - // as well as look for a .nuspec file from the extracted nupkg when it was installed - // the nuspec file contains the version we actually care about for now since the manifest json - // has a long number which is meaningless right now and will eventually be changed to a string - // when that happens we can use the actual resolver's method to get installed workload info - var installedPackageWorkloads = workloadManager.GetInstalledWorkloads(); - - var missingWorkloads = new List(); - - foreach (var rp in RequiredWorkloads) - { - if (!NuGetVersion.TryParse(rp.Version, out var rpVersion)) - rpVersion = new NuGetVersion(0, 0, 0); - - // TODO: Eventually check actual workload resolver api for installed workloads and - // compare the manifest version once it has a string in it - if (!installedPackageWorkloads.Any(ip => ip.id.Equals(rp.Id, StringComparison.OrdinalIgnoreCase) && NuGetVersion.TryParse(ip.version, out var ipVersion) && ipVersion == rpVersion)) - { - ReportStatus($"{rp.Id} ({rp.PackageId} : {rp.Version}) not installed.", Status.Error); - missingWorkloads.Add(rp); - } - else - { - ReportStatus($"{rp.Id} ({rp.PackageId} : {rp.Version}) installed.", Status.Ok); - } - } - - if (!missingWorkloads.Any()) - return Task.FromResult(DiagnosticResult.Ok(this)); - - return Task.FromResult(new DiagnosticResult( - Status.Error, - this, - new Suggestion("Install Missing SDK Workloads", - new DotNetWorkloadInstallSolution(SdkRoot, sdkVersion, missingWorkloads.ToArray(), NuGetPackageSources)))); - } - } -} diff --git a/UnoCheck/Checkups/OpenJdkCheckup.cs b/UnoCheck/Checkups/OpenJdkCheckup.cs index fa80c1fa..6b6716b0 100644 --- a/UnoCheck/Checkups/OpenJdkCheckup.cs +++ b/UnoCheck/Checkups/OpenJdkCheckup.cs @@ -6,6 +6,7 @@ using System.IO; using System.Linq; using System.Runtime.InteropServices; +using System.Security.Policy; using System.Text.RegularExpressions; using System.Threading.Tasks; using Xamarin.Android.Tools; @@ -43,7 +44,7 @@ public bool RequireExact static string PlatformJavaCExtension => Util.IsWindows ? ".exe" : string.Empty; public override bool IsPlatformSupported(Platform platform) - => platform == Platform.OSX || platform == Platform.Windows; + => platform == Platform.OSX || platform == Platform.Windows || platform == Platform.Linux; public override bool ShouldExamine(SharedState history) => Manifest?.Check?.OpenJdk != null; @@ -87,7 +88,8 @@ public override Task Examine(SharedState history) { Environment.SetEnvironmentVariable("JAVA_HOME", jdk.Directory.FullName, EnvironmentVariableTarget.Machine); ReportStatus($"Set Environment Variable: JAVA_HOME={jdk.Directory.FullName}", Status.Ok); - } catch { } + } + catch { } } } else @@ -97,10 +99,18 @@ public override Task Examine(SharedState history) if (ok) return Task.FromResult(DiagnosticResult.Ok(this)); - var url = Manifest?.Check?.OpenJdk?.Url; - return Task.FromResult(new DiagnosticResult(Status.Error, this, - new Suggestion("Install OpenJDK11", - new BootsSolution(url, "Download and Install Microsoft OpenJDK 11")))); + if (Util.IsLinux) + { + return Task.FromResult(new DiagnosticResult(Status.Error, this, + new Suggestion("Install OpenJDK11", "OpenJDK 11 is missing, follow the installation instructions here: https://learn.microsoft.com/en-us/java/openjdk/install#install-on-ubuntu"))); + } + else + { + var url = Manifest?.Check?.OpenJdk?.Url; + return Task.FromResult(new DiagnosticResult(Status.Error, this, + new Suggestion("Install OpenJDK11", + new BootsSolution(url, "Download and Install Microsoft OpenJDK 11")))); + } } IEnumerable FindJdks() @@ -130,7 +140,8 @@ IEnumerable FindJdks() SearchDirectoryForJdks(paths, Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), "Microsoft", "Jdk"), true); - } else if (Util.IsMac) + } + else if (Util.IsMac) { var ms11Dir = Path.Combine("/Library", "Java", "JavaVirtualMachines", "microsoft-11.jdk", "Contents", "Home"); SearchDirectoryForJdks(paths, ms11Dir, true); @@ -163,7 +174,7 @@ IEnumerable FindJdks() SearchDirectoryForJdks(paths, Environment.GetEnvironmentVariable("JAVA_HOME") ?? string.Empty, true); SearchDirectoryForJdks(paths, Environment.GetEnvironmentVariable("JDK_HOME") ?? string.Empty, true); - var environmentPaths = Environment.GetEnvironmentVariable("PATH")?.Split(';') ?? Array.Empty(); + var environmentPaths = Environment.GetEnvironmentVariable("PATH")?.Split(Path.PathSeparator) ?? Array.Empty(); foreach (var envPath in environmentPaths) { @@ -171,6 +182,29 @@ IEnumerable FindJdks() SearchDirectoryForJdks(paths, envPath, true); } + if (Util.IsLinux) + { + var r = ShellProcessRunner.Run("whereis", "-b javac"); + + if ( + r.Success + && r.StandardOutput.Count > 0 + && r.StandardOutput[0].Split(" ").Skip(1).FirstOrDefault() is { } javacBinPath) + { + var readlinkResult = ShellProcessRunner.Run("readlink", "-f " + javacBinPath); + + if ( + readlinkResult.Success + && r.StandardOutput.Count > 0) + { + if (TryGetJavaJdkInfo(readlinkResult.StandardOutput[0], out var jdkInfo)) + { + paths.Add(jdkInfo); + } + } + } + } + return paths .GroupBy(i => i.JavaC.FullName) .Select(g => g.First()); diff --git a/UnoCheck/DotNet/DotNetWorkloadManager.cs b/UnoCheck/DotNet/DotNetWorkloadManager.cs index f6355c4d..f1f97c7e 100644 --- a/UnoCheck/DotNet/DotNetWorkloadManager.cs +++ b/UnoCheck/DotNet/DotNetWorkloadManager.cs @@ -67,10 +67,10 @@ public async Task Install(Manifest.DotNetWorkload[] workloads) string WriteRollbackFile(Manifest.DotNetWorkload[] workloads) { - var workloadRolback = GetInstalledWorkloadManifestIdsAndVersions(); + var workloadRollback = GetInstalledWorkloadManifestIdsAndVersions(); foreach (var workload in workloads) - workloadRolback[workload.WorkloadManifestId] = workload.Version; + workloadRollback[workload.WorkloadManifestId] = workload.Version; var json = new StringBuilder(); json.AppendLine("{"); diff --git a/UnoCheck/Manifest/Urls.cs b/UnoCheck/Manifest/Urls.cs index d65b607e..c12d753c 100644 --- a/UnoCheck/Manifest/Urls.cs +++ b/UnoCheck/Manifest/Urls.cs @@ -23,6 +23,9 @@ public partial class Urls [JsonProperty("linux", NullValueHandling = NullValueHandling.Ignore)] public Uri Linux { get; set; } + [JsonProperty("linuxArm64", NullValueHandling = NullValueHandling.Ignore)] + public Uri LinuxArm64 { get; set; } + public Uri Get(string version, Platform? platform = default) { var uri = For(platform ?? Util.Platform)?.ToString(); @@ -49,7 +52,9 @@ Uri For(Platform platform) : (Util.Is64 ? Win64 ?? Win : Win), - Platform.Linux => Linux, + Platform.Linux => Util.IsArm64 + ? (LinuxArm64 ?? Linux) + : Linux, _ => Win }; } diff --git a/manifests/uno.ui.manifest.json b/manifests/uno.ui.manifest.json index b7bd2241..e9d5e82c 100644 --- a/manifests/uno.ui.manifest.json +++ b/manifests/uno.ui.manifest.json @@ -15,10 +15,13 @@ "openjdk": { "version": "11.0", "urls": { + // Sources https://learn.microsoft.com/en-us/java/openjdk/download#openjdk-11 "win64": "https://aka.ms/download-jdk/microsoft-jdk-$(OPENJDK_VERSION)-windows-x64.msi", "winArm64": "https://aka.ms/download-jdk/microsoft-jdk-$(OPENJDK_VERSION)-windows-aarch64.msi", "osx": "https://aka.ms/download-jdk/microsoft-jdk-$(OPENJDK_VERSION)-macos-x64.pkg", - "osxArm64": "https://aka.ms/download-jdk/microsoft-jdk-$(OPENJDK_VERSION)-macos-aarch64.pkg" + "osxArm64": "https://aka.ms/download-jdk/microsoft-jdk-$(OPENJDK_VERSION)-macos-aarch64.pkg", + "linux": "https://aka.ms/download-jdk/microsoft-jdk-$(OPENJDK_VERSION)-linux-x64.tar.gz", + "linuxArm64": "https://aka.ms/download-jdk/microsoft-jdk-$(OPENJDK_VERSION)-linux-aarch64.tar.gz" } }, "xcode": { @@ -104,7 +107,7 @@ "workloadManifestId": "microsoft.net.sdk.android", "packageId": "Microsoft.NET.Sdk.Android.Manifest-8.0.100", "version": "$(ANDROID_SDK_VERSION)", - "supportedPlatforms": [ "Windows", "OSX" ] + "supportedPlatforms": [ "Windows", "OSX", "Linux" ] }, { "workloadId": "ios",