Skip to content

Commit 54421d9

Browse files
committed
more options, better error reporting, added some tests, unified entry point (xake for everything),
1 parent c2bcad8 commit 54421d9

File tree

8 files changed

+154
-45
lines changed

8 files changed

+154
-45
lines changed

XakeLibTests/CommandLineTests.fs

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
namespace XakeLibTests
2+
3+
open System.IO
4+
open NUnit.Framework
5+
6+
open Xake
7+
8+
[<TestFixture (Description = "Command line tests")>]
9+
type CommandLineTests() =
10+
11+
let currentDir = Path.Combine (__SOURCE_DIRECTORY__, "..")
12+
13+
[<Test (Description = "Verifies reading common switches")>]
14+
member test.AcceptKnownSwitches() =
15+
16+
let scriptOptions = ref XakeOptions
17+
let args =
18+
["/t"; "33"; "/R"; currentDir; "/LL"; "Loud";
19+
"/FL"; "aaaaa"; "/D"; "AA=BBB"; "/D"; "AA1=CCC"; "/FLL"; "Silent"]
20+
21+
do xakeArgs args XakeOptions {
22+
wantOverride (["test"])
23+
24+
rules [
25+
"test" => action {
26+
let! opts = getCtxOptions()
27+
scriptOptions := opts
28+
}
29+
]
30+
}
31+
32+
let finalOptions = !scriptOptions
33+
Assert.AreEqual(33, finalOptions.Threads)
34+
Assert.AreEqual(currentDir, finalOptions.ProjectRoot)
35+
Assert.AreEqual("aaaaa", finalOptions.FileLog)
36+
Assert.AreEqual(Verbosity.Silent, finalOptions.FileLogLevel)
37+
Assert.AreEqual(Verbosity.Loud, finalOptions.ConLogLevel)
38+
Assert.AreEqual([("AA", "BBB"); ("AA1", "CCC")], finalOptions.Vars)
39+
40+
[<Test (Description = "Verifies reading target list")>]
41+
member test.ReadsTargets() =
42+
43+
let scriptOptions = ref XakeOptions
44+
let executed2 = ref false
45+
let args = ["/t"; "31"; "target1"; "target2"]
46+
47+
do xakeArgs args XakeOptions {
48+
49+
rules [
50+
"target1" => action {
51+
let! opts = getCtxOptions()
52+
scriptOptions := opts
53+
}
54+
"target2" => action {
55+
executed2 := true
56+
}
57+
]
58+
}
59+
60+
let finalOptions = !scriptOptions
61+
Assert.AreEqual(31, finalOptions.Threads)
62+
Assert.AreEqual(["target1"; "target2"], finalOptions.Want)
63+
Assert.IsTrue !executed2
64+
65+
66+
[<Test (Description = "Verifies reading incorrect"); Ignore>]
67+
member test.WarnsOnIncorrectSwitch() =
68+
69+
do xakeArgs ["/xxx"] XakeOptions {
70+
want ["ss"]
71+
}
72+
73+
//raise <| new System.NotImplementedException()
74+
75+
[<Test (Description = "Verifies that command line is ignored when Ignore option is set")>]
76+
member test.IgnoresCommandLine() =
77+
78+
let scriptOptions = ref XakeOptions
79+
let args =
80+
["/t"; "33"; "/R"; currentDir; "/LL"; "Loud";
81+
"/FL"; "aaaaa"; "target"]
82+
83+
do xakeArgs args {XakeOptions with IgnoreCommandLine = true; Threads = 2; FileLog = "ss"; Want = ["main"]} {
84+
rules [
85+
"main" => action {
86+
let! opts = getCtxOptions()
87+
scriptOptions := opts
88+
}
89+
]
90+
}
91+
92+
let finalOptions = !scriptOptions
93+
Assert.AreEqual(2, finalOptions.Threads)
94+
Assert.AreEqual("ss", finalOptions.FileLog)
95+
Assert.AreEqual(["main"], finalOptions.Want)

XakeLibTests/MiscTests.fs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ open Xake
77
open Storage
88
open BuildLog
99

10-
[<TestFixture (Description = "Verious tests")>]
10+
[<TestFixture (Description = "Various tests")>]
1111
type MiscTests() =
1212

1313
[<SetUp>]

XakeLibTests/XakeLibTests.fsproj

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,9 @@
4848
<Compile Include="MiscTests.fs" />
4949
<Compile Include="StorageTests.fs" />
5050
<Compile Include="FileTasksTests.fs" />
51-
<None Include="packages.config" />
5251
<Compile Include="ProgressTests.fs" />
52+
<Compile Include="CommandLineTests.fs" />
53+
<None Include="packages.config" />
5354
</ItemGroup>
5455
<ItemGroup>
5556
<ProjectReference Include="..\core\Xake.Core.fsproj">

core/Program.fs

Lines changed: 41 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -15,26 +15,27 @@ module internal ParseArgs = begin
1515
| "--" :: rest -> rest
1616
| _ :: tail -> get_script_args tail
1717

18-
let parseTopLevel arg optionsSoFar =
19-
match arg with
18+
let parseTopLevel (arg:string) optionsSoFar =
19+
match arg.ToLowerInvariant() with
2020

2121
// TODO support sequential/parallel runs e.g. "clean release-build;debug-build"
2222

2323
| "-t" | "/t" ->
2424
(optionsSoFar, Number ("thread count", fun o v -> {o with XakeOptionsType.Threads = v}))
25-
| "-R" | "/R" ->
25+
| "-r" | "/r" ->
2626
(optionsSoFar, String ("root folder", fun o v -> {o with XakeOptionsType.ProjectRoot = v}))
27-
| "-FL" | "/FL" ->
27+
| "-fl" | "/fl" ->
2828
(optionsSoFar, String ("file log filename", fun o v -> {o with XakeOptionsType.FileLog = v}))
29-
| "-D" | "/D" ->
29+
| "-d" | "/d" ->
3030
(optionsSoFar, KeyValue ("variable", fun o k v -> {o with Vars = o.Vars @ [(k,v)] }))
31-
| "-LL" | "/LL" ->
31+
| "-ll" | "/ll" ->
3232
(optionsSoFar, String ("console verbosity", fun o s -> {o with ConLogLevel = s |> parseVerbosity }))
33-
| "-FLL" | "/FLL" ->
33+
| "-fll" | "/fll" ->
3434
(optionsSoFar, String ("filelog verbosity", fun o s -> {o with FileLogLevel = s |> parseVerbosity }))
3535

3636
// handle unrecognized option
37-
| x when x.StartsWith("-") ->
37+
| x when x.StartsWith("-") || x.StartsWith("/") ->
38+
// TODO write errors to log?
3839
printfn "Option '%s' is unrecognized" x
3940
(optionsSoFar, TopLevel)
4041
| x ->
@@ -64,19 +65,29 @@ module internal ParseArgs = begin
6465

6566
(fn optionsSoFar k v, TopLevel)
6667

67-
let foldFunction state element =
68-
match state with
69-
| (optionsSoFar, TopLevel) ->
70-
parseTopLevel element optionsSoFar
71-
72-
| (optionsSoFar, Number (name, fn)) ->
73-
readNumber name element optionsSoFar fn
74-
75-
| (optionsSoFar, String (name, fn)) ->
76-
readString name element optionsSoFar fn
77-
78-
| (optionsSoFar, KeyValue (name, fn)) ->
79-
readKeyValue name element optionsSoFar fn
68+
let foldFunction state element =
69+
try
70+
match state with
71+
| (optionsSoFar, TopLevel) ->
72+
parseTopLevel element optionsSoFar
73+
74+
| (optionsSoFar, Number (name, fn)) ->
75+
readNumber name element optionsSoFar fn
76+
77+
| (optionsSoFar, String (name, fn)) ->
78+
readString name element optionsSoFar fn
79+
80+
| (optionsSoFar, KeyValue (name, fn)) ->
81+
readKeyValue name element optionsSoFar fn
82+
with e ->
83+
let argName =
84+
match state with
85+
| (_, Number (name, _)) | (_, KeyValue (name, _)) | (_, String (name, _)) ->
86+
name
87+
| _ ->
88+
"switch"
89+
printfn "Failed to parse '%s' due to %s" argName e.Message
90+
(fst state, TopLevel)
8091

8192
end
8293

@@ -85,28 +96,23 @@ module Main =
8596

8697
open ParseArgs
8798

88-
/// <summary>
89-
/// creates xake build script
90-
/// </summary>
91-
/// <param name="options"></param>
92-
let xake options =
93-
94-
new RulesBuilder(options)
95-
9699
/// <summary>
97100
/// Creates a script with script parameters passed as list of strings.
98101
/// </summary>
99102
/// <param name="args"></param>
100103
/// <param name="initialOptions"></param>
101-
let xakeArgsStr args initialOptions =
102-
let options = args |> List.fold foldFunction (initialOptions, TopLevel) |> fst
104+
let xakeArgs args initialOptions =
105+
let options =
106+
if initialOptions.IgnoreCommandLine then initialOptions
107+
else args |> List.fold foldFunction (initialOptions, TopLevel) |> fst
103108
new RulesBuilder (options)
104109

105110
/// <summary>
106111
/// Create xake build script using command-line arguments to define script options
107112
/// </summary>
108-
/// <param name="args"></param>
109-
/// <param name="options"></param>
110-
let xakeArgs =
113+
/// <param name="options">Initial options set. Could be overridden by a command line arguments.
114+
/// Define option IgnoreCommandLine=true to ignore command line arguments
115+
/// </param>
116+
let xake options =
111117
let args = get_args() |> get_script_args in
112-
xakeArgsStr args
118+
xakeArgs args options

core/XakeScript.fs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ module XakeScript =
2727

2828
/// Defines whether `run` should throw exception if script fails
2929
FailOnError: bool
30+
31+
/// Ignores command line swithes
32+
IgnoreCommandLine: bool
3033
}
3134

3235
type private ExecStatus = | Succeed | Skipped | JustFile
@@ -71,6 +74,7 @@ module XakeScript =
7174
Want = []
7275
FailOnError = false
7376
Vars = List<string*string>.Empty
77+
IgnoreCommandLine = false
7478
}
7579

7680
module private Impl = begin

docs/implnotes.md

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ Tasks:
8181
* NETFX - framework version to use for compilation, resources. E.g. "2.0", "3.5", "4.0". Default: highest available on the computer
8282

8383

84-
## Script arguments
84+
## Command line parameters
8585

8686
Script arguments allow to specify execution options, list of targets, logging options and others from command line.
8787
According to fsi.exe "--" arguments denotes the start of script arguments so in the most common case you will use it as:
@@ -93,13 +93,16 @@ where "clean" "build" and "deploy" are target names.
9393
The full list of parameters:
9494

9595
* -t <task count> -- use <task count> simultaneous processes to execute the build tasks. * Default value is the number of processors
96-
* -R <root path> -- override the root path. All the targets and filesets are resolved relatively to this path. Default is current directory
97-
* -LL <log level> -- console log level (Silent | Quiet | Normal | Loud | Chatty | Diag)
98-
* -FL <file log path> -- specifies the name of the log file
99-
* -FLL <log level> -- specifies the logging level to a log file
96+
* -r <root path> -- override the root path. All the targets and filesets are resolved relatively to this path. Default is current directory
97+
* -ll <log level> -- console log level (Silent | Quiet | Normal | Loud | Chatty | Diag)
98+
* -fl <file log path> -- specifies the name of the log file
99+
* -fll <log level> -- specifies the logging level to a log file
100100
* target1 .. targetN -- define the list of targets. Targets are executed in strict order, the second one starts only after the first one is complete.
101101
* target1;target2;..targetN -- execute the targets simultaneously
102-
* -D <name>=<value> -- defines a script variable value
102+
* -d <name>=<value> -- defines a script variable value
103+
104+
### Do not allow to override options
105+
Command line arguments override the script options (XakeOptions type) unless you define options.IgnoreCommandLine = true.
103106

104107
## Other
105108

samples/ar/build.fsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ module libs =
6363
let copyToOutput lib srcpath = ("out" </> lib) *> fun outfile -> action {do! cp (srcpath </> lib) outfile.FullName}
6464

6565
// do xake {XakeOptions with FileLog = "build.log"; FileLogLevel = Verbosity.Diag; Threads = 4 } {
66-
do xakeArgs {
66+
do xake {
6767
XakeOptions with FileLog = "build.log"; FileLogLevel = Verbosity.Diag; Threads = 4; Vars = [("NETFX", "4.0"); ("NETFX-TARGET","3.5")] } {
6868

6969
// top-level rules

samples/build-parms.fsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
open Xake
55

6-
do xakeArgs {XakeOptions with FileLog = "build.log"; Threads = 4 } {
6+
do xake {XakeOptions with FileLog = "build.log"; Threads = 4 } {
77

88
phony "main" (action {
99
do! writeLog Message "Hello world!"

0 commit comments

Comments
 (0)