diff options
Diffstat (limited to 'src/fedpkg')
| -rw-r--r-- | src/fedpkg/__init__.py | 229 |
1 files changed, 229 insertions, 0 deletions
diff --git a/src/fedpkg/__init__.py b/src/fedpkg/__init__.py new file mode 100644 index 0000000..750bea3 --- /dev/null +++ b/src/fedpkg/__init__.py @@ -0,0 +1,229 @@ +# fedpkg - a Python library for Fedora Packagers +# +# Copyright (C) 2009 Red Hat Inc. +# Author(s): Jesse Keating <jkeating@redhat.com> +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. See http://www.gnu.org/copyleft/gpl.html for +# the full text of the license. + +import os +#import pycurl +import subprocess +import hashlib + +# Define some global variables, put them here to make it easy to change +LOOKASIDE = 'http://cvs.fedoraproject.org/repo/pkgs' +LOOKASIDEHASH = 'md5' +GITBASEURL = 'ssh://%(user)s@pkgs.stg.fedoraproject.org/%(module)s' + +# Define some helper functions, they start with _ +def _hash_file(file, hashtype): + """Return the hash of a file given a hash type""" + + try: + sum = hashlib.new(hashtype) + except ValueError: + print("Invalid hash type: 0%s" % hashtype) + return False + + input = open(file, 'rb') + # Loop through the file reading chunks at a time as to not + # put the entire file in memory. That would suck for DVDs + while True: + chunk = input.read(8192) # magic number! Taking suggestions + if not chunk: + break # we're done with the file + sum.update(chunk) + input.close() + return sum.hexdigest() + +def _verify_file(file, hash, hashtype): + """Given a file, a hash of that file, and a hashtype, verify. + + Returns True if the file verifies, False otherwise + + """ + + # get the hash + sum = _hash_file(file, hashtype) + # now do the comparison + if sum == hash: + return True + return False + +def clone(module, user, branch=None): + """Clone a repo, optionally check out a specific branch. + + module is the name of the module to clone + + branch is the name of a branch to checkout instead of origin/master + + gitargs is an optional list of arguments to git clone + + """ + + # not implemented yet + # construct the git url + giturl = GITBASEURL % {'user': user, 'module': module} + cmd = ['git', 'clone'] + if branch: + cmd.extend(['--branch', branch]) + cmd.append(giturl) + print('Would have ran %s' % subprocess.list2cmdline(cmd)) + return + +def clone_with_dirs(module, user): + """Clone a repo old style with subdirs for each branch. + + module is the name of the module to clone + + gitargs is an option list of arguments to git clone + + """ + + # not implemented yet + print('would have cloned %s with dirs as user %s' % + (module, user)) + return + +# Create a class for package module +class PackageModule: + def _findbranch(self): + """Find the branch we're on""" + if not os.path.exists(os.path.join(self.path, 'branch')): + return 'devel' + branch = open(os.path.join(self.path, 'branch'), 'r').read().strip() + return branch + + def __init__(self, path=os.curdir): + # Initiate a PackageModule object in a given path + # Set some global variables used throughout + self.path = path + self.lookaside = LOOKASIDE + self.lookasidehash = LOOKASIDEHASH + self.spec = self.gimmespec() + self.module = self.spec.split('.spec')[0] + # Find the branch and set things based from that + # Still requires a 'branch' file in each branch + self.branch = self._findbranch() + if self.branch.startswith('F-'): + self.distval = self.branch.split('-')[1] + self.distvar = 'fedora' + self.dist = '.fc%s' % self.distval + elif self.branch.startswith('EL-'): + self.distval = self.branch.split('-')[1] + self.distvar = 'epel' + self.dist = '.el%s' % self.distval + elif self.branch.startswith('OLPC-'): + self.distval = self.branch.split('-')[1] + self.distvar = 'olpc' + self.dist = '.olpc%s' % self.distval + # Need to do something about no branch here + elif self.branch == 'devel': + self.distval = '13' # this is hardset for now, which is bad + self.distvar = 'fedora' + self.dist = '.fc%s' % self.distval + self.rpmdefines = ['--define', '_sourcedir %s' % path, + '--define', '_specdir %s' % path, + '--define', '_builddir %s' % path, + '--define', '_srcrpmdir %s' % path, + '--define', '_rpmdir %s' % path, + '--define', 'dist %s' % self.dist, + '--define', '%s %s' % (self.distvar, self.distval), + '--define', '%s 1' % self.distvar] + + def gimmespec(self): + """Print the name of a specfile within a package module""" + + # Get a list of files in the path we're looking at + files = os.listdir(self.path) + # Search the files for the first one that ends with ".spec" + for f in files: + if f.endswith('.spec'): + return f + return None + + def new_sources(self, files): + """Replace source file(s) in the lookaside cache""" + + # Not fully implimented yet + for file in files: + hash = _hash_file(file, self.lookasidehash) + print "Would upload %s:%s" % (hash, file) + return + + def sources(self, outdir=None): + """Download source files""" + + archives = open(os.path.join(self.path, 'sources'), + 'r').readlines() + # Default to putting the files where the module is + if not outdir: + outdir = self.path + for archive in archives: + csum, file = archive.split() + # See if we already have a valid copy downloaded + outfile = os.path.join(outdir, file) + if os.path.exists(outfile): + if _verify_file(outfile, csum, self.lookasidehash): + continue + url = '%s/%s/%s/%s/%s' % (self.lookaside, self.module, file, csum, + file) + # There is some code here for using pycurl, but for now, + # just use subprocess + #output = open(file, 'wb') + #curl = pycurl.Curl() + #curl.setopt(pycurl.URL, url) + #curl.setopt(pycurl.FOLLOWLOCATION, 1) + #curl.setopt(pycurl.MAXREDIRS, 5) + #curl.setopt(pycurl.CONNECTTIMEOUT, 30) + #curl.setopt(pycurl.TIMEOUT, 300) + #curl.setopt(pycurl.WRITEDATA, output) + #try: + # curl.perform() + #except: + # print "Problems downloading %s" % url + # curl.close() + # output.close() + # return 1 + #curl.close() + #output.close() + # These options came from Makefile.common. + # Probably need to support wget too + command = ['curl', '-H', 'Pragma:', '-O', '-R', '-S', '--fail', + '--show-error', url] + try: + subprocess.check_call(command, cwd=outdir) + except subprocess.CalledProcessError, e: + print "Could not download %s: %s" % (url, e) + return 1 + if not _verify_file(outfile, csum, self.lookasidehash): + print "%s failed checksum" % file + return 1 + return + + def srpm(self, hashtype='sha256'): + """Create an srpm using hashtype from content in the module + + Requires sources already downloaded. + + """ + + cmd = ['rpmbuild'] + cmd.extend(self.rpmdefines) + # This may need to get updated if we ever change our checksum default + if not hashtype == 'sha256': + cmd.extend(['--define', + '_source_filedigest_algorithm %s' % hashtype, + '--define', + '_binary_filedigest_algorithm %s' % hashtype]) + cmd.extend(['--nodeps', '-bs', os.path.join(self.path, self.spec)]) + try: + subprocess.check_call(cmd) + except subprocess.CalledProcessError, e: + print "Could not build %s: %s" % (self.module, e) + return 1 + return
\ No newline at end of file |
