
1 // 2 // Copyright (c) 2006, Brian Frank and Andy Frank 3 // Licensed under the Academic Free License version 3.0 4 // 5 // History: 6 // 3 Nov 06 Brian Frank Creation 7 // 8 9 ** 10 ** BuildGroup is the base class for build scripts which compose 11 ** a set of children build scripts into a single group. The 12 ** target's of a BuildGroup are the union of the target 13 ** names available in the children scripts. 14 ** 15 abstract class BuildGroup : BuildScript 16 { 17 18 ////////////////////////////////////////////////////////////////////////// 19 // Meta-Data 20 ////////////////////////////////////////////////////////////////////////// 21 22 ** 23 ** Required list of Uris relative to this scriptDir of 24 ** Fan build script files to group together. 25 ** 26 Uri[] childrenScripts := null 27 28 ////////////////////////////////////////////////////////////////////////// 29 // Setup 30 ////////////////////////////////////////////////////////////////////////// 31 32 ** 33 ** Validate subclass constructor setup required meta-data. 34 ** 35 internal override Void validate() 36 { 37 // validate required fields 38 ok := true 39 ok &= validateReqField("childrenScripts") 40 if (!ok) throw FatalBuildErr.make 41 42 // compile script Uris into BuildScript instances 43 children = BuildScript[,] 44 resolveFiles(childrenScripts).each |File f| 45 { 46 log.info("CompileScript [$f]") 47 s := (BuildScript)FanScript.make(this, f).compile.types.first.make 48 s.log = log 49 children.add(s) 50 } 51 } 52 53 ////////////////////////////////////////////////////////////////////////// 54 // Targets 55 ////////////////////////////////////////////////////////////////////////// 56 57 ** 58 ** Assume the default target is "compile". 59 ** 60 override Target defaultTarget() 61 { 62 return target("compile") 63 } 64 65 ** 66 ** BuildGroup publishes the union by name 67 ** of it's children script targets. 68 ** 69 override Target[] makeTargets() 70 { 71 // get union of names in my children scripts 72 Str[] names := null 73 children.each |BuildScript child| 74 { 75 // get all the target names in this subscript 76 n := (Str[])child.targets.map(Str[,]) |Target t->Str| { return t.name } 77 78 // get union of names 79 if (names == null) 80 names = n 81 else 82 names = names.union(n) 83 } 84 85 // now create a Target for each name 86 targets := Target[,] 87 names.map(targets) |Str name->Target| { return toTarget(name) } 88 return targets 89 } 90 91 ** 92 ** Make a target which will run the specified target 93 ** name on all my children scripts. 94 ** 95 private Target toTarget(Str name) 96 { 97 return Target.make(this, name, "run '$name' on all children") |,| { runOnChildren(name) } 98 } 99 100 ** 101 ** Run the specified target name on each of the 102 ** children scripts that support the specified name. 103 ** 104 Void runOnChildren(Str targetName) 105 { 106 children.each |BuildScript child, Int i| 107 { 108 target := child.target(targetName, false) 109 if (target != null) target.run 110 } 111 } 112 113 ** 114 ** Run the specified target name on each of the children 115 ** scripts that support the specified name. Unlike runOnChildren 116 ** this method actually spawns a new process to run the child 117 ** script. 118 ** 119 Void spawnOnChildren(Str targetName) 120 { 121 fanExe := (binDir+`fan.exe`).toStr 122 children.each |BuildScript child, Int i| 123 { 124 target := child.target(targetName) 125 if (target != null) 126 { 127 Exec.make(this, [fanExe, child.scriptFile.osPath, targetName]).run 128 } 129 } 130 } 131 132 ////////////////////////////////////////////////////////////////////////// 133 // Fields 134 ////////////////////////////////////////////////////////////////////////// 135 136 ** Compiled children scripts 137 BuildScript[] children 138 139 }