public bool HasNonCompatiblePackagesCombination(bool isCoverage, out string message) { message = string.Empty; if (myUnityVersion.GetActualVersionForSolution() < new Version("2019.2")) { return(false); } var manifestJsonFile = mySolution.SolutionDirectory.Combine("Packages/manifest.json"); if (manifestJsonFile.ExistsFile) { var text = manifestJsonFile.ReadAllText2().Text; var packages = ManifestJson.FromJson(text); var testFrameworkPackageId = "com.unity.test-framework"; var riderPackageId = "com.unity.ide.rider"; var testFrameworkMarketingName = "Test Framework"; var riderMarketingName = "Rider Editor"; if (PackageIsMissing(ref message, packages, testFrameworkPackageId, testFrameworkMarketingName)) { return(true); } if (PackageIsMissing(ref message, packages, riderPackageId, riderMarketingName)) { return(true); } var riderPackageVersion = packages[riderPackageId]; var testFrameworkVersion = packages[testFrameworkPackageId]; if (IsOldPackage(ref message, riderPackageVersion, riderMarketingName, "1.1.1")) { return(true); } if (IsOldPackage(ref message, testFrameworkVersion, testFrameworkMarketingName, "1.1.1")) { return(true); } if (isCoverage && packages.ContainsKey(riderPackageId) && packages.ContainsKey(testFrameworkPackageId)) { // https://youtrack.jetbrains.com/issue/RIDER-35880 if (riderPackageVersion != null && riderPackageVersion < new Version("1.2.0") && testFrameworkVersion != null && testFrameworkVersion >= new Version("1.1.5")) { message = $"Update {riderMarketingName} package to v.1.2.0 or later in Unity Package Manager. {HelpLink}"; return(true); } } } // todo: package may be installed locally, ignore this possibility for now // var localPackage = mySolution.SolutionDirectory.Combine("Packages/com.unity.ide.rider/package.json"); return(false); }
private FileID GetCorrespondingSourceObjectFileId(IYamlDocument document) { if (myVersion.GetActualVersionForSolution().Major == 2017) { return(document.GetUnityObjectPropertyValue(UnityYamlConstants.CorrespondingSourceObjectProperty2017)?.AsFileID()); } return(document.GetUnityObjectPropertyValue(UnityYamlConstants.CorrespondingSourceObjectProperty)?.AsFileID() ?? document.GetUnityObjectPropertyValue(UnityYamlConstants.CorrespondingSourceObjectProperty2017)?.AsFileID()); }
private void NotifyFrontend(UnityHost host, UnityVersion unityVersion) { host.PerformModelAction(rd => { // if model is there, then ApplicationPath was already set via UnityEditorProtocol, it would be more correct than any counted value if (myUnityEditorProtocol.UnityModel.Value != null) { return; } var version = unityVersion.GetActualVersionForSolution(); var info = UnityInstallationFinder.GetApplicationInfo(version, unityVersion); if (info == null) { return; } var contentsPath = UnityInstallationFinder.GetApplicationContentsPath(info.Path); rd.UnityApplicationData.SetValue(new UnityApplicationData(info.Path.FullPath, contentsPath.FullPath, UnityVersion.VersionToString(info.Version), UnityVersion.RequiresRiderPackage(info.Version) )); }); }
private static void NotifyFrontend(UnityHost host, UnityVersion unityVersion) { var version = unityVersion.GetActualVersionForSolution(); var info = UnityInstallationFinder.GetApplicationInfo(version); if (info == null) { return; } host.PerformModelAction(rd => { // ApplicationPath may be already set via UnityEditorProtocol, which is more accurate if (!rd.ApplicationPath.HasValue()) { rd.ApplicationPath.SetValue(info.Path.FullPath); } if (!rd.ApplicationContentsPath.HasValue()) { var contentsPath = UnityInstallationFinder.GetApplicationContentsPath(version); if (contentsPath != null) { rd.ApplicationContentsPath.SetValue(contentsPath.FullPath); } } if (!rd.ApplicationVersion.HasValue() && info.Version != null) { rd.ApplicationVersion.SetValue(UnityVersion.VersionToString(info.Version)); } }); }
public UnityInstallationSynchronizer(Lifetime lifetime, UnityReferencesTracker referencesTracker, UnityHost host, UnityInstallationFinder finder, UnityVersion unityVersion) { referencesTracker.HasUnityReference.Advise(lifetime, hasReference => { if (!hasReference) { return; } var version = unityVersion.GetActualVersionForSolution(); var path = finder.GetApplicationPath(version); if (path == null) { return; } var contentPath = finder.GetApplicationContentsPath(version); host.PerformModelAction(rd => { // ApplicationPath may be already set via UnityEditorProtocol, which is more accurate if (!rd.ApplicationPath.HasValue()) { rd.ApplicationPath.SetValue(path.FullPath); } if (!rd.ApplicationContentsPath.HasValue()) { rd.ApplicationContentsPath.SetValue(contentPath.FullPath); } }); }); }
private static void NotifyFrontend(UnityHost host, UnityVersion unityVersion) { var version = unityVersion.GetActualVersionForSolution(); var applicationPath = unityVersion.GetActualAppPathForSolution(); if (PlatformUtil.RuntimePlatform == PlatformUtil.Platform.MacOsX && !applicationPath.ExistsDirectory || PlatformUtil.RuntimePlatform != PlatformUtil.Platform.MacOsX && !applicationPath.ExistsFile) { var info = UnityInstallationFinder.GetApplicationInfo(version); if (info == null) { return; } applicationPath = info.Path; version = info.Version; } host.PerformModelAction(rd => { // ApplicationPath may be already set via UnityEditorProtocol, which will obviously be correct if (!rd.ApplicationPath.HasValue()) { rd.ApplicationPath.SetValue(applicationPath.FullPath); } if (!rd.ApplicationContentsPath.HasValue()) { var contentsPath = UnityInstallationFinder.GetApplicationContentsPath(applicationPath); if (!contentsPath.IsEmpty) { rd.ApplicationContentsPath.SetValue(contentsPath.FullPath); } } if (!rd.ApplicationVersion.HasValue() && version != null) { rd.ApplicationVersion.SetValue(UnityVersion.VersionToString(version)); } }); }
private void NotifyFrontend(UnityHost host, UnityVersion unityVersion) { var version = unityVersion.GetActualVersionForSolution(); var applicationPath = unityVersion.GetActualAppPathForSolution(); if (PlatformUtil.RuntimePlatform == PlatformUtil.Platform.MacOsX && !applicationPath.ExistsDirectory || PlatformUtil.RuntimePlatform != PlatformUtil.Platform.MacOsX && !applicationPath.ExistsFile) { var info = UnityInstallationFinder.GetApplicationInfo(version); if (info == null) { return; } applicationPath = info.Path; version = info.Version; } host.PerformModelAction(rd => { // if model is there, then ApplicationPath was already set via UnityEditorProtocol, it would be more correct than any counted value if (myUnityEditorProtocol.UnityModel.Value != null) { return; } rd.ApplicationPath.SetValue(applicationPath.FullPath); var contentsPath = UnityInstallationFinder.GetApplicationContentsPath(applicationPath); if (!contentsPath.IsEmpty) { rd.ApplicationContentsPath.SetValue(contentsPath.FullPath); } if (version != null) { rd.ApplicationVersion.SetValue(UnityVersion.VersionToString(version)); } }); }
public UnityInstallationSynchronizer(Lifetime lifetime, UnitySolutionTracker solutionTracker, UnityHost host, UnityInstallationFinder finder, UnityVersion unityVersion) { solutionTracker.IsUnityProjectFolder.AdviseNotNull(lifetime, isUnityProjectFolder => { if (!isUnityProjectFolder) { return; } var version = unityVersion.GetActualVersionForSolution(); var info = finder.GetApplicationInfo(version); if (info == null) { return; } var contentPath = finder.GetApplicationContentsPath(version); host.PerformModelAction(rd => { // ApplicationPath may be already set via UnityEditorProtocol, which is more accurate if (!rd.ApplicationPath.HasValue()) { rd.ApplicationPath.SetValue(info.Path.FullPath); } if (!rd.ApplicationContentsPath.HasValue()) { rd.ApplicationContentsPath.SetValue(contentPath.FullPath); } if (!rd.ApplicationVersion.HasValue()) { rd.ApplicationVersion.SetValue(UnityVersion.VersionToString(info.Version)); } }); }); }
private string GetCorrespondingSourceObjectProperty() { return(myVersion.GetActualVersionForSolution().Major == 2017 ? UnityYamlConstants.CorrespondingSourceObjectProperty2017 : UnityYamlConstants.CorrespondingSourceObjectProperty); }
private void CreateProtocols(FileSystemPath protocolInstancePath) { if (!protocolInstancePath.ExistsFile) { return; } List <ProtocolInstance> protocolInstanceList; try { protocolInstanceList = ProtocolInstance.FromJson(protocolInstancePath.ReadAllText2().Text); } catch (Exception e) { myLogger.Warn($"Unable to parse {protocolInstancePath}" + Environment.NewLine + e); return; } var protocolInstance = protocolInstanceList?.SingleOrDefault(a => a.SolutionName == mySolution.SolutionFilePath.NameWithoutExtension); if (protocolInstance == null) { return; } myLogger.Info($"EditorPlugin protocol port {protocolInstance.Port} for Solution: {protocolInstance.SolutionName}."); try { var lifetime = mySessionLifetimes.Next(); myLogger.Info("Create protocol..."); myLogger.Info("Creating SocketWire with port = {0}", protocolInstance.Port); var wire = new SocketWire.Client(lifetime, myDispatcher, protocolInstance.Port, "UnityClient"); var protocol = new Protocol("UnityEditorPlugin", new Serializers(), new Identities(IdKind.Client), myDispatcher, wire, lifetime); protocol.ThrowErrorOnOutOfSyncModels = false; protocol.OutOfSyncModels.AdviseOnce(lifetime, e => { if (myPluginInstallations.Contains(mySolution.SolutionFilePath)) { return; } myPluginInstallations.Add(mySolution.SolutionFilePath); // avoid displaying Notification multiple times on each AppDomain.Reload in Unity var appVersion = myUnityVersion.GetActualVersionForSolution(); if (appVersion < new Version(2019, 2)) { var entry = myBoundSettingsStore.Schema.GetScalarEntry((UnitySettings s) => s.InstallUnity3DRiderPlugin); var isEnabled = myBoundSettingsStore.GetValueProperty <bool>(lifetime, entry, null).Value; if (!isEnabled) { myHost.PerformModelAction(model => model.OnEditorModelOutOfSync()); } } else { var notification = new NotificationModel("Advanced Unity integration is unavailable", $"Please update External Editor to {myHostProductInfo.VersionMarketingString} in Unity Preferences.", true, RdNotificationEntryType.WARN); mySolution.Locks.ExecuteOrQueue(lifetime, "OutOfSyncModels.Notify", () => myNotificationsModel.Notification(notification)); } }); wire.Connected.WhenTrue(lifetime, lf => { myLogger.Info("WireConnected."); var editor = new EditorPluginModel(lf, protocol); editor.IsBackendConnected.Set(rdVoid => true); if (PlatformUtil.RuntimePlatform == PlatformUtil.Platform.Windows) { var frontendProcess = Process.GetCurrentProcess().GetParent(); // RiderProcessId is not used on non-Windows, but this line gives bad warning in the log if (frontendProcess != null) { editor.RiderProcessId.SetValue(frontendProcess.Id); } } myHost.PerformModelAction(m => m.SessionInitialized.Value = true); SubscribeToLogs(lf, editor); SubscribeToOpenFile(editor); editor.Play.Advise(lf, b => myHost.PerformModelAction(rd => rd.Play.SetValue(b))); editor.Pause.Advise(lf, b => myHost.PerformModelAction(rd => rd.Pause.SetValue(b))); editor.ClearOnPlay.Advise(lf, time => myHost.PerformModelAction(rd => rd.ClearOnPlay(time))); editor.UnityProcessId.View(lf, (_, pid) => myHost.PerformModelAction(t => t.UnityProcessId.Set(pid))); // I have split this into groups, because want to use async api for finding reference and pass them via groups to Unity myHost.PerformModelAction(t => t.ShowFileInUnity.Advise(lf, v => editor.ShowFileInUnity.Fire(v))); myHost.PerformModelAction(t => t.ShowPreferences.Advise(lf, v => { editor.ShowPreferences.Fire(); })); editor.EditorLogPath.Advise(lifetime, s => myHost.PerformModelAction(a => a.EditorLogPath.SetValue(s))); editor.PlayerLogPath.Advise(lifetime, s => myHost.PerformModelAction(a => a.PlayerLogPath.SetValue(s))); // Note that these are late-init properties. Once set, they are always set and do not allow nulls. // This means that if/when the Unity <-> Backend protocol closes, they still retain the last value // they had - so the front end will retain the log and application paths of the just-closed editor. // Opening a new editor instance will reconnect and push a new value through to the front end editor.UnityApplicationData.Advise(lifetime, s => myHost.PerformModelAction(a => { var version = UnityVersion.Parse(s.ApplicationVersion); a.UnityApplicationData.SetValue(new UnityApplicationData(s.ApplicationPath, s.ApplicationContentsPath, s.ApplicationVersion, UnityVersion.RequiresRiderPackage(version))); })); editor.ScriptCompilationDuringPlay.Advise(lifetime, s => myHost.PerformModelAction(a => a.ScriptCompilationDuringPlay.Set(ConvertToScriptCompilationEnum(s)))); myHost.PerformModelAction(rd => { rd.GenerateUIElementsSchema.Set((l, u) => editor.GenerateUIElementsSchema.Start(l, u).ToRdTask(l)); }); TrackActivity(editor, lf); if (!myComponentLifetime.IsTerminated) { myLocks.ExecuteOrQueueEx(myComponentLifetime, "setModel", () => { UnityModel.SetValue(editor); }); } lf.AddAction(() => { if (!myComponentLifetime.IsTerminated) { myLocks.ExecuteOrQueueEx(myComponentLifetime, "clearModel", () => { myLogger.Info("Wire disconnected."); myHost.PerformModelAction(m => m.SessionInitialized.Value = false); UnityModel.SetValue(null); }); } }); }); } catch (Exception ex) { myLogger.Error(ex); } }
private bool DoCopyFiles([NotNull] UnityPluginDetector.InstallationInfo installation, out FileSystemPath installedPath) { installedPath = null; var originPaths = new List <FileSystemPath>(); originPaths.AddRange(installation.ExistingFiles); var backups = originPaths.ToDictionary(f => f, f => f.AddSuffix(".backup")); foreach (var originPath in originPaths) { var backupPath = backups[originPath]; if (originPath.ExistsFile) { originPath.MoveFile(backupPath, true); myLogger.Info($"backing up: {originPath.Name} -> {backupPath.Name}"); } else { myLogger.Info($"backing up failed: {originPath.Name} doesn't exist."); } } try { var editorPluginPathDir = myPluginPathsProvider.GetEditorPluginPathDir(); var editorPluginPath = editorPluginPathDir.Combine(PluginPathsProvider.BasicPluginDllFile); var editorFullPluginPath = editorPluginPathDir.Combine(PluginPathsProvider.FullPluginDllFile); var targetPath = installation.PluginDirectory.Combine(editorPluginPath.Name); try { if (myUnityVersion.GetActualVersionForSolution() < new Version("5.6")) { myLogger.Verbose($"Coping {editorPluginPath} -> {targetPath}"); editorPluginPath.CopyFile(targetPath, true); } else { myLogger.Verbose($"Coping {editorFullPluginPath} -> {targetPath}"); editorFullPluginPath.CopyFile(targetPath, true); } } catch (Exception e) { myLogger.LogException(LoggingLevel.ERROR, e, ExceptionOrigin.Assertion, $"Failed to copy {editorPluginPath} => {targetPath}"); RestoreFromBackup(backups); } foreach (var backup in backups) { backup.Value.DeleteFile(); } installedPath = installation.PluginDirectory.Combine(PluginPathsProvider.BasicPluginDllFile); return(true); } catch (Exception e) { myLogger.LogExceptionSilently(e); RestoreFromBackup(backups); return(false); } }
private void InstallPluginIfRequired() { if (!myUnitySolutionTracker.IsUnityProjectFolder.Value) { return; } if (myPluginInstallations.Contains(mySolution.SolutionFilePath)) { return; } if (!myBoundSettingsStore.GetValue((UnitySettings s) => s.InstallUnity3DRiderPlugin)) { return; } var versionForSolution = myUnityVersion.GetActualVersionForSolution(); if (versionForSolution >= new Version("2019.2")) // 2019.2+ would not work fine either without Rider package, and when package is present it loads EditorPlugin directly from Rider installation. { var installationInfoToRemove = myDetector.GetInstallationInfo(myCurrentVersion, previousInstallationDir: FileSystemPath.Empty); var pluginDll = installationInfoToRemove.PluginDirectory.Combine(PluginPathsProvider.BasicPluginDllFile); if (pluginDll.ExistsFile) { myQueue.Enqueue(() => { myLogger.Info($"Remove {pluginDll}. Rider package should be used instead."); pluginDll.DeleteFile(); FileSystemPath.Parse(pluginDll.FullPath + ".meta").DeleteFile(); // jetbrainsDir is usually "Assets\Plugins\Editor\JetBrains", however custom locations were also possible var jetbrainsDir = installationInfoToRemove.PluginDirectory; if (jetbrainsDir.GetChildren().Any() || jetbrainsDir.Name != "JetBrains") { return; } jetbrainsDir.DeleteDirectoryNonRecursive(); FileSystemPath.Parse(jetbrainsDir.FullPath + ".meta").DeleteFile(); var pluginsEditorDir = jetbrainsDir.Directory; if (pluginsEditorDir.GetChildren().Any() || pluginsEditorDir.Name != "Editor") { return; } pluginsEditorDir.DeleteDirectoryNonRecursive(); FileSystemPath.Parse(pluginsEditorDir.FullPath + ".meta").DeleteFile(); var pluginsDir = pluginsEditorDir.Directory; if (pluginsDir.GetChildren().Any() || pluginsDir.Name != "Plugins") { return; } pluginsDir.DeleteDirectoryNonRecursive(); FileSystemPath.Parse(pluginsDir.FullPath + ".meta").DeleteFile(); }); } return; } // forcing fresh install due to being unable to provide proper setting until InputField is patched in Rider // ReSharper disable once ArgumentsStyleNamedExpression var installationInfo = myDetector.GetInstallationInfo(myCurrentVersion, previousInstallationDir: FileSystemPath.Empty); if (!installationInfo.ShouldInstallPlugin) { myLogger.Info("Plugin should not be installed."); if (installationInfo.ExistingFiles.Count > 0) { myLogger.Info("Already existing plugin files:\n{0}", string.Join("\n", installationInfo.ExistingFiles)); } return; } QueueInstall(installationInfo); myQueue.Enqueue(() => { mySolution.Locks.Tasks.StartNew(myLifetime, Scheduling.MainGuard, () => myRefresher.StartRefresh(RefreshType.Normal)); }); }