1 // SemiTwist D Tools 2 // STManage: STBuild 3 // Written in the D programming language. 4 5 module semitwist.apps.stmanage.stbuild.cmdArgs; 6 7 import getopt = std.getopt; 8 import semitwist.cmd.all; 9 10 import semitwist.apps.stmanage.stbuild.conf; 11 12 enum appName = "STBuild"; 13 enum appVerStr = "0.5.2"; 14 enum Ver appVer = appVerStr.toVer(); 15 16 private enum confFileWin = "stbuild-win.conf"; 17 private enum confFileLinux = "stbuild-linux.conf"; 18 private enum confFileOSX = "stbuild-osx.conf"; 19 private enum confFileBSD = "stbuild-bsd.conf"; 20 private enum confFilePosix = "stbuild-posix.conf"; 21 private enum confFileDefault = "stbuild.conf"; 22 23 struct Options 24 { 25 bool help; 26 bool cleanOnly; 27 string _confFile; 28 string buildToolStr = "rdmd"; 29 bool quiet; 30 bool showCmd; 31 string[] extraArgList; 32 string[] targetMode; 33 34 // Indirectly determined by cmd line params 35 string target; 36 string mode = defaultMode; 37 Conf conf; 38 BuildTool buildTool; 39 string extraArgs; 40 41 string infoHeader; 42 string helpScreen; 43 44 enum seeHelpMsg = "Run with --help to see usage."; 45 enum defaultMode = Conf.modeRelease; 46 47 @property string confFile() 48 { 49 void setDefaultConfFile(string file) 50 { 51 if(_confFile == "" && exists(file)) 52 _confFile = file; 53 } 54 version(Windows) setDefaultConfFile(confFileWin); 55 version(linux) setDefaultConfFile(confFileLinux); 56 version(FreeBSD) setDefaultConfFile(confFileBSD); 57 version(OpenBSD) setDefaultConfFile(confFileBSD); 58 version(NetBSD) setDefaultConfFile(confFileBSD); 59 version(DragonFlyBSD) setDefaultConfFile(confFileBSD); 60 version(OSX) setDefaultConfFile(confFileOSX); 61 version(Posix) setDefaultConfFile(confFilePosix); 62 if(_confFile == "") 63 _confFile = confFileDefault; 64 65 return _confFile; 66 } 67 68 // Returns errorlevel program should exit immediately with. 69 // If returns -1, everything is OK and program should continue without exiting. 70 int process(string[] args) 71 { 72 infoHeader = (` 73 `~appName~` v`~appVerStr~` 74 Copyright (c) 2009-2013 Nick Sabalausky 75 See LICENSE.txt for license info 76 Site: http://www.dsource.org/projects/semitwist 77 `).normalize(); 78 79 helpScreen = ` 80 Usage: stbuild [options] target [mode] [options] 81 82 --help Displays this help screen and exits 83 --clean Clean, don't build 84 --conf <filename> Configuration file to use (default: "stbuild-(os).conf" or else "stbuild.conf") 85 --tool <tool> Build tool ["rdmd", "re" or "xf"] (default: "rdmd") 86 -q, --quiet Quiet, ie. don't show progress messages 87 --cmd Show commands 88 -x <arg> Pass extra argument to build tool 89 `.normalize(); 90 91 if(args.length == 1) 92 return showHelpScreen(); 93 94 getopt.endOfOptions = ""; 95 try getopt.getopt( 96 args, 97 getopt.config.caseSensitive, 98 "help", &help, 99 "clean", &cleanOnly, 100 "conf", &_confFile, 101 "tool", &buildToolStr, 102 "q|quiet", &quiet, 103 "cmd", &showCmd, 104 "x", &extraArgList 105 ); 106 catch(Exception e) 107 { 108 writeln(e.msg); 109 writeln(seeHelpMsg); 110 return 1; 111 } 112 113 targetMode = args[1..$]; 114 115 if(help || args.contains("/?")) 116 return showHelpScreen(); 117 118 try 119 conf = new Conf(confFile); 120 catch(STBuildConfException e) 121 { 122 stderr.writeln(e.msg); 123 stderr.writeln(seeHelpMsg); 124 return false; 125 } 126 127 switch(targetMode.length) 128 { 129 case 1: 130 target = targetMode[0]; 131 break; 132 case 2: 133 target = targetMode[0]; 134 mode = targetMode[1]; 135 break; 136 case 0: 137 stderr.writeln("Must specify a target."); 138 stderr.writeln(seeHelpMsg); 139 return 1; 140 default: 141 stderr.writeln("Unexpected extra params: ", targetMode[2..$]); 142 stderr.writeln(seeHelpMsg); 143 return 1; 144 } 145 146 switch(buildToolStr) 147 { 148 case "rdmd": 149 buildTool = BuildTool.rdmd; 150 break; 151 case "re", "rebuild": 152 buildTool = BuildTool.rebuild; 153 break; 154 case "xf", "xfbuild": 155 buildTool = BuildTool.xfbuild; 156 break; 157 default: 158 stderr.writeln("Unknown build tool: '", buildToolStr, "'"); 159 stderr.writeln(seeHelpMsg); 160 return 1; 161 } 162 163 extraArgs = std..string.join(extraArgList, " "); 164 165 // Move to CmdLine 166 if(find(conf.targets, target) == []) 167 { 168 stderr.writeln("Unknown target: '", target, "'"); 169 showTargets(); 170 stderr.writeln(seeHelpMsg); 171 return 1; 172 } 173 if(find(conf.getModes(), mode) == []) 174 { 175 stderr.writeln("Unknown mode: '", mode, "'"); 176 showModes(); 177 stderr.writeln(seeHelpMsg); 178 return 1; 179 } 180 181 return -1; // All ok 182 } 183 184 private void showTargets() 185 { 186 if(conf && conf.targets.length > conf.predefTargets.length) 187 { 188 //TODO: Create array.moveIndex(index, newIndex) 189 //TODO: Create array.moveElement(elem, newIndex) 190 //TODO: Make "all" always first 191 auto targets = conf.targets.dup; 192 targets.sort(); 193 194 cmd.echo("Targets Available:", targets); 195 } 196 else 197 cmd.echo("No Targets Available"); 198 cmd.echo(); 199 } 200 201 private void showModes() 202 { 203 string[] modes; 204 if(conf) 205 modes = conf.getModes(); 206 207 if(modes.length > 0) 208 { 209 modes.sort(); 210 211 cmd.echo("Modes:", modes); 212 cmd.echo("Default Mode:", defaultMode); 213 } 214 else 215 cmd.echo("No Modes Available"); 216 cmd.echo(); 217 } 218 219 private void showUsage() 220 { 221 showTargets(); 222 showModes(); 223 writeln(helpScreen); 224 } 225 226 private void showHeader() 227 { 228 writeln(infoHeader); 229 writeln(); 230 } 231 232 private int showHelpScreen() 233 { 234 if(!conf) 235 { 236 try 237 conf = new Conf(confFile); 238 catch(STBuildConfException e) 239 { 240 stderr.writeln(e.msg); 241 stderr.writeln(seeHelpMsg); 242 return 1; 243 } 244 } 245 246 showHeader(); 247 showUsage(); 248 return 0; 249 } 250 }