// this method should be very fast as it gets called a lot public HostProviderAvailability GetAvailability(IUnitTestElement element) { var solution = element.Id.Project.GetSolution(); var tracker = solution.GetComponent <UnitySolutionTracker>(); if (tracker.IsUnityProject.HasValue() && !tracker.IsUnityProject.Value) { return(HostProviderAvailability.Available); } var frontendBackendModel = solution.GetProtocolSolution().GetFrontendBackendModel(); switch (frontendBackendModel.UnitTestPreference.Value) { case UnitTestLaunchPreference.NUnit: return(HostProviderAvailability.Available); case UnitTestLaunchPreference.Both: case UnitTestLaunchPreference.PlayMode: case UnitTestLaunchPreference.EditMode: { var unityVersion = UnityVersion.Parse(frontendBackendModel.UnityApplicationData.Maybe.ValueOrDefault?.ApplicationVersion ?? string.Empty); return(unityVersion == null || unityVersion < ourMinSupportedUnityVersion ? HostProviderAvailability.Nonexistent : HostProviderAvailability.Available); } default: return(HostProviderAvailability.Nonexistent); } }
public static UnityPluginParameter ParseUnityPluginParameter( Configs.UnityPlugins configs, Configs.UnityManagedPluginProject projectConfig) { Ensure.Argument.NotNull(configs, nameof(configs)); Ensure.Argument.NotNull(projectConfig, nameof(projectConfig)); StringToVersionInfo versions = null; if (projectConfig.ForMultipleVersions) { versions = projectConfig.Versions ?? new StringToVersionInfo(); foreach (var kvp in configs.DefaultVersions) { var ver = kvp.Key; var info = kvp.Value; if (!versions.ContainsKey(ver)) { versions.Add(ver, info); } } } var parameter = new UnityPluginParameter { ForEditor = projectConfig.ForEditor, Versions = versions?.ToDictionary(p => UnityVersion.Parse(p.Key), p => p.Value) }; return(parameter); }
private async Task RefreshInternal(Lifetime lifetime, RefreshType refreshType) { var lifetimeDef = Lifetime.Define(lifetime); myLogger.Verbose($"myPluginProtocolController.UnityModel.Value.Refresh.StartAsTask, force = {refreshType} Started"); mySolution.GetComponent <RiderBackgroundTaskHost>().AddNewTask(lifetimeDef.Lifetime, RiderBackgroundTaskBuilder.Create().WithHeader("Refreshing solution in Unity Editor...") .AsIndeterminate().AsNonCancelable()); try { try { var version = UnityVersion.Parse(myEditorProtocol.UnityModel.Value.UnityApplicationData.Value.ApplicationVersion); if (version != null && version.Major < 2018) { using (mySolution.GetComponent <VfsListener>().PauseChanges()) { await myEditorProtocol.UnityModel.Value.Refresh.Start(lifetimeDef.Lifetime, refreshType).AsTask(); } } else // it is a risk to pause vfs https://github.com/JetBrains/resharper-unity/issues/1601 { await myEditorProtocol.UnityModel.Value.Refresh.Start(lifetimeDef.Lifetime, refreshType).AsTask(); } } catch (Exception e) { myLogger.Warn("connection usually brakes during refresh.", e); } finally { try { myLogger.Verbose( $"myPluginProtocolController.UnityModel.Value.Refresh.StartAsTask, force = {refreshType} Finished"); var solution = mySolution.GetProtocolSolution(); var solFolder = mySolution.SolutionDirectory; var list = new List <string> { solFolder.FullPath }; myLogger.Verbose($"RefreshPaths.StartAsTask Finished."); await solution.GetFileSystemModel().RefreshPaths.Start(lifetimeDef.Lifetime, new RdRefreshRequest(list, true)).AsTask(); } finally { myLogger.Verbose($"RefreshPaths.StartAsTask Finished."); lifetimeDef.Terminate(); } } } catch (Exception e) { myLogger.LogException(e); } finally { lifetimeDef.Terminate(); } }
internal static bool UnityVersionSatisfiesPackageUnityVersion(string unityVersionString, string packageUnityVersionString) { var unityVersion = UnityVersion.Parse(unityVersionString); var packageUnityVersion = UnityVersion.Parse(packageUnityVersionString); // We only care about major and minor version var truncatedUnityVersion = new SemVersion(unityVersion.Major, unityVersion.Minor); var truncatedPackageUnityVersion = new SemVersion(packageUnityVersion.Major, packageUnityVersion.Minor); return(truncatedUnityVersion >= truncatedPackageUnityVersion); }
private static Version TryGetUnityVersionFromDll(XmlElement documentElement) { var referencePathElement = documentElement.ChildElements() .Where(a => a.Name == "ItemGroup").SelectMany(b => b.ChildElements()) .Where(c => c.Name == "Reference" && c.GetAttribute("Include").StartsWith("UnityEngine") || c.GetAttribute("Include").Equals("UnityEditor")) .SelectMany(d => d.ChildElements()) .FirstOrDefault(c => c.Name == "HintPath"); if (referencePathElement == null || string.IsNullOrEmpty(referencePathElement.InnerText)) { return(null); } var filePath = FileSystemPath.Parse(referencePathElement.InnerText); if (!filePath.IsAbsolute) // RIDER-21237 { return(null); } if (filePath.ExistsFile) { if (PlatformUtil.RuntimePlatform == PlatformUtil.Platform.Windows) { var exePath = filePath.Combine("../../../Unity.exe"); // Editor\Data\Managed\UnityEngine.dll if (!exePath.ExistsFile) { exePath = filePath.Combine("../../../../Unity.exe"); // Editor\Data\Managed\UnityEngine\UnityEngine.dll } if (exePath.ExistsFile) { return(new Version(new Version(FileVersionInfo.GetVersionInfo(exePath.FullPath).FileVersion).ToString(3))); } } else if (PlatformUtil.RuntimePlatform == PlatformUtil.Platform.MacOsX) { var infoPlistPath = filePath.Combine("../../Info.plist"); if (!infoPlistPath.ExistsFile) { infoPlistPath = filePath.Combine("../../../Info.plist"); } if (!infoPlistPath.ExistsFile) { return(null); } var fullVersion = UnityVersion.GetVersionFromInfoPlist(infoPlistPath); return(UnityVersion.Parse(fullVersion)); } } return(null); }
private static UnityVersion FindProjectVersion(DirectoryInfo unityProjectDir) { var versionPath = Path.Combine(unityProjectDir.FullName, "ProjectSettings", "ProjectVersion.txt"); var versionText = File.ReadAllText(versionPath); var match = UnityVersionRegex.Match(versionText); if (!match.Success) { throw new ConfigParseException("Failed to parse unity version from ProjectVersion.txt."); } var ver = match.Groups["ver"].Value; return(UnityVersion.Parse(ver)); }
private static UnityVersion ParseVersion() { var versionPath = Path.Combine(ProjectPaths.Settings, "ProjectVersion.txt"); var versionText = File.ReadAllText(versionPath); var match = VersionRegex.Match(versionText); if (!match.Success) { throw new InvalidOperationException("Failed to parse unity version from ProjectVersion.txt."); } var ver = match.Groups["ver"].Value; return(UnityVersion.Parse(ver)); }
private void TrackActivity(BackendUnityModel backendUnityModel, Lifetime modelLifetime) { backendUnityModel.UnityApplicationData.AdviseOnce(modelLifetime, data => { // ApplicationVersion may look like `2017.2.1f1-CustomPostfix` var unityVersion = UnityVersion.VersionToString(UnityVersion.Parse(data.ApplicationVersion)); if (data.ApplicationVersion.StartsWith(unityVersion) && unityVersion != data.ApplicationVersion) { myUsageStatistics.TrackActivity("UnityVersion", unityVersion + "-custom"); // impersonate, but still track that it is custom build } else { myUsageStatistics.TrackActivity("UnityVersion", unityVersion); } }); backendUnityModel.UnityProjectSettings.ScriptingRuntime.AdviseOnce(modelLifetime, runtime => { myUsageStatistics.TrackActivity("ScriptingRuntime", runtime.ToString()); }); }
protected override UnityVersion DetermineVersion(FilePath editorPath) { log.Debug($"Determining version of Unity Editor at path {editorPath}..."); string version; using (var stream = fileSystem.GetFile(PlistPath(editorPath)).OpenRead()) version = new InfoPlistParser().UnityVersionFromInfoPlist(stream); if (version == null) { log.Debug($"Can't find UnityVersion for {editorPath}"); return(null); } var unityVersion = UnityVersion.Parse(version); log.Debug($"Result Unity Editor version (full): {unityVersion}"); return(unityVersion); }
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 static UnityVersion VersionOfConfiguration(string configuration) { var match = configurationRegex.Match(configuration); return(!match.Success ? null : UnityVersion.Parse(match.Groups["ver"].Value)); }
private static void Parse(UnityVersion obj, string text) { Assert.AreEqual(obj, UnityVersion.Parse(text)); }
static SemVersion GetPackageUnityVersion(ManifestData manifest) { return(string.IsNullOrEmpty(manifest.unity) ? new SemVersion(0) : UnityVersion.Parse(manifest.unity)); }