| # common python utility routines for the Bionic tool scripts |
| |
| import commands |
| import logging |
| import os |
| import string |
| import sys |
| |
| |
| def panic(msg): |
| sys.stderr.write(os.path.basename(sys.argv[0]) + ": error: ") |
| sys.stderr.write(msg) |
| sys.exit(1) |
| |
| |
| def get_kernel_headers_dir(): |
| return os.path.join(get_android_root(), "external/kernel-headers") |
| |
| |
| def get_kernel_headers_original_dir(): |
| return os.path.join(get_kernel_headers_dir(), "original") |
| |
| |
| def get_kernel_headers_modified_dir(): |
| return os.path.join(get_kernel_headers_dir(), "modified") |
| |
| |
| def get_kernel_dir(): |
| return os.path.join(get_android_root(), "bionic/libc/kernel") |
| |
| |
| def get_android_root(): |
| if "ANDROID_BUILD_TOP" in os.environ: |
| return os.environ["ANDROID_BUILD_TOP"] |
| panic("Unable to find root of tree, did you forget to lunch a target?") |
| |
| |
| class StringOutput: |
| def __init__(self): |
| self.line = "" |
| |
| def write(self,msg): |
| self.line += msg |
| logging.debug("write '%s'" % msg) |
| |
| def get(self): |
| return self.line |
| |
| |
| def create_file_path(path): |
| dirs = [] |
| while 1: |
| parent = os.path.dirname(path) |
| #print "parent: %s <- %s" % (parent, path) |
| if parent == "/" or parent == "": |
| break |
| dirs.append(parent) |
| path = parent |
| |
| dirs.reverse() |
| for dir in dirs: |
| #print "dir %s" % dir |
| if os.path.isdir(dir): |
| continue |
| os.mkdir(dir) |
| |
| |
| class BatchFileUpdater: |
| """a class used to edit several files at once""" |
| def __init__(self): |
| self.old_files = set() |
| self.new_files = set() |
| self.new_data = {} |
| |
| def readFile(self,path): |
| #path = os.path.realpath(path) |
| if os.path.exists(path): |
| self.old_files.add(path) |
| |
| def readDir(self,path): |
| #path = os.path.realpath(path) |
| for root, dirs, files in os.walk(path): |
| for f in files: |
| dst = "%s/%s" % (root,f) |
| self.old_files.add(dst) |
| |
| def editFile(self,dst,data): |
| """edit a destination file. if the file is not mapped from a source, |
| it will be added. return 0 if the file content wasn't changed, |
| 1 if it was edited, or 2 if the file is new""" |
| #dst = os.path.realpath(dst) |
| result = 1 |
| if os.path.exists(dst): |
| f = open(dst, "r") |
| olddata = f.read() |
| f.close() |
| if olddata == data: |
| self.old_files.remove(dst) |
| return 0 |
| else: |
| result = 2 |
| |
| self.new_data[dst] = data |
| self.new_files.add(dst) |
| return result |
| |
| def getChanges(self): |
| """determine changes, returns (adds, deletes, edits)""" |
| adds = set() |
| edits = set() |
| deletes = set() |
| |
| for dst in self.new_files: |
| if not (dst in self.old_files): |
| adds.add(dst) |
| else: |
| edits.add(dst) |
| |
| for dst in self.old_files: |
| if not dst in self.new_files: |
| deletes.add(dst) |
| |
| return (adds, deletes, edits) |
| |
| def _writeFile(self,dst): |
| if not os.path.exists(os.path.dirname(dst)): |
| create_file_path(dst) |
| f = open(dst, "w") |
| f.write(self.new_data[dst]) |
| f.close() |
| |
| def updateFiles(self): |
| adds, deletes, edits = self.getChanges() |
| |
| for dst in sorted(adds): |
| self._writeFile(dst) |
| |
| for dst in sorted(edits): |
| self._writeFile(dst) |
| |
| for dst in sorted(deletes): |
| os.remove(dst) |
| |
| def updateGitFiles(self): |
| adds, deletes, edits = self.getChanges() |
| |
| if adds: |
| for dst in sorted(adds): |
| self._writeFile(dst) |
| commands.getoutput("git add " + " ".join(adds)) |
| |
| if deletes: |
| commands.getoutput("git rm " + " ".join(deletes)) |
| |
| if edits: |
| for dst in sorted(edits): |
| self._writeFile(dst) |
| commands.getoutput("git add " + " ".join(edits)) |