From 34be07c1ef61f47681eab92d8522de1c8f44628b Mon Sep 17 00:00:00 2001 From: Toni Kaihola Date: Tue, 27 Oct 2015 22:50:41 +0200 Subject: [PATCH 1/3] Added helper to support plain robocopy and mirroring. --- src/app/FakeLib/FakeLib.fsproj | 3 ++- src/app/FakeLib/RoboCopyHelper.fs | 38 +++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 src/app/FakeLib/RoboCopyHelper.fs diff --git a/src/app/FakeLib/FakeLib.fsproj b/src/app/FakeLib/FakeLib.fsproj index c844691a954..2c5b204d8b2 100644 --- a/src/app/FakeLib/FakeLib.fsproj +++ b/src/app/FakeLib/FakeLib.fsproj @@ -98,7 +98,7 @@ - + @@ -163,6 +163,7 @@ + diff --git a/src/app/FakeLib/RoboCopyHelper.fs b/src/app/FakeLib/RoboCopyHelper.fs new file mode 100644 index 00000000000..89f9c00cbce --- /dev/null +++ b/src/app/FakeLib/RoboCopyHelper.fs @@ -0,0 +1,38 @@ +[] +/// Contains a task to use [robocopy](https://en.wikipedia.org/wiki/Robocopy) on Windows. +module Fake.RoboCopyHelper + +type RoboCopyOptions = { Mirror: bool } + +/// Executes a RoboCopy command with options +/// ## Parameters +/// - `source` - The source directory +/// - `destination` - The target directory +/// - `options` - The options to pass to robocopy +let RoboCopyWithOptions (source:string) (destination:string) (options:RoboCopyOptions) = + let args = + "/D /c robocopy " + + (source.TrimEnd('\\') |> FullName |> toParam) + + (destination.TrimEnd('\\') |> FullName |> toParam) + + if options.Mirror then " /MIR /IT" + else " /IT" + + let result = ExecProcess (fun info -> + info.FileName <- "CMD.exe" + info.Arguments <- args) System.TimeSpan.MaxValue + + if result <> 0 then failwithf "Error during RoboCopy From: %s To: %s" source destination + +/// Executes a RoboCopy command +/// ## Parameters +/// - `source` - The source directory +/// - `destination` - The target directory +let RoboCopy (source:string) (destination:string) = + RoboCopyWithOptions source destination { Mirror = false } + +/// Executes a RoboCopy mirror command (potentially destructive) +/// ## Parameters +/// - `source` - The source directory +/// - `destination` - The target directory +let RoboCopyMirror (source:string) (destination:string) = + RoboCopyWithOptions source destination { Mirror = true } From a9bcb4d4d20b33914976eea69053a5f6faf507df Mon Sep 17 00:00:00 2001 From: Toni Kaihola Date: Sat, 31 Oct 2015 08:09:05 +0200 Subject: [PATCH 2/3] Removed AutoOpenAttribute from module. --- src/app/FakeLib/RoboCopyHelper.fs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/app/FakeLib/RoboCopyHelper.fs b/src/app/FakeLib/RoboCopyHelper.fs index 89f9c00cbce..1f5680b7a22 100644 --- a/src/app/FakeLib/RoboCopyHelper.fs +++ b/src/app/FakeLib/RoboCopyHelper.fs @@ -1,5 +1,4 @@ -[] -/// Contains a task to use [robocopy](https://en.wikipedia.org/wiki/Robocopy) on Windows. +/// Contains a task to use [robocopy](https://en.wikipedia.org/wiki/Robocopy) on Windows. module Fake.RoboCopyHelper type RoboCopyOptions = { Mirror: bool } @@ -9,7 +8,7 @@ type RoboCopyOptions = { Mirror: bool } /// - `source` - The source directory /// - `destination` - The target directory /// - `options` - The options to pass to robocopy -let RoboCopyWithOptions (source:string) (destination:string) (options:RoboCopyOptions) = +let private roboCopyWithOptions (source:string) (destination:string) (options:RoboCopyOptions) = let args = "/D /c robocopy " + (source.TrimEnd('\\') |> FullName |> toParam) + @@ -28,11 +27,11 @@ let RoboCopyWithOptions (source:string) (destination:string) (options:RoboCopyOp /// - `source` - The source directory /// - `destination` - The target directory let RoboCopy (source:string) (destination:string) = - RoboCopyWithOptions source destination { Mirror = false } + roboCopyWithOptions source destination { Mirror = false } /// Executes a RoboCopy mirror command (potentially destructive) /// ## Parameters /// - `source` - The source directory /// - `destination` - The target directory let RoboCopyMirror (source:string) (destination:string) = - RoboCopyWithOptions source destination { Mirror = true } + roboCopyWithOptions source destination { Mirror = true } From d92f3c31179dd08c958f9170411084a2d41e48cb Mon Sep 17 00:00:00 2001 From: Toni Kaihola Date: Sat, 31 Oct 2015 09:15:54 +0200 Subject: [PATCH 3/3] RoboCopyHelper: Added exit code translation --- src/app/FakeLib/RoboCopyHelper.fs | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/src/app/FakeLib/RoboCopyHelper.fs b/src/app/FakeLib/RoboCopyHelper.fs index 1f5680b7a22..097f6071446 100644 --- a/src/app/FakeLib/RoboCopyHelper.fs +++ b/src/app/FakeLib/RoboCopyHelper.fs @@ -16,11 +16,28 @@ let private roboCopyWithOptions (source:string) (destination:string) (options:Ro if options.Mirror then " /MIR /IT" else " /IT" - let result = ExecProcess (fun info -> + let exitcode = ExecProcess (fun info -> info.FileName <- "CMD.exe" info.Arguments <- args) System.TimeSpan.MaxValue - - if result <> 0 then failwithf "Error during RoboCopy From: %s To: %s" source destination + + // Exit codes from https://support.microsoft.com/en-us/kb/954404 + let exitCodeWithMessage = + match exitcode with + | 0 -> (exitcode, "No files were copied. No failure was encountered. No files were mismatched. The files already exist in the destination directory; therefore, the copy operation was skipped.") + | 1 -> (exitcode, "All files were copied successfully.") + | 2 -> (exitcode, "There are some additional files in the destination directory that are not present in the source directory. No files were copied.") + | 3 -> (exitcode, "Some files were copied. Additional files were present. No failure was encountered.") + | 4 -> (exitcode, "Some Mismatched files or directories were detected. Examine the output log. Housekeeping might be required.") + | 5 -> (exitcode, "Some files were copied. Some files were mismatched. No failure was encountered.") + | 6 -> (exitcode, "Additional files and mismatched files exist. No files were copied and no failures were encountered. This means that the files already exist in the destination directory. ") + | 7 -> (exitcode, "Files were copied, a file mismatch was present, and additional files were present.") + | 8 -> (exitcode, "Several files did not copy.") + | _ -> (exitcode, "UNKNOWN ERROR") + + match exitCodeWithMessage with + | (exitcode, message) when exitcode < 2 -> tracefn "Succeeded in RoboCopy From: %s To: %s \n%s\n" source destination message |> ignore + | (exitcode, message) when exitcode < 8 -> traceImportant <| sprintf "Important notice in RoboCopy From: %s To: %s \n%s\n" source destination message |> ignore + | (_, _) -> failwithf "Error during RoboCopy From: %s To: %s" source destination /// Executes a RoboCopy command /// ## Parameters