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