run-dart-action.py improvements

* Let Ctrl-C stop the script by making worker threads daemon threads.
* If a script is missing log an error. Previously a missing script
  would cause the program to never terminate.
* Add -j/--jobs to control the number of concurrent jobs.
* Don't show the output of successful scripts unless -v/--verbose is
  supplied.
* Show progress.

Change-Id: I780de1618e8427748ee962dbedbfc26be6300b86
diff --git a/run-dart-action.py b/run-dart-action.py
index e43ca17..a519776 100755
--- a/run-dart-action.py
+++ b/run-dart-action.py
@@ -31,6 +31,7 @@
         self.script_queue = script_queue
         self.result_queue = result_queue
         self.args = args
+        self.daemon = True
 
     def run(self):
         while True:
@@ -39,6 +40,9 @@
             except Queue.Empty, e:
                 # No more scripts to run.
                 return
+            if not os.path.exists(script):
+                self.result_queue.put((script, -1, 'Script does not exist.'))
+                continue
             job = subprocess.Popen(
                 [script] + self.args,
                 stdout=subprocess.PIPE,
@@ -61,6 +65,15 @@
         help='Restrict analysis to a source subtree, e.g. //apps/sysui/*',
         default='*')
     parser.add_argument(
+        '--jobs', '-j',
+        help='Number of concurrent instances to run',
+        type=int,
+        default=multiprocessing.cpu_count())
+    parser.add_argument(
+        '--verbose', '-v',
+        help='Show output from tests that pass',
+        action='store_true')
+    parser.add_argument(
         'action',
         help='Action to perform on the targets',
         choices=('analyze', 'test'))
@@ -102,20 +115,25 @@
     failed_scripts = []
 
     # Create a worker thread for each CPU on the machine.
-    for i in range(multiprocessing.cpu_count()):
+    for i in range(args.jobs):
         WorkerThread(script_queue, result_queue, extras).start()
 
     # Handle results from workers.
     while len(script_results) < len(scripts):
         script, returncode, output = result_queue.get(True)
         script_results.append(returncode)
+        sys.stdout.write('\rProgress: %d/%d\033[K' % (len(script_results), len(scripts)))
+        sys.stdout.flush()
         if returncode != 0:
             failed_scripts.append(script)
-        print '----------------------------------------------------------'
-        print output
+        if args.verbose or returncode != 0:
+            print '\r----------------------------------------------------------'
+            print script
+            print output
 
     if len(failed_scripts):
         failed_scripts.sort()
+        print ''
         print 'Failures in:'
         for script in failed_scripts:
             print '  %s' % script