Skip to content

Commit

Permalink
friendlier command line options
Browse files Browse the repository at this point in the history
  • Loading branch information
gabesoft committed Feb 22, 2011
1 parent 0aaf7d3 commit 5e3b75b
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 108 deletions.
95 changes: 48 additions & 47 deletions ProjApp/GabeSoft.FOPS.Core/Options.fs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
namespace GabeSoft.FOPS.Core

open System
open System.Collections.Generic
open Microsoft.FSharp.Text
open GabeSoft.FOPS.Cmd

Expand Down Expand Up @@ -30,49 +31,47 @@ type Options (args, ?log:Log, ?app) =
let mutable _jobId = String.Empty

let set = new OptionSet()
let add arg (action:'a -> unit) desc =
let add arg (action:string -> unit) desc =
set.Add(arg, desc, new Action<_>(action)) |> ignore
let add2 arg (action:string -> string -> unit) desc =
set.Add(arg, desc, new OptionAction<_, _>(action)) |> ignore

do
add "?|help" (fun (v:string) -> _help <- true)
"Show usage."
add "f|file=" (fun v -> _file <- v)
"Path to the file containing the jobs to run."
add "d|delete" (fun (v:string) -> _yank <- true)
@"Delete all files that match a wildcard
add "?|help" (fun v -> _help <- true)
"Show usage."
add "f|file=" (fun v -> _file <- v)
"Path to the file containing the jobs to run."
add "d|delete=" (fun v -> _yank <- true; _src <- v)
@"Delete all files that match a wildcard
pattern (including read-only!)."
add "D|deletedir" (fun (v:string) -> _yankd <- true)
"Delete an entire directory recursively!"
add "c|copy" (fun (v:string) -> _copy <- true)
"Copy files according to a wildcard pattern."
add "l|link" (fun (v:string) -> _link <- true)
"Link files according to a wildcard pattern."
add "copyfile" (fun (v:string) -> _copyf <- true)
"Copy a single file."
add "linkfile" (fun (v:string) -> _linkf <- true)
"Link a single file."
add "m|movefile" (fun (v:string) -> _movef <- true)
"Rename a file."
add "C|copydir" (fun (v:string) -> _copyd <- true)
"Copy a directory recursively."
add "L|linkdir" (fun (v:string) -> _linkd <- true)
"Link a directory recursively."
add "M|movedir" (fun (v:string) -> _moved <- true)
"Rename or move a directory."
add "F|force" (fun (v:string) -> _force <- true)
"Overwrite any existing files at destination"
add "v|verbose" (fun (v:string) -> _verbose <- true)
"Displays detailed information"
add "p|src=" (fun v -> _src <- v)
"Source path (filesystem path or wildcard pattern)."
add "P|dst=" (fun v -> _dst <- v)
"Destination path (filesystem path)."
add "b|basesrc=" (fun v -> _baseSrc <- v)
"Base source directory path."
add "B|basedst=" (fun v -> _baseDst <- v)
"Base destination directory path."
add "j|jobid=" (fun v -> _jobId <- v)
"The id of a job to run. Omit to run all jobs."
add "D|deleted=" (fun v -> _yankd <- true; _src <- v)
"Delete an entire directory recursively!"
add2 "c|copy={}" (fun src dst -> _copy <- true; _src <- src; _dst <- dst)
"Copy files according to a wildcard pattern."
add2 "l|link={}" (fun src dst -> _link <- true; _src <- src; _dst <- dst)
"Link files according to a wildcard pattern."
add2 "copyf={}" (fun src dst -> _copyf <- true; _src <- src; _dst <- dst)
"Copy a single file."
add2 "linkf={}" (fun src dst -> _linkf <- true; _src <- src; _dst <- dst)
"Link a single file."
add2 "m|movef={}" (fun src dst -> _movef <- true; _src <- src; _dst <- dst)
"Rename a file."
add2 "C|copyd={}" (fun src dst -> _copyd <- true; _src <- src; _dst <- dst)
"Copy a directory recursively."
add2 "L|linkd={}" (fun src dst -> _linkd <- true; _src <- src; _dst <- dst)
"Link a directory recursively."
add2 "M|moved={}" (fun src dst -> _moved <- true; _src <- src; _dst <- dst)
"Rename or move a directory."
add "F|force" (fun v -> _force <- true)
"Overwrite any existing files at destination"
add "v|verbose" (fun v -> _verbose <- true)
"Displays detailed information"
add "b|basesrc=" (fun v -> _baseSrc <- v)
"Base source directory path."
add "B|basedst=" (fun v -> _baseDst <- v)
"Base destination directory path."
add "j|jobid=" (fun v -> _jobId <- v)
"The id of a job to run. Omit to run all jobs."

set.Parse(args) |> ignore

Expand Down Expand Up @@ -101,14 +100,16 @@ type Options (args, ?log:Log, ?app) =
member x.JobId with get() = _jobId
member x.WriteUsage () =
cmd "--file=<path> [-basesrc=<path>] [-basedst=<path>] [-jobid=<id>]"
cmd "--delete --src=<pattern>"
cmd "--deletedir --src=<path>"
cmd "--copy --src=<pattern> --dst=<path> [options]"
cmd "--copyfile --src=<path> --dst=<path> [options]"
cmd "--copydir --src=<path> --dst=<path> [options]"
cmd "--link --src=<pattern> --dst=<path> [options]"
cmd "--linkfile --src=<path> --dst=<path> [options]"
cmd "--linkdir --src=<path> --dst=<path> [options]"
cmd "--copy <src_pattern> <dst_path> [options]"
cmd "--link <src_pattern> <dst_path> [options]"
cmd "--delete <src_pattern>"
cmd "--copyf <src_path> <dst_path> [options]"
cmd "--linkf <src_path> <dst_path> [options]"
cmd "--movef <src_path> <dst_path> [options]"
cmd "--copyd <src_path> <dst_path> [options]"
cmd "--linkd <src_path> <dst_path> [options]"
cmd "--moved <src_path> <dst_path> [options]"
cmd "--deleted <src_path>"
writeln String.Empty
writeOpts ()
writeln ""
Expand Down
97 changes: 49 additions & 48 deletions ProjTest/GabeSoft.FOPS.Test/OptionsTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -13,52 +13,53 @@ let creatingOptions args =
printMethod args
new Options (args)

let equal message a b =
sprintf "%s %s" message (prepareOutput (a, b)) |> toSpec
a = b
let expected f expected (opts:Options) =
let actual = f opts
printMethod (expected, actual)
expected = actual

//let file arg (o:Options) = equal "file" o.File arg
//let basePath arg (o:Options) = equal "basePath" o.BaseSrc arg
//let jobId arg (o:Options) = equal "jobId" o.JobId arg
//let source arg (o:Options) = equal "source" o.From arg
//let destination arg (o:Options) = equal "destination" o.To arg
//let overwrite (o:Options) = printMethod ""; o.Overwrite
//let hlinks (o:Options) = printMethod ""; o.Hlinks
//let invalid (o:Options) = printMethod ""; not o.Valid
//
//[<Scenario>]
//let ``Given a jobs file and a base path results in valid options`` () =
// let args = [ "-x"; "jobs.xml"; "-b"; @"C:\Temp"; "-j"; "123" ]
// Given args
// |> When creatingOptions
// |> It should have (file args.[1])
// |> It should have (basePath args.[3])
// |> It should have (jobId args.[5])
// |> Verify
//
//[<Scenario>]
//let ``Given a from and to path results in valid options`` () =
// let args = [ "-f"; @"C:\Source\*.txt"; "-t"; @"C:\Destination"; "-o"; "-h" ]
// Given args
// |> When creatingOptions
// |> It should have (source args.[1])
// |> It should have (destination args.[3])
// |> It should have overwrite
// |> It should have hlinks
// |> Verify
//
//[<Scenario>]
//let ``Given a jobs file and a source or destination results in invalid options`` () =
// let args = ["--file=jobs.xml"; "--to=Temp" ]
// Given args
// |> When creatingOptions
// |> It should be invalid
// |> Verify
//
//[<Scenario>]
//let ``Not given a source file requires both a source and a destination`` () =
// let args = ["--from=Destination"; "-o"; "-h"]
// Given args
// |> When creatingOptions
// |> It should be invalid
// |> Verify
[<Scenario>]
let File () =
Given ["-f"; "jobs.xml"; "-b=src"; "-B:dst"; "-j"; "12" ]
|> When creatingOptions
|> It should have (fun o -> o.File = "jobs.xml")
|> It should have (fun o -> o.BaseSrc = "src")
|> It should have (fun o -> o.BaseDst = "dst")
|> It should have (fun o -> o.JobId = "12")
|> Verify

[<Scenario>]
let Delete () =
Given ["-d"; "/a/b/c"]
|> When creatingOptions
|> It should have (fun o -> o.Yank)
|> It should have (fun o -> o.Src = "/a/b/c")
|> Verify

[<Scenario>]
let ``Delete dir`` () =
Given ["-D"; "/a/b/c"]
|> When creatingOptions
|> It should have (fun o -> o.YankDir)
|> It should have (fun o -> o.Src = "/a/b/c")
|> Verify

[<Scenario>]
let Copy () =
Given ["-c"; @"C:\a\src"; @"C:\b\dst"; "-F"]
|> When creatingOptions
|> It should have (fun o -> o.Copy)
|> It should have (expected (fun o -> o.Src) @"C:\a\src")
|> It should have (expected (fun o -> o.Dst) @"C:\b\dst")
|> It should have (fun o -> o.Force)
|> Verify

[<Scenario>]
let Link () =
Given ["-l"; @"C:\a\src"; @"C:\b\dst"; "-F"]
|> When creatingOptions
|> It should have (fun o -> o.Link)
|> It should have (expected (fun o -> o.Src) @"C:\a\src")
|> It should have (expected (fun o -> o.Dst) @"C:\b\dst")
|> It should have (fun o -> o.Force)
|> Verify
19 changes: 6 additions & 13 deletions ProjTest/GabeSoft.FOPS.Test/OptionsValidatorTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,6 @@ open GabeSoft.FOPS.Core
open GabeSoft.FOPS.Test

let opts args = new Options(args)
let srcArg src = sprintf "--src=%s" src
let dstArg dst = sprintf "--dst=%s" dst

let validating opts =
printMethod "\n"
let log = new LogImpl()
Expand Down Expand Up @@ -80,15 +77,15 @@ let ``File - overrides base-src and base-dst`` () =
[<Scenario>]
let ``Delete - has expected type and source`` () =
let src = @"C:\a\b\*\c.txt"
Given (opts ["-d"; srcArg src])
Given (opts ["-d"; src])
|> When validating
|> It should have (expected_type [check_yank src PatternMode])
|> Verify

[<Scenario>]
let ``Delete dir - has expected type and source`` () =
let src = @"C:\a\b"
Given (opts ["-D"; srcArg src])
Given (opts ["-D"; src])
|> When validating
|> It should have (expected_type [check_yank src DirectoryMode])
|> Verify
Expand All @@ -100,7 +97,7 @@ let ``Copy - has expected type and paths`` (arg) =
let fn = check_funs.[arg]
let src = @"C:\a\?*\b\f?.p*"
let dst = @"F:\Temp"
Given (opts [arg; srcArg src; dstArg dst; "-F"])
Given (opts [arg; src; dst; "-F"])
|> When validating
|> It should have (expected_type [fn src dst true PatternMode])
|> Verify
Expand All @@ -112,7 +109,7 @@ let ``Copy file - has expected type and paths`` (arg) =
let fn = check_funs.[arg]
let src = @"C:\a\b\f1.doc"
let dst = @"C:\a\c\f2.txt"
Given (opts [arg; srcArg src; dstArg dst])
Given (opts [arg; src; dst])
|> When validating
|> It should have (expected_type [fn src dst false FileMode])
|> Verify
Expand All @@ -124,7 +121,7 @@ let ``Copy dir - has expected type and paths`` (arg) =
let fn = check_funs.[arg]
let src = @"C:\a\b\"
let dst = @"C:\a\c\"
Given (opts [arg; srcArg src; dstArg dst])
Given (opts [arg; src; dst])
|> When validating
|> It should have (expected_type [fn src dst false DirectoryMode])
|> Verify
Expand All @@ -136,12 +133,8 @@ let ``Move file - has expected job items`` (arg) =
let ymodes = Map.ofList ["-m", PatternMode; "-M", DirectoryMode]
let src = @"C:\a\b\f1"
let dst = @"C:\a\c\f2"
Given (opts [arg; srcArg src; dstArg dst; "-F"])
Given (opts [arg; src; dst; "-F"])
|> When validating
|> It should have (expected_type [ check_copy src dst true cmodes.[arg]
check_yank src ymodes.[arg] ])
|> Verify

// TODO: fix parsing to work with move
// when moving ensure that src is not
// deleted if the copy did not succeed

0 comments on commit 5e3b75b

Please sign in to comment.