UnityGame/Library/PackageCache/com.unity.ide.visualstudio/Editor/VisualStudioForMacInstallation.cs
2024-10-27 10:53:47 +03:00

182 lines
5.4 KiB
C#

/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
#if UNITY_EDITOR_OSX
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using Unity.CodeEditor;
using IOPath = System.IO.Path;
namespace Microsoft.Unity.VisualStudio.Editor
{
internal class VisualStudioForMacInstallation : VisualStudioInstallation
{
// C# language version support for Visual Studio for Mac
private static readonly VersionPair[] OSXVersionTable =
{
// VisualStudio for Mac 2022
new VersionPair(17,4, /* => */ 11,0),
new VersionPair(17,0, /* => */ 10,0),
// VisualStudio for Mac 8.x
new VersionPair(8,8, /* => */ 9,0),
new VersionPair(8,3, /* => */ 8,0),
new VersionPair(8,0, /* => */ 7,3),
};
private static readonly IGenerator _generator = new LegacyStyleProjectGeneration();
public override bool SupportsAnalyzers
{
get
{
return Version >= new Version(8, 3);
}
}
public override Version LatestLanguageVersionSupported
{
get
{
return GetLatestLanguageVersionSupported(OSXVersionTable);
}
}
private string GetExtensionPath()
{
const string addinName = "MonoDevelop.Unity";
const string addinAssembly = addinName + ".dll";
// user addins repository
var localAddins = IOPath.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.Personal),
$"Library/Application Support/VisualStudio/${Version.Major}.0" + "/LocalInstall/Addins");
// In the user addins repository, the addins are suffixed by their versions, like `MonoDevelop.Unity.1.0`
// When installing another local user addin, MD will remove files inside the folder
// So we browse all VSTUM addins, and return the one with an addin assembly
if (Directory.Exists(localAddins))
{
foreach (var folder in Directory.GetDirectories(localAddins, addinName + "*", SearchOption.TopDirectoryOnly))
{
if (File.Exists(IOPath.Combine(folder, addinAssembly)))
return folder;
}
}
// Check in Visual Studio.app/
// In that case the name of the addin is used
var addinPath = IOPath.Combine(Path, $"Contents/Resources/lib/monodevelop/AddIns/{addinName}");
if (File.Exists(IOPath.Combine(addinPath, addinAssembly)))
return addinPath;
addinPath = IOPath.Combine(Path, $"Contents/MonoBundle/Addins/{addinName}");
if (File.Exists(IOPath.Combine(addinPath, addinAssembly)))
return addinPath;
return null;
}
public override string[] GetAnalyzers()
{
var vstuPath = GetExtensionPath();
if (string.IsNullOrEmpty(vstuPath))
return Array.Empty<string>();
return GetAnalyzers(vstuPath);
}
public override IGenerator ProjectGenerator
{
get
{
return _generator;
}
}
private static bool IsCandidateForDiscovery(string path)
{
return Directory.Exists(path) && Regex.IsMatch(path, "Visual\\s?Studio(?!.*Code.*).*.app$", RegexOptions.IgnoreCase);
}
public static bool TryDiscoverInstallation(string editorPath, out IVisualStudioInstallation installation)
{
installation = null;
if (string.IsNullOrEmpty(editorPath))
return false;
if (!IsCandidateForDiscovery(editorPath))
return false;
// On Mac we use the .app folder, so we need to access to main assembly
var fvi = IOPath.Combine(editorPath, "Contents/Resources/lib/monodevelop/bin/VisualStudio.exe");
if (!File.Exists(fvi))
fvi = IOPath.Combine(editorPath, "Contents/MonoBundle/VisualStudio.exe");
if (!File.Exists(fvi))
fvi = IOPath.Combine(editorPath, "Contents/MonoBundle/VisualStudio.dll");
if (!File.Exists(fvi))
return false;
// VS preview are not using the isPrerelease flag so far
// On Windows FileDescription contains "Preview", but not on Mac
var vi = FileVersionInfo.GetVersionInfo(fvi);
var version = new Version(vi.ProductVersion);
var isPrerelease = vi.IsPreRelease || string.Concat(editorPath, "/" + vi.FileDescription).ToLower().Contains("preview");
installation = new VisualStudioForMacInstallation()
{
IsPrerelease = isPrerelease,
Name = $"{vi.FileDescription}{(isPrerelease ? " Preview" : string.Empty)} [{version.ToString(3)}]",
Path = editorPath,
Version = version
};
return true;
}
public static IEnumerable<IVisualStudioInstallation> GetVisualStudioInstallations()
{
var candidates = Directory.EnumerateDirectories("/Applications", "*.app");
foreach (var candidate in candidates)
{
if (TryDiscoverInstallation(candidate, out var installation))
yield return installation;
}
}
[DllImport("AppleEventIntegration")]
private static extern bool OpenVisualStudio(string appPath, string solutionPath, string filePath, int line);
public override void CreateExtraFiles(string projectDirectory)
{
}
public override bool Open(string path, int line, int column, string solution)
{
string absolutePath = "";
if (!string.IsNullOrWhiteSpace(path))
{
absolutePath = IOPath.GetFullPath(path);
}
return OpenVisualStudio(CodeEditor.CurrentEditorInstallation, solution, absolutePath, line);
}
public static void Initialize()
{
}
}
}
#endif