-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathOpenCommand.cs
More file actions
103 lines (87 loc) · 3.19 KB
/
Copy pathOpenCommand.cs
File metadata and controls
103 lines (87 loc) · 3.19 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
internal class OpenCommand(PlatformSupport platformSupport, UnityHub unityHub)
: SearchPathCommand<OpenSettings>(unityHub)
{
protected override int ExecuteImpl(OpenSettings settings)
{
string searchPath = ResolveSearchPath(settings.SearchPath, settings.Favorite);
ProjectInfo project = Project.Parse(searchPath);
string infoLine = string.Empty;
if (settings.SearchPath != project.Path)
infoLine = "Project: " + project.Path;
infoLine += "\nVersion: " + project.VersionAndChangeset;
Debug.WriteLine(infoLine);
if (!settings.OnlyCodeEditor)
{
UnityHub.InstallEditorChecked(project.Version, project.Changeset, settings.MutatingProcess);
string editorPath = UnityHub.GetEditorPath(project.Version);
AnsiConsole.MarkupLine($"[dim]Editor: {editorPath}[/]");
string[] additionalArgs = Context.Remaining.Raw.ToArray();
var args = new List<string> { "-projectPath", project.Path };
if (!settings.NoHubArgs)
args.Add(UnityHub.GetProjectArgs(project.Path));
args.AddRange(additionalArgs);
settings.MutatingProcess.Run(
new ProcessStartInfo(fileName: editorPath, arguments: ProcessRunner.JoinQuoted(args)));
}
if (settings.CodeEditor || settings.OnlyCodeEditor)
{
OpenSolutionFile(project.Path, settings.MutatingProcess);
}
// Unity doesn't report an exit code if the editor fails to open a project.
// Instead, it prints error into the log. So, for now, we must assume it succeeded.
return 0;
}
private void OpenSolutionFile(string projectDir, IProcessRunner processRunner)
{
// Files might need to be generated by Unity (e.g. first project open).
string solutionFile = WaitForFileAsync(projectDir, "*.sln").Result;
AnsiConsole.MarkupLine($"[dim]Solution: {Path.GetFileName(solutionFile)}[/]");
foreach (var strategy in OpenSolutionStrategies())
{
try
{
ProcessStartInfo? processInfo = strategy.Invoke(solutionFile);
if (processInfo != null)
{
var process = processRunner.Run(processInfo);
process.WaitForExit();
if (process.ExitCode == 0)
break;
}
}
catch (Exception e)
{
WriteError(e);
}
}
}
private IEnumerable<Func<string, ProcessStartInfo?>> OpenSolutionStrategies()
{
yield return OpenWithUnityDefault;
yield return platformSupport.OpenFile;
}
private ProcessStartInfo? OpenWithUnityDefault(string solutionFile)
{
string? scriptingEditor = platformSupport.GetUnityScriptingEditorPath();
// Handle executables or app bundles.
if (File.Exists(scriptingEditor) || Directory.Exists(scriptingEditor))
{
return platformSupport.OpenFileWithApp(solutionFile, scriptingEditor);
}
return null;
}
/// <summary>
/// Returns as soon as a file found by the pattern exists in the directory.
/// </summary>
internal static async Task<string> WaitForFileAsync(string projectDir, string searchPattern)
{
string? path = Directory.GetFiles(projectDir, searchPattern, SearchOption.TopDirectoryOnly).FirstOrDefault();
if (path != null)
return path;
var tcs = new TaskCompletionSource<string>();
using var watcher = new FileSystemWatcher(projectDir, searchPattern);
watcher.Created += (_, e) => tcs.TrySetResult(e.FullPath);
watcher.EnableRaisingEvents = true;
return await tcs.Task;
}
}