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" 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 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 123def 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 143def 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 148def _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 155def _cp(p, src, dst): 156 if p.DRY: 157 print "cp", src, dst 158 else: 159 shutil.copyfile(src, dst) 160 161 162def 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 169if __name__ == "__main__": 170 main() 171