public MonoInstallTrigger(Lifetime lifetime, ILogger logger, ISolutionLoadTasksScheduler scheduler,
                                  ISolution solution, UnitySolutionTracker unitySolutionTracker, UnityHost host,
                                  NotificationsModel notificationsModel)
        {
            if (PlatformUtil.RuntimePlatform == PlatformUtil.Platform.Windows)
            {
                return;
            }

            scheduler.EnqueueTask(new SolutionLoadTask("Check mono runtime", SolutionLoadTaskKinds.AfterDone, () =>
            {
                if (!unitySolutionTracker.IsUnityGeneratedProject.Value)
                {
                    return;
                }

                if (!HasModernUnityProjects(solution))
                {
                    return;
                }

                solution.Locks.Tasks.Queue(lifetime, () =>
                {
                    var wellKnownMonoRuntimes = MonoRuntimeDetector.DetectWellKnownMonoRuntimes();
                    var installedValidMono    = wellKnownMonoRuntimes
                                                .Any(runtime =>
                    {
                        var parsedVersion = string.Empty;
                        try
                        {
                            parsedVersion = ProcessOutputUtil.ExtractMonoVersion(runtime.ExePath);
                        }
                        catch (Exception e)
                        {
                            logger.Warn(e);
                        }

                        // if we fail to parse version - consider it is old
                        if (Version.TryParse(parsedVersion, out var version))
                        {
                            return(version >= new Version(5, 16));    // mono 5.16+ supports C# 7.3
                        }
                        logger.Warn("Failed to parse ProcessOutputUtil.ExtractMonoVersion output.");
                        return(false);
                    });

                    if (installedValidMono)
                    {
                        return;
                    }

                    if (PlatformUtil.RuntimePlatform == PlatformUtil.Platform.MacOsX)
                    {
                        solution.Locks.ExecuteOrQueue(lifetime, "Show install mono dialog",
                                                      () => { host.PerformModelAction(model => model.ShowInstallMonoDialog()); });
                    }
                    else if (PlatformUtil.RuntimePlatform == PlatformUtil.Platform.Linux)
                    {
                        var notification = new NotificationModel("Mono 5.16+ is required",
                                                                 "<html>Project requires new Mono with MSBuild for new C# language features support.<br>" +
                                                                 RiderContextNotificationHelper.MakeOpenSettingsLink(
                                                                     WellKnownSettingPages.Environment,
                                                                     "Install the latest Mono")
                                                                 + ".<br>" +
                                                                 "If a Mono runtime is available in a non-standard location, please " +
                                                                 RiderContextNotificationHelper.MakeOpenSettingsLink(
                                                                     WellKnownSettingPages.ToolsetAndBuild,
                                                                     "specify the custom runtime location in settings")
                                                                 + ".</html>"

                                                                 , true,
                                                                 RdNotificationEntryType.WARN);
                        solution.Locks.ExecuteOrQueue(lifetime, "MonoInstallTrigger.Notify", () => notificationsModel.Notification(notification));
                    }
                });
            }));
        }
示例#2
0
        public UnrealPluginDetector(Lifetime lifetime, ILogger logger,
                                    CppUE4SolutionDetector solutionDetector, ISolution solution,
                                    IShellLocks locks, ISolutionLoadTasksScheduler scheduler)
        {
            myLifetime          = lifetime;
            InstallInfoProperty =
                new Property <UnrealPluginInstallInfo>(myLifetime, "UnrealPlugin.InstallInfoNotification", null, true);
            myLogger           = logger;
            mySolution         = solution;
            mySolutionDetector = solutionDetector;

            mySolutionDetector.IsUE4Solution_Observable.Change.Advise_When(myLifetime,
                                                                           newValue => newValue == TriBool.True, _ =>
            {
                scheduler.EnqueueTask(new SolutionLoadTask("Find installed RiderLink plugins",
                                                           SolutionLoadTaskKinds.Done,
                                                           () =>
                {
                    myLogger.Info("[UnrealLink]: Looking for RiderLink plugins");
                    myUnrealVersion = mySolutionDetector.Version;

                    if (myUnrealVersion < myMinimalSupportedVersion)
                    {
                        locks.ExecuteOrQueue(myLifetime, "UnrealLink.CheckSupportedVersion",
                                             () =>
                        {
                            var notification =
                                new NotificationModel(
                                    $"Unreal Engine {myMinimalSupportedVersion}+ is required",
                                    $"<html>UnrealLink supports Unreal Engine versions starting with {myMinimalSupportedVersion}<br>" +
                                    "<b>WARNING: Advanced users only</b><br>" +
                                    "You can manually download the latest version of plugin and build It for your version of Unreal Editor<br>" +
                                    RiderContextNotificationHelper.MakeLink(
                                        "https://github.com/JetBrains/UnrealLink/releases/latest",
                                        "Download latest Unreal Editor plugin") +
                                    "</html>",
                                    true,
                                    RdNotificationEntryType.WARN,
                                    new List <NotificationHyperlink>());
                            var notificationsModel = Shell.Instance.GetComponent <NotificationsModel>();
                            notificationsModel.Notification(notification);
                        });
                        return;
                    }

                    var installInfo       = new UnrealPluginInstallInfo();
                    var foundEnginePlugin = TryGetEnginePluginFromSolution(solutionDetector, installInfo);
                    ISet <FileSystemPath> uprojectLocations;
                    using (solution.Locks.UsingReadLock())
                    {
                        var allProjects = mySolution.GetAllProjects();
                        if (solutionDetector.SupportRiderProjectModel ==
                            CppUE4ProjectModelSupportMode.UprojectOpened)
                        {
                            uprojectLocations = allProjects.Where(project =>
                            {
                                if (project.IsMiscProjectItem() || project.IsMiscFilesProject())
                                {
                                    return(false);
                                }

                                var location = project.Location;
                                if (location == null)
                                {
                                    return(false);
                                }

                                if (EXCLUDED_PROJECTS.Contains(location.NameWithoutExtension))
                                {
                                    return(false);
                                }

                                // TODO: drop this ugly check after updating to net211 where Location == "path/to/game.uproject"
                                var isUproject =
                                    location.ExistsFile && location.ExtensionNoDot == UPROJECT_FILE_FORMAT &&
                                    location.NameWithoutExtension == project.Name;
                                return(isUproject || (location / $"{location.Name}.uproject").ExistsFile);
                            }).Select(project =>
                            {
                                var location = project.Location;
                                if (location.ExistsFile)
                                {
                                    return(location);
                                }
                                return(location / $"{location.Name}.uproject");
                            }).ToSet();
                        }
                        else
                        {
                            uprojectLocations = allProjects.SelectMany(project =>
                                                                       project.GetAllProjectFiles(projectFile =>
                            {
                                var location = projectFile.Location;
                                if (location == null || !location.ExistsFile)
                                {
                                    return(false);
                                }

                                return(location.ExtensionNoDot == UPROJECT_FILE_FORMAT &&
                                       location.NameWithoutExtension == project.Name);
                            })).Select(file => file.Location).ToSet();
                        }
                    }

                    myLogger.Info($"[UnrealLink]: Found {uprojectLocations.Count} uprojects");

                    if (!foundEnginePlugin && !uprojectLocations.IsEmpty())
                    {
                        // All projects in the solution are bound to the same engine
                        // So take first project and use it to find Unreal Engine
                        TryGetEnginePluginFromUproject(uprojectLocations.FirstNotNull(), installInfo);
                        foundEnginePlugin = installInfo.EnginePlugin.IsPluginAvailable;
                    }

                    // Gather data about Project plugins
                    foreach (var uprojectLocation in uprojectLocations)
                    {
                        myLogger.Info($"[UnrealLink]: Looking for plugin in {uprojectLocation}");
                        var projectPlugin = GetProjectPluginForUproject(uprojectLocation);
                        if (projectPlugin.IsPluginAvailable)
                        {
                            myLogger.Info(
                                $"[UnrealLink]: found plugin {projectPlugin.UnrealPluginRootFolder}");
                        }

                        installInfo.ProjectPlugins.Add(projectPlugin);
                    }

                    if (foundEnginePlugin)
                    {
                        installInfo.Location = PluginInstallLocation.Engine;
                    }
                    else if (installInfo.ProjectPlugins.Any(description => description.IsPluginAvailable))
                    {
                        installInfo.Location = PluginInstallLocation.Game;
                    }
                    else
                    {
                        installInfo.Location = PluginInstallLocation.NotInstalled;
                    }
                    InstallInfoProperty.SetValue(installInfo);
                }));
            });
        }