Resharper-unity: Improve method of finding Unity version

Created on 6 Apr 2018  路  13Comments  路  Source: JetBrains/resharper-unity

Currently, the target version of Unity comes from the defines in the .csproj (e.g. UNITY_5_5). This doesn't work for external class libraries, where the define isn't set manually, and if the version isn't set

The version should come from /ProjectSettings/ProjectVersion.txt, or even from the editor itself via the protocol (although this doesn't help class libraries).

See #121 for more context, and examples of how to get the version

refactor

Most helpful comment

It may be worth noting that ProjectSettings/ProjectVersion.txt doesn't get proactively saved by Unity when you open a project with a newer version of Unity. (Which frustrates me.)

User must trigger the save for the new version to be written out. (Not sure about all of the entry-points for that to happen, other than Cmd/Ctrl-S or File->Save Project.)

Your layered approach will account for this, I just wanted to mention this issue if you didn't already know about it.

EDIT: This is only for external class libraries, right? Any reason to not tell authors via a build error that they should add a project define for the Unity version they're targeting?

All 13 comments

  1. External class libraries do not have /ProjectSettings/ProjectVersion.txt
  2. External class libraries do not have protocol connection to UnityEditor.

On 182 even without known version Generate Unity event functions is available.
So is this still an issue?

@citizenmatt ^

I'll take a look. Thanks for the ping :)

I'd say that this is not urgent, but we should refactor things a bit at some point. It's a little hard to reason about right now.

For example, I _think_ we'll get a cached version of 0.0 if there are no defines, but in another place (which shouldn't get hit) we'd end up with a version of 5.4.

But then when we use the version to look things up in the API, we make it fit into our currently supported range of 5.0 to 2018.1, matching lowest first (so 0.0 would be treated like 5.0).

So right now, as long as we have a reference to UnityEngine.dll, we should get all features, even in class libraries, although generated items and inspections will be based on the oldest version of the Unity API.

I think we need a layered, prioritised approach:

  • Manually specified via project options
  • Project defines
  • ProjectSettings/ProjectVersion.txt
  • Protocol

And we should show this on the settings page, with an explanation of where the version has come from. But this will require rework, as some of these are project level and some are solution level.

It may be worth noting that ProjectSettings/ProjectVersion.txt doesn't get proactively saved by Unity when you open a project with a newer version of Unity. (Which frustrates me.)

User must trigger the save for the new version to be written out. (Not sure about all of the entry-points for that to happen, other than Cmd/Ctrl-S or File->Save Project.)

Your layered approach will account for this, I just wanted to mention this issue if you didn't already know about it.

EDIT: This is only for external class libraries, right? Any reason to not tell authors via a build error that they should add a project define for the Unity version they're targeting?

When Unity dll is inside Unity installation, we can determine its version
On Windows - FileVersion of Unity.exe
On Mac - read from Info.plist
On Linux - read from path (worst, but only option on Linux for now)

So, in order of priority, most accurate to least:

  • Get version from the protocol. We'll need to cope with this appearing and disappearing during the solution lifetime. I don't see this being an issue
  • Parse version from defines in C# project. This is likely to be most accurate, as the currently open Unity will have generated the project files
  • Fetch version from Unity app if UnityEngine.dll is from an install folder. This should hopefully help class libraries, but the assembly is not guaranteed to be referenced from the install folder
  • Read version from ProjectSettings/ProjectVersion.txt. This is the least reliable, as it really reflects the version of Unity that last saved the project, and could be different to currently open. Class libraries might not even have this file
  • A per-project setting, saved to .sln.dotSettings
  • Default value of the latest supported Unity (get it from our Unity API data)

And also show version information in the settings page, with a message where it came from.

2018.3 EAP5 will have "Fetch version from Unity app if UnityEngine.dll is from an install folder. This should hopefully help class libraries, but the assembly is not guaranteed to be referenced from the install folder" for Windows and Mac.

Update, because I missed out EditorInstance.json, and didn't mention finding application path, because they're related:

Getting the Unity version in priority order, most accurate to least:

  • Get version from the protocol. We'll need to cope with this appearing and disappearing during the solution lifetime. I don't see this being an issue
  • Parse version from EditorInstance.json if available. This requires Unity 2017.1 and above, or the Rider plugin installed, and it's only available if the project is currently open.
  • Parse version from defines in C# project. This is likely to be most accurate, as the currently open Unity will have generated the project files
  • Fetch version from Unity app if UnityEngine.dll is from an install folder. This should hopefully help class libraries, but the assembly is not guaranteed to be referenced from the install folder
  • Read version from ProjectSettings/ProjectVersion.txt. This is the least reliable, as it really reflects the version of Unity that last saved the project, and could be different to currently open. Class libraries might not even have this file
  • A per-project setting, saved to .sln.dotSettings
  • Default value of the latest supported Unity (get it from our Unity API data)

Getting application path and application contents paths, in priority order, most accurate to least:

  • Get paths from protocol (editor -> backend -> frontend). This is the most accurate, but only available when Unity is open + the plugin is installed
  • Default app install locations, when installed manually or via hub. Also look for alternative hub install location. Use the version to discover the correct install:

    • We might not have an exact match. The discovered versions are last generated/last saved versions, and might not reflect what versions are installed.

    • Try to match full version.

    • If we can't match full version, find the closest matching version:

    • Major + minor match, choose newest available build

    • Major matches, choose newest minor.build

And also show version information in the settings page, with a message where it came from.

EditorInstance.json doesn't add anything, it exists nearly at the same time, when there is a protocol connection to Editor.
https://github.com/JetBrains/resharper-unity/blob/183/unity/EditorPlugin/PluginEntryPoint.cs#L445-L449

Yes, but only if the plugin is installed and initialised.

I think what we have now is already good for 2019.1.
From the plan we miss only:

  • A per-project setting, saved to .sln.dotSettings
  • version information in the settings page

Where first bullet is excessive and shouldn't be done at all. Second might still be useful.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

RealMSHB picture RealMSHB  路  3Comments

citizenmatt picture citizenmatt  路  5Comments

Baste-RainGames picture Baste-RainGames  路  4Comments

mihakrajnc picture mihakrajnc  路  5Comments

AmazingThew picture AmazingThew  路  4Comments