Ticket #225: cmdline-subOpts.patch
File cmdline-subOpts.patch, 24.7 KB (added by hopscc, 14 years ago) |
---|
-
Source/BackEndClr/SharpGenerator.cobra
72 72 _modules.add(SharpModule(fileName, _verbosity)) 73 73 74 74 def writeSharpRunAllTests(cw as CurlyWriter) 75 runner = .options ['test-runner']to String # ex: Cobra.Lang.CobraCore.runAllTests, ex: MyProgram.runTests75 runner = .options.getSubOpt('testifyArgs', 'runner') to String # ex: Cobra.Lang.CobraCore.runAllTests, ex: MyProgram.runTests 76 76 if runner <> 'nil' 77 77 if runner.endsWith('()'), runner = runner[:-2] 78 78 if runner.startsWith('Cobra.Lang.'), runner = 'CobraLangInternal.' + runner['Cobra.Lang.'.length:] -
Source/CommandLine.cobra
34 34 35 35 get type as String 36 36 require .isUnpacked 37 ensure result in ['accumulator', 'args-list', 'bool', 'int', 'menu', 'set', 'string' ]37 ensure result in ['accumulator', 'args-list', 'bool', 'int', 'menu', 'set', 'string', 'multival'] 38 38 return _type 39 39 40 40 get synonyms from var … … 77 77 if _type == 'main' 78 78 _isMain, _type = true, 'bool' 79 79 if .containsKey('is-main'), _isMain = this['is-main'] to bool 80 assert _type in ['accumulator', 'args-list', 'bool', 'int', 'menu', 'set', 'string' ]80 assert _type in ['accumulator', 'args-list', 'bool', 'int', 'menu', 'set', 'string', 'multival'] 81 81 if .containsKey('synonyms') 82 82 for syn in this['synonyms'] 83 83 _synonyms.add(syn) … … 94 94 _unpackPlatforms 95 95 _isUnpacked = true 96 96 assert .type=='menu' implies .choices.count > 0 97 assert .choices.count <> 0 implies .type in ['menu', 'set'] 97 assert .choices.count <> 0 implies .type in ['menu', 'set', 'multival'] 98 assert .type=='multival' implies .containsKey('subOptions') and .containsKey('choices') 99 assert .type=='multival' implies this['subOptions'].specsList.count == this['choices'].count 100 assert .type=='multival' implies .choices.count > 0 98 101 99 102 def _unpackPlatforms 100 103 if not .containsKey('platforms') … … 103 106 assert platform in ['jvm', '.net', 'objc'] 104 107 this['platforms'] = Set<of String>(this['platforms'] to List<of String>) 105 108 109 def defaultIfOn as dynamic 110 if .containsKey('defaultIfOn'), return this['defaultIfOn'] 111 if .containsKey('default'), return this['default'] 112 return 'on' 113 114 def subOptions as List<of OptionSpec> 115 """Return SubOption list ( of OptionSpec) or empty list if no subOptions""" 116 if .containsKey('subOptions') 117 clos = this['subOptions'] 118 assert clos inherits CommandLineOptionSpecs 119 return clos.specsList 120 return List<of OptionSpec>() 121 # TODO: cache this in unpack and just return cached value from here 106 122 123 def subOptionValue(name as String, keyList as vari String) as dynamic 124 """ 125 Find subOptions spec with given name; using keys from keyList return the value for 126 the first existing key in spec. 127 Return empty string if no subOptions or no matching keys found. 128 """ 129 for subOpt in .subOptions 130 if subOpt['name'] == name 131 for key in keyList 132 if subOpt.containsKey(key), return subOpt[key] 133 break 134 return '' 135 136 def subOptionSpec(name as String) as OptionSpec 137 """Return subOption for name or fail""" 138 require .containsKey('subOptions') 139 for subOpt in .subOptions 140 if subOpt['name'] == name 141 return subOpt 142 assert subOpt, name 143 return OptionSpec() 144 107 145 class CommandLineOptionSpecs 108 146 """ 109 147 Returns the command line option specifications, via .specsList, as a List of OptionSpec. … … 114 152 115 153 cue init 116 154 base.init 117 for rawSpec in _rawCommandLineOptionSpecs 155 __initInternal(_rawCommandLineOptionSpecs) 156 157 cue init(rawOptionSpecs) 158 base.init 159 __initInternal(rawOptionSpecs) 160 161 def __initInternal(rawOptionSpecs) 162 assert rawOptionSpecs.count 163 for rawSpec in rawOptionSpecs 118 164 spec = OptionSpec() 119 165 if rawSpec inherits Dictionary<of String, Object> 120 for key in rawSpec.keys, spec[key] = rawSpec[key] 166 for key in rawSpec.keys 167 spec[key] = if(key == 'subOptions', CommandLineOptionSpecs(rawSpec[key]), rawSpec[key]) 121 168 else if rawSpec inherits Dictionary<of String, String> 122 169 for key in rawSpec.keys, spec[key] = rawSpec[key] 123 170 else 124 171 throw FallThroughException(rawSpec.getType) 125 172 spec.unpack 126 173 _specs.add(spec) 127 174 128 175 def specsList as List<of OptionSpec> 129 176 """ 130 177 Returns the option specs in the order they were declared. 131 178 """ 132 179 return _specs 133 180 181 # Spec for each cobra compiler commandline option - List of Dictionaries 182 # TODO: doc the types 183 #type: main 184 #type: string 185 #type: int 186 #type: bool 187 #type: set 188 #type: menu 189 # 190 # type: multival supports a single cmdline option supporting multiple subOptions as comma separated name[=value] pairs 191 # e.g. -multiValueDefault -multival:key0,key1=15,key2=fred 192 # Uses standard entries 193 # (e.g. 'default' for a default value (commaSep list of pairs) if the cmdline option not given) 194 # On the cmdline you can specify just the option (without any subOptions - to enable a default set) 195 # this uses the value of entry 'defaultIfOn' (or 'default' if non existent.) 196 # Must have a 'choices' entry which is a list of the recognised subOption names AND 197 # Must have a 'subOptions' entry whose contents is a list of Dictionaries, one for each subOption supported 198 # Each subOption dict must have at least entry for 'name' but more commonly also 199 # 'type', 'description' (for help display) and possibly entries for defaults 200 # 'defaultIfKeyOnly' and 'default' 201 # On cmdline can give just a subOption( without '=value'). If want to support this and its different from 202 # a value for 'default' (below) provide an entry for 'defaultIfKeyOnly' giving the value for this case. 203 # If want a subOption value set if the option is enabled regardless of the subOption being given 204 # then provide a 'default' entry. 205 # 134 206 var _rawCommandLineOptionSpecs = [ 135 207 { 136 208 'name': 'about', … … 332 404 'args': 'TYPENAME', 333 405 }, 334 406 { 407 'name': 'metrics', 408 'type': 'multival', 409 'args': r'[loc[=value],][mcc[=value]...]', 410 'description': 'Enable metrics calculations; name specific metrics to be done and any threshold values as comma separated name=value pairs.', 411 'choices': ['loc', 'mcc'], #allowable subOption keys 412 'example': ['loc=80,mcc=10', 'mcc,loc=50', 'mcc=12', 'mcc,loc'], 413 #'default': 'loc=100,mcc=25', # default if not specify name at all (none) 414 'defaultIfOn': 'loc=100,mcc=25', # default (what subOpt values enabled) if only specify name 415 'subOptions' : [ 416 { 417 'name': 'loc', 418 'type': 'int', 419 'description': 'Show methodname and number of codelines if greater than threshold value.', 420 'defaultIfKeyOnly': '100', # value to set if only specify subOpt name 421 }, 422 { 423 'name': 'mcc', 424 'type': 'int', 425 'description': 'Show method name and McCabe Complexity Calculation value if omplexity more than threshold. Reasonable values are in range 12-30', 426 'defaultIfKeyOnly': '25', # value to set if only specify subOpt name 427 }, 428 ], 429 }, 430 { 335 431 'name': 'namespace', 336 432 'synonyms': ['name-space', 'ns'], 337 433 'type': 'string', … … 429 525 'type': 'main', 430 526 }, 431 527 { 432 'name': 'test-runner',433 'type': 'string',434 'description': 'Specify the method to invoke to run the unit tests. The method must be "shared". Typically the method will make use of classes in Cobra.Lang.Test to set up and initiate the test run.',435 'default': 'Cobra.Lang.CobraCore.runAllTests',436 'args': 'QUALIFIED-METHOD-NAME|nil',437 },438 {439 528 'name': 'testify', 440 'description': ' ...',529 'description': 'Run Cobra compiler test suite', 441 530 'type': 'main', 442 531 'developer-only': true, 443 532 }, 444 533 { 445 'name': 'testify-results', 446 'description': 'The filename to write the testify results to. Progress is still written to console.', 447 'type': 'string', 448 'default': 'r-testify', 534 'name': 'testifyArgs', 535 'type': 'multival', 536 'description': 'Set names and values for controlling testify as a list of comma separated name=value pairs.', 537 'choices': ['resultsFile', 'runner', 'numThreads'], #allowable subOption keys 538 'example': ['numThreads=4,resultsFile=testResult', 'runner=Core.myTestRunner', 'numThreads=2'], 449 539 'developer-only': true, 540 'default': 'resultsFile=r-testify,runner=Cobra.Lang.CobraCore.runAllTests,numThreads=1', 541 'subOptions' : [ 542 { 543 'name': 'resultsFile', 544 'type': 'string', 545 'description': 'Filename to write the testify results to. Progress is still written to console.', 546 'default': 'r-testify', # value to default to if not specify name at all 547 #'defaultIfKeyOnly': 'r-testify', # value to set if only specify subOpt name 548 }, 549 { 550 'name': 'runner', 551 'type': 'string', 552 'description': 'method to invoke to run the unit tests. The method must be "shared". Typically the method will make use of classes in Cobra.Lang.Test to setup and initiate the test run.', 553 'default': 'Cobra.Lang.CobraCore.runAllTests', 554 }, 555 { 556 'name': 'numThreads', 557 'type': 'int', 558 'description': 'Number of threads to run the testify testsuite in.', 559 'default': '1', 560 }, 561 ], 450 562 }, 451 563 { 452 'name': 'testify-threads',453 'description': '...',454 'type': 'int',455 'developer-only': true,456 },457 {458 564 'name': 'timeit', 459 565 'description': 'Gives the total duration of running cobra (including the target program, if it is to be run). This is "wall time", not "cpu time".', 460 566 # although this option is implied by 'testify', the description does not say so, since 'testify' is a hidden option … … 488 594 'type': 'main', 489 595 }, 490 596 ] 597 491 598 492 493 599 class CommandLine 494 600 """ 495 601 The main options that control the command line's behavior are: … … 589 695 dest = _htmlWriter to TextWriter 590 696 else 591 697 dest = Console.out 592 if _htmlWriter 593 stylePath = Path.combine(Path.getDirectoryName(CobraCore.exePath), 'styles-output-html.css') 594 _htmlWriter.writeHtml('<html><head><link href="file://[stylePath]" rel=stylesheet type="text/css"></head><body>[_htmlWriter.newLine]') 698 699 _runPreamble 595 700 print to dest 596 701 paths = _pathList to ! 597 702 options = _options … … 609 714 print 'Paths:' 610 715 for path in paths 611 716 print ' [path]' 717 612 718 if options.boolValue('testify') 613 719 .doTestify(paths) 614 720 else if options.boolValue('run') … … 635 741 .doHelp 636 742 else 637 743 .doRun(paths) 744 _runPostamble 745 746 def _runPreamble 638 747 if _htmlWriter 748 stylePath = Path.combine(Path.getDirectoryName(CobraCore.exePath), 'styles-output-html.css') 749 _htmlWriter.writeHtml('<html><head><link href="file://[stylePath]" rel=stylesheet type="text/css"></head><body>[_htmlWriter.newLine]') 750 751 def _runPostamble 752 if _htmlWriter 639 753 _htmlWriter.writeHtml('</body></html>[_htmlWriter.newLine]') 640 754 641 755 def doHighlight(paths as List<of String>) as Compiler … … 679 793 # Each phase of the compiler may throw an exception to stop compilation. 680 794 # Before doing so, it prints its errors. 681 795 assert c.errors.count>0 682 if _options.containsKey('editor') 683 spec = _options['editor'] to String? 684 else 685 spec = Environment.getEnvironmentVariable('COBRA_EDITOR') 686 if spec and spec <> '' 687 if spec.indexOf('FILE')==-1 688 .error('Missing FILE from editor spec.') 689 if spec.indexOf('LINE')==-1 690 .error('Missing LINE from editor spec.') 691 i = spec.indexOf('_') 692 if i == -1 693 i = spec.indexOf(' ') 694 if i == -1 695 .error('Missing underscore or space from editor spec.') 696 exeName = spec.substring(0, i) 697 args = spec.substring(i+1) 698 for error in c.errors 699 if error.isError and error.hasSourceSite 700 if error.fileName.trim <> '' 701 # trace error.fileName, error.lineNum 702 args = args.replace('FILE', error.fileName) 703 args = args.replace('LINE', error.lineNum.toString) 704 p = System.Diagnostics.Process() 705 p.startInfo.fileName = exeName 706 p.startInfo.arguments = args 707 p.startInfo.useShellExecute = false 708 if _verbosity >= 3 709 print 'Running: [p.startInfo.fileName] [p.startInfo.arguments]' 710 try 711 p.start 712 p.waitForExit # TODO: is this really needed? 713 catch exc as Exception 714 print 'Cannot invoke editor:' 715 print ' Command: [p.startInfo.fileName] [p.startInfo.arguments]' 716 print ' Exception: [exc]' 717 break 796 editorSpec = if(_options.containsKey('editor'), _options['editor'] to String?, Environment.getEnvironmentVariable('COBRA_EDITOR')) 797 if editorSpec and editorSpec.length 798 _editorOnErrorLines(c, editorSpec to !) 799 718 800 CobraMain.linesCompiled = c.linesCompiled 719 801 CobraMain.nodesCompiled = c.nodesCompiled 720 802 CobraMain.tokensCompiled = c.tokensCompiled 721 803 return c 722 804 805 def _editorOnErrorLines(c as Compiler, editorSpec as String) 806 if editorSpec.indexOf('FILE')==-1, .error('Missing FILE from editor spec.') 807 if editorSpec.indexOf('LINE')==-1, .error('Missing LINE from editor spec.') 808 i = editorSpec.indexOf('_') 809 if i == -1 810 i = editorSpec.indexOf(' ') 811 if i == -1, .error('Missing underscore or space from editor spec.') 812 813 editorExe = editorSpec.substring(0, i) 814 args = editorSpec.substring(i+1) 815 for error in c.errors 816 if error.isError and error.hasSourceSite 817 if error.fileName.trim <> '' 818 # trace error.fileName, error.lineNum 819 args = args.replace('FILE', error.fileName) 820 args = args.replace('LINE', error.lineNum.toString) 821 p = System.Diagnostics.Process() 822 p.startInfo.fileName = editorExe 823 p.startInfo.arguments = args 824 p.startInfo.useShellExecute = false 825 if _verbosity >= 3 826 print 'Running: [p.startInfo.fileName] [p.startInfo.arguments]' 827 try 828 p.start 829 p.waitForExit # TODO: is this really needed? 830 catch exc as Exception 831 print 'Cannot invoke editor:' 832 print ' Command: [p.startInfo.fileName] [p.startInfo.arguments]' 833 print ' Exception: [exc]' 834 break 835 723 836 def doDocument(paths as List<of String>) as Compiler 724 837 comp = .doCompile(paths, false, false, do(c as Compiler)=c.lastPhase inherits BindInterfacePhase) 725 838 GenerateHtmlDocVisitor(do(module)=module inherits CobraModule).gen(comp) … … 799 912 800 913 exeFileName as String? = nil 801 914 runArgs = .options.getStringList('run-args') 802 # TODO: what's this?915 # TODO: exeArgs as arglist of Strings exe-name exe-arg-0 exe-arg-1 ... cf argv list 803 916 # exeArgs = .options.getDefaultLOStr('exe-args') 804 917 # if exeArgs.count 805 918 # exeFileName = exeArgs[0] … … 838 951 print ' -test ....... Run the unit tests of a library.' 839 952 print ' -document ... Document the program (partial compilation). Also, -doc' 840 953 print ' -highlight .. Syntax highlight the program in HTML.' 954 if Utils.isDevMachine 955 print ' -testify .... Run the compiler testsuite (cwd must be cobra Source dir).' 841 956 print '' 842 957 print ' cobra <options> <command>' 843 958 print ' * standalone commands are:' … … 877 992 sep = ', ' 878 993 print 879 994 s = spec.description 880 while s.length 881 if s.length < width 882 print '[leftMarginStr][s]' 883 s = '' 884 else 885 # TODO: bug in here for narrow widths. try "width = 20" to reproduce 886 j = width + 1 887 if j >= s.length, j = s.length - 1 888 while j > 0 and s[j] <> ' ', j -= 1 889 if j 890 sub = s.substring(0, j) 891 s = if(s.length, s.substring(j+1), '') 892 print '[leftMarginStr][sub]' 995 if s.length 996 _printWrapped(s, width, leftMarginStr) 997 for subOptionSpec in spec.subOptions 998 assert subOptionSpec.name.length 999 if subOptionSpec.containsKey('description') 1000 _printWrapped('"[subOptionSpec.name]" = [subOptionSpec.description]' , width, leftMarginStr + ' ') 1001 if subOptionSpec.hasDefault 1002 soDefault = subOptionSpec['default'] 1003 print '[leftMarginStr] (default is [soDefault])' 893 1004 if spec.containsKey('example') 894 1005 if spec['example'] inherits System.Collections.IList 895 1006 first = true … … 903 1014 if spec.containsKey('eg') # verbatim example line 904 1015 print '[leftMarginStr]e.g. [spec["eg"]]' 905 1016 1017 def _printWrapped(s as String, width as int, leftMarginStr as String) 1018 while s.length 1019 if s.length < width 1020 print '[leftMarginStr][s]' 1021 s ='' 1022 else 1023 # TODO: bug in here for narrow widths. try "width = 20" to reproduce 1024 j = width + 1 1025 if j >= s.length, j = s.length - 1 1026 while j > 0 and s[j] <> ' ', j -= 1 1027 if j 1028 sub = s.substring(0, j) 1029 s = if(s.length, s.substring(j+1), '') 1030 print '[leftMarginStr][sub]' 1031 906 1032 def doAbout 907 1033 # CC: multiline string 908 1034 print … … 1257 1383 1258 1384 def _addInDefaults(valueDict as Dictionary<of String, Object>) 1259 1385 for spec in _optionSpecs 1386 if spec.containsKey('subOptions') and valueDict.containsKey(spec.name) 1387 # set defaults for unspecified subOptions with defaults if any subOption is set 1388 _addInSubOptionDefaults(spec, valueDict) 1389 1260 1390 if not valueDict.containsKey(spec.name) and spec.hasDefault 1261 1391 defaultValue = _interpretValue(spec.default, spec) to ! 1262 1392 if .verbosity 1263 1393 print 'Setting option "[spec.name]" to default value [defaultValue].' 1264 1394 valueDict[spec.name] = defaultValue 1265 1395 1396 def _addInSubOptionDefaults(spec as OptionSpec, valueDict as Dictionary<of String, Object>) 1397 ov = valueDict[spec.name] to OptionValues # that whats been explicitly set 1398 for subOptSpec in spec.subOptions 1399 if subOptSpec.hasDefault 1400 if not ov.containsKey(subOptSpec.name) # value not set already 1401 defaultValue = _interpretValue(subOptSpec['default'], subOptSpec) to ! 1402 # Should we force subOptions to always have a default value ?? 1403 if .verbosity 1404 print 'Setting option "[spec.name]:[subOptSpec.name]" to default value [defaultValue].' 1405 ov[subOptSpec.name] = defaultValue 1406 1407 1266 1408 def _unpackOptions(valueDict as Dictionary<of String, Object>, fileList as List<of String>) 1267 1409 """ 1268 1410 Unpack certain options (verbosity and timeit) into specific class fields, … … 1381 1523 else 1382 1524 valueSet.add(choice) 1383 1525 value = valueSet 1526 on 'multival' # comma separated key=value pairs - key1[=value],key2[=value],... 1527 if valueStr =='on', valueStr = spec.defaultIfOn 1528 pairs = List<of String>(valueStr.split(c',')) 1529 assert pairs.count > 0 1530 subValueOpts = OptionValues() 1531 for kvp in pairs 1532 kve = List<of String>(kvp.trim.split(c'=')) 1533 assert kve.count > 0 1534 key = kve[0] 1535 if not key in spec.choices and key <> 'on' 1536 print 'Unknown subOption key "[key]" in option "[spec.name]"' 1537 continue 1538 valStr = if(kve.count > 1, kve[1], spec.subOptionValue(key, 'defaultIfKeyOnly', 'default') to String) 1539 iValue = _interpretValue(valStr, spec.subOptionSpec(key)) 1540 subValueOpts.setKV(key, iValue) 1541 value = subValueOpts 1384 1542 else 1385 1543 throw FallThroughException(spec.type) 1386 1544 return value … … 1428 1586 1429 1587 1430 1588 class OptionValues inherits Dictionary<of String, Object> 1431 1589 1432 1590 var _isSpecified = Dictionary<of String, bool>() # CC: could just be a Set 1433 1591 1434 1592 cue init … … 1460 1618 1461 1619 def get(key as String) as dynamic? 1462 1620 return this[key] 1463 1621 1622 def setKV(key as String, value as Object) 1623 this[key] = value 1624 .didSpecify(key) 1625 1464 1626 def getDefault(key as String, default as dynamic?) as dynamic? 1465 1627 if .containsKey(key) 1466 1628 return this[key] … … 1477 1639 else 1478 1640 return List<of String>() 1479 1641 1642 def getSubOpt(majorKey as String, minorKey as String, default as dynamic) as dynamic 1643 """ 1644 Return subOption value for the given option and subOption (for a multi key=value Option) 1645 SubOptions are stored themselves as a set of OptionValues. 1646 If no major or minor key value return default. 1647 """ 1648 if .containsKey(majorKey) 1649 so = .get(majorKey) to OptionValues 1650 if so.containsKey(minorKey) 1651 return so[minorKey] 1652 return default 1653 1654 def getSubOpt(majorKey as String, minorKey as String ) as dynamic 1655 """ 1656 Return subOption value for the given option and subOption (multivalued option, multi key=value). 1657 Both the Option and subOption must exist otherwise an assert exception is incurred 1658 """ 1659 assert .containsKey(majorKey) 1660 so = .get(majorKey) to OptionValues 1661 assert so.containsKey(minorKey) 1662 return so[minorKey] 1663 1480 1664 # CC: def getDefault<of T>(key as String, value as T) as T ... 1481 1665 1482 1666 def setValue(key as String) as Set<of String> -
Source/TestifyRunner.cobra
58 58 paths = _pathList 59 59 if paths.count == 0 60 60 paths = .cobraTestPaths + [Path.getFullPath(Path.combine('..', 'HowTo'))] 61 numThreads = .options.getDefault('testify-threads', 1) to int 61 #numThreads = .options.getDefault('testify-threads', 1) to int 62 numThreads = .options.getSubOpt('testifyArgs', 'numThreads', 1) to int 62 63 if numThreads > 1 63 64 .runThreaded(numThreads, paths) 64 65 else … … 77 78 78 79 args = CobraCore.commandLineArgs 79 80 _subCobraExe = args[0] 80 _subCommandLineArgs = for arg in args[1:] where arg.startsWith('-') and not '-testify-threads:' in arg 81 #_subCommandLineArgs = for arg in args[1:] where arg.startsWith('-') and not '-testify-threads:' in arg 82 _subCommandLineArgs = for arg in args[1:] where arg.startsWith('-') and not '-testifyArgs:' in arg 81 83 82 84 _statusWriter.writeLine('Queueing for threads:') 83 85 for path in paths … … 102 104 concat.append(sep) 103 105 concat.append(File.readAllText(fileName)) 104 106 sep = sepNl 105 File.writeAllText(.options ['testify-results']to String, concat.toString)107 File.writeAllText(.options.getSubOpt('testifyArgs','resultsFile') to String, concat.toString) 106 108 for fileName in _subResultsFileNames 107 109 try 108 110 File.delete(fileName) … … 110 112 _statusWriter.writeLine('warning: Cannot delete "[fileName]" due to: [exc]') 111 113 112 114 def _printTotals 113 resultsFileName = .options ['testify-results']to String115 resultsFileName = .options.getSubOpt('testifyArgs', 'resultsFile') to String 114 116 using resultsWriter = File.appendText(resultsFileName) 115 117 __printTotals(resultsWriter to !) 116 118 __printTotals(_statusWriter to !) … … 133 135 pathIndex = _subDirQueue.count 134 136 resultsFileName = 'r-testify-[pathIndex]' 135 137 lock _subResultsFileNames, _subResultsFileNames[pathIndex] = resultsFileName 136 args = _subCommandLineArgs + ['-testify -results:[resultsFileName]', '-testify-threads:1', '"[path]"']137 lock _statusWriter, _statusWriter.writeLine('Thread [tid] start: [ args.join(" ")]')138 args = _subCommandLineArgs + ['-testifyArgs:resultsFile=[resultsFileName],numThreads=1', '"[path]"'] 139 lock _statusWriter, _statusWriter.writeLine('Thread [tid] start: [_subCobraExe] [args.join(" ")]') 138 140 p = Process() 139 141 p.startInfo.useShellExecute = false 140 142 p.startInfo.redirectStandardOutput = true … … 177 179 _statusWriter = IndentedWriter(AutoFlushWriter(Console.out)) 178 180 _statusWriter.indentString = ' ' 179 181 try 180 resultsFileName = .options ['testify-results']to String182 resultsFileName = .options.getSubOpt('testifyArgs', 'resultsFile') to String 181 183 using resultsWriter = File.createText(resultsFileName) 182 184 _resultsWriter = IndentedWriter(AutoFlushWriter(resultsWriter)) 183 185 print to _resultsWriter to ! -
Developer/IntermediateReleaseNotes.text
94 94 95 95 * Added -verbosity-ref option to output information about resolving references to libraries. 96 96 97 97 * Added support for specifying a cmdline option with subOptions and modified 98 -test-runner, -testify-Threads, -testify-results to use it becoming a new multival option 99 -testifyArgs with subOptions runner,results and numThreads. 100 e.g. -testifyArgs:results=tResults,numThreads=4,runner=Core.Runner 101 -testifyArgs:numThreads=4 102 98 103 ================================================================================ 99 104 Samples etc. 100 105 ================================================================================