+++ /dev/null
-#!/usr/bin/env python
-
-import itertools
-import optparse
-import os
-import shlex
-import subprocess
-import sys
-import time
-
-
-def run(running_jobs, cmd):
- p = subprocess.Popen(cmd, stdin=file(os.devnull, 'r'))
- running_jobs.append(p)
-
-def wait_for_completion(max_jobs, running_jobs):
- while len(running_jobs) >= max_jobs:
- time.sleep(1)
- for job in running_jobs:
- if job.poll() is not None:
- running_jobs.remove(job)
- job.wait()
-
-def parse_file(fd):
- def count_indent(s):
- level = 0
- for ch in s:
- if ch == "\t":
- level += 1
- else:
- break
- return level
-
- for line in fd:
- if not line.strip():
- continue # Ignore blank lines
- level = count_indent(line)
- line = line[level:] # Slice off the indentation
- yield level, line
- yield 0, None
-
-def batch_process(opts, lines):
- running_jobs = []
- cmd = []
-
- for level, line in lines:
- old_level = len(cmd) - 1
- if level <= old_level:
- run(running_jobs, itertools.chain(*cmd))
- wait_for_completion(opts.jobs, running_jobs)
-
- # Delete all options that belong to groups that are indented more than
- # this one
- cmd = cmd[:level]
- assert len(cmd) == level
-
- if line:
- cmd.append(shlex.split(line))
-
- # Wait for remaining jobs to finish
- wait_for_completion(1, running_jobs)
-
-def parse_args():
- parser = optparse.OptionParser(usage="%prog batchfile1 [batchfile2] ...")
- parser.add_option("-j", "--jobs",
- action="store", dest="jobs", default=1, type="int",
- help="The number of concurrent jobs to run")
- opts, args = parser.parse_args(sys.argv[1:])
- opts.running_jobs = []
- return opts, args
-
-def main():
- opts, args = parse_args()
- for name in args:
- batch_process(opts, parse_file(open(name)))
-
-if __name__ == "__main__":
- main()
-