check_boot_jars.py revision e987400207c120f64de9fcc2be905ccfd6ca1c03
1#!/usr/bin/env python
2
3"""
4Check boot jars.
5
6Usage: check_boot_jars.py <package_whitelist_file> <jar1> <jar2> ...
7"""
8import logging
9import os.path
10import re
11import subprocess
12import sys
13
14
15# The compiled whitelist RE.
16whitelist_re = None
17
18
19def LoadWhitelist(filename):
20  """ Load and compile whitelist regular expressions from filename.
21  """
22  lines = []
23  with open(filename, 'r') as f:
24    for line in f:
25      line = line.strip()
26      if not line or line.startswith('#'):
27        continue
28      lines.append(line)
29  combined_re = r'^(%s)$' % '|'.join(lines)
30  global whitelist_re
31  try:
32    whitelist_re = re.compile(combined_re)
33  except re.error:
34    logging.exception(
35        'Cannot compile package whitelist regular expression: %r',
36        combined_re)
37    whitelist_re = None
38    return False
39  return True
40
41
42def CheckJar(jar):
43  """Check a jar file.
44  """
45  # Get the list of files inside the jar file.
46  p = subprocess.Popen(args='jar tf %s' % jar,
47      stdout=subprocess.PIPE, shell=True)
48  stdout, _ = p.communicate()
49  if p.returncode != 0:
50    return False
51  items = stdout.split()
52  for f in items:
53    if f.endswith('.class'):
54      package_name = os.path.dirname(f)
55      package_name = package_name.replace('/', '.')
56      # Skip class without a package name
57      if package_name and not whitelist_re.match(package_name):
58        print >> sys.stderr, ('Error: %s: unknown package name of class file %s'
59                              % (jar, f))
60        return False
61  return True
62
63
64def main(argv):
65  if len(argv) < 2:
66    print __doc__
67    sys.exit(1)
68
69  if not LoadWhitelist(argv[0]):
70    sys.exit(1)
71
72  passed = True
73  for jar in argv[1:]:
74    if not CheckJar(jar):
75      passed = False
76  if not passed:
77    return 1
78
79  return 0
80
81
82if __name__ == '__main__':
83  main(sys.argv[1:])
84