<commit_before>#
# Copyright (c) 2004 Specifix, Inc.
#
# This program is distributed under the terms of the Common Public License,
# version 1.0. A copy of this license should have been distributed with this
# source file in a file called LICENSE. If it is not present, the license
# is always available at http://www.opensource.org/licenses/cpl.php.
#
# This program is distributed in the hope that it will be useful, but
# without any waranty; without even the implied warranty of merchantability
# or fitness for a particular purpose. See the Common Public License for
# full details.
#

"""
Modules used by recipes to find source code, check GPG signatures on
it, unpack it, and patch it in the correct directory.  Each of the
public classes in this module is accessed from a recipe as addI{Name}.
"""

import gzip
import log
import lookaside
import os
import rpmhelper
import util
import action
import string

class _Source(action.RecipeAction):
    keywords = {'rpm': '',
		'dir': '',
		'keyid': None }

	        
    def __init__(self, recipe, *args, **keywords):
	sourcename = args[0]
	action.RecipeAction.__init__(self, recipe, *args, **keywords)
	self.sourcename = sourcename % recipe.macros
	self.rpm = self.rpm % recipe.macros
	self.prep()
	    
    def prep(self):
	if self.keyid:
	    self._addSignature()
	if self.rpm:
	    self._extractFromRPM()

    def doAction(self):
	self.builddir = self.recipe.macros.builddir
	self.dir = self.dir % self.recipe.macros
	action.RecipeAction.doAction(self)

    def _addSignature(self):
        for suffix in ('sig', 'sign', 'asc'):
            self.gpg = '%s.%s' %(self.sourcename, suffix)
            self.localgpgfile = lookaside.searchAll(self.recipe.cfg,
				    self.recipe.laReposCache, self.gpg, 
                                    self.recipe.name, self.recipe.srcdirs)
	    if self.localgpgfile:
		return
	if not self.localgpgfile:
	    log.warning('No GPG signature file found for %s', self.sourcename)
	    del self.localgpgfile

    def _checkSignature(self, filepath):
	if 'localgpgfile' not in self.__dict__:
	    return
        if not util.checkPath("gpg"):
            return
	# FIXME: our own keyring
	if not self._checkKeyID(filepath, self.keyid):
	    # FIXME: only do this if key missing, this is cheap for now
	    os.system("gpg --no-secmem-warning --keyserver pgp.mit.edu --recv-keys 0x%s")
	    if not self._checkKeyID(filepath, self.keyid):
		log.error(self.failedtest)
		raise SourceError, "GPG signature %s failed" %(self.localgpgfile)

    def _checkKeyID(self, filepath, keyid):
	p = util.popen("gpg --logger-fd 1 --no-secmem-warning --verify %s %s"
		      %(self.localgpgfile, filepath))
	result = p.read()
	found = result.find("key ID %s" % keyid)
	if found == -1:
	    self.failedtest = result
	    return False
	return True

    def _extractFromRPM(self):
        """
        Extracts filename from rpm file and creates an entry in the
        source lookaside cache for the extracted file
        """
	# XXX check signature in RPM package?
	r = lookaside.findAll(self.recipe.cfg, self.recipe.laReposCache,
			      self.rpm, self.recipe.name,
			      self.recipe.srcdirs)
	c = lookaside.createCacheName(self.recipe.cfg, self.sourcename,
				      self.recipe.name)
	_extractFilesFromRPM(r, targetfile=c)


    def _findSource(self):
	if self.rpm:
	    # the file was already unpacked from the RPM, and so it
	    # must be in the lookaside cache.
	    return lookaside.searchCache(self.recipe.cfg,self.sourcename,
				         self.recipe.name)
	# otherwise, we use a standard search that looks in the repository
	# first
	return lookaside.findAll(self.recipe.cfg, self.recipe.laReposCache,
	    self.sourcename, self.recipe.name, self.recipe.srcdirs)

    def fetch(self):
	if 'sourcename' not in self.__dict__:
	    return None
	f = lookaside.findAll(self.recipe.cfg, self.recipe.laReposCache,
			      self.sourcename, self.recipe.name,
			      self.recipe.srcdirs)
	self._checkSignature(f)
	return f

    def do(self):
	raise NotImplementedError


class Archive(_Source):
    """
    Called as C{r.addArchive()} from a recipe, this class adds an archive
    such as an optionally compressed tarball or zip file, unpacking it
    into the appropriate directory.
    
    If you provide the C{keyid} argument, it will search for a file
    named I{sourcename}C{.{sig,sign,asc}} and make sure that it is
    signed with the appropriate GPG key.  A missing signature is a
    warning; a failed signature check is fatal.

    By default, C{addArchive} assumes that the archive contains the 
    first directory level in which all the build commands will run,
    called C{%(maindir)s}.  If an archive needs to be unpacked within
    this directory, pass in C{dir=r.macros.maindir} or for a
    subdirectory of maindir, pass in
    C{dir=r.macros.maindir + '/subdir'}
    """

    def __init__(self, recipe, *args, **keywords):
	"""
	@param recipe: The recipe object currently being built.
	    Provided automatically by the PackageRecipe object;
	    do not pass in C{r} from within a recipe.
	@keyword sourcename: The name of the archive
	@keyword rpm: If specified, causes Archive to look in the URL or
	    file specified by C{rpm} for an RPM containing C{sourcename}
	@keyword dir: If specified, the subdirectory in which to unpack
	    the sources, relative to C{%(builddir)s}; defaults to
	    C{%(maindir)s}
	@keyword keyid: The 8-digit GPG key ID (no leading C{0x}) for the
	    signature.  Indicates that a signature should be sought and
	    checked.
	@keyword use: A Use flag or boolean, or a tuple of Use flags and/or
	    booleans, that determine whether the archive is actually
	    unpacked or merely stored in the archive.
	"""
	_Source.__init__(self, recipe, *args, **keywords)

    def do(self):
	f = self._findSource()
	self._checkSignature(f)

	if self.dir:
	    destdir = '%s/%s' % (self.builddir, self.dir)
	    util.mkdirChain(destdir)
	else:
	    destdir = self.builddir

	if f.endswith(".zip"):
	    util.execute("unzip -q -o -d %s %s" % (destdir, f))
	    return

	if f.endswith(".rpm"):
	    _extractFilesFromRPM(r, directory=destdir)
	    return

	if f.endswith(".bz2") or f.endswith(".tbz2"):
	    tarflags = "-jxf"
	elif f.endswith(".gz") or f.endswith(".tgz"):<commit_msg>f is the correct variable name, not r<commit_after>#
# Copyright (c) 2004 Specifix, Inc.
#
# This program is distributed under the terms of the Common Public License,
# version 1.0. A copy of this license should have been distributed with this
# source file in a file called LICENSE. If it is not present, the license
# is always available at http://www.opensource.org/licenses/cpl.php.
#
# This program is distributed in the hope that it will be useful, but
# without any waranty; without even the implied warranty of merchantability
# or fitness for a particular purpose. See the Common Public License for
# full details.
#

"""
Modules used by recipes to find source code, check GPG signatures on
it, unpack it, and patch it in the correct directory.  Each of the
public classes in this module is accessed from a recipe as addI{Name}.
"""

import gzip
import log
import lookaside
import os
import rpmhelper
import util
import action
import string

class _Source(action.RecipeAction):
    keywords = {'rpm': '',
		'dir': '',
		'keyid': None }

	        
    def __init__(self, recipe, *args, **keywords):
	sourcename = args[0]
	action.RecipeAction.__init__(self, recipe, *args, **keywords)
	self.sourcename = sourcename % recipe.macros
	self.rpm = self.rpm % recipe.macros
	self.prep()
	    
    def prep(self):
	if self.keyid:
	    self._addSignature()
	if self.rpm:
	    self._extractFromRPM()

    def doAction(self):
	self.builddir = self.recipe.macros.builddir
	self.dir = self.dir % self.recipe.macros
	action.RecipeAction.doAction(self)

    def _addSignature(self):
        for suffix in ('sig', 'sign', 'asc'):
            self.gpg = '%s.%s' %(self.sourcename, suffix)
            self.localgpgfile = lookaside.searchAll(self.recipe.cfg,
				    self.recipe.laReposCache, self.gpg, 
                                    self.recipe.name, self.recipe.srcdirs)
	    if self.localgpgfile:
		return
	if not self.localgpgfile:
	    log.warning('No GPG signature file found for %s', self.sourcename)
	    del self.localgpgfile

    def _checkSignature(self, filepath):
	if 'localgpgfile' not in self.__dict__:
	    return
        if not util.checkPath("gpg"):
            return
	# FIXME: our own keyring
	if not self._checkKeyID(filepath, self.keyid):
	    # FIXME: only do this if key missing, this is cheap for now
	    os.system("gpg --no-secmem-warning --keyserver pgp.mit.edu --recv-keys 0x%s")
	    if not self._checkKeyID(filepath, self.keyid):
		log.error(self.failedtest)
		raise SourceError, "GPG signature %s failed" %(self.localgpgfile)

    def _checkKeyID(self, filepath, keyid):
	p = util.popen("gpg --logger-fd 1 --no-secmem-warning --verify %s %s"
		      %(self.localgpgfile, filepath))
	result = p.read()
	found = result.find("key ID %s" % keyid)
	if found == -1:
	    self.failedtest = result
	    return False
	return True

    def _extractFromRPM(self):
        """
        Extracts filename from rpm file and creates an entry in the
        source lookaside cache for the extracted file
        """
	# XXX check signature in RPM package?
	r = lookaside.findAll(self.recipe.cfg, self.recipe.laReposCache,
			      self.rpm, self.recipe.name,
			      self.recipe.srcdirs)
	c = lookaside.createCacheName(self.recipe.cfg, self.sourcename,
				      self.recipe.name)
	_extractFilesFromRPM(r, targetfile=c)


    def _findSource(self):
	if self.rpm:
	    # the file was already unpacked from the RPM, and so it
	    # must be in the lookaside cache.
	    return lookaside.searchCache(self.recipe.cfg,self.sourcename,
				         self.recipe.name)
	# otherwise, we use a standard search that looks in the repository
	# first
	return lookaside.findAll(self.recipe.cfg, self.recipe.laReposCache,
	    self.sourcename, self.recipe.name, self.recipe.srcdirs)

    def fetch(self):
	if 'sourcename' not in self.__dict__:
	    return None
	f = lookaside.findAll(self.recipe.cfg, self.recipe.laReposCache,
			      self.sourcename, self.recipe.name,
			      self.recipe.srcdirs)
	self._checkSignature(f)
	return f

    def do(self):
	raise NotImplementedError


class Archive(_Source):
    """
    Called as C{r.addArchive()} from a recipe, this class adds an archive
    such as an optionally compressed tarball or zip file, unpacking it
    into the appropriate directory.
    
    If you provide the C{keyid} argument, it will search for a file
    named I{sourcename}C{.{sig,sign,asc}} and make sure that it is
    signed with the appropriate GPG key.  A missing signature is a
    warning; a failed signature check is fatal.

    By default, C{addArchive} assumes that the archive contains the 
    first directory level in which all the build commands will run,
    called C{%(maindir)s}.  If an archive needs to be unpacked within
    this directory, pass in C{dir=r.macros.maindir} or for a
    subdirectory of maindir, pass in
    C{dir=r.macros.maindir + '/subdir'}
    """

    def __init__(self, recipe, *args, **keywords):
	"""
	@param recipe: The recipe object currently being built.
	    Provided automatically by the PackageRecipe object;
	    do not pass in C{r} from within a recipe.
	@keyword sourcename: The name of the archive
	@keyword rpm: If specified, causes Archive to look in the URL or
	    file specified by C{rpm} for an RPM containing C{sourcename}
	@keyword dir: If specified, the subdirectory in which to unpack
	    the sources, relative to C{%(builddir)s}; defaults to
	    C{%(maindir)s}
	@keyword keyid: The 8-digit GPG key ID (no leading C{0x}) for the
	    signature.  Indicates that a signature should be sought and
	    checked.
	@keyword use: A Use flag or boolean, or a tuple of Use flags and/or
	    booleans, that determine whether the archive is actually
	    unpacked or merely stored in the archive.
	"""
	_Source.__init__(self, recipe, *args, **keywords)

    def do(self):
	f = self._findSource()
	self._checkSignature(f)

	if self.dir:
	    destdir = '%s/%s' % (self.builddir, self.dir)
	    util.mkdirChain(destdir)
	else:
	    destdir = self.builddir

	if f.endswith(".zip"):
	    util.execute("unzip -q -o -d %s %s" % (destdir, f))
	    return

	if f.endswith(".rpm"):
	    _extractFilesFromRPM(f, directory=destdir)
	    return

	if f.endswith(".bz2") or f.endswith(".tbz2"):
	    tarflags = "-jxf"
	elif f.endswith(".gz") or f.endswith(".tgz"):
{'fraction_non_alphanumeric': 0.10014272121788773, 'fraction_numerical': 0.0022201078338090706, 'mean_word_length': 3.1959414504324686, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1596135', 'n_tokens_mistral': 4273, 'n_tokens_neox': 3998, 'n_words': 1364}