import util
from constants import *
+from i18n import _
from errors import BuildError, BuildRootLocked, Error
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):
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
return ret in ("y", "Y")
-
class Cli(object):
def __init__(self):
self.parser = argparse.ArgumentParser(
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.
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"):
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
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):
"""
if comp == "X"*3:
comp = None
- # XXX remove that later, because of compatibility for naoki.
- elif not comp:
- comp = "xz"
-
return comp
@property
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.
def arch(self):
return "src"
- def extract(self, path):
- pass
-
@property
def requires(self):
"""
import progressbar
import sys
import tarfile
-import tempfile
-import compress
import depsolve
import packages
import util
"""
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):
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():
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)
import ctypes
import fcntl
import os
+import progressbar
import random
import select
import shutil
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,