summaryrefslogtreecommitdiff
path: root/scripts/cleanup-workdir
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/cleanup-workdir')
-rwxr-xr-xscripts/cleanup-workdir198
1 files changed, 198 insertions, 0 deletions
diff --git a/scripts/cleanup-workdir b/scripts/cleanup-workdir
new file mode 100755
index 0000000..01ebd52
--- /dev/null
+++ b/scripts/cleanup-workdir
@@ -0,0 +1,198 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2012 Wind River Systems, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+import os
+import sys
+import optparse
+import re
+import subprocess
+import shutil
+
+pkg_cur_dirs = {}
+obsolete_dirs = []
+parser = None
+
+def err_quit(msg):
+ print msg
+ parser.print_usage()
+ sys.exit(1)
+
+def parse_version(verstr):
+ elems = verstr.split(':')
+ epoch = elems[0]
+ if len(epoch) == 0:
+ return elems[1]
+ else:
+ return epoch + '_' + elems[1]
+
+def run_command(cmd):
+ pipe = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
+ output = pipe.communicate()[0]
+ if pipe.returncode != 0:
+ print "Execute command '%s' failed." % cmd
+ sys.exit(1)
+ return output
+
+def get_cur_arch_dirs(workdir, arch_dirs):
+ pattern = workdir + '/(.*?)/'
+
+ cmd = "bitbake -e | grep ^SDK_ARCH="
+ output = run_command(cmd)
+ sdk_arch = output.split('"')[1]
+
+ # select thest 5 packages to get the dirs of current arch
+ pkgs = ['hicolor-icon-theme', 'base-files', 'acl-native', 'binutils-crosssdk-' + sdk_arch, 'nativesdk-autoconf']
+
+ for pkg in pkgs:
+ cmd = "bitbake -e " + pkg + " | grep ^IMAGE_ROOTFS="
+ output = run_command(cmd)
+ output = output.split('"')[1]
+ m = re.match(pattern, output)
+ arch_dirs.append(m.group(1))
+
+def main():
+ global parser
+ parser = optparse.OptionParser(
+ usage = """%prog
+
+%prog removes the obsolete packages' build directories in WORKDIR.
+This script must be ran under BUILDDIR after source file \"oe-init-build-env\".
+
+Any file or directory under WORKDIR which is not created by Yocto
+will be deleted. Be CAUTIOUS.""")
+
+ options, args = parser.parse_args(sys.argv)
+
+ builddir = run_command('echo $BUILDDIR').strip()
+ if len(builddir) == 0:
+ err_quit("Please source file \"oe-init-build-env\" first.\n")
+
+ if os.getcwd() != builddir:
+ err_quit("Please run %s under: %s\n" % (os.path.basename(args[0]), builddir))
+
+ print 'Updating bitbake caches...'
+ cmd = "bitbake -s"
+ output = run_command(cmd)
+
+ output = output.split('\n')
+ index = 0
+ while len(output[index]) > 0:
+ index += 1
+ alllines = output[index+1:]
+
+ for line in alllines:
+ # empty again means end of the versions output
+ if len(line) == 0:
+ break
+ line = line.strip()
+ line = re.sub('\s+', ' ', line)
+ elems = line.split(' ')
+ if len(elems) == 2:
+ version = parse_version(elems[1])
+ else:
+ version = parse_version(elems[2])
+ pkg_cur_dirs[elems[0]] = version
+
+ cmd = "bitbake -e"
+ output = run_command(cmd)
+
+ tmpdir = None
+ image_rootfs = None
+ output = output.split('\n')
+ for line in output:
+ if tmpdir and image_rootfs:
+ break
+
+ if not tmpdir:
+ m = re.match('TMPDIR="(.*)"', line)
+ if m:
+ tmpdir = m.group(1)
+
+ if not image_rootfs:
+ m = re.match('IMAGE_ROOTFS="(.*)"', line)
+ if m:
+ image_rootfs = m.group(1)
+
+ # won't fail just in case
+ if not tmpdir or not image_rootfs:
+ print "Can't get TMPDIR or IMAGE_ROOTFS."
+ return 1
+
+ pattern = tmpdir + '/(.*?)/(.*?)/'
+ m = re.match(pattern, image_rootfs)
+ if not m:
+ print "Can't get WORKDIR."
+ return 1
+
+ workdir = os.path.join(tmpdir, m.group(1))
+
+ # we only deal the dirs of current arch, total numbers of dirs are 6
+ cur_arch_dirs = [m.group(2)]
+ get_cur_arch_dirs(workdir, cur_arch_dirs)
+
+ for workroot, dirs, files in os.walk(workdir):
+ # For the files, they should NOT exist in WORKDIR. Remove them.
+ for f in files:
+ obsolete_dirs.append(os.path.join(workroot, f))
+
+ for d in dirs:
+ if d not in cur_arch_dirs:
+ continue
+
+ for pkgroot, pkgdirs, filenames in os.walk(os.path.join(workroot, d)):
+ for f in filenames:
+ obsolete_dirs.append(os.path.join(pkgroot, f))
+
+ for pkgdir in sorted(pkgdirs):
+ if pkgdir not in pkg_cur_dirs:
+ obsolete_dirs.append(os.path.join(pkgroot, pkgdir))
+ else:
+ for verroot, verdirs, verfiles in os.walk(os.path.join(pkgroot, pkgdir)):
+ for f in verfiles:
+ obsolete_dirs.append(os.path.join(pkgroot, f))
+ for v in sorted(verdirs):
+ if v not in pkg_cur_dirs[pkgdir]:
+ obsolete_dirs.append(os.path.join(pkgroot, pkgdir, v))
+ break
+
+ # just process the top dir of every package under tmp/work/*/,
+ # then jump out of the above os.walk()
+ break
+
+ # it is convenient to use os.walk() to get dirs and files at same time
+ # both of them have been dealed in the loop, so jump out
+ break
+
+ for d in obsolete_dirs:
+ print "Deleting %s" % d
+ shutil.rmtree(d, True)
+
+ if len(obsolete_dirs):
+ print '\nTotal %d items.' % len(obsolete_dirs)
+ else:
+ print '\nNo obsolete directory found under %s.' % workdir
+
+ return 0
+
+if __name__ == '__main__':
+ try:
+ ret = main()
+ except Exception:
+ ret = 2
+ import traceback
+ traceback.print_exc()
+ sys.exit(ret)