internal static void UpdateAssemblies()
        {
            var assembliesToUpdate = GetAssembliesToBeUpdated();

            if (assembliesToUpdate.Count == 0)
            {
                return;
            }

            var assemblyPaths             = assembliesToUpdate.Select(c => c.Path);
            var anyAssemblyInAssetsFolder = assemblyPaths.Any(path => path.IndexOf("Assets/", StringComparison.OrdinalIgnoreCase) != -1);

            // Only try to connect to VCS if there are files under VCS that need to be updated
            if (anyAssemblyInAssetsFolder)
            {
                var failedToConnectToVcs = false;
                if (WaitForVCSServerConnection(true))
                {
                    failedToConnectToVcs = Provider.enabled && !APIUpdaterHelper.CheckoutAndValidateVCSFiles(assemblyPaths);
                }

                if (failedToConnectToVcs)
                {
                    assembliesToUpdate.Clear();
                    return;
                }
            }

            var sw           = Stopwatch.StartNew();
            var updatedCount = 0;

            var assembliesToCheckCount = assembliesToUpdate.Count;
            var tasks = assembliesToUpdate.Select(a => new AssemblyUpdaterUpdateTask(a)).ToArray();

            foreach (var task in tasks)
            {
                CollectAssemblyObsoleteAPIUsage(task.Candidate.Path);
                ThreadPool.QueueUserWorkItem(RunAssemblyUpdaterTask, task);
            }

            var finishOk   = false;
            var waitEvents = tasks.Select(t => t.Event).ToArray();
            var timeout    = TimeSpan.FromSeconds(30);

            if (WaitHandle.WaitAll(waitEvents, timeout))
            {
                if (!HandleAssemblyUpdaterErrors(tasks))
                {
                    updatedCount = ProcessSuccessfulUpdates(tasks);
                    finishOk     = true;
                }
            }
            else
            {
                LogTimeoutError(tasks);
            }

            sw.Stop();
            APIUpdaterLogger.WriteToFile(L10n.Tr("Update finished with {0} in {1} ms ({2}/{3} assemblie(s) updated)."), finishOk ? L10n.Tr("success") : L10n.Tr("error"), sw.ElapsedMilliseconds, updatedCount, assembliesToCheckCount);

            if (updatedCount > 0 && !EditorCompilationInterface.Instance.DoesProjectFolderHaveAnyScripts())
            {
                ReportPossibleUpdateFinished(false);
            }

            PersistListOfAssembliesToUpdate();
        }
示例#2
0
        private static int ProcessSuccessfulUpdates(AssemblyUpdaterUpdateTask[] tasks)
        {
            var assembliesToUpdate = GetAssembliesToBeUpdated();
            var succeededUpdates   = tasks.Where(t => t.Result == APIUpdaterAssemblyHelper.UpdatesApplied);

            if (!succeededUpdates.Any())
            {
                assembliesToUpdate.Clear();
                return(0);
            }

            var assembliesRequiringConsent = FilterOutLocalAndEmbeddedPackagesWhenAskingForConsent(assembliesToUpdate.Select(a => a.Path)).ToArray();

            if (assembliesRequiringConsent.Length > 0 && !AskForConsent(assembliesRequiringConsent))
            {
                APIUpdaterLogger.WriteToFile(L10n.Tr("User declined to run APIUpdater"));
                return(0);
            }

            var updatedAssemblyPaths = succeededUpdates.Select(u => u.Candidate.Path).ToArray();

            if (!CheckoutFromVCSIfNeeded(updatedAssemblyPaths))
            {
                return(-1);
            }

            APIUpdaterHelper.HandleFilesInPackagesVirtualFolder(updatedAssemblyPaths);
            if (!APIUpdaterHelper.CheckReadOnlyFiles(updatedAssemblyPaths))
            {
                return(0);
            }

            foreach (var succeed in succeededUpdates)
            {
                APIUpdaterLogger.WriteToFile("{0}{1}", Environment.NewLine, succeed.StdOut);
                FileUtil.MoveFileIfExists(succeed.OutputPath, succeed.Candidate.Path);
            }

            assembliesToUpdate.Clear();
            return(succeededUpdates.Count());

            bool CheckoutFromVCSIfNeeded(string[] assemblyPathsToCheck)
            {
                // Only try to connect to VCS if there are files under VCS that need to be updated
                var assembliesInAssetsFolder = assemblyPathsToCheck.Where(path => path.IndexOf("Assets/", StringComparison.OrdinalIgnoreCase) != -1).ToArray();

                if (!assembliesInAssetsFolder.Any())
                {
                    return(true);
                }

                if (!WaitForVCSServerConnection())
                {
                    return(false);
                }

                var failedToCheckoutFiles = !APIUpdaterHelper.MakeEditable(assembliesInAssetsFolder);

                if (failedToCheckoutFiles)
                {
                    assembliesToUpdate.Clear();
                    return(false);
                }

                return(true);
            }

            IEnumerable <string> FilterOutLocalAndEmbeddedPackagesWhenAskingForConsent(IEnumerable <string> ass)
            {
                foreach (var path in ass.Select(path => path.Replace("\\", "/"))) // package manager paths are always separated by /
                {
                    var packageInfo = UnityEditor.PackageManager.PackageInfo.FindForAssetPath(path);
                    if (packageInfo == null || packageInfo.source == PackageSource.Local || packageInfo.source == PackageSource.Embedded)
                    {
                        yield return(path);
                    }
                }
            }
        }