Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | |
| 2 // for details. All rights reserved. Use of this source code is governed by a | |
| 3 // BSD-style license that can be found in the LICENSE file. | |
| 4 | |
| 5 List stdout, stderr, log; | |
| 6 var replyPort; | |
| 7 int _procId = 1; | |
| 8 Map _procs = {}; | |
| 9 | |
| 10 /** | |
| 11 * Create a file path for a temporary file. The file will be in the | |
| 12 * [tmpDir] directory, with name [basis], but with any extension | |
| 13 * stripped and replaced by [suffix]. | |
| 14 */ | |
| 15 String createTempName(String tmpDir, String basis, String suffix) { | |
| 16 var p = new Path(basis); | |
| 17 return '$tmpDir${Platform.pathSeparator}' | |
| 18 '${p.filenameWithoutExtension}${suffix}'; | |
| 19 } | |
| 20 | |
| 21 /** Create a file [fileName] and populate it with [contents]. */ | |
| 22 void writeFile(String fileName, String contents) { | |
| 23 var file = new File(fileName); | |
| 24 var ostream = file.openOutputStream(FileMode.WRITE); | |
| 25 ostream.writeString(contents); | |
| 26 ostream.close(); | |
| 27 } | |
| 28 | |
| 29 /* | |
| 30 * Run an external process [cmd] with command line arguments [args]. | |
| 31 * [timeout] can be used to forcefully terminate the process after | |
| 32 * some number of seconds. This is used by runCommand and startProcess. | |
| 33 * If [procId] is null (runCommand) then this will return a [Future] for | |
| 34 * when the process terminates; if [procId] is instead a non-null string | |
| 35 * (startProcess) then a reference to the [Process] will be put in a | |
| 36 * map with key [procId] and [procId] will be returned; in this case | |
| 37 * the process can be terminated later by calling [stopProcess] and | |
| 38 * passing in the [procId]. | |
|
Siggi Cherem (dart-lang)
2012/10/02 23:43:56
we should update the comment though...
| |
| 39 */ | |
| 40 Future _processHelper(String command, List<String> args, | |
| 41 [int timeout = 300, int procId = 0]) { | |
| 42 var completer = null; | |
| 43 log.add('Running $command ${Strings.join(args, " ")}'); | |
| 44 var timer = null; | |
| 45 var stdoutHandler, stderrHandler; | |
| 46 var process = Process.start(command, args); | |
| 47 if (procId == 0) { | |
| 48 completer = new Completer(); | |
| 49 } else { | |
| 50 _procs[procId] = process; | |
| 51 } | |
| 52 process.onStart = () { | |
| 53 timer = new Timer(1000 * timeout, (t) { | |
| 54 timer = null; | |
| 55 process.kill(); | |
| 56 }); | |
| 57 }; | |
| 58 process.onExit = (exitCode) { | |
| 59 if (timer != null) { | |
| 60 timer.cancel(); | |
| 61 } | |
| 62 process.close(); | |
| 63 if (completer != null) { | |
| 64 completer.complete(exitCode); | |
| 65 } | |
| 66 }; | |
| 67 process.onError = (e) { | |
| 68 stderr.add("Error starting process:"); | |
| 69 stderr.add(" Command: $command"); | |
| 70 stderr.add(" Error: $e"); | |
| 71 completePipeline(-1); | |
| 72 }; | |
| 73 | |
| 74 _pipeStream(process.stdout, stdout); | |
| 75 _pipeStream(process.stderr, stderr); | |
| 76 | |
| 77 return (completer == null) ? null : completer.future; | |
| 78 } | |
| 79 | |
| 80 void _pipeStream(InputStream stream, List<String> destination) { | |
| 81 var source = new StringInputStream(stream); | |
| 82 source.onLine = () { | |
| 83 if (source.closed) return; | |
| 84 var line = source.readLine(); | |
| 85 while (null != line) { | |
| 86 if (config["immediate"] && line.startsWith('###')) { | |
| 87 // TODO - when we dump the list later skip '###' messages if immediate. | |
| 88 print(line.substring(3)); | |
| 89 } | |
| 90 destination.add(line); | |
| 91 line = source.readLine(); | |
| 92 } | |
| 93 }; | |
| 94 } | |
| 95 | |
| 96 /** | |
| 97 * Run an external process [cmd] with command line arguments [args]. | |
| 98 * [timeout] can be used to forcefully terminate the process after | |
| 99 * some number of seconds. | |
| 100 * Returns a [Future] for when the process terminates. | |
| 101 */ | |
| 102 Future runCommand(String command, List<String> args, [int timeout = 300]) { | |
| 103 return _processHelper(command, args, timeout); | |
| 104 } | |
| 105 | |
| 106 /** | |
| 107 * Start an external process [cmd] with command line arguments [args]. | |
| 108 * Returns an ID by which it can later be stopped. | |
| 109 */ | |
| 110 int startProcess(String command, List<String> args) { | |
| 111 int id = _procId++; | |
| 112 _processHelper(command, args, 3000, id); | |
| 113 return id; | |
| 114 } | |
| 115 | |
| 116 /** | |
| 117 * Stop a process previously started with [startProcess] or [runCommand], | |
| 118 * given the id string. | |
| 119 */ | |
| 120 void stopProcess(int id) { | |
| 121 Process p = _procs.remove(id); | |
| 122 p.kill(); | |
| 123 } | |
| 124 | |
| 125 /** Delete a file named [fname] if it exists. */ | |
| 126 bool cleanup(String fname) { | |
| 127 if (fname != null && !config['keep-files']) { | |
| 128 var f = new File(fname); | |
| 129 try { | |
| 130 if (f.existsSync()) { | |
| 131 f.deleteSync(); | |
| 132 } | |
| 133 } catch (e) { | |
| 134 return false; | |
| 135 } | |
| 136 } | |
| 137 return true; | |
| 138 } | |
| 139 | |
| 140 initPipeline(port) { | |
| 141 replyPort = port; | |
| 142 stdout = new List(); | |
| 143 stderr = new List(); | |
| 144 log = new List(); | |
| 145 } | |
| 146 | |
| 147 void completePipeline([exitCode = 0]) { | |
| 148 replyPort.send([stdout, stderr, log, exitCode]); | |
| 149 } | |
| 150 | |
| 151 /** Utility function to log diagnostic messages. */ | |
| 152 void logMessage(msg) => log.add(msg); | |
| OLD | NEW |