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""" 18Description: 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 23See usage() below. 24 25Copyright (C) 2009 The Android Open Source Project 26Licensed under the Apache License, Version 2.0 (the "License"). 27""" 28 29import re 30import os 31import sys 32import getopt 33import shutil 34 35_RE_PKG = re.compile("^\s*package\s+([^\s;]+)\s*;.*") 36 37# Holds cmd-line arguments 38class Params(object): 39 def __init__(self): 40 self.DRY = False 41 self.DIR = "frameworks libcore" 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 49def 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. 70def 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 107def parseSrcDir(p, srcdir): 108 if not os.path.exists(srcdir): 109 print >>sys.stderr, "Error: Skipping unknown directory", srcdir 110 return 111 112 for f in os.listdir(srcdir): 113 fp = os.path.join(srcdir, f) 114 if f.endswith(".java") and os.path.isfile(fp): 115 pkg = checkJavaFile(fp) 116 if pkg: 117 pkg = pkg.replace(".", os.path.sep) # e.g. android.view => android/view 118 copy(p, fp, f, pkg) 119 p.CNT_USED += 1 # one more copied 120 else: 121 p.CNT_NOPKG += 1 # this java file lacked a package declaration 122 elif os.path.isdir(fp): 123 parseSrcDir(p, fp) 124 125 126# Check a java file to find its package declaration, if any 127def checkJavaFile(path): 128 print "Process", path 129 130 try: 131 f = None 132 try: 133 f = file(path) 134 for l in f.readlines(): 135 m = _RE_PKG.match(l) 136 if m: 137 return m.group(1) 138 finally: 139 if f: f.close() 140 except Exception: 141 pass 142 143 return None 144 145 146# Create destination directory based on package name then copy the 147# source file in there 148def copy(p, fp, f, pkg): 149 dstdir = os.path.join(p.DST, pkg) 150 _mkdir(p, dstdir) 151 _cp(p, fp, os.path.join(dstdir, f)) 152 153 154def _mkdir(p, dir): 155 if not os.path.isdir(dir): 156 if p.DRY: 157 print "mkdir", dir 158 else: 159 os.makedirs(dir) 160 161 162def _cp(p, src, dst): 163 if p.DRY: 164 print "cp", src, dst 165 else: 166 shutil.copyfile(src, dst) 167 168 169def main(): 170 p = parseArgs(sys.argv) 171 for d in p.DIR.split(): 172 if d: 173 parseSrcDir(p, os.path.join(p.SRC, d)) 174 print "%d java files copied" % p.CNT_USED 175 if p.CNT_NOPKG: print "%d java files ignored (no package)" % p.CNT_NOPKG 176 if p.DRY: print "This was in *DRY* mode. No copies done." 177 178 179if __name__ == "__main__": 180 main() 181