summaryrefslogtreecommitdiffstats
path: root/scripts/cleanup-workdir
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/cleanup-workdir')
-rwxr-xr-xscripts/cleanup-workdir194
1 files changed, 194 insertions, 0 deletions
diff --git a/scripts/cleanup-workdir b/scripts/cleanup-workdir
new file mode 100755
index 0000000000..25fef976b6
--- /dev/null
+++ b/scripts/cleanup-workdir
@@ -0,0 +1,194 @@
1#!/usr/bin/env python
2
3# Copyright (c) 2012 Wind River Systems, Inc.
4#
5# This program is free software; you can redistribute it and/or modify
6# it under the terms of the GNU General Public License version 2 as
7# published by the Free Software Foundation.
8#
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12# See the GNU General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License
15# along with this program; if not, write to the Free Software
16# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
18import os
19import sys
20import optparse
21import re
22import subprocess
23import shutil
24
25pkg_cur_dirs = {}
26obsolete_dirs = []
27parser = None
28
29def err_quit(msg):
30 print msg
31 parser.print_usage()
32 sys.exit(1)
33
34def parse_version(verstr):
35 elems = verstr.split(':')
36 epoch = elems[0]
37 if len(epoch) == 0:
38 return elems[1]
39 else:
40 return epoch + '_' + elems[1]
41
42def run_command(cmd):
43 pipe = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
44 output = pipe.communicate()[0]
45 if pipe.returncode != 0:
46 print "Execute command '%s' failed." % cmd
47 sys.exit(1)
48 return output
49
50def get_cur_arch_dirs(workdir, arch_dirs):
51 pattern = workdir + '/(.*?)/'
52
53 # select thest 5 packages to get the dirs of current arch
54 pkgs = ['hicolor-icon-theme', 'base-files', 'acl-native', 'binutils-crosssdk', 'nativesdk-autoconf']
55
56 for pkg in pkgs:
57 cmd = "bitbake -e " + pkg + " | grep ^IMAGE_ROOTFS="
58 output = run_command(cmd)
59 output = output.split('"')[1]
60 m = re.match(pattern, output)
61 arch_dirs.append(m.group(1))
62
63def main():
64 global parser
65 parser = optparse.OptionParser(
66 usage = """%prog
67
68%prog removes the obsolete packages' build directories in WORKDIR.
69This script must be ran under BUILDDIR after source file \"oe-init-build-env\".
70
71Any file or directory under WORKDIR which is not created by Yocto
72will be deleted. Be CAUTIOUS.""")
73
74 options, args = parser.parse_args(sys.argv)
75
76 builddir = run_command('echo $BUILDDIR').strip()
77 if len(builddir) == 0:
78 err_quit("Please source file \"oe-init-build-env\" first.\n")
79
80 if os.getcwd() != builddir:
81 err_quit("Please run %s under: %s\n" % (os.path.basename(args[0]), builddir))
82
83 print 'Updating bitbake caches...'
84 cmd = "bitbake -s"
85 output = run_command(cmd)
86
87 output = output.split('\n')
88 index = 0
89 while len(output[index]) > 0:
90 index += 1
91 alllines = output[index+1:]
92
93 for line in alllines:
94 # empty again means end of the versions output
95 if len(line) == 0:
96 break
97 line = line.strip()
98 line = re.sub('\s+', ' ', line)
99 elems = line.split(' ')
100 if len(elems) == 2:
101 version = parse_version(elems[1])
102 else:
103 version = parse_version(elems[2])
104 pkg_cur_dirs[elems[0]] = version
105
106 cmd = "bitbake -e"
107 output = run_command(cmd)
108
109 tmpdir = None
110 image_rootfs = None
111 output = output.split('\n')
112 for line in output:
113 if tmpdir and image_rootfs:
114 break
115
116 if not tmpdir:
117 m = re.match('TMPDIR="(.*)"', line)
118 if m:
119 tmpdir = m.group(1)
120
121 if not image_rootfs:
122 m = re.match('IMAGE_ROOTFS="(.*)"', line)
123 if m:
124 image_rootfs = m.group(1)
125
126 # won't fail just in case
127 if not tmpdir or not image_rootfs:
128 print "Can't get TMPDIR or IMAGE_ROOTFS."
129 return 1
130
131 pattern = tmpdir + '/(.*?)/(.*?)/'
132 m = re.match(pattern, image_rootfs)
133 if not m:
134 print "Can't get WORKDIR."
135 return 1
136
137 workdir = os.path.join(tmpdir, m.group(1))
138
139 # we only deal the dirs of current arch, total numbers of dirs are 6
140 cur_arch_dirs = [m.group(2)]
141 get_cur_arch_dirs(workdir, cur_arch_dirs)
142
143 for workroot, dirs, files in os.walk(workdir):
144 # For the files, they should NOT exist in WORKDIR. Remove them.
145 for f in files:
146 obsolete_dirs.append(os.path.join(workroot, f))
147
148 for d in dirs:
149 if d not in cur_arch_dirs:
150 continue
151
152 for pkgroot, pkgdirs, filenames in os.walk(os.path.join(workroot, d)):
153 for f in filenames:
154 obsolete_dirs.append(os.path.join(pkgroot, f))
155
156 for pkgdir in sorted(pkgdirs):
157 if pkgdir not in pkg_cur_dirs:
158 obsolete_dirs.append(os.path.join(pkgroot, pkgdir))
159 else:
160 for verroot, verdirs, verfiles in os.walk(os.path.join(pkgroot, pkgdir)):
161 for f in verfiles:
162 obsolete_dirs.append(os.path.join(pkgroot, f))
163 for v in sorted(verdirs):
164 if v not in pkg_cur_dirs[pkgdir]:
165 obsolete_dirs.append(os.path.join(pkgroot, pkgdir, v))
166 break
167
168 # just process the top dir of every package under tmp/work/*/,
169 # then jump out of the above os.walk()
170 break
171
172 # it is convenient to use os.walk() to get dirs and files at same time
173 # both of them have been dealed in the loop, so jump out
174 break
175
176 for d in obsolete_dirs:
177 print "Deleting %s" % d
178 shutil.rmtree(d, True)
179
180 if len(obsolete_dirs):
181 print '\nTotal %d items.' % len(obsolete_dirs)
182 else:
183 print '\nNo obsolete directory found under %s.' % workdir
184
185 return 0
186
187if __name__ == '__main__':
188 try:
189 ret = main()
190 except Exception:
191 ret = 2
192 import traceback
193 traceback.print_exc(3)
194 sys.exit(ret)