async Task <bool> InstallRuntimes(Context context, List <Runtime> enabledRuntimes)
        {
            StatusStep(context, "Installing tests");
            foreach (TestAssembly tasm in allRuntimes.TestAssemblies)
            {
                string sourceBasePath;

                switch (tasm.TestType)
                {
                case TestAssemblyType.Reference:
                case TestAssemblyType.TestRunner:
                    sourceBasePath = Path.Combine(Configurables.Paths.MonoProfileDir);
                    break;

                case TestAssemblyType.XUnit:
                case TestAssemblyType.NUnit:
                case TestAssemblyType.Satellite:
                    sourceBasePath = Configurables.Paths.BCLTestsSourceDir;
                    break;

                default:
                    throw new InvalidOperationException($"Unsupported test assembly type: {tasm.TestType}");
                }

                (string destFilePath, string debugSymbolsDestPath) = MonoRuntimesHelpers.GetDestinationPaths(tasm);
                CopyFile(Path.Combine(sourceBasePath, tasm.Name), destFilePath);
                if (debugSymbolsDestPath != null)
                {
                    CopyFile(Path.Combine(sourceBasePath, Utilities.GetDebugSymbolsPath(tasm.Name)), debugSymbolsDestPath);
                }
            }

            StatusSubStep(context, "Creating BCL tests archive");
            Utilities.DeleteFileSilent(MonoRuntimesHelpers.BCLTestsArchivePath);
            var sevenZip = new SevenZipRunner(context);

            if (!await sevenZip.Zip(MonoRuntimesHelpers.BCLTestsArchivePath, MonoRuntimesHelpers.BCLTestsDestinationDir, new List <string> {
                "."
            }))
            {
                Log.ErrorLine("BCL tests archive creation failed, see the log files for details.");
                return(false);
            }

            StatusStep(context, "Installing runtimes");
            foreach (Runtime runtime in enabledRuntimes)
            {
                StatusSubStep(context, $"Installing {runtime.Flavor} runtime {runtime.Name}");

                string src, dst;
                bool   skipFile;
                foreach (RuntimeFile rtf in allRuntimes.RuntimeFilesToInstall)
                {
                    if (rtf.Shared && rtf.AlreadyCopied)
                    {
                        continue;
                    }

                    (skipFile, src, dst) = MonoRuntimesHelpers.GetRuntimeFilePaths(runtime, rtf);
                    if (skipFile)
                    {
                        continue;
                    }

                    CopyFile(src, dst);
                    if (!StripFile(runtime, rtf, dst))
                    {
                        return(false);
                    }

                    if (rtf.Shared)
                    {
                        rtf.AlreadyCopied = true;
                    }
                }
            }

            return(true);

            bool StripFile(Runtime runtime, RuntimeFile rtf, string filePath)
            {
                if (rtf.Type != RuntimeFileType.StrippableBinary)
                {
                    return(true);
                }

                var monoRuntime = runtime.As <MonoRuntime> ();

                if (monoRuntime == null || !monoRuntime.CanStripNativeLibrary || !rtf.Strip)
                {
                    return(true);
                }

                if (String.IsNullOrEmpty(monoRuntime.Strip))
                {
                    Log.WarningLine($"Binary stripping impossible, runtime {monoRuntime.Name} doesn't define the strip command");
                    return(true);
                }

                if (context.OS.IsWindows && (context.IsWindowsCrossAotAbi(monoRuntime.Name) || context.IsMingwHostAbi(monoRuntime.Name)))
                {
                    Log.WarningLine($"Unable to strip '{monoRuntime.Name}' on Windows.");
                    return(true);
                }

                bool result;

                if (!String.IsNullOrEmpty(monoRuntime.StripFlags))
                {
                    result = Utilities.RunCommand(monoRuntime.Strip, monoRuntime.StripFlags, filePath);
                }
                else
                {
                    result = Utilities.RunCommand(monoRuntime.Strip, filePath);
                }

                if (result)
                {
                    return(true);
                }

                Log.ErrorLine($"Failed to {monoRuntime.Strip} the binary file {filePath}, see logs for error details");
                return(false);
            }

            void CopyFile(string src, string dest)
            {
                if (!CheckFileExists(src, true))
                {
                    return;
                }

                Utilities.CopyFile(src, dest);
            }
        }
Exemplo n.º 2
0
        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");
                    return(false);
                }
            }

            string tempDir = $"{destinationDirectory}.tmp";

            if (!await Utilities.Unpack(localPath, tempDir, cleanDestinatioBeforeUnpacking: true))
            {
                Utilities.DeleteFileSilent(localPath);
                Utilities.DeleteDirectorySilent(destinationDirectory);
                Log.WarningLine($"Failed to unpack {name} archive {localPath}");
                Utilities.DeleteFileSilent(localPath);
                return(false);
            }

            Log.DebugLine($"Moving unpacked Mono archive from {tempDir} to {destinationDirectory}");
            try {
                Utilities.MoveDirectoryContentsRecursively(tempDir, destinationDirectory, resetFileTimestamp: true);
            } finally {
                Utilities.DeleteDirectorySilent(tempDir);
                // Clean up zip after extraction if running on a hosted azure pipelines agent.
                if (context.IsRunningOnHostedAzureAgent)
                {
                    Utilities.DeleteFileSilent(localPath);
                }
            }

            return(true);
        }
Exemplo n.º 3
0
        protected override async Task <bool> Execute(Context context)
        {
            if (Directory.Exists(Configurables.Paths.OldOpenJDKInstallDir))
            {
                Log.DebugLine($"Found old OpenJDK directory at {Configurables.Paths.OldOpenJDKInstallDir}, removing");
                Utilities.DeleteDirectorySilent(Configurables.Paths.OldOpenJDKInstallDir);
            }

            string jdkInstallDir = JdkInstallDir;

            if (OpenJDKExistsAndIsValid(jdkInstallDir, out string installedVersion))
            {
                Log.Status($"{ProductName} version ");
                Log.Status(installedVersion, ConsoleColor.Yellow);
                Log.StatusLine(" already installed in: ", jdkInstallDir, tailColor: ConsoleColor.Cyan);
                return(true);
            }

            Log.StatusLine($"JetBrains JDK {JdkVersion} r{JdkRelease} will be installed");
            Uri jdkURL = JdkUrl;

            if (jdkURL == null)
            {
                throw new InvalidOperationException($"{ProductName} URL must not be null");
            }

            string[] queryParams = jdkURL.Query.TrimStart('?').Split(QuerySeparator, StringSplitOptions.RemoveEmptyEntries);
            if (queryParams.Length == 0)
            {
                Log.ErrorLine($"Unable to extract file name from {ProductName} URL as it contains no query component");
                return(false);
            }

            string?packageName = null;

            foreach (string p in queryParams)
            {
                if (!p.StartsWith(URLQueryFilePathField, StringComparison.Ordinal))
                {
                    continue;
                }

                int idx = p.IndexOf('=');
                if (idx < 0)
                {
                    Log.DebugLine($"{ProductName} URL query field '{URLQueryFilePathField}' has no value, unable to detect file name");
                    break;
                }

                packageName = p.Substring(idx + 1).Trim();
            }

            if (String.IsNullOrEmpty(packageName))
            {
                Log.ErrorLine($"Unable to extract file name from {ProductName} URL");
                return(false);
            }

            string localPackagePath = Path.Combine(JdkCacheDir, packageName);

            if (!await DownloadOpenJDK(context, localPackagePath, jdkURL))
            {
                return(false);
            }

            string tempDir = $"{jdkInstallDir}.temp";

            try {
                if (!await Unpack(localPackagePath, tempDir, cleanDestinationBeforeUnpacking: true))
                {
                    Log.ErrorLine($"Failed to install {ProductName}");
                    return(false);
                }

                string rootDir = Path.Combine(tempDir, RootDirName);
                if (!Directory.Exists(rootDir))
                {
                    Log.ErrorLine($"JetBrains root directory not found after unpacking: {RootDirName}");
                    return(false);
                }

                MoveContents(rootDir, jdkInstallDir);
                File.WriteAllText(Path.Combine(jdkInstallDir, XAVersionInfoFile), $"{JdkRelease}{Environment.NewLine}");
            } finally {
                Utilities.DeleteDirectorySilent(tempDir);
                // Clean up zip after extraction if running on a hosted azure pipelines agent.
                if (context.IsRunningOnHostedAzureAgent)
                {
                    Utilities.DeleteFileSilent(localPackagePath);
                }
            }

            return(true);
        }