Loading ConfigParser.fs 0 → 100644 +39 −0 Original line number Diff line number Diff line module Mbackup.ConfigParser open System open System.IO open System.Text.RegularExpressions open Mbackup.Lib type WellsConfig(fn: string) = let mutable keyValuePairs: Map<string, string> = Map.empty do let dropEmptyLinesAndComments lines = Seq.filter (fun (line: string) -> not (line.TrimStart().StartsWith("#") || line.TrimEnd().Equals(""))) lines let dropQuotesMaybe (value: string) = if value.StartsWith("\"") || value.StartsWith("'") then value.Substring(1, value.Length - 2) else value let toKeyValue = Seq.map (fun (line: string) -> let result: string[] = line.Split('=', 2) (result.[0].Trim(), dropQuotesMaybe (result.[1].Trim()))) let result = File.ReadAllLines(fn) // file IO can throw Exception |> dropEmptyLinesAndComments |> toKeyValue |> Seq.fold (fun (m: Map<string, string>) (k, v) -> m.Add(k, v)) keyValuePairs keyValuePairs <- result member this.ConfigFile = fn member this.GetStr key = let getEnv (varName: string) = Environment.GetEnvironmentVariable varName let configKeyToEnvVar (key: string) = key.ToUpper().Replace(".", "_").Replace("-", "_") match getEnv (configKeyToEnvVar key) with | null | "" -> keyValuePairs.TryFind key | envValue -> Some envValue member this.GetBool key = Option.map (fun value -> Regex.IsMatch(value, "^(yes|true|enable|1)$", RegexOptions.IgnoreCase)) (this.GetStr key) member this.GetFloat key = let value = keyValuePairs.TryGetValue key let parseFloat s = try Some (float s) with | _ -> None Option.map parseFloat (this.GetStr key) member this.GetInt key = let value = keyValuePairs.TryGetValue key let parseInt s = try Some (int s) with | _ -> None Option.map parseInt (this.GetStr key) Lib.fs +5 −8 Original line number Diff line number Diff line Loading @@ -39,9 +39,9 @@ type Logger() = // append string s to list if pred is true let appendWhen (pred: bool) (lst: string list) (s: string) = if pred then List.append lst [s] else lst let GetEnv (varName: string) = Environment.GetEnvironmentVariable varName let getEnv (varName: string) = Environment.GetEnvironmentVariable varName let GetEnvDefault (varName: string) (defaultValue: string) = let getEnvDefault (varName: string) (defaultValue: string) = let value = Environment.GetEnvironmentVariable varName match value with | null -> defaultValue Loading @@ -51,7 +51,7 @@ let GetEnvDefault (varName: string) (defaultValue: string) = // Convert windows path to Mingw64 path. // Supported windows path: C:\foo, C:/foo, /c/foo // MingwPath format: /cygdrive/c/foo let ToMingwPath (windowsPath: string) = let toMingwPath (windowsPath: string) = let pattern = Regex("^/([c-zC-Z])/", RegexOptions.None) let result = if pattern.IsMatch(windowsPath) then Loading @@ -65,8 +65,5 @@ let ToMingwPath (windowsPath: string) = windowsPath result let EnsureDir (path: string) = if path.EndsWith "/" then path else path + "/" let EnsureWinDir (path: string) = if path.EndsWith "\\" then path else path + "\\" let parseMbackupConfig fn = () let ensureDir (path: string) = if path.EndsWith "/" then path else path + "/" let ensureWinDir (path: string) = if path.EndsWith "\\" then path else path + "\\" Program.fs +26 −25 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ open System.Diagnostics.CodeAnalysis open Argu open Mbackup.Lib open Mbackup.ConfigParser let ExitBadParam = 1 let ExitTimeout = 2 Loading @@ -43,28 +44,27 @@ with | Node_Name _ -> "local node's name, used in remote logging" | Ssh_Key _ -> "ssh private key, used when backup to remote ssh node" let appDataRoamingDir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) |> ToMingwPath |> EnsureDir let programDataDirWin = GetEnv "PROGRAMDATA" |> EnsureWinDir let programDataDir = ToMingwPath programDataDirWin let appDataLocalDirWin = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) |> EnsureWinDir let appDataLocalDir = appDataLocalDirWin |> ToMingwPath let appDataRoamingDir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) |> toMingwPath |> ensureDir let programDataDirWin = getEnv "PROGRAMDATA" |> ensureWinDir let programDataDir = toMingwPath programDataDirWin let appDataLocalDirWin = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) |> ensureWinDir let appDataLocalDir = appDataLocalDirWin |> toMingwPath let mbackupInstallDirWin = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles) |> EnsureDir |> fun s -> s + "mbackup" let mbackupInstallDir = mbackupInstallDirWin |> ToMingwPath let mbackupInstallDirWin = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles) |> ensureDir |> fun s -> s + "mbackup" let mbackupInstallDir = mbackupInstallDirWin |> toMingwPath let userHomeWin = GetEnvDefault "HOME" (Environment.GetFolderPath(Environment.SpecialFolder.UserProfile)) |> EnsureWinDir getEnvDefault "HOME" (Environment.GetFolderPath(Environment.SpecialFolder.UserProfile)) |> ensureWinDir let userHome = userHomeWin |> ToMingwPath let userHome = userHomeWin |> toMingwPath let userConfigDirWin = programDataDirWin + "mbackup\\" let userConfigDir = programDataDir + "mbackup/" let runtimeDirWin = appDataLocalDirWin + "mbackup\\" let runtimeDir = appDataLocalDir + "mbackup/" let mbackupConfigFile = userConfigDirWin + "mbackup.ini" let mbackupConfig: unit = parseMbackupConfig mbackupConfigFile let mbackupConfigFile = userConfigDirWin + "mbackup.txt" let isLocalTarget (target: string) = target.StartsWith "/" Loading @@ -75,9 +75,9 @@ let isLocalTarget (target: string) = target.StartsWith "/" // etc let expandUserFile (fn: string) = let fn = let documentsDir = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) |> ToMingwPath |> EnsureDir let picturesDir = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures) |> ToMingwPath |> EnsureDir let desktopDir = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory) |> ToMingwPath |> EnsureDir let documentsDir = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) |> toMingwPath |> ensureDir let picturesDir = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures) |> toMingwPath |> ensureDir let desktopDir = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory) |> toMingwPath |> ensureDir let fn = Regex.Replace(fn, "^My Documents/", documentsDir, RegexOptions.IgnoreCase) let fn = Regex.Replace(fn, "^Documents/", documentsDir, RegexOptions.IgnoreCase) let fn = Regex.Replace(fn, "^我的文档/", documentsDir) Loading @@ -103,14 +103,14 @@ let generateMbackupList (logger: Logger) = let mbackupList = runtimeDirWin + "mbackup.list" // local functions let dropEmptyLinesAndComments = Seq.filter (fun (line: string) -> not (line.TrimStart().StartsWith("#") || line.TrimEnd().Equals(""))) let dropEmptyLinesAndComments lines = Seq.filter (fun (line: string) -> not (line.TrimStart().StartsWith("#") || line.TrimEnd().Equals(""))) lines let readMbackupListFile fn = File.ReadAllLines(fn) |> dropEmptyLinesAndComments try let defaultListLines = readMbackupListFile mbackupDefaultList |> Seq.map ToMingwPath let defaultListLines = readMbackupListFile mbackupDefaultList |> Seq.map toMingwPath let localListLinesMaybe = try let lines = readMbackupListFile mbackupLocalList |> Seq.map ToMingwPath let lines = readMbackupListFile mbackupLocalList |> Seq.map toMingwPath (true, lines) with | :? System.IO.FileNotFoundException -> Loading Loading @@ -170,19 +170,20 @@ let main argv = // TODO remove usage of test dir. let mbackupInstallDirWinTest = "D:\\downloads\\apps\\mbackupTest\\" let mbackupInstallDirTest = mbackupInstallDirWinTest |> ToMingwPath |> EnsureDir let mbackupInstallDirTest = mbackupInstallDirWinTest |> toMingwPath |> ensureDir let sshExeFile = mbackupInstallDirTest + "rsync-w64/usr/bin/ssh.exe" let sshConfigFile = userHome + ".ssh/config" let sshPrivateKeyFile = results.GetResult(Ssh_Key, defaultValue = userHome + ".ssh/id_rsa") |> ToMingwPath let sshPrivateKeyFile = results.GetResult(Ssh_Key, defaultValue = userHome + ".ssh/id_rsa") |> toMingwPath let rsyncCmd = List.append rsyncCmd [sprintf "-e \"%s -F %s -i %s -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null\"" sshExeFile sshConfigFile sshPrivateKeyFile] let backupTarget = results.GetResult (Target, defaultValue = Environment.GetEnvironmentVariable "TARGET") match backupTarget with | null -> let mbackupConfig = WellsConfig(mbackupConfigFile) let backupTargetMaybe = mbackupConfig.GetStr("target") match backupTargetMaybe with | None -> logger.Error "TARGET is not defined" ExitBadParam | _ -> let backupTarget = ToMingwPath backupTarget | Some backupTarget -> let backupTarget = toMingwPath backupTarget let rsyncCmd = if not (isLocalTarget backupTarget) then Loading mbackup-for-windows.fsproj +1 −0 Original line number Diff line number Diff line Loading @@ -8,6 +8,7 @@ <ItemGroup> <Compile Include="Lib.fs" /> <Compile Include="ConfigParser.fs" /> <Compile Include="Program.fs" /> </ItemGroup> Loading mbackup-tests/MbackupTest.fs +25 −13 Original line number Diff line number Diff line Loading @@ -12,19 +12,19 @@ let TestDumb () = Assert.Pass() [<Test>] let TestToMingwPath () = Assert.That("/cygdrive/c/", Is.EqualTo(ToMingwPath "c:\\")) Assert.That("/cygdrive/c/", Is.EqualTo(ToMingwPath "C:\\")) Assert.That("/cygdrive/c/foo", Is.EqualTo(ToMingwPath "C:\\foo")) Assert.That("/cygdrive/d/foo", Is.EqualTo(ToMingwPath "D:\\foo")) Assert.That("/cygdrive/d/Foo", Is.EqualTo(ToMingwPath "D:\\Foo")) Assert.That("/cygdrive/c/foo/bar/", Is.EqualTo(ToMingwPath "C:\\foo\\bar\\")) Assert.That("/cygdrive/c/foo/bar/baz.txt", Is.EqualTo(ToMingwPath "C:\\foo\\bar\\baz.txt")) Assert.That("/cygdrive/c/foo", Is.EqualTo(ToMingwPath "C:/foo")) Assert.That("/cygdrive/c/foo/bar", Is.EqualTo(ToMingwPath "C:/foo/bar")) Assert.That("/cygdrive/c/foo", Is.EqualTo(ToMingwPath "/c/foo")) Assert.That("/cygdrive/D/foo", Is.EqualTo(ToMingwPath "/D/foo")) Assert.That("/var/log", Is.EqualTo(ToMingwPath "/var/log")) let TesttoMingwPath () = Assert.That("/cygdrive/c/", Is.EqualTo(toMingwPath "c:\\")) Assert.That("/cygdrive/c/", Is.EqualTo(toMingwPath "C:\\")) Assert.That("/cygdrive/c/foo", Is.EqualTo(toMingwPath "C:\\foo")) Assert.That("/cygdrive/d/foo", Is.EqualTo(toMingwPath "D:\\foo")) Assert.That("/cygdrive/d/Foo", Is.EqualTo(toMingwPath "D:\\Foo")) Assert.That("/cygdrive/c/foo/bar/", Is.EqualTo(toMingwPath "C:\\foo\\bar\\")) Assert.That("/cygdrive/c/foo/bar/baz.txt", Is.EqualTo(toMingwPath "C:\\foo\\bar\\baz.txt")) Assert.That("/cygdrive/c/foo", Is.EqualTo(toMingwPath "C:/foo")) Assert.That("/cygdrive/c/foo/bar", Is.EqualTo(toMingwPath "C:/foo/bar")) Assert.That("/cygdrive/c/foo", Is.EqualTo(toMingwPath "/c/foo")) Assert.That("/cygdrive/D/foo", Is.EqualTo(toMingwPath "/D/foo")) Assert.That("/var/log", Is.EqualTo(toMingwPath "/var/log")) let mysprintf fmt = sprintf fmt Loading @@ -45,3 +45,15 @@ let TestMylogger () = Assert.That("INFO 123", Is.EqualTo(mylogger "%d" 123)) Assert.That("INFO 123 456", Is.EqualTo(mylogger "%d %d" 123 456)) Assert.That("INFO 123 456 a", Is.EqualTo(mylogger "%d %d %s" 123 456 "a")) [<Test>] let TestStringSplit () = let r = "a=b".Split('=') Assert.That("a", Is.EqualTo(r.[0])) Assert.That("b", Is.EqualTo(r.[1])) let r = "a= b".Split('=') Assert.That("a", Is.EqualTo(r.[0])) Assert.That(" b", Is.EqualTo(r.[1])) let r = "a=b=c".Split('=', 2) Assert.That("a", Is.EqualTo(r.[0])) Assert.That("b=c", Is.EqualTo(r.[1])) Loading
ConfigParser.fs 0 → 100644 +39 −0 Original line number Diff line number Diff line module Mbackup.ConfigParser open System open System.IO open System.Text.RegularExpressions open Mbackup.Lib type WellsConfig(fn: string) = let mutable keyValuePairs: Map<string, string> = Map.empty do let dropEmptyLinesAndComments lines = Seq.filter (fun (line: string) -> not (line.TrimStart().StartsWith("#") || line.TrimEnd().Equals(""))) lines let dropQuotesMaybe (value: string) = if value.StartsWith("\"") || value.StartsWith("'") then value.Substring(1, value.Length - 2) else value let toKeyValue = Seq.map (fun (line: string) -> let result: string[] = line.Split('=', 2) (result.[0].Trim(), dropQuotesMaybe (result.[1].Trim()))) let result = File.ReadAllLines(fn) // file IO can throw Exception |> dropEmptyLinesAndComments |> toKeyValue |> Seq.fold (fun (m: Map<string, string>) (k, v) -> m.Add(k, v)) keyValuePairs keyValuePairs <- result member this.ConfigFile = fn member this.GetStr key = let getEnv (varName: string) = Environment.GetEnvironmentVariable varName let configKeyToEnvVar (key: string) = key.ToUpper().Replace(".", "_").Replace("-", "_") match getEnv (configKeyToEnvVar key) with | null | "" -> keyValuePairs.TryFind key | envValue -> Some envValue member this.GetBool key = Option.map (fun value -> Regex.IsMatch(value, "^(yes|true|enable|1)$", RegexOptions.IgnoreCase)) (this.GetStr key) member this.GetFloat key = let value = keyValuePairs.TryGetValue key let parseFloat s = try Some (float s) with | _ -> None Option.map parseFloat (this.GetStr key) member this.GetInt key = let value = keyValuePairs.TryGetValue key let parseInt s = try Some (int s) with | _ -> None Option.map parseInt (this.GetStr key)
Lib.fs +5 −8 Original line number Diff line number Diff line Loading @@ -39,9 +39,9 @@ type Logger() = // append string s to list if pred is true let appendWhen (pred: bool) (lst: string list) (s: string) = if pred then List.append lst [s] else lst let GetEnv (varName: string) = Environment.GetEnvironmentVariable varName let getEnv (varName: string) = Environment.GetEnvironmentVariable varName let GetEnvDefault (varName: string) (defaultValue: string) = let getEnvDefault (varName: string) (defaultValue: string) = let value = Environment.GetEnvironmentVariable varName match value with | null -> defaultValue Loading @@ -51,7 +51,7 @@ let GetEnvDefault (varName: string) (defaultValue: string) = // Convert windows path to Mingw64 path. // Supported windows path: C:\foo, C:/foo, /c/foo // MingwPath format: /cygdrive/c/foo let ToMingwPath (windowsPath: string) = let toMingwPath (windowsPath: string) = let pattern = Regex("^/([c-zC-Z])/", RegexOptions.None) let result = if pattern.IsMatch(windowsPath) then Loading @@ -65,8 +65,5 @@ let ToMingwPath (windowsPath: string) = windowsPath result let EnsureDir (path: string) = if path.EndsWith "/" then path else path + "/" let EnsureWinDir (path: string) = if path.EndsWith "\\" then path else path + "\\" let parseMbackupConfig fn = () let ensureDir (path: string) = if path.EndsWith "/" then path else path + "/" let ensureWinDir (path: string) = if path.EndsWith "\\" then path else path + "\\"
Program.fs +26 −25 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ open System.Diagnostics.CodeAnalysis open Argu open Mbackup.Lib open Mbackup.ConfigParser let ExitBadParam = 1 let ExitTimeout = 2 Loading @@ -43,28 +44,27 @@ with | Node_Name _ -> "local node's name, used in remote logging" | Ssh_Key _ -> "ssh private key, used when backup to remote ssh node" let appDataRoamingDir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) |> ToMingwPath |> EnsureDir let programDataDirWin = GetEnv "PROGRAMDATA" |> EnsureWinDir let programDataDir = ToMingwPath programDataDirWin let appDataLocalDirWin = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) |> EnsureWinDir let appDataLocalDir = appDataLocalDirWin |> ToMingwPath let appDataRoamingDir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) |> toMingwPath |> ensureDir let programDataDirWin = getEnv "PROGRAMDATA" |> ensureWinDir let programDataDir = toMingwPath programDataDirWin let appDataLocalDirWin = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) |> ensureWinDir let appDataLocalDir = appDataLocalDirWin |> toMingwPath let mbackupInstallDirWin = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles) |> EnsureDir |> fun s -> s + "mbackup" let mbackupInstallDir = mbackupInstallDirWin |> ToMingwPath let mbackupInstallDirWin = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles) |> ensureDir |> fun s -> s + "mbackup" let mbackupInstallDir = mbackupInstallDirWin |> toMingwPath let userHomeWin = GetEnvDefault "HOME" (Environment.GetFolderPath(Environment.SpecialFolder.UserProfile)) |> EnsureWinDir getEnvDefault "HOME" (Environment.GetFolderPath(Environment.SpecialFolder.UserProfile)) |> ensureWinDir let userHome = userHomeWin |> ToMingwPath let userHome = userHomeWin |> toMingwPath let userConfigDirWin = programDataDirWin + "mbackup\\" let userConfigDir = programDataDir + "mbackup/" let runtimeDirWin = appDataLocalDirWin + "mbackup\\" let runtimeDir = appDataLocalDir + "mbackup/" let mbackupConfigFile = userConfigDirWin + "mbackup.ini" let mbackupConfig: unit = parseMbackupConfig mbackupConfigFile let mbackupConfigFile = userConfigDirWin + "mbackup.txt" let isLocalTarget (target: string) = target.StartsWith "/" Loading @@ -75,9 +75,9 @@ let isLocalTarget (target: string) = target.StartsWith "/" // etc let expandUserFile (fn: string) = let fn = let documentsDir = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) |> ToMingwPath |> EnsureDir let picturesDir = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures) |> ToMingwPath |> EnsureDir let desktopDir = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory) |> ToMingwPath |> EnsureDir let documentsDir = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) |> toMingwPath |> ensureDir let picturesDir = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures) |> toMingwPath |> ensureDir let desktopDir = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory) |> toMingwPath |> ensureDir let fn = Regex.Replace(fn, "^My Documents/", documentsDir, RegexOptions.IgnoreCase) let fn = Regex.Replace(fn, "^Documents/", documentsDir, RegexOptions.IgnoreCase) let fn = Regex.Replace(fn, "^我的文档/", documentsDir) Loading @@ -103,14 +103,14 @@ let generateMbackupList (logger: Logger) = let mbackupList = runtimeDirWin + "mbackup.list" // local functions let dropEmptyLinesAndComments = Seq.filter (fun (line: string) -> not (line.TrimStart().StartsWith("#") || line.TrimEnd().Equals(""))) let dropEmptyLinesAndComments lines = Seq.filter (fun (line: string) -> not (line.TrimStart().StartsWith("#") || line.TrimEnd().Equals(""))) lines let readMbackupListFile fn = File.ReadAllLines(fn) |> dropEmptyLinesAndComments try let defaultListLines = readMbackupListFile mbackupDefaultList |> Seq.map ToMingwPath let defaultListLines = readMbackupListFile mbackupDefaultList |> Seq.map toMingwPath let localListLinesMaybe = try let lines = readMbackupListFile mbackupLocalList |> Seq.map ToMingwPath let lines = readMbackupListFile mbackupLocalList |> Seq.map toMingwPath (true, lines) with | :? System.IO.FileNotFoundException -> Loading Loading @@ -170,19 +170,20 @@ let main argv = // TODO remove usage of test dir. let mbackupInstallDirWinTest = "D:\\downloads\\apps\\mbackupTest\\" let mbackupInstallDirTest = mbackupInstallDirWinTest |> ToMingwPath |> EnsureDir let mbackupInstallDirTest = mbackupInstallDirWinTest |> toMingwPath |> ensureDir let sshExeFile = mbackupInstallDirTest + "rsync-w64/usr/bin/ssh.exe" let sshConfigFile = userHome + ".ssh/config" let sshPrivateKeyFile = results.GetResult(Ssh_Key, defaultValue = userHome + ".ssh/id_rsa") |> ToMingwPath let sshPrivateKeyFile = results.GetResult(Ssh_Key, defaultValue = userHome + ".ssh/id_rsa") |> toMingwPath let rsyncCmd = List.append rsyncCmd [sprintf "-e \"%s -F %s -i %s -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null\"" sshExeFile sshConfigFile sshPrivateKeyFile] let backupTarget = results.GetResult (Target, defaultValue = Environment.GetEnvironmentVariable "TARGET") match backupTarget with | null -> let mbackupConfig = WellsConfig(mbackupConfigFile) let backupTargetMaybe = mbackupConfig.GetStr("target") match backupTargetMaybe with | None -> logger.Error "TARGET is not defined" ExitBadParam | _ -> let backupTarget = ToMingwPath backupTarget | Some backupTarget -> let backupTarget = toMingwPath backupTarget let rsyncCmd = if not (isLocalTarget backupTarget) then Loading
mbackup-for-windows.fsproj +1 −0 Original line number Diff line number Diff line Loading @@ -8,6 +8,7 @@ <ItemGroup> <Compile Include="Lib.fs" /> <Compile Include="ConfigParser.fs" /> <Compile Include="Program.fs" /> </ItemGroup> Loading
mbackup-tests/MbackupTest.fs +25 −13 Original line number Diff line number Diff line Loading @@ -12,19 +12,19 @@ let TestDumb () = Assert.Pass() [<Test>] let TestToMingwPath () = Assert.That("/cygdrive/c/", Is.EqualTo(ToMingwPath "c:\\")) Assert.That("/cygdrive/c/", Is.EqualTo(ToMingwPath "C:\\")) Assert.That("/cygdrive/c/foo", Is.EqualTo(ToMingwPath "C:\\foo")) Assert.That("/cygdrive/d/foo", Is.EqualTo(ToMingwPath "D:\\foo")) Assert.That("/cygdrive/d/Foo", Is.EqualTo(ToMingwPath "D:\\Foo")) Assert.That("/cygdrive/c/foo/bar/", Is.EqualTo(ToMingwPath "C:\\foo\\bar\\")) Assert.That("/cygdrive/c/foo/bar/baz.txt", Is.EqualTo(ToMingwPath "C:\\foo\\bar\\baz.txt")) Assert.That("/cygdrive/c/foo", Is.EqualTo(ToMingwPath "C:/foo")) Assert.That("/cygdrive/c/foo/bar", Is.EqualTo(ToMingwPath "C:/foo/bar")) Assert.That("/cygdrive/c/foo", Is.EqualTo(ToMingwPath "/c/foo")) Assert.That("/cygdrive/D/foo", Is.EqualTo(ToMingwPath "/D/foo")) Assert.That("/var/log", Is.EqualTo(ToMingwPath "/var/log")) let TesttoMingwPath () = Assert.That("/cygdrive/c/", Is.EqualTo(toMingwPath "c:\\")) Assert.That("/cygdrive/c/", Is.EqualTo(toMingwPath "C:\\")) Assert.That("/cygdrive/c/foo", Is.EqualTo(toMingwPath "C:\\foo")) Assert.That("/cygdrive/d/foo", Is.EqualTo(toMingwPath "D:\\foo")) Assert.That("/cygdrive/d/Foo", Is.EqualTo(toMingwPath "D:\\Foo")) Assert.That("/cygdrive/c/foo/bar/", Is.EqualTo(toMingwPath "C:\\foo\\bar\\")) Assert.That("/cygdrive/c/foo/bar/baz.txt", Is.EqualTo(toMingwPath "C:\\foo\\bar\\baz.txt")) Assert.That("/cygdrive/c/foo", Is.EqualTo(toMingwPath "C:/foo")) Assert.That("/cygdrive/c/foo/bar", Is.EqualTo(toMingwPath "C:/foo/bar")) Assert.That("/cygdrive/c/foo", Is.EqualTo(toMingwPath "/c/foo")) Assert.That("/cygdrive/D/foo", Is.EqualTo(toMingwPath "/D/foo")) Assert.That("/var/log", Is.EqualTo(toMingwPath "/var/log")) let mysprintf fmt = sprintf fmt Loading @@ -45,3 +45,15 @@ let TestMylogger () = Assert.That("INFO 123", Is.EqualTo(mylogger "%d" 123)) Assert.That("INFO 123 456", Is.EqualTo(mylogger "%d %d" 123 456)) Assert.That("INFO 123 456 a", Is.EqualTo(mylogger "%d %d %s" 123 456 "a")) [<Test>] let TestStringSplit () = let r = "a=b".Split('=') Assert.That("a", Is.EqualTo(r.[0])) Assert.That("b", Is.EqualTo(r.[1])) let r = "a= b".Split('=') Assert.That("a", Is.EqualTo(r.[0])) Assert.That(" b", Is.EqualTo(r.[1])) let r = "a=b=c".Split('=', 2) Assert.That("a", Is.EqualTo(r.[0])) Assert.That("b=c", Is.EqualTo(r.[1]))