async Task <bool> DownloadAndUpackIfNeeded(Context context, string name, string customUrl, string localPath, string archiveFileName, string destinationDirectory) { if (File.Exists(localPath)) { Log.StatusLine($"{name} archive already downloaded"); } else { Utilities.DeleteFileSilent(localPath); var url = string.IsNullOrEmpty(customUrl) ? new Uri(Configurables.Urls.MonoArchive_BaseUri, archiveFileName) : new Uri(customUrl); Log.StatusLine($"Downloading {name} archive from {url}"); (bool success, ulong size, HttpStatusCode status) = await Utilities.GetDownloadSizeWithStatus(url); if (!success) { if (status == HttpStatusCode.NotFound) { Log.Info($"{name} archive URL not found"); } else { Log.Info($"Failed to obtain {name} archive size. HTTP status code: {status} ({(int)status})"); } Log.InfoLine(". Mono runtimes will be rebuilt"); return(false); } DownloadStatus downloadStatus = Utilities.SetupDownloadStatus(context, size, context.InteractiveSession); Log.StatusLine($" {context.Characters.Link} {url}", ConsoleColor.White); await Download(context, url, localPath, $"{name} Archive", archiveFileName, downloadStatus); if (!File.Exists(localPath)) { Log.InfoLine($"Download of {name} archive from {url} failed, Mono will be rebuilt"); return(false); } } string tempDir = $"{destinationDirectory}.tmp"; if (!await Utilities.Unpack(localPath, tempDir, cleanDestinatioBeforeUnpacking: true)) { Utilities.DeleteDirectorySilent(destinationDirectory); Log.WarningLine($"Failed to unpack {name} archive {localPath}, Mono will be rebuilt"); return(false); } Log.DebugLine($"Moving unpacked Mono archive from {tempDir} to {destinationDirectory}"); try { Utilities.MoveDirectoryContentsRecursively(tempDir, destinationDirectory, resetFileTimestamp: true); } finally { Utilities.DeleteDirectorySilent(tempDir); } return(true); }
async Task <bool> DownloadBinutils(Context context, string localPackagePath, Uri url) { if (Utilities.FileExists(localPackagePath)) { Log.StatusLine($"{ProductName} archive already downloaded"); return(true); } Log.StatusLine($"Downloading {ProductName} from ", url.ToString(), tailColor: ConsoleColor.White); (bool success, ulong size, HttpStatusCode status) = await Utilities.GetDownloadSizeWithStatus(url); if (!success) { if (status == HttpStatusCode.NotFound) { Log.ErrorLine($"{ProductName} archive URL not found"); return(false); } Log.WarningLine($"Failed to obtain {ProductName} size. HTTP status code: {status} ({(int)status})"); } DownloadStatus downloadStatus = Utilities.SetupDownloadStatus(context, size, context.InteractiveSession); Log.StatusLine($" {context.Characters.Link} {url}", ConsoleColor.White); await Download(context, url, localPackagePath, ProductName, Path.GetFileName(localPackagePath), downloadStatus); if (!File.Exists(localPackagePath)) { Log.ErrorLine($"Download of {ProductName} from {url} failed."); return(false); } return(true); }
protected override async Task <bool> Execute(Context context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } Uri nugetUrl = Configurables.Urls.NugetUri; string localNugetPath = Configurables.Paths.LocalNugetPath; if (Utilities.FileExists(localNugetPath)) { Log.StatusLine($"NuGet already downloaded ({localNugetPath})"); return(true); } Utilities.CreateDirectory(Path.GetDirectoryName(localNugetPath)); Log.StatusLine("Downloading NuGet"); (bool success, ulong size, HttpStatusCode status) = await Utilities.GetDownloadSizeWithStatus(nugetUrl); if (!success) { if (status == HttpStatusCode.NotFound) { Log.ErrorLine("NuGet URL not found"); } else { Log.ErrorLine("Failed to obtain NuGet size. HTTP status code: {status} ({(int)status})"); } return(false); } DownloadStatus downloadStatus = Utilities.SetupDownloadStatus(context, size, context.InteractiveSession); Log.StatusLine($" {context.Characters.Link} {nugetUrl}", ConsoleColor.White); await Download(context, nugetUrl, localNugetPath, "NuGet", Path.GetFileName(localNugetPath), downloadStatus); if (!File.Exists(localNugetPath)) { Log.ErrorLine($"Download of NuGet from {nugetUrl} failed"); return(false); } return(true); }
async Task <bool> DownloadCorretto(Context context, string localPackagePath, Uri url) { if (File.Exists(localPackagePath)) { if (await Utilities.VerifyArchive(localPackagePath)) { Log.StatusLine("Corretto archive already downloaded and valid"); return(true); } Utilities.DeleteFileSilent(localPackagePath); } Log.StatusLine("Downloading Corretto from ", url.ToString(), tailColor: ConsoleColor.White); (bool success, ulong size, HttpStatusCode status) = await Utilities.GetDownloadSizeWithStatus(url); if (!success) { if (status == HttpStatusCode.NotFound) { Log.ErrorLine("Corretto archive URL not found"); } else { Log.ErrorLine($"Failed to obtain Corretto size. HTTP status code: {status} ({(int)status})"); } return(false); } DownloadStatus downloadStatus = Utilities.SetupDownloadStatus(context, size, context.InteractiveSession); Log.StatusLine($" {context.Characters.Link} {url}", ConsoleColor.White); await Download(context, url, localPackagePath, "Corretto", Path.GetFileName(localPackagePath), downloadStatus); if (!File.Exists(localPackagePath)) { Log.ErrorLine($"Download of Corretto from {url} failed."); return(false); } return(true); }
protected override async Task <bool> Execute(Context context) { if (context.ForceRuntimesBuild) { if (osSupportsMonoBuild) { Log.InfoLine("Rebuilding Mono runtimes as requested"); return(false); } Log.InfoLine($"Forced Mono runtimes rebuild requested but rebuilding on {context.OS.Type} is currently not supported."); } string localPackagePath = Configurables.Paths.BundleArchivePath; Log.DebugLine($"Local bundle path: {localPackagePath}"); if (await Utilities.VerifyArchive(localPackagePath)) { Log.StatusLine("Xamarin.Android Bundle archive already downloaded and valid"); } else { if (!String.IsNullOrEmpty(context.XABundlePath)) { // User indicated they wanted to use a specific bundle that's supposed to be on disk. It's not (or // it's invalid) and that means we have no way of getting it - we can't download the default one // since that was not the intention behind overriding the location. Thus, we error out. Log.DebugLine($"Bundle directory from command line: {context.XABundlePath}"); throw new InvalidOperationException($"Xamarin.Android bundle indicated on the command line does not exist ({context.XABundlePath})"); } var bundleUrl = new Uri(BundleUriPrefix, BundleFileName); Log.StatusLine("Bundle URL: ", $"{bundleUrl}", tailColor: ConsoleColor.Cyan); HttpStatusCode status; bool success; ulong size; (success, size, status) = await Utilities.GetDownloadSizeWithStatus(bundleUrl); if (!success) { if (status == HttpStatusCode.NotFound) { if (osSupportsMonoBuild) { Log.StatusLine(" not found, will need to rebuild"); } else { Log.ErrorLine($" not found, rebuilding on {context.OS.Type} is not currently supported"); } return(false); } if (String.IsNullOrEmpty(bundle404Message)) { throw new InvalidOperationException($"Failed to access bundle at {bundleUrl} (HTTP status: {status})"); } else { throw new InvalidOperationException(bundle404Message); } } DownloadStatus downloadStatus = Utilities.SetupDownloadStatus(context, size, context.InteractiveSession); Log.StatusLine($" {context.Characters.Link} {bundleUrl}", ConsoleColor.White); await Download(context, bundleUrl, localPackagePath, "Xamarin.Android Bundle", Path.GetFileName(localPackagePath), downloadStatus); if (!File.Exists(localPackagePath)) { Log.ErrorLine($"Download of Xamarin.Android Bundle from {bundleUrl} failed."); return(false); } } Log.StatusLine($"Unpacking bundle to {Utilities.GetRelativePath (BuildPaths.XamarinAndroidSourceRoot, Configurables.Paths.BundleInstallDir)}"); string tempDir = $"{Configurables.Paths.BundleInstallDir}-bundle.temp"; try { if (!await Utilities.Unpack(localPackagePath, tempDir, cleanDestinatioBeforeUnpacking: true)) { Log.WarningLine("Failed to unpack bundle, will need to rebuild"); return(false); } Log.DebugLine($"Moving unpacked bundle from {tempDir} to {Configurables.Paths.BundleInstallDir}"); Utilities.MoveDirectoryContentsRecursively(tempDir, Configurables.Paths.BundleInstallDir, resetFileTimestamp: true, ignoreDeletionErrors: true); } finally { Utilities.DeleteDirectorySilent(tempDir); } string managedRuntime = context.Properties.GetRequiredValue(KnownProperties.ManagedRuntime); bool haveManagedRuntime = !String.IsNullOrEmpty(managedRuntime); if (!await Utilities.BuildRemapRef(context, haveManagedRuntime, managedRuntime)) { return(false); } Utilities.PropagateXamarinAndroidCecil(context); if (String.IsNullOrEmpty(context.XABundleCopyDir)) { return(HaveEverything()); } string destPackagePath = Path.Combine(context.XABundleCopyDir, Path.GetFileName(localPackagePath)); Log.DebugLine($"Copy of the XA bundle was requested to be created at {destPackagePath}"); if (Utilities.FileExists(destPackagePath)) { Log.DebugLine("Bundle copy already exists"); return(HaveEverything()); } // Utilities.FileExists above will return `false` for a dangling symlink at `destPackagePath`, doesn't hurt // to remove it here just in case Utilities.DeleteFileSilent(destPackagePath); Utilities.CopyFile(localPackagePath, destPackagePath); return(HaveEverything()); bool HaveEverything() { bool ret = MonoRuntimesHelpers.AllBundleItemsPresent(new Runtimes()); if (!ret) { Log.Instance.StatusLine($"Some bundle files are missing, download/rebuild/reinstall forced"); } return(ret); } }
protected override async Task <bool> Execute(Context context) { string localPackagePath = Configurables.Paths.AntArchivePath; if (await Utilities.VerifyArchive(localPackagePath)) { Log.StatusLine("Ant archive already downloaded and valid"); } else { Uri antUrl = new Uri(Configurables.Urls.AntBaseUri, Configurables.Paths.AntArchiveName); Log.StatusLine("Ant URL: ", $"{antUrl}", tailColor: ConsoleColor.Cyan); HttpStatusCode status; bool success; ulong size; (success, size, status) = await Utilities.GetDownloadSizeWithStatus(antUrl); if (!success) { Log.ErrorLine($"Failed to access Ant at {antUrl} (HTTP status: {status})"); return(false); } DownloadStatus downloadStatus = Utilities.SetupDownloadStatus(context, size, context.InteractiveSession); Log.StatusLine($" {context.Characters.Link} {antUrl}", ConsoleColor.White); await Download(context, antUrl, localPackagePath, "Apache Ant", Path.GetFileName(localPackagePath), downloadStatus); if (!File.Exists(localPackagePath)) { Log.ErrorLine($"Download of Xamarin.Android Bundle from {antUrl} failed."); return(false); } } Log.StatusLine($"Unpacking Ant to {Configurables.Paths.AntInstallDir}"); string tempDir = $"{Configurables.Paths.AntInstallDir}-ant.temp"; try { if (!await Utilities.Unpack(localPackagePath, tempDir, cleanDestinatioBeforeUnpacking: true)) { Log.ErrorLine("Failed to unpack Ant"); return(false); } Log.DebugLine($"Moving unpacked Ant from {tempDir} to {Configurables.Paths.AntInstallDir}"); // There should be just a single subdirectory List <string> subdirs = Directory.EnumerateDirectories(tempDir).ToList(); if (subdirs.Count > 1) { throw new InvalidOperationException($"Unexpected contents layout of the Ant archive - expected a single subdirectory, instead found {subdirs.Count}"); } Utilities.MoveDirectoryContentsRecursively(subdirs [0], Configurables.Paths.AntInstallDir); } finally { Utilities.DeleteDirectorySilent(tempDir); } return(true); }
protected override async Task <bool> Execute(Context context) { if (context.ForceRuntimesBuild) { if (osSupportsMonoBuild) { Log.InfoLine("Rebuilding Mono runtimes as requested"); return(false); } Log.InfoLine($"Forced Mono runtimes rebuild requested but rebuilding on {context.OS.Type} is currently not supported."); } string localPackagePath = Path.Combine(Configurables.Paths.BundleArchivePath); if (await Utilities.VerifyArchive(localPackagePath)) { Log.StatusLine("Xamarin.Android Bundle archive already downloaded and valid"); } else { if (!String.IsNullOrEmpty(context.XABundlePath)) { // User indicated they wanted to use a specific bundle that's supposed to be on disk. It's not (or // it's invalid) and that means we have no way of getting it - we can't download the default one // since that was not the intention behind overriding the location. Thus, we error out. throw new InvalidOperationException($"Xamarin.Android bundle indicated on the command line does not exist ({context.XABundlePath})"); } var bundleUrl = new Uri(BundleUriPrefix, BundleFileName); Log.StatusLine("Bundle URL: ", $"{bundleUrl}", tailColor: ConsoleColor.Cyan); HttpStatusCode status; bool success; ulong size; (success, size, status) = await Utilities.GetDownloadSizeWithStatus(bundleUrl); if (!success) { if (status == HttpStatusCode.NotFound) { if (osSupportsMonoBuild) { Log.StatusLine(" not found, will need to rebuild"); } else { Log.ErrorLine($" not found, rebuilding on {context.OS.Type} is not currently supported"); } return(false); } if (String.IsNullOrEmpty(bundle404Message)) { throw new InvalidOperationException($"Failed to access bundle at {bundleUrl} (HTTP status: {status})"); } else { throw new InvalidOperationException(bundle404Message); } } DownloadStatus downloadStatus = Utilities.SetupDownloadStatus(context, size, context.InteractiveSession); Log.StatusLine($" {context.Characters.Link} {bundleUrl}", ConsoleColor.White); await Download(context, bundleUrl, localPackagePath, "Xamarin.Android Bundle", Path.GetFileName(localPackagePath), downloadStatus); if (!File.Exists(localPackagePath)) { Log.ErrorLine($"Download of Xamarin.Android Bundle from {bundleUrl} failed."); return(false); } } Log.StatusLine($"Unpacking bundle to {Utilities.GetRelativePath (BuildPaths.XamarinAndroidSourceRoot, Configurables.Paths.BundleInstallDir)}"); string tempDir = $"{Configurables.Paths.BundleInstallDir}-bundle.temp"; try { if (!await Utilities.Unpack(localPackagePath, tempDir, cleanDestinatioBeforeUnpacking: true)) { Log.WarningLine("Failed to unpack bundle, will need to rebuild"); return(false); } Log.DebugLine("Moving unpacked bundle from {tempDir} to {Configurables.Paths.Bundle_InstallDir}"); Utilities.MoveDirectoryContentsRecursively(tempDir, Configurables.Paths.BundleInstallDir, resetFileTimestamp: true); } finally { Utilities.DeleteDirectorySilent(tempDir); } return(true); }
async Task <bool> InstallDotNetAsync(Context context, string dotnetPath, string version, bool runtimeOnly = false) { if (Directory.Exists(Path.Combine(dotnetPath, "sdk", version)) && !runtimeOnly) { Log.Status($"dotnet SDK version "); Log.Status(version, ConsoleColor.Yellow); Log.StatusLine(" already installed in: ", Path.Combine(dotnetPath, "sdk", version), tailColor: ConsoleColor.Cyan); return(true); } if (Directory.Exists(Path.Combine(dotnetPath, "shared", "Microsoft.NETCore.App", version)) && runtimeOnly) { Log.Status($"dotnet runtime version "); Log.Status(version, ConsoleColor.Yellow); Log.StatusLine(" already installed in: ", Path.Combine(dotnetPath, "shared", "Microsoft.NETCore.App", version), tailColor: ConsoleColor.Cyan); return(true); } Uri dotnetScriptUrl = Configurables.Urls.DotNetInstallScript; string dotnetScriptPath = Path.Combine(dotnetPath, Path.GetFileName(dotnetScriptUrl.LocalPath)); if (File.Exists(dotnetScriptPath)) { Utilities.DeleteFile(dotnetScriptPath); } Log.StatusLine("Downloading dotnet-install..."); (bool success, ulong size, HttpStatusCode status) = await Utilities.GetDownloadSizeWithStatus(dotnetScriptUrl); if (!success) { if (status == HttpStatusCode.NotFound) { Log.ErrorLine("dotnet-install URL not found"); } else { Log.ErrorLine("Failed to obtain dotnet-install size. HTTP status code: {status} ({(int)status})"); } return(false); } DownloadStatus downloadStatus = Utilities.SetupDownloadStatus(context, size, context.InteractiveSession); Log.StatusLine($" {context.Characters.Link} {dotnetScriptUrl}", ConsoleColor.White); await Download(context, dotnetScriptUrl, dotnetScriptPath, "dotnet-install", Path.GetFileName(dotnetScriptUrl.LocalPath), downloadStatus); if (!File.Exists(dotnetScriptPath)) { Log.ErrorLine($"Download of dotnet-install from {dotnetScriptUrl} failed"); return(false); } Log.StatusLine($"Installing dotnet SDK/runtime '{version}'..."); if (Context.IsWindows) { var args = new List <string> { "-NoProfile", "-ExecutionPolicy", "unrestricted", "-file", dotnetScriptPath, "-Version", version, "-InstallDir", dotnetPath, "-Verbose" }; if (runtimeOnly) { args.AddRange(new string [] { "-Runtime", "dotnet" }); } return(Utilities.RunCommand("powershell.exe", args.ToArray())); } else { var args = new List <string> { dotnetScriptPath, "--version", version, "--install-dir", dotnetPath, "--verbose" }; if (runtimeOnly) { args.AddRange(new string [] { "-Runtime", "dotnet" }); } return(Utilities.RunCommand("bash", args.ToArray())); } }