]> git.ipfire.org Git - pakfire.git/commitdiff
Add support to build source packages and fix for empty requires on source packages.
authorMichael Tremer <michael.tremer@ipfire.org>
Tue, 5 Apr 2011 15:07:33 +0000 (17:07 +0200)
committerMichael Tremer <michael.tremer@ipfire.org>
Tue, 5 Apr 2011 15:07:33 +0000 (17:07 +0200)
pakfire/builder.py
pakfire/cli.py
pakfire/packages/base.py
pakfire/packages/binary.py
pakfire/packages/file.py
pakfire/packages/packager.py
pakfire/packages/source.py
pakfire/transaction.py
pakfire/util.py

index eb6b363e56fc077ddfa7b13fdb16773cbfdc04c7..effe71a303a43921d1cd4a42a2298eed3a407609 100644 (file)
@@ -19,6 +19,7 @@ import transaction
 import util
 
 from constants import *
+from i18n import _
 from errors import BuildError, BuildRootLocked, Error
 
 
@@ -169,6 +170,10 @@ class Builder(object):
                if isinstance(self.pkg, packages.Makefile):
                        self.pkg.extract(self)
 
+               elif isinstance(self.pkg, packages.SourcePackage):
+                       self.pkg.extract(_("Extracting: %s (source)") % self.pkg.name,
+                               prefix=os.path.join(self.path, "build"))
+
                # If we have a makefile, we can only get the build dependencies
                # after we have extracted all the rest.
                if build_deps and isinstance(self.pkg, packages.Makefile):
@@ -501,8 +506,12 @@ class Builder(object):
                return ret
 
        def make(self, *args, **kwargs):
-               return self.do("make -f /build/%s %s" % \
-                       (os.path.basename(self.pkg.filename), " ".join(args)),
+               if isinstance(self.pkg, packages.Makefile):
+                       filename = os.path.basename(self.pkg.filename)
+               elif isinstance(self.pkg, packages.SourcePackage):
+                       filename = "%s.%s" % (self.pkg.name, MAKEFILE_EXTENSION)
+
+               return self.do("make -f /build/%s %s" % (filename, " ".join(args)),
                        **kwargs)
 
        @property
index 2241fcc3dee7ef46e51d59b48e1551218391ada3..d0649ade572a1aa49fcf39951f303ee894515023 100644 (file)
@@ -29,7 +29,6 @@ def ask_user(question):
 
        return ret in ("y", "Y")
 
-
 class Cli(object):
        def __init__(self):
                self.parser = argparse.ArgumentParser(
index 8f926c1a0c7d8a38faac6498936a62d4d9281324..f2c5ad9b12be28c4e3558bb7cc2a5d2a5a5e2770 100644 (file)
@@ -281,6 +281,24 @@ class Package(object):
        def uuid(self):
                return self.metadata.get("PKG_UUID", None)
 
+       @property
+       def requires(self):
+               ret = ""
+
+               # The default attributes, that are process for the requires.
+               attrs = ("PKG_REQUIRES", "PKG_DEPS")
+
+               # Source packages do depend on their build dependencies.
+               if self.arch == "src":
+                       attrs = ("PKG_BUILD_DEPS",)
+
+               for i in attrs:
+                       ret = self.metadata.get(i, ret)
+                       if ret:
+                               break
+
+               return ret.split()
+
        @property
        def _provides(self):
                # Make package identifyable by its name and version/release tuples.
index 3ce9ef5c3463a554b5448837a33a430eca66cd53..89d41049f8cc561b8a19d1105df61e96e4e4562c 100644 (file)
@@ -9,17 +9,6 @@ class BinaryPackage(FilePackage):
        def arch(self):
                return self.metadata.get("PKG_ARCH")
 
-       @property
-       def requires(self):
-               ret = ""
-
-               for i in ("PKG_REQUIRES", "PKG_DEPS"):
-                       ret = self.metadata.get(i, ret)
-                       if ret:
-                               break
-
-               return ret.split()
-
        @property
        def provides(self):
                if not hasattr(self, "__provides"):
index c8d35bc8b389280be29443a093741239e242188c..cb70bb45fdba5fa85049c47d297073e9979818b7 100644 (file)
@@ -4,11 +4,15 @@ import logging
 import os
 import re
 import tarfile
+import tempfile
 import xattr
 
 import util
 
+import pakfire.util as util
+import pakfire.compress as compress
 from pakfire.errors import FileError
+from pakfire.constants import *
 
 from base import Package
 
@@ -118,6 +122,99 @@ class FilePackage(Package):
        def open_archive(self):
                return tarfile.open(self.filename)
 
+       def extract(self, message=None, prefix=None):
+               logging.debug("Extracting package %s" % self.friendly_name)
+
+               if prefix is None:
+                       prefix = ""
+
+               # A place to store temporary data.
+               tempf = None
+
+               # Open package data for read.
+               archive = self.open_archive()
+
+               # Get the package payload.
+               payload = archive.extractfile("data.img")
+
+               # Decompress the payload if needed.
+               logging.debug("Compression: %s" % self.payload_compression)
+
+               # Create a temporary file to store the decompressed output.
+               garbage, tempf = tempfile.mkstemp(prefix="pakfire")
+
+               i = payload
+               o = open(tempf, "w")
+
+               # Decompress the package payload.
+               if self.payload_compression:
+                       compress.decompressobj(i, o, algo=self.payload_compression)
+
+               else:
+                       buf = i.read(BUFFER_SIZE)
+                       while buf:
+                               o.write(buf)
+                               buf = i.read(BUFFER_SIZE)
+
+               i.close()
+               o.close()
+
+               payload = open(tempf)
+
+               # Open the tarball in the package.
+               payload_archive = InnerTarFile.open(fileobj=payload)
+
+               members = payload_archive.getmembers()
+
+               # Load progressbar.
+               pb = None
+               if message:
+                       pb = util.make_progress("%-40s" % message, len(members))
+
+               i = 0
+               for member in members:
+                       # Update progress.
+                       if pb:
+                               i += 1
+                               pb.update(i)
+
+                       target = os.path.join(prefix, member.name)
+
+                       # If the member is a directory and if it already exists, we
+                       # don't need to create it again.
+
+                       if os.path.exists(target):
+                               if member.isdir():
+                                       continue
+
+                               else:
+                                       # Remove file if it has been existant
+                                       os.unlink(target)
+
+                       #if self.pakfire.config.get("debug"):
+                       #       msg = "Creating file (%s:%03d:%03d) " % \
+                       #               (tarfile.filemode(member.mode), member.uid, member.gid)
+                       #       if member.issym():
+                       #               msg += "/%s -> %s" % (member.name, member.linkname)
+                       #       elif member.islnk():
+                       #               msg += "/%s link to /%s" % (member.name, member.linkname)
+                       #       else:
+                       #               msg += "/%s" % member.name
+                       #       logging.debug(msg)
+
+                       payload_archive.extract(member, path=prefix)
+
+               # Close all open files.
+               payload_archive.close()
+               payload.close()
+               archive.close()
+
+               if tempf:
+                       os.unlink(tempf)
+
+               if pb:
+                       pb.finish()
+
        @property
        def file_version(self):
                """
@@ -218,10 +315,6 @@ class FilePackage(Package):
                if comp == "X"*3:
                        comp = None
 
-               # XXX remove that later, because of compatibility for naoki.
-               elif not comp:
-                       comp = "xz"
-
                return comp
 
        @property
index a3b1a957771bd4b9d0cc3e419040368cb75c8edb..28d150194efb448381756ec0be928bf523573aaa 100644 (file)
@@ -88,6 +88,10 @@ class Packager(object):
 
                                self.info[key] = " ".join(sorted(val))
 
+               elif self.type == "source":
+                       # Save the build requirements.
+                       self.info["requires"] = " ".join(self.pkg.requires)
+
                self.create_info()
 
                # Create the outer tarball.
index 1e53f575229328ac7f750d07def4ba3c2d1b7d00..9bea3b13c7b240f4a61a356a1aab0fb6099d1dfb 100644 (file)
@@ -7,9 +7,6 @@ class SourcePackage(FilePackage):
        def arch(self):
                return "src"
 
-       def extract(self, path):
-               pass
-
        @property
        def requires(self):
                """
index 9ba103c94eebaf05c5a4287bffad29d4845a77a1..d2dc90bec703eb1dab9b865057684aa7668f8335 100644 (file)
@@ -5,9 +5,7 @@ import os
 import progressbar
 import sys
 import tarfile
-import tempfile
 
-import compress
 import depsolve
 import packages
 import util
@@ -49,30 +47,6 @@ class Action(object):
                """
                return self.pakfire.repos.local
 
-       @staticmethod
-       def make_progress(message, maxval):
-               # Return nothing if stdout is not a terminal.
-               if not sys.stdout.isatty():
-                       return
-
-               widgets = [
-                       "  ",
-                       message,
-                       " ",
-                       progressbar.Bar(left="[", right="]"),
-                       "  ",
-                       progressbar.ETA(),
-                       "  ",
-               ]
-
-               if not maxval:
-                       maxval = 1
-
-               pb = progressbar.ProgressBar(widgets=widgets, maxval=maxval)
-               pb.start()
-
-               return pb
-
 
 class ActionCleanup(Action):
        def gen_files(self):
@@ -99,7 +73,7 @@ class ActionCleanup(Action):
                if not files:
                        return
 
-               pb = self.make_progress(message, len(files))
+               pb = util.make_progress(message, len(files))
                i = 0
 
                for f in self.gen_files():
@@ -161,88 +135,11 @@ class ActionInstall(Action):
                if prefix is None:
                        prefix = self.pakfire.path
 
-               # A place to store temporary data.
-               tempf = None
-
-               # Open package data for read.
-               archive = self.pkg.open_archive()
-
-               # Get the package payload.
-               payload = archive.extractfile("data.img")
-
-               # Decompress the payload if needed.
-               if self.pkg.payload_compression:
-                       # Create a temporary file to store the decompressed output.
-                       garbage, tempf = tempfile.mkstemp(prefix="pakfire")
-
-                       i = payload
-                       o = open(tempf, "w")
-
-                       # Decompress the package payload.
-                       compress.decompressobj(i, o, algo=self.pkg.payload_compression)
-
-                       i.close()
-                       o.close()
-
-                       payload = open(tempf)
-
-               # Open the tarball in the package.
-               payload_archive = packages.InnerTarFile.open(fileobj=payload)
-
-               members = payload_archive.getmembers()
-
-               # Load progressbar.
-               pb = self.make_progress("%-40s" % message, len(members))
-
-               i = 0
-               for member in members:
-                       # Update progress.
-                       if pb:
-                               i += 1
-                               pb.update(i)
-
-                       target = os.path.join(prefix, member.name)
-
-                       # If the member is a directory and if it already exists, we
-                       # don't need to create it again.
-
-                       if os.path.exists(target):
-                               if member.isdir():
-                                       continue
-
-                               else:
-                                       # Remove file if it has been existant
-                                       os.unlink(target)
-
-                       #if self.pakfire.config.get("debug"):
-                       #       msg = "Creating file (%s:%03d:%03d) " % \
-                       #               (tarfile.filemode(member.mode), member.uid, member.gid)
-                       #       if member.issym():
-                       #               msg += "/%s -> %s" % (member.name, member.linkname)
-                       #       elif member.islnk():
-                       #               msg += "/%s link to /%s" % (member.name, member.linkname)
-                       #       else:
-                       #               msg += "/%s" % member.name
-                       #       logging.debug(msg)
-
-                       payload_archive.extract(member, path=prefix)
-
-                       # XXX implement setting of xattrs/acls here
-
-               # Close all open files.
-               payload_archive.close()
-               payload.close()
-               archive.close()
-
-               if tempf:
-                       os.unlink(tempf)
+               self.pkg.extract(message, prefix=prefix)
 
                # Create package in the database
                self.local.index.add_package(self.pkg)
 
-               if pb:
-                       pb.finish()
-
        def run(self):
                self.extract(_("Installing: %s") % self.pkg.name)
 
index ced8ca01d76eaf2a3c590bc4367593471d0e4704..99c8999d7d86d65a33808ab850d1146a1001498b 100644 (file)
@@ -3,6 +3,7 @@
 import ctypes
 import fcntl
 import os
+import progressbar
 import random
 import select
 import shutil
@@ -27,6 +28,29 @@ def cli_is_interactive():
 
        return False
 
+def make_progress(message, maxval):
+       # Return nothing if stdout is not a terminal.
+       if not sys.stdout.isatty():
+               return
+
+       widgets = [
+               "  ",
+               "%-40s" % message,
+               " ",
+               progressbar.Bar(left="[", right="]"),
+               "  ",
+               progressbar.ETA(),
+               "  ",
+       ]
+
+       if not maxval:
+               maxval = 1
+
+       pb = progressbar.ProgressBar(widgets=widgets, maxval=maxval)
+       pb.start()
+
+       return pb
+
 def rm(path, *args, **kargs):
        """
                version of shutil.rmtree that ignores no-such-file-or-directory errors,