Skip to content

Commit 81e7f38

Browse files
committed
completed sequential/parallel execution of targets, renamed Want to Targets
1 parent 54421d9 commit 81e7f38

File tree

9 files changed

+97
-53
lines changed

9 files changed

+97
-53
lines changed

XakeLibTests/CommandLineTests.fs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ type CommandLineTests() =
5959

6060
let finalOptions = !scriptOptions
6161
Assert.AreEqual(31, finalOptions.Threads)
62-
Assert.AreEqual(["target1"; "target2"], finalOptions.Want)
62+
Assert.AreEqual(["target1"; "target2"], finalOptions.Targets)
6363
Assert.IsTrue !executed2
6464

6565

@@ -80,7 +80,7 @@ type CommandLineTests() =
8080
["/t"; "33"; "/R"; currentDir; "/LL"; "Loud";
8181
"/FL"; "aaaaa"; "target"]
8282

83-
do xakeArgs args {XakeOptions with IgnoreCommandLine = true; Threads = 2; FileLog = "ss"; Want = ["main"]} {
83+
do xakeArgs args {XakeOptions with IgnoreCommandLine = true; Threads = 2; FileLog = "ss"; Targets = ["main"]} {
8484
rules [
8585
"main" => action {
8686
let! opts = getCtxOptions()
@@ -92,4 +92,4 @@ type CommandLineTests() =
9292
let finalOptions = !scriptOptions
9393
Assert.AreEqual(2, finalOptions.Threads)
9494
Assert.AreEqual("ss", finalOptions.FileLog)
95-
Assert.AreEqual(["main"], finalOptions.Want)
95+
Assert.AreEqual(["main"], finalOptions.Targets)

XakeLibTests/FileTasksTests.fs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ open Xake.Storage
1212
[<TestFixture>]
1313
type FileTasksTests() =
1414

15-
let TestOptions = {XakeOptions with Threads = 1; Want = ["main"]; ConLogLevel = Chatty; FileLogLevel = Silent}
15+
let TestOptions = {XakeOptions with Threads = 1; Targets = ["main"]; ConLogLevel = Chatty; FileLogLevel = Silent}
1616

1717
[<Test>]
1818
member this.DeleteSimple() =

XakeLibTests/MiscTests.fs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -326,7 +326,7 @@ type MiscTests() =
326326

327327
let count = ref 0
328328

329-
do xake {XakeOptions with Want = ["xxx"]; Threads = 1; FileLog=""} { // one thread to avoid simultaneous access to 'wasExecuted'
329+
do xake {XakeOptions with Targets = ["xxx"]; Threads = 1; FileLog=""} { // one thread to avoid simultaneous access to 'wasExecuted'
330330
rules [
331331
"main" => action {
332332
count := !count + 1

core/Program.fs

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,24 @@ module internal ParseArgs = begin
1818
let parseTopLevel (arg:string) optionsSoFar =
1919
match arg.ToLowerInvariant() with
2020

21-
// TODO support sequential/parallel runs e.g. "clean release-build;debug-build"
22-
21+
| "-h" | "/h" ->
22+
printf """
23+
Usage:
24+
fsi <script file> [-- options target..]
25+
26+
Options:
27+
-h - displays help screen
28+
-t <task count> - parallelize execution to <task count> processes. Defaults to CPU cores
29+
-r <root path> - override the root path. Default is current directory
30+
-ll <log level> - console log level (Silent | Quiet | Normal | Loud | Chatty | Diag)
31+
-fl <file log path> - specifies the name of the log file
32+
-fll <log level> - specifies the logging level to a log file
33+
target1 .. targetN - define the list of targets to be executed sequentially
34+
target1;target2;..targetN -- execute the targets simultaneously
35+
-d <name>=<value> - defines a script variable value
36+
37+
"""
38+
exit(0)
2339
| "-t" | "/t" ->
2440
(optionsSoFar, Number ("thread count", fun o v -> {o with XakeOptionsType.Threads = v}))
2541
| "-r" | "/r" ->
@@ -32,14 +48,14 @@ module internal ParseArgs = begin
3248
(optionsSoFar, String ("console verbosity", fun o s -> {o with ConLogLevel = s |> parseVerbosity }))
3349
| "-fll" | "/fll" ->
3450
(optionsSoFar, String ("filelog verbosity", fun o s -> {o with FileLogLevel = s |> parseVerbosity }))
51+
| "-nologo" ->
52+
({optionsSoFar with Nologo = true}, TopLevel)
3553

36-
// handle unrecognized option
3754
| x when x.StartsWith("-") || x.StartsWith("/") ->
38-
// TODO write errors to log?
3955
printfn "Option '%s' is unrecognized" x
4056
(optionsSoFar, TopLevel)
4157
| x ->
42-
({optionsSoFar with Want = optionsSoFar.Want @ [x]}, TopLevel)
58+
({optionsSoFar with Targets = optionsSoFar.Targets @ [x]}, TopLevel)
4359

4460
let (|NumberVar|_|) str =
4561
match System.Int32.TryParse str with
@@ -105,6 +121,10 @@ module Main =
105121
let options =
106122
if initialOptions.IgnoreCommandLine then initialOptions
107123
else args |> List.fold foldFunction (initialOptions, TopLevel) |> fst
124+
125+
if not options.Nologo then
126+
printf "XAKE build tool %s\n\n" Xake.Const.Version
127+
108128
new RulesBuilder (options)
109129

110130
/// <summary>

core/Xake.Core.fsproj

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,15 +56,14 @@
5656
<Compile Include="WorkerPool.fs" />
5757
<Compile Include="Progress.fs" />
5858
<Compile Include="XakeScript.fs" />
59-
<Compile Include="Program.fs" />
6059
<Compile Include="CommonTasks.fs" />
6160
<Compile Include="FileTasks.fs" />
6261
<Compile Include="ResourceFileset.fs" />
6362
<Compile Include="DotNetFwk.fs" />
6463
<Compile Include="DotnetTasks.fs" />
65-
<None Include="filesets.fsx" />
6664
<Compile Include="VersionInfo.fs" />
6765
<Compile Include="AssemblyInfo.fs" />
66+
<Compile Include="Program.fs" />
6867
</ItemGroup>
6968
<PropertyGroup>
7069
<MinimumVisualStudioVersion Condition="'$(MinimumVisualStudioVersion)' == ''">11</MinimumVisualStudioVersion>

core/XakeScript.fs

Lines changed: 56 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,19 @@ module XakeScript =
2222
/// Console output verbosity level. Default is Warn
2323
ConLogLevel: Verbosity
2424
/// Overrides "want", i.e. target list
25-
Want: string list
25+
Targets: string list
26+
27+
/// Global script variables
2628
Vars: (string * string) list
2729

2830
/// Defines whether `run` should throw exception if script fails
2931
FailOnError: bool
3032

3133
/// Ignores command line swithes
3234
IgnoreCommandLine: bool
35+
36+
/// Disable logo message
37+
Nologo: bool
3338
}
3439

3540
type private ExecStatus = | Succeed | Skipped | JustFile
@@ -71,10 +76,11 @@ module XakeScript =
7176
CustomLogger = CustomLogger (fun _ -> false) ignore
7277
FileLog = "build.log"
7378
FileLogLevel = Chatty
74-
Want = []
79+
Targets = []
7580
FailOnError = false
7681
Vars = List<string*string>.Empty
7782
IgnoreCommandLine = false
83+
Nologo = false
7884
}
7985

8086
module private Impl = begin
@@ -328,7 +334,7 @@ module XakeScript =
328334
/// <summary>
329335
/// Executes several artifacts in parallel.
330336
/// </summary>
331-
and private execMany ctx = Seq.ofList >> Seq.map (execOne ctx) >> Async.Parallel
337+
and private execParallel ctx = Seq.ofList >> Seq.map (execOne ctx) >> Async.Parallel
332338

333339
/// <summary>
334340
/// Gets the status of dependency artifacts (obtained from 'need' calls).
@@ -341,7 +347,7 @@ module XakeScript =
341347
ctx.Tgt |> Option.iter (Progress.TaskSuspend >> ctx.Progress.Post)
342348

343349
do ctx.Throttler.Release() |> ignore
344-
let! statuses = targets |> execMany ctx
350+
let! statuses = targets |> execParallel ctx
345351
do! ctx.Throttler.WaitAsync(-1) |> Async.AwaitTask |> Async.Ignore
346352

347353
ctx.Tgt |> Option.iter (Progress.TaskResume >> ctx.Progress.Post)
@@ -393,40 +399,39 @@ module XakeScript =
393399
NeedRebuild = fun _ -> false
394400
Tgt = None
395401
}
396-
// TODO wrap more elegantly
397-
let rec get_changed_deps = CommonLib.memoize (getDepsImpl ctx (fun x -> get_changed_deps x)) in
398-
399-
let check_rebuild target =
400-
get_changed_deps >>
401-
function
402-
| [] -> false, ""
403-
| DepState.Other reason::_ -> true, reason
404-
| DepState.Depends (t,_) ::_ -> true, "Depends on target " + (getFullName t)
405-
| DepState.FilesChanged (file::_) ::_ -> true, "File(s) changed " + file
406-
| reasons -> true, sprintf "Some reason %A" reasons
407-
>>
408-
function
409-
| false, _ -> false
410-
| true, reason ->
411-
do ctx.Logger.Log Info "Rebuild %A: %s" (getShortname target) reason
412-
true
413-
<| target
414-
415-
// define targets
416-
let targets =
417-
match options.Want with
418-
| [] ->
419-
do logger.Log Level.Message "No target(s) specified. Defaulting to 'main'"
420-
["main"]
421-
| tt -> tt
422-
|> List.map (makeTarget ctx)
423-
424-
let getDurationDeps t =
425-
let collectTargets = List.collect (function |Depends (t,_) -> [t] | _ -> [])
426-
(getExecTime ctx t) / 1000<ms>, get_changed_deps t |> collectTargets
427-
let progressSink = Progress.openProgress getDurationDeps options.Threads targets
428-
429-
let ctx = {ctx with NeedRebuild = check_rebuild; Progress = progressSink}
402+
403+
let runStep targetNames =
404+
// TODO wrap more elegantly
405+
let rec get_changed_deps = CommonLib.memoize (getDepsImpl ctx (fun x -> get_changed_deps x)) in
406+
407+
let check_rebuild target =
408+
get_changed_deps >>
409+
function
410+
| [] -> false, ""
411+
| DepState.Other reason::_ -> true, reason
412+
| DepState.Depends (t,_) ::_ -> true, "Depends on target " + (getFullName t)
413+
| DepState.FilesChanged (file::_) ::_ -> true, "File(s) changed " + file
414+
| reasons -> true, sprintf "Some reason %A" reasons
415+
>>
416+
function
417+
| false, _ -> false
418+
| true, reason ->
419+
do ctx.Logger.Log Info "Rebuild %A: %s" (getShortname target) reason
420+
true
421+
<| target
422+
423+
let targets = targetNames |> List.map (makeTarget ctx)
424+
let getDurationDeps t =
425+
let collectTargets = List.collect (function |Depends (t,_) -> [t] | _ -> [])
426+
(getExecTime ctx t) / 1000<ms>, get_changed_deps t |> collectTargets
427+
let progressSink = Progress.openProgress getDurationDeps options.Threads targets
428+
429+
let stepCtx = {ctx with NeedRebuild = check_rebuild; Progress = progressSink}
430+
431+
try
432+
targets |> execParallel stepCtx |> Async.RunSynchronously |> ignore
433+
finally
434+
do Progress.Finish |> progressSink.Post
430435

431436
logger.Log Info "Options: %A" options
432437

@@ -436,9 +441,20 @@ module XakeScript =
436441
| a -> yield a
437442
}
438443

444+
// splits list of targets ["t1;t2"; "t3;t4"] into list of list.
445+
let targetLists =
446+
options.Targets
447+
|> function
448+
| [] ->
449+
do logger.Log Level.Message "No target(s) specified. Defaulting to 'main'"
450+
[["main"]]
451+
| tt ->
452+
tt |> List.map (fun s -> s.Split(';', '|') |> List.ofArray)
453+
439454
try
440455
try
441-
targets |> execMany ctx |> Async.RunSynchronously |> ignore
456+
for list in targetLists do
457+
runStep list
442458
logger.Log Message "\n\n\tBuild completed in %A\n" (System.DateTime.Now - start)
443459
with
444460
| exn ->
@@ -448,7 +464,6 @@ module XakeScript =
448464
logger.Log Message "\n\n\tBuild failed after running for %A\n" (System.DateTime.Now - start)
449465
finally
450466
db.PostAndReply Storage.CloseWait
451-
do Progress.Finish |> ctx.Progress.Post
452467

453468
/// <summary>
454469
/// "need" implementation
@@ -478,7 +493,7 @@ module XakeScript =
478493
type RulesBuilder(options) =
479494

480495
let updRules (XakeScript (options,rules)) f = XakeScript (options, f(rules))
481-
let updTargets (XakeScript (options,rules)) f = XakeScript ({options with Want = f(options.Want)}, rules)
496+
let updTargets (XakeScript (options,rules)) f = XakeScript ({options with Targets = f(options.Targets)}, rules)
482497

483498
member o.Bind(x,f) = f x
484499
member o.Zero() = XakeScript (options, Rules [])

docs/implnotes.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ where "clean" "build" and "deploy" are target names.
9292

9393
The full list of parameters:
9494

95+
* -h -- displays help screen
9596
* -t <task count> -- use <task count> simultaneous processes to execute the build tasks. * Default value is the number of processors
9697
* -r <root path> -- override the root path. All the targets and filesets are resolved relatively to this path. Default is current directory
9798
* -ll <log level> -- console log level (Silent | Quiet | Normal | Loud | Chatty | Diag)
@@ -100,6 +101,7 @@ The full list of parameters:
100101
* target1 .. targetN -- define the list of targets. Targets are executed in strict order, the second one starts only after the first one is complete.
101102
* target1;target2;..targetN -- execute the targets simultaneously
102103
* -d <name>=<value> -- defines a script variable value
104+
* -nologo -- remove logo string
103105

104106
### Do not allow to override options
105107
Command line arguments override the script options (XakeOptions type) unless you define options.IgnoreCommandLine = true.

samples/build-parms.fsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,11 @@ do xake {XakeOptions with FileLog = "build.log"; Threads = 4 } {
1818
return ()
1919
})
2020

21+
rules [
22+
"t1" => action {do! writeLog Message "t1!"}
23+
"t2" => action {do! writeLog Message "t2!"}
24+
"t3" => action {do! writeLog Message "t3!"}
25+
"t4" => action {do! writeLog Message "t4!"}
26+
]
27+
2128
}

xake.sln

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ EndProject
4242
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Project files", "Project files", "{CA08F45F-D8B4-46D4-B7EC-38C68C7AF0B2}"
4343
ProjectSection(SolutionItems) = preProject
4444
.travis.yml = .travis.yml
45+
core\filesets.fsx = core\filesets.fsx
4546
EndProjectSection
4647
EndProject
4748
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{0D5E4046-AD73-4D3F-BF54-5D7E31450641}"

0 commit comments

Comments
 (0)