prepare_pdk_tree.py revision e0e2abb814e49fa389463d9ef19feece241a20ea
1#!/usr/bin/env python
2#
3# Copyright (C) 2012 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# prepare_pdk_tree.py target_dir [-m manifest] pdk_groups
19# Ex: prepare_pdk_tree.py ../tmp/pdk grouper
20# create mount_pdk.sh and umount_pdk.sh, which mounts/umounts pdk sources.
21
22import os
23import re
24import sys
25import subprocess
26
27
28class ManifestHandler(object):
29
30    def __init__(self):
31        # current pattern
32        self.current = 0
33        self.patterns = [re.compile('path=\"([^\"]*)\".*groups=\"([^\"]*)\"'), \
34                         re.compile('groups=\"([^\"]*)\".*path=\"([^\"]*)\"')]
35
36    def getAttribs(self, line):
37        attrib = [None, None] # list of path, groups
38        m = self.patterns[self.current].search(line)
39        # if match fails, try both pattens and change default one
40        # if match founds
41        if m is None:
42            notCurrent = 1 - self.current
43            mOther = self.patterns[notCurrent].search(line)
44            if mOther is not None:
45                # toggle
46                self.current = notCurrent
47                m = mOther
48        if m is not None:
49            if (self.current == 0):
50                attrib[0] = m.group(1)
51                attrib[1] = m.group(2)
52            else:
53                attrib[0] = m.group(2)
54                attrib[1] = m.group(1)
55        return attrib
56
57def isInGroups(groupsAttrib, groups):
58    if groupsAttrib is None:
59        return False
60    for group in groups:
61        if group in groupsAttrib:
62            return True
63    return False
64
65def getPDKDirs(manifest, groups):
66    subdirs = []
67    handler = ManifestHandler()
68    f = open(manifest, 'r')
69    for line in f:
70        [path, groupsAttrib] = handler.getAttribs(line)
71        if isInGroups(groupsAttrib, groups):
72            subdirs.append(path)
73    f.close()
74    return subdirs
75
76def create_symbolic_link(src_top, dest_top, dir_name):
77    src_full = src_top + "/" + dir_name
78    dest_full = dest_top + "/" + dir_name
79    #print "create symbolic link from " + dest_full + " to " + src_full
80    # remove existing link first to prevent recursive loop
81    os.system("rm -rf " + dest_full)
82    os.system("ln -s " + src_full + " " + dest_full)
83
84# The only file not from manifest.
85copy_files_list = [ "Makefile" ]
86MOUNT_FILE = 'mount_pdk.sh'
87UMOUNT_FILE = 'umount_pdk.sh'
88SH_HEADER = "#!/bin/bash\n#Auto-generated file, do not edit!\n"
89
90def main(argv):
91    manifestFile = ".repo/manifest.xml"
92    groups = ["pdk"]
93    if len(argv) < 2:
94        print "create_pdk_tree.py target_dir [-m manifest] [-a dir_to_add] pdk_groups"
95        print " ex) create_pdk_tree.py ../tmp grouper"
96        print " -a option is to include a directory which does not belong to specified group"
97        print "   multiple -a options can be specified like -a frameworks/base -a external/aaa"
98        print " Note that pdk group is included by default"
99        print " Do not create target_dir under the current source tree. This will cause build error."
100        sys.exit(1)
101    targetDir = argv[1]
102    argc = 2
103    subdirs = []
104    if len(argv) > 2:
105        if argv[2] == "-m":
106            manifestFile = argv[3]
107            argc += 2
108    while argc < len(argv):
109        if argv[argc] == "-a":
110            argc += 1
111            subdirs.append(argv[argc])
112        else:
113            groups.append(argv[argc])
114        argc += 1
115    sourceDir = os.path.abspath('.')
116    targetDir = os.path.abspath(targetDir)
117
118    p = subprocess.Popen("mount", stdout = subprocess.PIPE)
119    targetMounted = False
120    for line in p.stdout:
121        if targetDir in line:
122            targetMounted = True
123    p.stdout.close()
124
125    if targetMounted:
126        print "target dir already mounted"
127        if os.path.exists(targetDir + '/' + UMOUNT_FILE):
128            print "Use existing file", UMOUNT_FILE, "to unmount"
129            sys.exit(1)
130        else:
131            print "Will create scripts, but may need manual unmount"
132
133    subdirs += getPDKDirs(manifestFile, groups)
134    print subdirs
135    os.system("mkdir -p " + targetDir)
136    mountf = open(targetDir + '/' + MOUNT_FILE, 'w+')
137    mountf.write(SH_HEADER)
138    umountf = open(targetDir + '/' + UMOUNT_FILE, 'w+')
139    umountf.write(SH_HEADER)
140    for subdir in subdirs:
141        os.system("mkdir -p " + targetDir + '/' + subdir)
142        mountf.write("mount --bind " + sourceDir + "/" + subdir + " " + targetDir + "/" + subdir + \
143                        "\n")
144        umountf.write("umount " + targetDir + "/" + subdir + "\n")
145    for file_name in copy_files_list:
146        create_symbolic_link(sourceDir, targetDir, file_name)
147    mountf.close()
148    umountf.close()
149    os.system("chmod 700 " + targetDir + '/' + MOUNT_FILE)
150    os.system("chmod 700 " + targetDir + '/' + UMOUNT_FILE)
151
152if __name__ == '__main__':
153    main(sys.argv)
154