-
-
Notifications
You must be signed in to change notification settings - Fork 35
/
Utils.fs
163 lines (131 loc) · 5.29 KB
/
Utils.fs
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
namespace Ionide.ProjInfo
open System.Runtime.InteropServices
open System.IO
open System
module Paths =
let private isUnix = RuntimeInformation.IsOSPlatform(OSPlatform.Linux) || RuntimeInformation.IsOSPlatform(OSPlatform.OSX)
let private dotnetBinaryName =
if isUnix then
"dotnet"
else
"dotnet.exe"
let private potentialDotnetHostEnvVars =
[ "DOTNET_HOST_PATH", id // is a full path to dotnet binary
"DOTNET_ROOT", (fun s -> Path.Combine(s, dotnetBinaryName)) // needs dotnet binary appended
"DOTNET_ROOT(x86)", (fun s -> Path.Combine(s, dotnetBinaryName)) ] // needs dotnet binary appended
let private existingEnvVarValue envVarValue =
match envVarValue with
| null
| "" -> None
| other -> Some other
/// <summary>
/// provides the path to the `dotnet` binary running this library, respecting various dotnet <see href="https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-environment-variables#dotnet_root-dotnet_rootx86%5D">environment variables</see>
/// </summary>
let dotnetRoot =
potentialDotnetHostEnvVars
|> List.tryPick
(fun (envVar, transformer) ->
match Environment.GetEnvironmentVariable envVar |> existingEnvVarValue with
| Some varValue -> Some(transformer varValue |> FileInfo)
| None -> None)
|> Option.defaultWith
(fun _ ->
System
.Diagnostics
.Process
.GetCurrentProcess()
.MainModule
.FileName
|> FileInfo)
let sdksPath (dotnetRoot: string) =
System.IO.Path.Combine(dotnetRoot, "Sdks")
module internal CommonHelpers =
let chooseByPrefix (prefix: string) (s: string) =
if s.StartsWith(prefix) then
Some(s.Substring(prefix.Length))
else
None
let chooseByPrefix2 prefixes (s: string) =
prefixes |> List.tryPick (fun prefix -> chooseByPrefix prefix s)
let splitByPrefix (prefix: string) (s: string) =
if s.StartsWith(prefix) then
Some(prefix, s.Substring(prefix.Length))
else
None
let splitByPrefix2 prefixes (s: string) =
prefixes |> List.tryPick (fun prefix -> splitByPrefix prefix s)
module FscArguments =
open CommonHelpers
open Types
open System.IO
let outType rsp =
match List.tryPick (chooseByPrefix "--target:") rsp with
| Some "library" -> ProjectOutputType.Library
| Some "exe" -> ProjectOutputType.Exe
| Some v -> ProjectOutputType.Custom v
| None -> ProjectOutputType.Exe // default if arg is not passed to fsc
let private outputFileArg = [ "--out:"; "-o:" ]
let private makeAbs (projDir: string) (f: string) =
if Path.IsPathRooted f then
f
else
Path.Combine(projDir, f)
let outputFile projDir rsp =
rsp |> List.tryPick (chooseByPrefix2 outputFileArg) |> Option.map (makeAbs projDir)
let isCompileFile (s: string) =
let isArg = s.StartsWith("-") && s.Contains(":")
(not isArg) && (s.EndsWith(".fs") || s.EndsWith(".fsi") || s.EndsWith(".fsx"))
let references =
//TODO valid also --reference:
List.choose (chooseByPrefix "-r:")
let useFullPaths projDir (s: string) =
match s |> splitByPrefix2 outputFileArg with
| Some (prefix, v) -> prefix + (v |> makeAbs projDir)
| None ->
if isCompileFile s then
s |> makeAbs projDir |> Path.GetFullPath
else
s
let isTempFile (name: string) =
let tempPath = System.IO.Path.GetTempPath()
let s = name.ToLower()
s.StartsWith(tempPath.ToLower())
let isDeprecatedArg n =
// TODO put in FCS
(n = "--times") || (n = "--no-jit-optimize")
let isSourceFile (file: string) : (string -> bool) =
if System.IO.Path.GetExtension(file) = ".fsproj" then
isCompileFile
else
(fun n -> n.EndsWith ".cs")
module CscArguments =
open CommonHelpers
open System.IO
open Types
let private outputFileArg = [ "--out:"; "-o:" ]
let private makeAbs (projDir: string) (f: string) =
if Path.IsPathRooted f then
f
else
Path.Combine(projDir, f)
let isCompileFile (s: string) =
let isArg = s.StartsWith("-") && s.Contains(":")
(not isArg) && s.EndsWith(".cs")
let useFullPaths projDir (s: string) =
if isCompileFile s then
s |> makeAbs projDir |> Path.GetFullPath
else
s
let isSourceFile (file: string) : (string -> bool) =
if System.IO.Path.GetExtension(file) = ".csproj" then
isCompileFile
else
(fun n -> n.EndsWith ".fs")
let outputFile projDir rsp =
rsp |> List.tryPick (chooseByPrefix2 outputFileArg) |> Option.map (makeAbs projDir)
let outType rsp =
match List.tryPick (chooseByPrefix "/target:") rsp with
| Some "library" -> ProjectOutputType.Library
| Some "exe" -> ProjectOutputType.Exe
| Some v -> ProjectOutputType.Custom v
| None -> ProjectOutputType.Exe // default if arg is not passed to fsc