apk-tools Code
Brought to you by:
ncopa
#!/usr/bin/python
# Distributed under the terms of the GNU General Public License v2
# $Header: $
import sys
#if len(sys.argv) < 2:
# print "Usage: tbz2apk [-u] </path/package.tbz2> ..."
# print " -u Update mode. Only convert where souce is newer than dest"
# sys.exit(1)
import os, xpak, string, socket, portage, re
def convertpkg(filename, options):
tbz2ball = os.path.realpath(filename)
pkgname = os.path.splitext(os.path.basename(tbz2ball))[0]
destdir = os.getcwd()
currentdir = os.getcwd()
apkfile = os.getcwd()+"/"+pkgname+".apk"
apkoverlay = "/usr/local/apk/"+pkgname
if options.update and os.path.exists(apkfile):
if os.path.getctime(apkfile) > os.path.getctime(tbz2ball):
return 0
if not os.path.exists(tbz2ball):
print "File: "+tbz2ball+" does not appear to exist."
sys.exit(1)
print ">>> Building "+pkgname+".apk..."
use=[]; iuse=[];
priority = "optional";
licence="";
depend="";
desc=pkgname+"\n";
arch="Unknown\n";
tmpdir = portage.settings["PORTAGE_TMPDIR"];
tmpdir += "/apk/"
if not os.path.exists(tmpdir):
os.mkdir(tmpdir)
tmpdir += os.path.basename(pkgname)+"/"
if os.path.exists(tmpdir):
os.system("rm -r "+tmpdir)
os.mkdir(tmpdir)
tmpapkdb = tmpdir+"/var/lib/apkdb/"
tbz2file = xpak.tbz2(tbz2ball)
keys = tbz2file.filelist()
if not os.path.exists(tmpapkdb):
os.system("mkdir -p "+tmpapkdb)
# open the control file and print mapping values.
control_file = tmpapkdb+pkgname+".control"
if os.path.exists(control_file):
os.unlink(control_file)
for key in keys:
val = " ".join(tbz2file.getfile(key).split())
if val != "":
if key == "CHOST":
chost = val
if key == "CFLAGS":
cflags = val
if key == "PF":
package = val
if key == "PV":
version = val
if key == "RDEPEND":
depend = val;
if key == "ARCH":
arch = val
if key == "CATEGORY":
section = val
if key == "LICENSE":
licence = val
if key == "environment.bz2":
val = tbz2file.getfile(key)
fp=open(tmpdir+key, "wb")
fp.write(tbz2file.getfile(key))
fp.flush()
fp.close()
os.system("bzcat "+ tmpdir + key +" > "+tmpdir+"/env")
# FIXME: use native API and get this in a buffer.
os.system("grep ^ARCH= "+tmpdir+"/env | cut -d = -f 2 > "+tmpdir+"/arch")
os.system("grep ^DESCRIPTION= "+tmpdir+"/env | awk -F = '{print $2}' >"+tmpdir+"/desc")
fp = open(tmpdir+"/arch", "rb")
arch = fp.read()
fp.close()
fp = open(tmpdir+"/desc", "rb")
desc = fp.read()
fp.close()
os.unlink(tmpdir+"/desc")
os.unlink(tmpdir+"/arch")
os.unlink(tmpdir+key)
val = ""
if key == "USE":
use = string.split(val, " ")
if key == "IUSE":
iuse = string.split(val, " ")
# actually we might not want to map unknowns.
#if val != "":
# sys.stdout.write(key+": "+val + "\n")
# Open the control file and write to it.
fp = open(control_file, "w")
p = re.compile('(^.*)-(\d.*$)')
m = p.match(package)
fp.write("Package: " + m.group(1) + "\n")
fp.write("Version: " + m.group(2) + "\n")
fp.write("Section: " + section + "\n");
fp.write("Architecture: " + arch )
fp.write("Description: " + desc )
fp.write("Licence: " + licence + "\n")
fp.write("Vendor: " + vendor + "\n")
fp.write("Depend: " + depend + "\n")
fp.write("Iuse: " +string.join(iuse) +"\n")
fp.write("Use: " + string.join(use) + "\n")
if os.environ['USER']:
fp.write("Maintainer: " +os.environ['USER'] + "@"+socket.gethostname()+"\n")
# map IUSE->USE and look for build flag set in both.
# if set then we change the package priority from optional to required.
for x in iuse:
for y in use:
if x == y:
if x == "build":
priority = "required"
# break
fp.write("Priority: " + priority + "\n")
fp.write("#CHOST: " + chost + "\n")
fp.write("#CFLAGS: " + cflags + "\n")
fp.flush()
fp.close()
ret = os.system("/bin/tar -jxpf "+ tbz2ball + " -C" + tmpdir
+ " 2>/dev/null || :")
if vendor == "Gentoo":
for x in ['doc', 'info', 'man', 'html', 'sgml']:
if "no"+x in portage.features:
ret = os.system("/bin/rm -rf "+tmpdir+"/data/usr/share/"+x)
# really need to find . -name '*.a' | xargs rm -rf
for x in ['/usr/include', '/usr/lib/*.a', '/usr/lib/*.la',
'/usr/share/doc', '/usr/share/man', '/usr/share/info', '/env']:
ret = os.system("/bin/rm -rf "+tmpdir+x)
for ext in ['*.a', '*.la', '*.o']:
os.system("find "+tmpdir+ " -type f -name '" + ext +"' | xargs rm -f")
# remove emtpy dirs
os.system("find "+tmpdir+ " -type d | xargs rmdir 2>/dev/null")
# sstrip things
os.system("for f in $(find "+tmpdir+" -type f | xargs -n1 file | grep ELF | grep -v relocatable | cut -d : -f 1); do sstrip ${f} ; done")
# copy the overlay files
os.system(" [ -d "+apkoverlay+" ] && cp -rva "+apkoverlay+"/* "+tmpdir)
os.chdir(tmpdir)
for i in ['./etc', './home', './root']:
if os.path.exists(i):
ret = os.system("find "+i+" > "+tmpapkdb+pkgname+".config")
os.system("busybox tar -zcf "+apkfile+" .")
os.system("sha1sum "+apkfile+">"+apkfile+".sha1")
if os.path.exists(tmpdir):
os.system("rm -rf "+tmpdir)
os.chdir(destdir)
return 1
#####################################################################
# Main
os.umask(0022)
# If we are not using this tool from a gentoo system it should still
# function, so we only want to import portage system unless we are indeed
# a gentoo system.
if os.path.exists("/etc/gentoo-release"):
vendor = "Gentoo"
import portage
else:
vendor = "Generic"
from optparse import OptionParser
parser = OptionParser()
parser.add_option("-u", "--update",
action="store_true", dest="update", default=False,
help="don't overwrite newer files")
(options, args) = parser.parse_args()
for tbz2 in args:
convertpkg(tbz2, options)
sys.exit(0)