private static bool TryExtractConverter(string assetsFolder, string unityInstallFolder, out string converterPath)
    {
        converterPath = Path.Combine(Path.GetTempPath(), "Unity3D/UnityScript2CSharp");
        if (Directory.Exists(converterPath))
        {
            Directory.Delete(converterPath, true);
        }

        Directory.CreateDirectory(converterPath);

        var decompressProgramPath = Application.platform == RuntimePlatform.OSXEditor
                                            ? Path.Combine(unityInstallFolder, "Unity.app/Contents/Tools/7za")
                                            : Path.Combine(unityInstallFolder, "Data/Tools/7z.exe");

        var compressedConverterPath = Quote(Path.Combine(Path.Combine(assetsFolder, ConverterPackageFolder), "UnityScript2CSharp_*.zip"));

        var startInfo = new ProcessStartInfo
        {
            Arguments              = string.Format("e {0} -o{1} -y", compressedConverterPath, converterPath),
            CreateNoWindow         = true,
            FileName               = decompressProgramPath,
            RedirectStandardError  = true,
            RedirectStandardOutput = true,
            WorkingDirectory       = Application.dataPath + "/..",
            UseShellExecute        = false
        };

        using (var process = Process.Start(startInfo))
        {
            var stdOut = new ProcessOutputStreamReader(process, process.StandardOutput);
            var stdErr = new ProcessOutputStreamReader(process, process.StandardError);

            process.WaitForExit(10000);
            if (!process.HasExited)
            {
                EditorUtility.DisplayDialog("Error", "Failed to extract the conversion tool.", "Ok");
                return(false);
            }

            if (process.ExitCode != 0)
            {
                Debug.Log(string.Join("\r\n", stdOut.GetOutput()));
                Debug.Log(string.Join("\r\n", stdErr.GetOutput()));

                EditorUtility.DisplayDialog("Error", "Failed to extract the conversion tool. Exit code = " + process.ExitCode, "Ok");
                return(false);
            }

            converterPath = Path.Combine(converterPath, "UnityScript2CSharp.exe");
            return(true);
        }
    }
        private void RunValidator(IEnumerable <string> references, string validatorPath, IEnumerable <string> assemblyPaths)
        {
            var responseFilePath = Path.GetTempFileName();

            File.WriteAllLines(responseFilePath, references);

            var monoPath = Utilities.GetMonoPath();

            var argumentsForValidator = ArgumentsForValidator();

            File.WriteAllText($"{Path.Combine(Path.GetTempPath(), Context.ProjectPackageInfo?.name)}.updater.validation.arguments", argumentsForValidator);

            var processStartInfo = new ProcessStartInfo(monoPath, $@"""{validatorPath}"" {argumentsForValidator}")
            {
                UseShellExecute        = false,
                RedirectStandardError  = true,
                RedirectStandardOutput = true,
                CreateNoWindow         = true
            };
            var process = Process.Start(processStartInfo);
            var stderr  = new ProcessOutputStreamReader(process, process.StandardError);
            var stdout  = new ProcessOutputStreamReader(process, process.StandardOutput);

            process.WaitForExit();
            if (process.ExitCode != 0)
            {
                var stdContent = string.Join("\n", stderr.GetOutput().Concat(stdout.GetOutput()));
                if (ApiUpdaterConfigurationExemptions(stdContent))
                {
                    AddWarning(stdContent);
                }
                else
                {
                    AddError(stdContent);
                }
            }

            bool ApiUpdaterConfigurationExemptions(string stdContent)
            {
#if UNITY_2019_3_OR_NEWER
                return(false);
#else
                if (stdContent.Contains("Mono.Cecil.AssemblyResolutionException"))
                {
                    return(true);
                }

                // This is a temporary workaround to unblock dots team.
                var requiredEntries = new[]
                {
                    "Target of update (method ComponentSystemBase.GetEntityQuery) is less accessible than original (Unity.Entities.ComponentGroup Unity.Entities.ComponentSystemBase::GetComponentGroup(Unity.Entities.ComponentType[])).",
                    "Target of update (method ComponentSystemBase.GetEntityQuery) is less accessible than original (Unity.Entities.ComponentGroup Unity.Entities.ComponentSystemBase::GetComponentGroup(Unity.Collections.NativeArray`1<Unity.Entities.ComponentType>)).",
                    "Target of update (method ComponentSystemBase.GetEntityQuery) is less accessible than original (Unity.Entities.ComponentGroup Unity.Entities.ComponentSystemBase::GetComponentGroup(Unity.Entities.EntityArchetypeQuery[])).",
                };

                return(requiredEntries.All(stdContent.Contains));
#endif
            }

            string ArgumentsForValidator()
            {
                var whitelistArg = string.Empty;

                // Resolves ValidationWhiteList.txt in folders
                //      - ApiUpdater~/{Editor Exact Version} (ex: 2019.3.0f1)
                //      - ApiUpdater~/{Editor Version Without Alpha/Beta/RC/Final info} (ex: 2019.3)
                //      - ApiUpdater~/
                // first one found will be used.
                var probingFolders = new[] { $"{UnityEngine.Application.unityVersion}", $"{Regex.Replace(UnityEngine.Application.unityVersion, @"(?<=20[1-5][0-9]\.\d{1,3})\.[0-9]{1,4}.*", string.Empty)}", "." };

                foreach (var path in probingFolders)
                {
                    var whitelistPath = Path.Combine(Context.ProjectPackageInfo.path, $"ApiUpdater~/{path}/ValidationWhiteList.txt");
                    if (File.Exists(whitelistPath))
                    {
                        whitelistArg = $@" --whitelist ""{whitelistPath}""";
                        break;
                    }
                }

                return($"\"{responseFilePath}\" -a {string.Join(",", assemblyPaths.Select(p => $"\"{Path.GetFullPath(p)}\""))} {whitelistArg}");
            }
        }
Example #3
0
        protected override void Run(AssemblyInfo[] info)
        {
            TestState = TestState.Succeeded;
            var monopath = Utilities.GetMonoPath();
            var exePath  = Path.GetFullPath("packages/com.unity.package-validation-suite/Bin~/FindMissingDocs/FindMissingDocs.exe");

            List <string> excludePaths = new List <string>();

            excludePaths.AddRange(Directory.GetDirectories(this.Context.ProjectPackageInfo.path, "*~", SearchOption.AllDirectories));
            excludePaths.AddRange(Directory.GetDirectories(this.Context.ProjectPackageInfo.path, ".*", SearchOption.AllDirectories));
            excludePaths.AddRange(Directory.GetDirectories(this.Context.ProjectPackageInfo.path, "Tests", SearchOption.AllDirectories));
            foreach (var assembly in info)
            {
                //exclude sources from test assemblies explicitly. Do not exclude entire directories, as there may be nested public asmdefs
                if (validationAssemblyInformation.IsTestAssembly(assembly) && assembly.assemblyKind == AssemblyInfo.AssemblyKind.Asmdef)
                {
                    excludePaths.AddRange(assembly.assembly.sourceFiles);
                }
            }
            string responseFileParameter = string.Empty;
            string responseFilePath      = null;

            if (excludePaths.Count > 0)
            {
                responseFilePath = Path.GetTempFileName();
                var excludedPathsParameter = $@"--excluded-paths=""{string.Join(",", excludePaths.Select(s => Path.GetFullPath(s)))}""";
                File.WriteAllText(responseFilePath, excludedPathsParameter);
                responseFileParameter = $@"--response-file=""{responseFilePath}""";
            }

            var startInfo = new ProcessStartInfo(monopath, $@"""{exePath}"" --root-path=""{this.Context.ProjectPackageInfo.path}"" {responseFileParameter}")
            {
                UseShellExecute        = false,
                CreateNoWindow         = true,
                RedirectStandardOutput = true,
                RedirectStandardError  = true
            };
            var process = Process.Start(startInfo);

            var stdout = new ProcessOutputStreamReader(process, process.StandardOutput);
            var stderr = new ProcessOutputStreamReader(process, process.StandardError);

            process.WaitForExit();
            var stdoutLines = stdout.GetOutput();
            var stderrLines = stderr.GetOutput();

            if (process.ExitCode != 0)
            {
                // If FindMissingDocs fails and returns a non-zero exit code (like an unhandled exception) it means that
                // we couldn't validate the XmdDocValidation because the result is inconclusive. For that reason, we
                // should add it as an error to be addressed by the developer. If there's any bug with the tool itself
                // then that will need to be addressed in the XmlDoc repo and rebuild the binaries from PVS.
                AddError($"FindMissingDocs.exe returned {process.ExitCode}, a non-zero exit code and XmlDocValidation test is inconclusive.");
            }
            if (stderrLines.Length > 0)
            {
                AddWarning($"Internal Error running FindMissingDocs. Output:\n{string.Join("\n",stderrLines)}");
                return;
            }

            if (stdoutLines.Length > 0)
            {
                var errorMessage = FormatErrorMessage(stdoutLines);
                AddWarning(errorMessage);

                //// JonH: Enable errors in non-preview packages once the check has been put through its paces and the change is coordinated with RM and PM
                // if (Context.ProjectPackageInfo.IsPreview)
                //     Warning(errorMessage);
                // else
                // {
                //     TestState = TestState.Failed;
                //     Error(errorMessage);
                // }
            }

            if (responseFilePath != null)
            {
                File.Delete(responseFilePath);
            }
        }