Home | History | Annotate | Download | only in tools
      1 #!/usr/bin/env python
      2 #
      3 # Copyright (C) 2016 The Android Open Source Project
      4 #
      5 # Licensed under the Apache License, Version 2.0 (the "License");
      6 # you may not use this file except in compliance with the License.
      7 # You may obtain a copy of the License at
      8 #
      9 #      http://www.apache.org/licenses/LICENSE-2.0
     10 #
     11 # Unless required by applicable law or agreed to in writing, software
     12 # distributed under the License is distributed on an "AS IS" BASIS,
     13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14 # See the License for the specific language governing permissions and
     15 # limitations under the License.
     16 
     17 """Utility to verify modules link against acceptable module types"""
     18 
     19 from __future__ import print_function
     20 import argparse
     21 import os
     22 import sys
     23 
     24 WARNING_MSG = ('\033[1m%(makefile)s: \033[35mwarning:\033[0m\033[1m '
     25     '%(module)s (%(type)s) should not link to %(dep_name)s (%(dep_type)s)'
     26     '\033[0m')
     27 ERROR_MSG = ('\033[1m%(makefile)s: \033[31merror:\033[0m\033[1m '
     28     '%(module)s (%(type)s) should not link to %(dep_name)s (%(dep_type)s)'
     29     '\033[0m')
     30 
     31 def parse_args():
     32     """Parse commandline arguments."""
     33     parser = argparse.ArgumentParser(description='Check link types')
     34     parser.add_argument('--makefile', help='Makefile defining module')
     35     parser.add_argument('--module', help='The module being checked')
     36     parser.add_argument('--type', help='The link type of module')
     37     parser.add_argument('--allowed', help='Allow deps to use these types',
     38                         action='append', default=[], metavar='TYPE')
     39     parser.add_argument('--warn', help='Warn if deps use these types',
     40                         action='append', default=[], metavar='TYPE')
     41     parser.add_argument('deps', help='The dependencies to check',
     42                         metavar='DEP', nargs='*')
     43     return parser.parse_args()
     44 
     45 def print_msg(msg, args, dep_name, dep_type):
     46     """Print a warning or error message"""
     47     print(msg % {
     48           "makefile": args.makefile,
     49           "module": args.module,
     50           "type": args.type,
     51           "dep_name": dep_name,
     52           "dep_type": dep_type}, file=sys.stderr)
     53 
     54 def main():
     55     """Program entry point."""
     56     args = parse_args()
     57 
     58     failed = False
     59     for dep in args.deps:
     60         dep_name = os.path.basename(os.path.dirname(dep))
     61         if dep_name.endswith('_intermediates'):
     62             dep_name = dep_name[:len(dep_name)-len('_intermediates')]
     63 
     64         with open(dep, 'r') as dep_file:
     65             dep_types = dep_file.read().strip().split(' ')
     66 
     67         for dep_type in dep_types:
     68             if dep_type in args.allowed:
     69                 continue
     70             if dep_type in args.warn:
     71                 print_msg(WARNING_MSG, args, dep_name, dep_type)
     72             else:
     73                 print_msg(ERROR_MSG, args, dep_name, dep_type)
     74                 failed = True
     75 
     76     if failed:
     77         sys.exit(1)
     78 
     79 if __name__ == '__main__':
     80     main()
     81