-
Notifications
You must be signed in to change notification settings - Fork 417
/
Copy pathDnxPaths.cs
216 lines (185 loc) · 8.02 KB
/
DnxPaths.cs
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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.CodeAnalysis;
using Microsoft.Framework.Logging;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using OmniSharp.Models;
using OmniSharp.Options;
using OmniSharp.Services;
namespace OmniSharp.Dnx
{
public class DnxPaths
{
private readonly IOmnisharpEnvironment _env;
private readonly DnxOptions _options;
private readonly ILogger _logger;
public DnxRuntimePathResult RuntimePath { get; private set; }
public string Dnx { get; private set; }
public string Dnu { get; private set; }
public string Klr { get; private set; }
public string Kpm { get; private set; }
public string K { get; private set; }
public DnxPaths(IOmnisharpEnvironment env,
DnxOptions options,
ILoggerFactory loggerFactory)
{
_env = env;
_options = options;
_logger = loggerFactory.CreateLogger<DnxPaths>();
RuntimePath = GetRuntimePath();
Dnx = FirstPath(RuntimePath.Value, "dnx", "dnx.exe");
Dnu = FirstPath(RuntimePath.Value, "dnu", "dnu.cmd");
Klr = FirstPath(RuntimePath.Value, "klr", "klr.exe");
Kpm = FirstPath(RuntimePath.Value, "kpm", "kpm.cmd");
K = FirstPath(RuntimePath.Value, "k", "k.cmd");
}
private DnxRuntimePathResult GetRuntimePath()
{
var root = ResolveRootDirectory(_env.Path);
var globalJson = Path.Combine(root, "global.json");
var versionOrAliasToken = GetRuntimeVersionOrAlias(globalJson);
var versionOrAlias = versionOrAliasToken?.Value<string>() ?? _options.Alias ?? "default";
var seachedLocations = new List<string>();
foreach (var location in GetRuntimeLocations())
{
// Need to expand variables, because DNX_HOME variable might include %USERPROFILE%.
var paths = GetRuntimePathsFromVersionOrAlias(versionOrAlias, Environment.ExpandEnvironmentVariables(location));
foreach (var path in paths)
{
if (string.IsNullOrEmpty(path))
{
continue;
}
if (Directory.Exists(path))
{
_logger.LogInformation(string.Format("Using runtime '{0}'.", path));
return new DnxRuntimePathResult()
{
Value = path
};
}
seachedLocations.Add(path);
}
}
var message = new ErrorMessage()
{
Text = string.Format("The specified runtime path '{0}' does not exist. Searched locations {1}.\nVisit https://github.com/aspnet/Home for an installation guide.", versionOrAlias, string.Join("\n", seachedLocations))
};
if (versionOrAliasToken != null)
{
message.FileName = globalJson;
message.Line = ((IJsonLineInfo)versionOrAliasToken).LineNumber;
message.Column = ((IJsonLineInfo)versionOrAliasToken).LinePosition;
}
_logger.LogError(message.Text);
return new DnxRuntimePathResult()
{
Error = message
};
}
private JToken GetRuntimeVersionOrAlias(string globalJson)
{
if (File.Exists(globalJson))
{
_logger.LogInformation("Looking for sdk version in '{0}'.", globalJson);
using (var stream = File.OpenRead(globalJson))
{
using (var streamReader = new StreamReader(stream))
{
using (var textReader = new JsonTextReader(streamReader))
{
var obj = JObject.Load(textReader);
return obj["sdk"]?["version"];
}
}
}
}
return null;
}
private static string ResolveRootDirectory(string projectPath)
{
var di = new DirectoryInfo(projectPath);
while (di.Parent != null)
{
if (di.EnumerateFiles("global.json").Any())
{
return di.FullName;
}
di = di.Parent;
}
// If we don't find any files then make the project folder the root
return projectPath;
}
private IEnumerable<string> GetRuntimeLocations()
{
yield return Environment.GetEnvironmentVariable("DNX_HOME") ?? string.Empty;
yield return Environment.GetEnvironmentVariable("KRE_HOME") ?? string.Empty;
// %HOME% and %USERPROFILE% might point to different places.
foreach (var home in new string[] { Environment.GetEnvironmentVariable("HOME"), Environment.GetEnvironmentVariable("USERPROFILE") }.Where(s => !string.IsNullOrEmpty(s)))
{
// Newer path
yield return Path.Combine(home, ".dnx");
// New path
yield return Path.Combine(home, ".k");
// Old path
yield return Path.Combine(home, ".kre");
}
}
private IEnumerable<string> GetRuntimePathsFromVersionOrAlias(string versionOrAlias, string runtimePath)
{
// Newer format
yield return GetRuntimePathFromVersionOrAlias(versionOrAlias, runtimePath, ".dnx", "dnx-mono.{0}", "dnx-clr-win-x86.{0}", "runtimes");
// New format
yield return GetRuntimePathFromVersionOrAlias(versionOrAlias, runtimePath, ".k", "kre-mono.{0}", "kre-clr-win-x86.{0}", "runtimes");
// Old format
yield return GetRuntimePathFromVersionOrAlias(versionOrAlias, runtimePath, ".kre", "KRE-Mono.{0}", "KRE-CLR-x86.{0}", "packages");
}
private string GetRuntimePathFromVersionOrAlias(string versionOrAlias,
string runtimeHome,
string sdkFolder,
string monoFormat,
string windowsFormat,
string runtimeFolder)
{
if (string.IsNullOrEmpty(runtimeHome))
{
return null;
}
var aliasDirectory = Path.Combine(runtimeHome, "alias");
var aliasFiles = new[] { "{0}.alias", "{0}.txt" };
// Check alias first
foreach (var shortAliasFile in aliasFiles)
{
var aliasFile = Path.Combine(aliasDirectory, string.Format(shortAliasFile, versionOrAlias));
if (File.Exists(aliasFile))
{
var fullName = File.ReadAllText(aliasFile).Trim();
return Path.Combine(runtimeHome, runtimeFolder, fullName);
}
}
// There was no alias, look for the input as a version
var version = versionOrAlias;
if (PlatformHelper.IsMono)
{
return Path.Combine(runtimeHome, runtimeFolder, string.Format(monoFormat, versionOrAlias));
}
else
{
return Path.Combine(runtimeHome, runtimeFolder, string.Format(windowsFormat, versionOrAlias));
}
}
internal static string FirstPath(string runtimePath, params string[] candidates)
{
if (runtimePath == null)
{
return null;
}
return candidates
.Select(candidate => Path.Combine(runtimePath, "bin", candidate))
.FirstOrDefault(File.Exists);
}
}
}