Home | History | Annotate | Download | only in scripts
      1 #!/usr/bin/python
      2 #
      3 # Copyright (C) 2009 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 """
     18 Description:
     19    This script collects all framework Java sources from the current android
     20    source code and places them in a source folder suitable for the eclipse ADT
     21    plugin.
     22 
     23 See usage() below.
     24 
     25 Copyright (C) 2009 The Android Open Source Project
     26 Licensed under the Apache License, Version 2.0 (the "License").
     27 """
     28 
     29 import re
     30 import os
     31 import sys
     32 import getopt
     33 import shutil
     34 
     35 _RE_PKG = re.compile("^\s*package\s+([^\s;]+)\s*;.*")
     36 
     37 # Holds cmd-line arguments
     38 class Params(object):
     39     def __init__(self):
     40         self.DRY = False
     41         self.DIR = "frameworks"
     42         self.SRC = None
     43         self.DST = None
     44         self.CNT_USED = 0
     45         self.CNT_NOPKG = 0
     46 
     47 
     48 # Prints a usage summary
     49 def usage(error=None):
     50     print """
     51  Description:
     52    This script collects all framework Java sources from the current android
     53    source code and places them in a source folder suitable for the eclipse ADT
     54    plugin.
     55 
     56  Usage:
     57    %s [-n] <android-git-repo root> <sdk/platforms/xyz/sources>
     58  
     59  The source and destination directories must already exist.
     60  Use -n for a dry-run.
     61 
     62 """ % sys.argv[0]
     63 
     64     if error:
     65         print >>sys.stderr, "Error:", error
     66 
     67 
     68 # Parse command line args, returns a Params instance or sys.exit(2) on error
     69 # after printing the error and the usage.
     70 def parseArgs(argv):
     71     p = Params()
     72     error = None
     73     
     74     try:
     75         opts, args = getopt.getopt(argv[1:],
     76                                    "ns:",
     77                                    [ "--dry", "--sourcedir=" ])
     78     except getopt.GetoptError, e:
     79         error = str(e)
     80 
     81     if error is None:
     82         for o, a in opts:
     83             if o in [ "-n", "--dry" ]:
     84                 p.DRY = True
     85             elif o in [ "-s", "--sourcedir" ]:
     86                 p.DIR = a
     87 
     88         if len(args) != 2:
     89             error = "Missing arguments: <source> <dest>"
     90         else:
     91             p.SRC = args[0]
     92             p.DST = args[1]
     93 
     94             if not os.path.isdir(p.SRC):
     95                 error = "%s is not a directory" % p.SRC
     96             elif not os.path.isdir(p.DST):
     97                 error = "%s is not a directory" % p.DST
     98 
     99     if error:
    100         usage(error)
    101         sys.exit(2)
    102 
    103     return p
    104 
    105 
    106 # Recursively parses the given directory and process java files found
    107 def parseSrcDir(p, srcdir):
    108     for f in os.listdir(srcdir):
    109         fp = os.path.join(srcdir, f)
    110         if f.endswith(".java") and os.path.isfile(fp):
    111             pkg = checkJavaFile(fp)
    112             if pkg:
    113                 pkg = pkg.replace(".", os.path.sep)  # e.g. android.view => android/view
    114                 copy(p, fp, f, pkg)
    115                 p.CNT_USED += 1   # one more copied
    116             else:
    117                 p.CNT_NOPKG += 1  # this java file lacked a package declaration
    118         elif os.path.isdir(fp):
    119             parseSrcDir(p, fp)
    120 
    121 
    122 # Check a java file to find its package declaration, if any
    123 def checkJavaFile(path):
    124     print "Process", path
    125 
    126     try:
    127         f = None
    128         try:
    129             f = file(path)
    130             for l in f.readlines():
    131                 m = _RE_PKG.match(l)
    132                 if m:
    133                     return m.group(1)
    134         finally:
    135             if f: f.close()
    136     except Exception:
    137         pass
    138 
    139     return None
    140 
    141 # Create destination directory based on package name then copy the
    142 # source file in there
    143 def copy(p, fp, f, pkg):
    144     dstdir = os.path.join(p.DST, pkg)
    145     _mkdir(p, dstdir)
    146     _cp(p, fp, os.path.join(dstdir, f))
    147 
    148 def _mkdir(p, dir):
    149     if not os.path.isdir(dir):
    150         if p.DRY:
    151             print "mkdir", dir
    152         else:
    153             os.makedirs(dir)
    154 
    155 def _cp(p, src, dst):
    156     if p.DRY:
    157         print "cp", src, dst
    158     else:
    159         shutil.copyfile(src, dst)
    160 
    161 
    162 def main():
    163     p = parseArgs(sys.argv)
    164     parseSrcDir(p, os.path.join(p.SRC, p.DIR))
    165     print "%d java files copied" % p.CNT_USED
    166     if p.CNT_NOPKG: print "%d java files ignored (no package)" % p.CNT_NOPKG
    167     if p.DRY: print "This was in *DRY* mode. No copies done."
    168 
    169 if __name__ == "__main__":
    170     main()
    171