2017-08-28 21:26:42 +03:00
|
|
|
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
|
2016-10-18 01:31:53 +03:00
|
|
|
//
|
|
|
|
// Scripting utilities
|
|
|
|
//=========================================================================================
|
|
|
|
|
|
|
|
namespace global
|
|
|
|
|
|
|
|
open System
|
|
|
|
open System.IO
|
Merge master to dev15.8 (#5087)
* Update README.md
* Update README.md
* Update README.md
* [RFCs FS-1051, FS-1052, FS-1053] support for span, readonly refs, byref-like structs (#4888)
* initial support for span, readonly refs, byref-like structs
* fix proto build
* make proto work with previous FSharp.Core
* make proto work with previous FSharp.Core
* update baselines
* integrate code cleanup
* integrate code cleanup
* integrate code cleanup
* integrate code cleanup
* fix build
* fix build
* implicit deref of byref returns
* add tests for Memory, ReadOnlySpan and ReadOnlyMemory
* fix tests
* simplify diff
* simplify diff
* remove duplicate error messages
* fix build
* test updates
* fix build
* fix build
* update baselines
* fix uses of NativePtr.toByRef
* switch to inference using byref pointer capabilities
* fix proto build
* update baselines, byref extension methods
* fix test errors
* emit in,out,modreq attributes correctly
* update tests
* fix build
* fix build
* fix tests
* fix tests
* get it right silly boy
* fix test
* minor cleanup
* add more tests
* clarify overloading behaviour + test case
* fix build break
* fix build of tests
* update tests
* add more tests
* byref fixes
* updates for subsumption calls, error message, assign-to-return-byref
* test updates, implicit deref on byref return for normal functions
* update baseline
* improve debug formatting, better error message on implicit deref, improve error messages
* add more tests for recursive functions
* update baselines
* fix baselines
* updates for new test cases
* updates for new test cases
* test updates and byref-to-byreflike
* deal with 'M() <- expr'
* restrict addresses of immutable top-level things
* fix IsByRefLike on struct
* update tests
* fix test
* fix test
* improve check for no-return-of-struct-field-addresses
* fix test case
* Provide fast generic comparer for bool values (#5076)
* provide fast generic comparer for bool values
* formatting
* no completion on name of value and function declaration (#5083)
* LOC CHECKIN | Microsoft/visualfsharp master | 20180604 | Termchange (#5082)
* fix merge
2018-06-05 16:23:37 +03:00
|
|
|
open System.Text
|
2016-10-18 01:31:53 +03:00
|
|
|
open System.Diagnostics
|
|
|
|
|
|
|
|
[<AutoOpen>]
|
|
|
|
module Scripting =
|
|
|
|
|
|
|
|
let isNullOrEmpty s = String.IsNullOrEmpty s
|
|
|
|
|
2022-05-07 09:29:52 +03:00
|
|
|
let executeProcess fileName arguments =
|
2016-10-18 01:31:53 +03:00
|
|
|
let processWriteMessage (chan:TextWriter) (message:string) =
|
|
|
|
if message <> null then
|
|
|
|
chan.WriteLine(message)
|
2022-05-07 09:29:52 +03:00
|
|
|
printfn "%s %s" fileName arguments
|
2016-10-18 01:31:53 +03:00
|
|
|
let info = ProcessStartInfo(Arguments=arguments, UseShellExecute=false,
|
|
|
|
RedirectStandardOutput=true, RedirectStandardError=true,
|
2022-05-07 09:29:52 +03:00
|
|
|
CreateNoWindow=true, FileName=fileName)
|
2016-10-18 01:31:53 +03:00
|
|
|
let p = new Process(StartInfo=info)
|
|
|
|
p.OutputDataReceived.Add(fun x -> processWriteMessage stdout x.Data)
|
|
|
|
p.ErrorDataReceived.Add(fun x -> processWriteMessage stderr x.Data)
|
|
|
|
if p.Start() then
|
|
|
|
p.BeginOutputReadLine()
|
|
|
|
p.BeginErrorReadLine()
|
|
|
|
p.WaitForExit()
|
|
|
|
p.ExitCode
|
|
|
|
else
|
|
|
|
0
|
|
|
|
|
2016-11-17 00:40:11 +03:00
|
|
|
#if INTERACTIVE
|
2019-02-20 19:15:40 +03:00
|
|
|
let argv = FSharp.Compiler.Interactive.Settings.fsi.CommandLineArgs |> Seq.skip 1 |> Seq.toArray
|
2016-11-06 21:49:18 +03:00
|
|
|
|
2018-03-28 17:49:03 +03:00
|
|
|
let getCmdLineArgOptional (switchName: string) =
|
2016-11-06 21:49:18 +03:00
|
|
|
argv |> Array.filter(fun t -> t.StartsWith(switchName)) |> Array.map(fun t -> t.Remove(0, switchName.Length).Trim()) |> Array.tryHead
|
2016-10-18 01:31:53 +03:00
|
|
|
|
|
|
|
let getCmdLineArg switchName defaultValue =
|
2016-11-06 21:49:18 +03:00
|
|
|
match getCmdLineArgOptional switchName with
|
|
|
|
| Some file -> file
|
2016-10-18 01:31:53 +03:00
|
|
|
| _ -> defaultValue
|
|
|
|
|
2016-11-06 21:49:18 +03:00
|
|
|
let getCmdLineArgReqd switchName =
|
|
|
|
match getCmdLineArg switchName null with
|
|
|
|
| null -> failwith (sprintf "The argument %s is required" switchName)
|
|
|
|
| x -> x
|
|
|
|
|
2016-11-17 03:21:24 +03:00
|
|
|
let getCmdLineExtraArgs isSwitch = argv |> Array.skipWhile isSwitch
|
2016-11-17 00:40:11 +03:00
|
|
|
|
|
|
|
#endif
|
|
|
|
|
2016-10-18 01:31:53 +03:00
|
|
|
let makeDirectory output =
|
|
|
|
if not (Directory.Exists(output)) then
|
|
|
|
Directory.CreateDirectory(output) |> ignore
|
|
|
|
|
|
|
|
let (++) a b = Path.Combine(a,b)
|
|
|
|
|
2018-11-27 21:10:43 +03:00
|
|
|
let getBasename (a:string) = Path.GetFileNameWithoutExtension a
|
|
|
|
let getFullPath (a:string) = Path.GetFullPath a
|
|
|
|
let getFilename (a:string) = Path.GetFileName a
|
|
|
|
let getDirectoryName (a:string) = Path.GetDirectoryName a
|
2016-12-14 00:59:45 +03:00
|
|
|
|
2018-11-27 21:10:43 +03:00
|
|
|
let copyFile (source:string) dir =
|
2016-10-18 01:31:53 +03:00
|
|
|
let dest =
|
|
|
|
if not (Directory.Exists dir) then Directory.CreateDirectory dir |>ignore
|
2018-10-18 01:58:45 +03:00
|
|
|
let result = Path.Combine(dir, getFilename source)
|
2016-10-18 01:31:53 +03:00
|
|
|
result
|
|
|
|
//printfn "Copy %s --> %s" source dest
|
|
|
|
File.Copy(source, dest, true)
|
|
|
|
|
|
|
|
let deleteDirectory output =
|
|
|
|
if Directory.Exists output then
|
|
|
|
Directory.Delete(output, true)
|
|
|
|
|
2016-11-17 00:40:11 +03:00
|
|
|
let log format = printfn format
|
|
|
|
|
|
|
|
type FilePath = string
|
|
|
|
|
|
|
|
type CmdResult =
|
|
|
|
| Success
|
|
|
|
| ErrorLevel of string * int
|
|
|
|
|
|
|
|
type CmdArguments =
|
|
|
|
{ RedirectOutput : (string -> unit) option
|
|
|
|
RedirectError : (string -> unit) option
|
|
|
|
RedirectInput : (StreamWriter -> unit) option }
|
|
|
|
|
|
|
|
module Process =
|
|
|
|
|
2018-11-27 21:10:43 +03:00
|
|
|
let processExePath baseDir (exe:string) =
|
2016-11-17 00:40:11 +03:00
|
|
|
if Path.IsPathRooted(exe) then exe
|
|
|
|
else
|
2018-10-18 01:58:45 +03:00
|
|
|
match getDirectoryName exe with
|
2016-11-17 00:40:11 +03:00
|
|
|
| "" -> exe
|
|
|
|
| _ -> Path.Combine(baseDir,exe) |> Path.GetFullPath
|
|
|
|
|
2023-06-27 19:29:41 +03:00
|
|
|
let exec cmdArgs (workDir: FilePath) envs (path: FilePath) (arguments: string) =
|
2016-11-17 00:40:11 +03:00
|
|
|
|
|
|
|
let exePath = path |> processExePath workDir
|
|
|
|
let processInfo = new ProcessStartInfo(exePath, arguments)
|
2021-08-04 14:54:47 +03:00
|
|
|
|
|
|
|
processInfo.EnvironmentVariables.["DOTNET_ROLL_FORWARD"] <- "LatestMajor"
|
|
|
|
processInfo.EnvironmentVariables.["DOTNET_ROLL_FORWARD_TO_PRERELEASE"] <- "1"
|
|
|
|
|
2016-11-17 00:40:11 +03:00
|
|
|
processInfo.CreateNoWindow <- true
|
|
|
|
processInfo.UseShellExecute <- false
|
|
|
|
processInfo.WorkingDirectory <- workDir
|
|
|
|
|
|
|
|
ignore envs // work out what to do about this
|
|
|
|
|
|
|
|
let p = new Process()
|
|
|
|
p.EnableRaisingEvents <- true
|
|
|
|
p.StartInfo <- processInfo
|
Merge master to dev15.8 (#5087)
* Update README.md
* Update README.md
* Update README.md
* [RFCs FS-1051, FS-1052, FS-1053] support for span, readonly refs, byref-like structs (#4888)
* initial support for span, readonly refs, byref-like structs
* fix proto build
* make proto work with previous FSharp.Core
* make proto work with previous FSharp.Core
* update baselines
* integrate code cleanup
* integrate code cleanup
* integrate code cleanup
* integrate code cleanup
* fix build
* fix build
* implicit deref of byref returns
* add tests for Memory, ReadOnlySpan and ReadOnlyMemory
* fix tests
* simplify diff
* simplify diff
* remove duplicate error messages
* fix build
* test updates
* fix build
* fix build
* update baselines
* fix uses of NativePtr.toByRef
* switch to inference using byref pointer capabilities
* fix proto build
* update baselines, byref extension methods
* fix test errors
* emit in,out,modreq attributes correctly
* update tests
* fix build
* fix build
* fix tests
* fix tests
* get it right silly boy
* fix test
* minor cleanup
* add more tests
* clarify overloading behaviour + test case
* fix build break
* fix build of tests
* update tests
* add more tests
* byref fixes
* updates for subsumption calls, error message, assign-to-return-byref
* test updates, implicit deref on byref return for normal functions
* update baseline
* improve debug formatting, better error message on implicit deref, improve error messages
* add more tests for recursive functions
* update baselines
* fix baselines
* updates for new test cases
* updates for new test cases
* test updates and byref-to-byreflike
* deal with 'M() <- expr'
* restrict addresses of immutable top-level things
* fix IsByRefLike on struct
* update tests
* fix test
* fix test
* improve check for no-return-of-struct-field-addresses
* fix test case
* Provide fast generic comparer for bool values (#5076)
* provide fast generic comparer for bool values
* formatting
* no completion on name of value and function declaration (#5083)
* LOC CHECKIN | Microsoft/visualfsharp master | 20180604 | Termchange (#5082)
* fix merge
2018-06-05 16:23:37 +03:00
|
|
|
let out = StringBuilder()
|
|
|
|
let err = StringBuilder()
|
2016-11-17 00:40:11 +03:00
|
|
|
|
|
|
|
cmdArgs.RedirectOutput|> Option.iter (fun f ->
|
|
|
|
processInfo.RedirectStandardOutput <- true
|
Merge master to dev15.8 (#5087)
* Update README.md
* Update README.md
* Update README.md
* [RFCs FS-1051, FS-1052, FS-1053] support for span, readonly refs, byref-like structs (#4888)
* initial support for span, readonly refs, byref-like structs
* fix proto build
* make proto work with previous FSharp.Core
* make proto work with previous FSharp.Core
* update baselines
* integrate code cleanup
* integrate code cleanup
* integrate code cleanup
* integrate code cleanup
* fix build
* fix build
* implicit deref of byref returns
* add tests for Memory, ReadOnlySpan and ReadOnlyMemory
* fix tests
* simplify diff
* simplify diff
* remove duplicate error messages
* fix build
* test updates
* fix build
* fix build
* update baselines
* fix uses of NativePtr.toByRef
* switch to inference using byref pointer capabilities
* fix proto build
* update baselines, byref extension methods
* fix test errors
* emit in,out,modreq attributes correctly
* update tests
* fix build
* fix build
* fix tests
* fix tests
* get it right silly boy
* fix test
* minor cleanup
* add more tests
* clarify overloading behaviour + test case
* fix build break
* fix build of tests
* update tests
* add more tests
* byref fixes
* updates for subsumption calls, error message, assign-to-return-byref
* test updates, implicit deref on byref return for normal functions
* update baseline
* improve debug formatting, better error message on implicit deref, improve error messages
* add more tests for recursive functions
* update baselines
* fix baselines
* updates for new test cases
* updates for new test cases
* test updates and byref-to-byreflike
* deal with 'M() <- expr'
* restrict addresses of immutable top-level things
* fix IsByRefLike on struct
* update tests
* fix test
* fix test
* improve check for no-return-of-struct-field-addresses
* fix test case
* Provide fast generic comparer for bool values (#5076)
* provide fast generic comparer for bool values
* formatting
* no completion on name of value and function declaration (#5083)
* LOC CHECKIN | Microsoft/visualfsharp master | 20180604 | Termchange (#5082)
* fix merge
2018-06-05 16:23:37 +03:00
|
|
|
p.OutputDataReceived.Add (fun ea ->
|
|
|
|
if ea.Data <> null then
|
|
|
|
out.Append(ea.Data + Environment.NewLine) |> ignore
|
|
|
|
f ea.Data)
|
2016-11-17 00:40:11 +03:00
|
|
|
)
|
|
|
|
|
|
|
|
cmdArgs.RedirectError |> Option.iter (fun f ->
|
|
|
|
processInfo.RedirectStandardError <- true
|
Merge master to dev15.8 (#5087)
* Update README.md
* Update README.md
* Update README.md
* [RFCs FS-1051, FS-1052, FS-1053] support for span, readonly refs, byref-like structs (#4888)
* initial support for span, readonly refs, byref-like structs
* fix proto build
* make proto work with previous FSharp.Core
* make proto work with previous FSharp.Core
* update baselines
* integrate code cleanup
* integrate code cleanup
* integrate code cleanup
* integrate code cleanup
* fix build
* fix build
* implicit deref of byref returns
* add tests for Memory, ReadOnlySpan and ReadOnlyMemory
* fix tests
* simplify diff
* simplify diff
* remove duplicate error messages
* fix build
* test updates
* fix build
* fix build
* update baselines
* fix uses of NativePtr.toByRef
* switch to inference using byref pointer capabilities
* fix proto build
* update baselines, byref extension methods
* fix test errors
* emit in,out,modreq attributes correctly
* update tests
* fix build
* fix build
* fix tests
* fix tests
* get it right silly boy
* fix test
* minor cleanup
* add more tests
* clarify overloading behaviour + test case
* fix build break
* fix build of tests
* update tests
* add more tests
* byref fixes
* updates for subsumption calls, error message, assign-to-return-byref
* test updates, implicit deref on byref return for normal functions
* update baseline
* improve debug formatting, better error message on implicit deref, improve error messages
* add more tests for recursive functions
* update baselines
* fix baselines
* updates for new test cases
* updates for new test cases
* test updates and byref-to-byreflike
* deal with 'M() <- expr'
* restrict addresses of immutable top-level things
* fix IsByRefLike on struct
* update tests
* fix test
* fix test
* improve check for no-return-of-struct-field-addresses
* fix test case
* Provide fast generic comparer for bool values (#5076)
* provide fast generic comparer for bool values
* formatting
* no completion on name of value and function declaration (#5083)
* LOC CHECKIN | Microsoft/visualfsharp master | 20180604 | Termchange (#5082)
* fix merge
2018-06-05 16:23:37 +03:00
|
|
|
p.ErrorDataReceived.Add (fun ea ->
|
|
|
|
if ea.Data <> null then
|
|
|
|
err.Append(ea.Data + Environment.NewLine) |> ignore
|
|
|
|
f ea.Data)
|
2016-11-17 00:40:11 +03:00
|
|
|
)
|
|
|
|
|
|
|
|
cmdArgs.RedirectInput
|
|
|
|
|> Option.iter (fun _ -> p.StartInfo.RedirectStandardInput <- true)
|
|
|
|
|
|
|
|
p.Start() |> ignore
|
2016-12-14 00:59:45 +03:00
|
|
|
|
2016-11-17 00:40:11 +03:00
|
|
|
cmdArgs.RedirectOutput |> Option.iter (fun _ -> p.BeginOutputReadLine())
|
|
|
|
cmdArgs.RedirectError |> Option.iter (fun _ -> p.BeginErrorReadLine())
|
|
|
|
|
|
|
|
cmdArgs.RedirectInput |> Option.iter (fun input ->
|
|
|
|
async {
|
|
|
|
let inputWriter = p.StandardInput
|
|
|
|
do! inputWriter.FlushAsync () |> Async.AwaitIAsyncResult |> Async.Ignore
|
|
|
|
input inputWriter
|
|
|
|
do! inputWriter.FlushAsync () |> Async.AwaitIAsyncResult |> Async.Ignore
|
|
|
|
inputWriter.Dispose ()
|
|
|
|
}
|
|
|
|
|> Async.Start)
|
|
|
|
|
|
|
|
p.WaitForExit()
|
|
|
|
|
|
|
|
match p.ExitCode with
|
|
|
|
| 0 -> Success
|
2021-08-04 14:54:47 +03:00
|
|
|
| errCode ->
|
Merge master to dev15.8 (#5087)
* Update README.md
* Update README.md
* Update README.md
* [RFCs FS-1051, FS-1052, FS-1053] support for span, readonly refs, byref-like structs (#4888)
* initial support for span, readonly refs, byref-like structs
* fix proto build
* make proto work with previous FSharp.Core
* make proto work with previous FSharp.Core
* update baselines
* integrate code cleanup
* integrate code cleanup
* integrate code cleanup
* integrate code cleanup
* fix build
* fix build
* implicit deref of byref returns
* add tests for Memory, ReadOnlySpan and ReadOnlyMemory
* fix tests
* simplify diff
* simplify diff
* remove duplicate error messages
* fix build
* test updates
* fix build
* fix build
* update baselines
* fix uses of NativePtr.toByRef
* switch to inference using byref pointer capabilities
* fix proto build
* update baselines, byref extension methods
* fix test errors
* emit in,out,modreq attributes correctly
* update tests
* fix build
* fix build
* fix tests
* fix tests
* get it right silly boy
* fix test
* minor cleanup
* add more tests
* clarify overloading behaviour + test case
* fix build break
* fix build of tests
* update tests
* add more tests
* byref fixes
* updates for subsumption calls, error message, assign-to-return-byref
* test updates, implicit deref on byref return for normal functions
* update baseline
* improve debug formatting, better error message on implicit deref, improve error messages
* add more tests for recursive functions
* update baselines
* fix baselines
* updates for new test cases
* updates for new test cases
* test updates and byref-to-byreflike
* deal with 'M() <- expr'
* restrict addresses of immutable top-level things
* fix IsByRefLike on struct
* update tests
* fix test
* fix test
* improve check for no-return-of-struct-field-addresses
* fix test case
* Provide fast generic comparer for bool values (#5076)
* provide fast generic comparer for bool values
* formatting
* no completion on name of value and function declaration (#5083)
* LOC CHECKIN | Microsoft/visualfsharp master | 20180604 | Termchange (#5082)
* fix merge
2018-06-05 16:23:37 +03:00
|
|
|
let msg = sprintf "Error running command '%s' with args '%s' in directory '%s'.\n---- stdout below --- \n%s\n---- stderr below --- \n%s " exePath arguments workDir (out.ToString()) (err.ToString())
|
2018-08-08 02:48:04 +03:00
|
|
|
ErrorLevel (msg, errCode)
|
2016-11-17 00:40:11 +03:00
|
|
|
|
|
|
|
type OutPipe (writer: TextWriter) =
|
|
|
|
member x.Post (msg:string) = lock writer (fun () -> writer.WriteLine(msg))
|
|
|
|
interface System.IDisposable with
|
2020-12-23 21:50:00 +03:00
|
|
|
member _.Dispose() = writer.Flush()
|
2016-12-14 00:59:45 +03:00
|
|
|
|
2016-11-17 00:40:11 +03:00
|
|
|
let redirectTo (writer: TextWriter) = new OutPipe (writer)
|
|
|
|
|
|
|
|
let redirectToLog () = redirectTo System.Console.Out
|
|
|
|
|
2020-04-22 20:37:27 +03:00
|
|
|
#if !NETCOREAPP
|
2016-11-17 03:21:24 +03:00
|
|
|
let defaultPlatform =
|
|
|
|
match Environment.OSVersion.Platform, Environment.Is64BitOperatingSystem with
|
2016-12-14 00:59:45 +03:00
|
|
|
| PlatformID.MacOSX, true -> "osx.10.11-x64"
|
2016-11-17 03:21:24 +03:00
|
|
|
| PlatformID.Unix,true -> "ubuntu.14.04-x64"
|
|
|
|
| _, true -> "win7-x64"
|
|
|
|
| _, false -> "win7-x86"
|
2016-12-14 00:59:45 +03:00
|
|
|
#endif
|
2016-11-22 23:29:46 +03:00
|
|
|
|
2022-05-07 09:29:52 +03:00
|
|
|
let executeProcessNoRedirect fileName arguments =
|
2016-11-22 23:29:46 +03:00
|
|
|
let info = ProcessStartInfo(Arguments=arguments, UseShellExecute=false,
|
|
|
|
RedirectStandardOutput=true, RedirectStandardError=true,RedirectStandardInput=true,
|
2022-05-07 09:29:52 +03:00
|
|
|
CreateNoWindow=true, FileName=fileName)
|
2016-11-22 23:29:46 +03:00
|
|
|
let p = new Process(StartInfo=info)
|
|
|
|
if p.Start() then
|
|
|
|
|
|
|
|
async { try
|
|
|
|
let buffer = Array.zeroCreate 4096
|
|
|
|
while not p.StandardOutput.EndOfStream do
|
|
|
|
let n = p.StandardOutput.Read(buffer, 0, buffer.Length)
|
|
|
|
if n > 0 then System.Console.Out.Write(buffer, 0, n)
|
|
|
|
with _ -> () } |> Async.Start
|
|
|
|
async { try
|
|
|
|
let buffer = Array.zeroCreate 4096
|
|
|
|
while not p.StandardError.EndOfStream do
|
|
|
|
let n = p.StandardError.Read(buffer, 0, buffer.Length)
|
|
|
|
if n > 0 then System.Console.Error.Write(buffer, 0, n)
|
|
|
|
with _ -> () } |> Async.Start
|
|
|
|
async { try
|
|
|
|
while true do
|
|
|
|
let c = System.Console.In.ReadLine()
|
|
|
|
p.StandardInput.WriteLine(c)
|
|
|
|
with _ -> () } |> Async.Start
|
|
|
|
p.WaitForExit()
|
|
|
|
p.ExitCode
|
|
|
|
else
|
|
|
|
0
|