
## sourcedsc.bbclass: Generates the debian source package.

## Deploy:
##         * .dsc - debian source package control file
##         * .orig.tar.gz - Original source package
##         * .diff.gz - patches that we apply
##         * .changes - changes file

DEPLOY_DIR_DSC ?= "${DEPLOY_DIR}/dsc"

def gen_controldir(d, workdir, basedir, controldir, pkgname, srcfile):
    import pexpect
    import bb
    import os

    if not os.path.exists(srcfile):
        bb.note("Source not found. Unable to generate debian control dir")
        return

    # If the package already has a debian control dir we need to remove it
    if os.path.exists(controldir):
        os.system("rm -rf %s" % controldir)

    M = bb.data.getVar("MAINTAINER", d, 1) or \
        "<openembedded-devel@lists.openembedded.org>"
    maintainer_email = M[M.rindex("<")+1:M.rindex(">")]

    # Generating a template of debian control dir
    child = pexpect.spawn("dh_make -m -e %s -f %s -p %s" %
                          (maintainer_email, srcfile,
                           pkgname[0:pkgname.rindex('-')].lower()))
    child.expect("Hit <enter> to confirm:")
    child.sendline('')
    child.expect(pexpect.EOF, timeout=None)

    if not os.path.exists(controldir):
        bb.error("dh_make has failed: Control dir not found")
        return

    # Cleaning controldir
    os.system("rm -rf %s %s" % (os.path.join(controldir, "*.{ex,EX}"),
                                os.path.join(controldir, "README.Debian")))

    # Modifying changelog file
    os.system("sed -i -e \"s,(Closes: #nnnn)  <nnnn is the bug number of your ITP>,,g\" %s" % os.path.join(controldir, "changelog"))

    # Modifying copyright file
    os.system("sed -i -e \"s,<fill in http/ftp site>,%s,g\" %s" %
              (bb.data.getVar("SRC_URI", d, 1),
               os.path.join(controldir, "copyright")))
    os.system("sed -i -e \"s,file://,+ OE Patch: ,g\" %s" %
              os.path.join(controldir, "copyright"))
    os.system("sed -i -e \"s,;patch=1,,g\" %s" %
              os.path.join(controldir, "copyright"))
    os.system("sed -i -e \"s,Upstream Author: <put author(s) name and email here>,,g\" %s" % os.path.join(controldir, "copyright"))
    os.system("sed -i -e \"s,Copyright: <put the year(s) of the copyright\, and the names of the,,g\" %s" % os.path.join(controldir, "copyright"))
    os.system("sed -i -e \"s,copyright holder(s) here>,,g\" %s" %
              os.path.join(controldir, "copyright"))
    os.system("sed -i -e \"s,<Put the license of the package here>,%s,g\" %s" %
              (bb.data.getVar("LICENSE", d, 1),
               os.path.join(controldir, "copyright")))

    # Modifying control file
    os.system("sed -i -e \"s,Section: unknown,Section: %s,g\" debian/control" %
              bb.data.getVar("SECTION", d, 1))
    os.system("sed -i -e \"s,<insert up to 60 chars description>,%s,g\" %s" %
              (bb.data.getVar("DESCRIPTION", d, 1),
               os.path.join(controldir, "control")))
    os.system("sed -i -e \"s,<insert long description\, indented with spaces>,,g\" %s" % os.path.join(controldir, "control"))

    o_patchesdir = os.path.join(workdir, pkgname, "patches")
    patchesdir = os.path.join(controldir, "patches")
    bb.mkdirhier(patchesdir)
    if os.path.isdir(o_patchesdir):
        os.system("cp -a %s/*.{patch,diff} %s 2>/dev/null" %
                  (o_patchesdir, patchesdir))

addtask create_dsc after do_patch before do_configure
python do_create_dsc () {
    import re
    import os

    # Setting up package names:
    pkgname = bb.data.getVar('P', d, 1)
    if pkgname.count("intermediate") or \
       pkgname.count("native") or pkgname.count("cross"):
        bb.note("dsc is not generated for native or cross packages")
        return

    # Setting up directories names
    workdir = bb.data.getVar("WORKDIR", d, 1)
    if not workdir:
        bb.error("WORKDIR not defined, unable to package")
        return
    builddir = os.path.join(workdir, pkgname, "dscgen")
    outdir = bb.data.getVar("DEPLOY_DIR_DSC", d, 1)
    if not outdir:
        bb.error("DEPLOY_DIR_DSC not defined, unable to package")
        return
    pkgoutdir = os.path.join(outdir, pkgname[0:pkgname.rindex('-')])

    srcdir = bb.data.getVar("DL_DIR", d, 1)
    if not srcdir:
        bb.error("DL_DIR not defined, unable to package")
        return

    # Creating and changing to the directory where this build will occurs.
    os.system("rm -rf %s" % builddir)
    bb.mkdirhier(builddir)
    os.chdir(builddir)

    # Unpacking the source file
    from glob import glob

    srcfile = glob(os.path.join(srcdir, "%s.tar.gz" % pkgname)) \
              or glob(os.path.join(srcdir, "%s.tar.bz2" % pkgname)) \
              or glob(os.path.join(srcdir, "%s.Z" % pkgname)) \
              or glob(os.path.join(srcdir, "%s.tar" % pkgname)) \
              or glob(os.path.join(srcdir, "%s.gz" % pkgname)) \
              or glob(os.path.join(srcdir, "%s.bz2" % pkgname)) \
              or glob(os.path.join(srcdir, "%s.zip" % pkgname))

    if not srcfile:
        bb.error("Source not found: %s" % srcfile)
        return
    srcfile = srcfile[0]

    cmd = None
    if srcfile.endswith(".tar"):
        cmd = "tar x --no-same-owner -f %s" % srcfile
    elif srcfile.endswith(".tgz") or srcfile.endswith(".tar.gz") \
                                  or srcfile.endswith(".tar.Z"):
        cmd = "tar xz --no-same-owner -f %s" % srcfile
    elif srcfile.endswith(".tbz") or srcfile.endswith(".tar.bz2"):
        cmd = "bzip2 -dc %s | tar x --no-same-owner -f -" % srcfile
    elif srcfile.endswith(".gz") or srcfile.endswith(".Z") \
                                 or srcfile.endswith(".z"):
        cmd = "gzip -dc %s" % srcfile
    elif srcfile.endswith(".bz2"):
        cmd = "bzip2 -dc %s" % srcfile
    elif srcfile.endswith(".zip"):
        cmd = "unzip -q"
        if "dos" in parm:
            cmd = "%s -a" % cmd
        cmd = "%s %s" % (cmd, srcfile)

    if not cmd:
        return True

    cmd = "PATH=\"%s\" %s" % (bb.data.getVar("PATH", d, 1), cmd)
    bb.note("Unpacking %s to %s/" % (srcfile, os.getcwd()))
    os.system(cmd)

    # Setting up these variables that depends on extracted directory
    basedir = os.path.join(builddir, os.listdir(os.getcwd())[0])
    controldir = os.path.join(basedir, "debian")

    # Let's build:
    os.chdir(basedir)
    gen_controldir(d, workdir, basedir, controldir, pkgname, srcfile)
    bb.note("Building dsc package: %s" % os.getcwd())
    ret = os.system("dpkg-buildpackage -uc -us -S -rfakeroot")
    if ret != 0:
        raise bb.build.FuncFailed("dpkg-buildpackage -S execution failed")
    else:
        bb.mkdirhier(pkgoutdir)
        os.system("mv ../*.{dsc,diff.gz,changes,orig.tar.gz} %s" % pkgoutdir)

    # Let's clean
    os.chdir(workdir)
    os.system("rm -rf %s" % builddir)
}
