summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--__init__.py0
-rwxr-xr-xdevshell.py438
-rw-r--r--modules/__init__.py0
-rw-r--r--modules/audit.py9
-rw-r--r--modules/bugs.py24
-rw-r--r--modules/mail.py116
-rw-r--r--modules/pkg.py132
-rwxr-xr-xports.py20
-rw-r--r--rebuild-scripts/CVS/Entries12
-rw-r--r--rebuild-scripts/CVS/Repository1
-rw-r--r--rebuild-scripts/CVS/Root1
-rwxr-xr-xrebuild-scripts/add_owner28
-rwxr-xr-xrebuild-scripts/buildcheck58
-rw-r--r--rebuild-scripts/buildcheck-extras-development.repo12
-rwxr-xr-xrebuild-scripts/bumpspecfile.py116
-rwxr-xr-xrebuild-scripts/check_rebuild17
-rwxr-xr-xrebuild-scripts/check_rebuild220
-rwxr-xr-xrebuild-scripts/check_release12
-rwxr-xr-xrebuild-scripts/gen_nr_226
-rwxr-xr-xrebuild-scripts/gen_rebuild_lst26
-rwxr-xr-xrebuild-scripts/rm_noarch21
-rw-r--r--rebuild-scripts/semi_auto_rebuild.txt67
22 files changed, 828 insertions, 328 deletions
diff --git a/__init__.py b/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/__init__.py
diff --git a/devshell.py b/devshell.py
index 119692b..0518cc7 100755
--- a/devshell.py
+++ b/devshell.py
@@ -1,5 +1,4 @@
#!/usr/bin/python -tt
-# $Id: $
# Fedora Developer Shell
#
# This program is free software; you can redistribute it and/or modify
@@ -51,11 +50,6 @@ __description__ = 'A shell for hacking on the Fedora project'
FEDORA_DIR = join(expanduser('~'), 'code', 'fedora')
DEVSHELL_DIR = join(expanduser('~'), '.devshell')
-repos = {
- 'fedora_cvs' : ':ext:cvs.fedora.redhat.com:/cvs/pkgs',
- 'bodhi_hg' : 'http://hg.fedoraproject.org/hg/hosted/bodhi',
-}
-
stack = []
prompt = ['\033[34;1mfedora\033[0m']
modules = {}
@@ -63,275 +57,23 @@ header = lambda x: "%s %s %s" % ('=' * 2, x, '=' * (76 - len(x)))
log = logging.getLogger(__name__)
class Module:
- """ The parent class of all modules """
- def __init__(self):
- # setup stack and prompt
- pass
-
-class Mail(Module):
-
- url = 'https://www.redhat.com/archives/%s/%s'
-
- def search(self, mailinglist, text):
- """ <list> <text>. Search specific mailing list for given text """
- now = datetime.now()
- while True:
- fetch = True
- filename = now.strftime("%Y-%B") + '.txt.gz'
- try:
- f = urllib2.urlopen(self.url % (mailinglist, filename))
- except urllib2.HTTPError:
- break
- local = join(DEVSHELL_DIR, mailinglist, filename)
-
- # Don't fetch the mbox if we already have a good local copy
- if exists(local):
- info = os.stat(local)
- if info[stat.ST_SIZE] == int(f.headers.get('Content-Length')):
- fetch = False
- log.debug("Using local mbox: %s" % local)
- if fetch:
- if not exists(dirname(local)):
- os.makedirs(dirname(local))
- mbox = file(local, 'w')
- log.debug("Downloading %s" % local)
- mbox.write(f.read())
- mbox.close()
- f.close()
-
- self.__search_mbox(local, text)
-
- # Go back in time
- now = now - timedelta(days=31)
-
- def __search_mbox(self, mboxfile, text):
- """
- Search a compressed mbox for any specified keywords
- """
- num = 0
- statinfo = os.stat(mboxfile)
- gzmbox = gzip.open(mboxfile)
- mbox = UnixMailbox(gzmbox, email.message_from_file)
- while True:
- msg = mbox.next()
- if not msg: break
- num += 1
- fields = [msg['From'], msg['Subject']] + self.__body(msg)
- for field in fields:
- if re.search(text, field, re.IGNORECASE):
- id = "%s.%s" % (statinfo[stat.ST_INO], num)
- print "[%s] %s %s" % (id, msg['From'], msg['Subject'])
- break
- gzmbox.close()
-
- def __body(self, msg):
- """
- Recursively gather multipart message bodies
- """
- body = []
- if msg.is_multipart():
- for payload in msg.get_payload():
- for part in payload.walk():
- body += self.__body(part)
- else:
- body = [msg.get_payload()]
- return body
-
- def show(self, id):
- """ Show a message with a given ID """
- inode, msgnum = map(int, id.split('.'))
- olddir = os.getcwd()
- os.chdir(DEVSHELL_DIR)
- mboxfile = None
- for dir in filter(isdir, os.listdir('.')):
- for file in os.listdir(dir):
- statinfo = os.stat(join(dir, file))
- if statinfo[stat.ST_INO] == inode:
- mboxfile = join(dir, file)
- break
- if mboxfile: break
- if mboxfile:
- gzmbox = gzip.open(mboxfile)
- mbox = UnixMailbox(gzmbox, email.message_from_file)
- num = 0
- while num != msgnum:
- msg = mbox.next()
- num += 1
- self.__print_msg(msg)
- else:
- log.error("Cannot find message %s" % id)
- os.chdir(olddir)
-
- def __print_msg(self, msg):
- log.info("From: %s" % msg['From'])
- log.info("To: %s" % msg['To'])
- log.info("Subject: %s" % msg['Subject'])
- log.info('\n'.join(self.__body(msg)))
-
-
-class SCM:
- """
- Our generic SCM wrapper. Based on the name_scm of the repos dictionary key,
- we should be able to get our hands on any up-to-date code, and easily drop
- into any file, make modifications, and commit upstream.
- """
- def __init__(self, name, url):
- self.url = url
- self.name = name
- self.type = name.split('_')[-1]
- if self.type not in ('cvs', 'git', 'bzr', 'hg'):
- log.error("Unknown SCM '%s' for repo %s" % (self.type, name))
- return
-
- def co(self, module, branch=''):
- self.module = module
- self.branch = branch
- if os.path.isdir(os.path.join(FEDORA_DIR, module)):
- # from here, we have no idea what scm we're dealing with
- log.debug("%s module already checked out!" % module)
- return os.path.join(FEDORA_DIR, module, branch)
- path = os.getcwd()
- os.chdir(FEDORA_DIR)
- cmd = "%s checkout %s" % (self.type, module)
- status, output = commands.getstatusoutput(cmd)
- log.debug("Ran `%s`\nstatus = %s\noutput= %s" % (cmd, status, output))
- os.chdir(path)
- return status == 0
-
- def patches(self):
- path = os.getcwd()
- os.chdir(os.path.join(FEDORA_DIR, self.module, self.branch))
- i = 0
- for patch in glob('*.patch'):
- log.info(" [ %d ] %s" % (i, patch))
- i += 1
- os.chdir(path)
-
- def log(self, file=None):
- path = os.getcwd()
- os.chdir(os.path.join(FEDORA_DIR, self.module, self.branch))
- if not file:
- os.system("%s log | less" % self.type)
- else:
- os.system("%s log %s | less" % (self.type, file))
- os.chdir(path)
-
- def update(self):
- path = os.getcwd()
- os.chdir(FEDORA_DIR)
- cmd = "%s update" % self.type
- status, output = commands.getstatusoutput(cmd)
- os.chdir(path)
- return status == 0
-
-class Pkg(Module):
-
- def __init__(self, name, branch='devel', scm=None):
- """
- Open a given project
- """
- log.debug("Pkg(%s, %s, %s)" % (name, branch, scm))
- global stack, prompt
- self.name = name
- self.branch = branch
- self.scm = scm
- stack += [self]
- prompt += [name, branch]
- self.__find_scm()
-
- def __find_scm(self):
- global repos
- if self.scm:
- if repos.has_key(self.scm):
- self.scm = SCM(scm, repos[scm])
- else:
- log.debug("TODO: use specified SCM")
- else:
- # Try and find our corresponding SCM.. trial-and-error style.
- for scm in [SCM(repo, url) for repo, url in repos.items()]:
- log.debug("checking with SCM %s" % scm)
- if scm.co(self.name, self.branch):
- self.scm = scm
- log.debug("Found relevant scm: %s" % scm)
- break
- if not self.scm:
- log.error("Cannot find corresponding SCM for %s" % self.name)
-
- def spec(self):
- """
- View the RPM spec file for this project
- """
- editor = os.getenv('EDITOR', 'vim')
- os.system("%s %s/%s.spec" % (editor, os.path.join(FEDORA_DIR, self.name,
- self.branch), self.name))
-
- def patches(self):
- """
- List all patches applied against this package
- """
- self.scm.patches()
-
- def log(self, item=None):
- """
- Show the log
- """
- self.scm.log(item)
-
- def patch(self, num):
- self.scm.patch(num)
-
- def diff(self):
- raise NotImplementedError
-
- def prep(self):
- raise NotImplementedError
-
- def build(self):
- raise NotImplementedError
-
- def srpm(self):
- raise NotImplementedError
-
- def qa(self):
- raise NotImplementedError
-
- def bugs(self):
- raise NotImplementedError
-
-class Bugs(Module):
- """
- Interface for doing useful things with Bugs.
- TODO: add support for arbitrary bug trackers!
- python-bugzilla integration!
- """
- def view(self, data):
- """
- View a given bug number, or show all bugs for a given component
- Example: bugs view #1234, bugs view nethack
- """
- if data[0] == '#':
- os.system('firefox "https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=%s"' % data[1:])
- else:
- os.system('firefox "https://bugzilla.redhat.com/bugzilla/buglist.cgi?product=Fedora+Core&component=%s&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&bug_status=MODIFIED&short_desc_type=allwordssubstr&short_desc=&long_desc_type=allwordssubstr&long_desc="' % data)
-
- def search(self, text):
- """
- Search bugzilla for a given keyword
- """
- os.system('firefox "https://bugzilla.redhat.com/buglist.cgi?query_format=specific&order=bugs.bug_id&bug_status=__open__&product=&content=%s"' % text)
+ """ Our parent class for all command modules """
+ pass
def load_modules():
global modules
from inspect import isclass
log.debug("Loading modules")
- for key in globals().keys():
- module = globals()[key]
- if isclass(module):
- if issubclass(module, Module) and key != 'Module':
- # Cache reference to class, *not* an instance. We'll instantiate
- # modules on the fly when we need them
- log.debug(" * %s" % key)
- modules[key.lower()] = module
+ for f in os.listdir(os.path.abspath('modules')):
+ module_name, ext = os.path.splitext(f)
+ if ext == '.py':
+ exec "from modules import %s as module" % module_name
+ for item in dir(module):
+ obj = getattr(module, item)
+ if item[0] != '_' and isclass(obj):
+ modules[item.lower()] = obj
+ log.info(" * %s" % item)
+ del module
def print_docstrings(module=None):
"""
@@ -359,86 +101,127 @@ def shell():
except (EOFError, KeyboardInterrupt):
print
break
-
if not data: continue
if data in ('quit', 'exit'): break
keyword = data.split()[0]
- data = data.split()[1:]
-
+ args = data.split()[1:]
+
# Show the docstrings to all methods for all loaded modules
if keyword == 'help':
print_docstrings()
-
+
# Go up a module in our stack
- elif keyword == 'up':
+ elif keyword in ('up', 'cd..', 'cd ..'):
stack = stack[:-1]
prompt = prompt[:-1]
-
+
# Show the docstrings for all methods in our current module
- elif keyword in ('ls', 'help'):
+ elif keyword in ('ls', 'help', '?'):
if len(stack):
print_docstrings(stack[-1])
else:
print_docstrings()
-
+
# Flush our module stack
elif keyword == 'cd':
stack = []
prompt = ['\033[34;1mfedora\033[0m']
-
+
# iPython. Never leave home without it.
elif keyword in ('py', 'python'):
os.system("ipython -noconfirm_exit")
-
- # Do some intelligent handling of unknown input.
- # For the given input 'foo bar', we first check if we have the
- # module 'foo' loaded, then we push it on the top of our module
- # stack and check if it has the 'bar' attribute. If so, we call
- # it with any remaining arguments
else:
- args = []
- top = None
-
- # See if our keyword is a global module
- if keyword in modules.keys():
- log.debug("%s is a module!" % keyword)
- #top = modules[keyword]
- if len(data) and not hasattr(modules[keyword], data[0]):
- log.debug("Loading %s.__init__(%s)" % (keyword, data))
- top = modules[keyword](*data)
- #stack += [top]
- #prompt += [keyword] + data
- continue
- else:
- log.debug("Loading %s" % keyword)
- try:
- top = modules[keyword]()
- stack += [top]
- prompt += [keyword]
- except TypeError, e:
- log.error("%s.%s" % (keyword, e))
- continue
-
- # Try the top module on our stack
if len(stack):
- if hasattr(stack[-1], keyword):
- log.debug("Current module has %s" % keyword)
- top = getattr(stack[-1], keyword)
-
- # Iterate over the rest of our arguments, either going deeper
- # into the top module, or appending tokens to our args list.
- for value in data:
- if hasattr(top, value):
- log.debug("next property %s found in %s" % (value, top))
- top = getattr(top, value)
- elif top:
- log.debug("adding argument: %s" % value)
- args.append(value)
- if top:
- log.debug("calling %s with %s" % (top, args))
- top(*args)
+ top = stack[-1]
+ else:
+ top = None
+ output, top, params = do_command(data.split(), top)
+ stack += [top]
+ prompt += [top.__class__.__name__] + params
+
+class ModuleError(Exception):
+ def __init__(self, reason, error):
+ self.reason = reason
+ self.error = error
+
+def load_module(name, data=[]):
+# stack = []
+# prompt = []
+ top = None
+ try:
+ log.debug("Loading %s.__init__(%s)" % (name, data))
+ top = modules[name](*data)
+# stack += [top]
+# prompt += [name] + data
+ except TypeError, e:
+ log.debug('got type error')
+ log.error("%s: %s" % (name, e))
+ raise ModuleError('probably bad call to __init__' , e)
+ return top
+
+
+def do_command(data, top=None):
+
+ # Do some intelligent handling of unknown input.
+ # For the given input 'foo bar', we first check if we have the
+ # module 'foo' loaded, then we push it on the top of our module
+ # stack and check if it has the 'bar' attribute. If so, we call
+ # it with any remaining arguments
+ from collections import deque
+ data = deque(data)
+ log.debug(data)
+ params = []
+
+ module = None
+ while len(data):
+ if not top:
+ log.debug('not top')
+ mod = data.popleft()
+ try:
+ module = modules[mod]
+ except KeyError, e:
+ log.error('%s is not a known module' % e.message)
+ return None, None, None
+ log.debug('mod is %s' % mod)
+ params = []
+ while len(data):
+ log.debug('params so far %s' % params)
+ log.debug('inner loop %s' % data)
+ param = data.popleft()
+ if hasattr(module, param):
+ data.appendleft(param)
+ break
+ params += [param]
+ try:
+ top = module = load_module(mod, params)
+ mod_params = params
+ loaded_module = True
+ except ModuleError, e:
+ log.debug(e.reason)
+ break
+ else:
+ log.debug('is top')
+ params = []
+ log.debug('params so far %s' % params)
+ param = data.popleft()
+ if hasattr(top, param):
+ log.debug("next property %s found in %s" % (param, top))
+ top = getattr(top, param)
+ else:
+ log.debug("adding argument: %s" % param)
+ params += [param]
+ output = None
+ if len(params):
+ output = top(*params)
+
+ if module:
+ return output, module, mod_params
+ else:
+ return output, None, None
+
def main():
+ global log
from optparse import OptionParser
parser = OptionParser(usage="%prog [options]",
version="%s %s" % ('%prog', __version__),
@@ -466,7 +249,6 @@ def main():
load_modules()
shell()
-
-
+
if __name__ == '__main__':
- main()
+ main() \ No newline at end of file
diff --git a/modules/__init__.py b/modules/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/modules/__init__.py
diff --git a/modules/audit.py b/modules/audit.py
new file mode 100644
index 0000000..5e89f53
--- /dev/null
+++ b/modules/audit.py
@@ -0,0 +1,9 @@
+
+
+class Audit:
+ """ Perform various code audits on a specified Pkg """
+
+ tools = ['flawfinder', 'rats']
+
+ def __init__(self, pkg):
+ """ @param pkg: a Pkg instance """
diff --git a/modules/bugs.py b/modules/bugs.py
new file mode 100644
index 0000000..359a06e
--- /dev/null
+++ b/modules/bugs.py
@@ -0,0 +1,24 @@
+import os
+
+class Bugs:
+ """
+ Interface for doing useful things with Bugs.
+ TODO: add support for arbitrary bug trackers!
+ python-bugzilla integration!
+ """
+ def view(self, data):
+ """
+ View a given bug number, or show all bugs for a given component
+ Example: bugs view #1234, bugs view nethack
+ """
+ if data[0] == '#':
+ os.system('firefox "https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=%s"' % data[1:])
+ else:
+ os.system('firefox "https://bugzilla.redhat.com/bugzilla/buglist.cgi?product=Fedora+Core&component=%s&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&bug_status=MODIFIED&short_desc_type=allwordssubstr&short_desc=&long_desc_type=allwordssubstr&long_desc="' % data)
+
+ def search(self, text):
+ """
+ Search bugzilla for a given keyword
+ """
+ os.system('firefox "https://bugzilla.redhat.com/buglist.cgi?query_format=specific&order=bugs.bug_id&bug_status=__open__&product=&content=%s"' % text)
+
diff --git a/modules/mail.py b/modules/mail.py
new file mode 100644
index 0000000..790845d
--- /dev/null
+++ b/modules/mail.py
@@ -0,0 +1,116 @@
+import re
+import os
+import gzip
+import stat
+import email
+import urllib2
+import logging
+
+from os.path import join, exists, dirname, isdir
+from mailbox import UnixMailbox
+from datetime import datetime, timedelta
+
+from devshell import DEVSHELL_DIR
+
+log = logging.getLogger(__name__)
+
+class Mail:
+ """ A module for searching/viewing mailing lists """
+
+ url = 'https://www.redhat.com/archives/%s/%s'
+
+ def search(self, mailinglist, text):
+ """ <list> <text>. Search specific mailing list for given text """
+ now = datetime.now()
+ while True:
+ fetch = True
+ filename = now.strftime("%Y-%B") + '.txt.gz'
+ try:
+ f = urllib2.urlopen(self.url % (mailinglist, filename))
+ except urllib2.HTTPError:
+ break
+ local = join(DEVSHELL_DIR, mailinglist, filename)
+
+ # Don't fetch the mbox if we already have a good local copy
+ if exists(local):
+ info = os.stat(local)
+ if info[stat.ST_SIZE] == int(f.headers.get('Content-Length')):
+ fetch = False
+ log.debug("Using local mbox: %s" % local)
+ if fetch:
+ if not exists(dirname(local)):
+ os.makedirs(dirname(local))
+ mbox = file(local, 'w')
+ log.debug("Downloading %s" % local)
+ mbox.write(f.read())
+ mbox.close()
+ f.close()
+
+ self.__search_mbox(local, text)
+
+ # Go back in time
+ now = now - timedelta(days=31)
+
+ def __search_mbox(self, mboxfile, text):
+ """
+ Search a compressed mbox for any specified keywords
+ """
+ num = 0
+ statinfo = os.stat(mboxfile)
+ gzmbox = gzip.open(mboxfile)
+ mbox = UnixMailbox(gzmbox, email.message_from_file)
+ while True:
+ msg = mbox.next()
+ if not msg: break
+ num += 1
+ fields = [msg['From'], msg['Subject']] + self.__body(msg)
+ for field in fields:
+ if re.search(text, field, re.IGNORECASE):
+ id = "%s.%s" % (statinfo[stat.ST_INO], num)
+ print "[%s] %s %s" % (id, msg['From'], msg['Subject'])
+ break
+ gzmbox.close()
+
+ def __body(self, msg):
+ """
+ Recursively gather multipart message bodies
+ """
+ body = []
+ if msg.is_multipart():
+ for payload in msg.get_payload():
+ for part in payload.walk():
+ body += self.__body(part)
+ else:
+ body = [msg.get_payload()]
+ return body
+
+ def show(self, id):
+ """ Show a message with a given ID """
+ inode, msgnum = map(int, id.split('.'))
+ olddir = os.getcwd()
+ os.chdir(DEVSHELL_DIR)
+ mboxfile = None
+ for dir in filter(isdir, os.listdir('.')):
+ for file in os.listdir(dir):
+ statinfo = os.stat(join(dir, file))
+ if statinfo[stat.ST_INO] == inode:
+ mboxfile = join(dir, file)
+ break
+ if mboxfile: break
+ if mboxfile:
+ gzmbox = gzip.open(mboxfile)
+ mbox = UnixMailbox(gzmbox, email.message_from_file)
+ num = 0
+ while num != msgnum:
+ msg = mbox.next()
+ num += 1
+ self.__print_msg(msg)
+ else:
+ log.error("Cannot find message %s" % id)
+ os.chdir(olddir)
+
+ def __print_msg(self, msg):
+ log.info("From: %s" % msg['From'])
+ log.info("To: %s" % msg['To'])
+ log.info("Subject: %s" % msg['Subject'])
+ log.info('\n'.join(self.__body(msg)))
diff --git a/modules/pkg.py b/modules/pkg.py
new file mode 100644
index 0000000..a748b92
--- /dev/null
+++ b/modules/pkg.py
@@ -0,0 +1,132 @@
+import os
+import commands
+
+from os.path import isdir, join
+from devshell import FEDORA_DIR
+
+
+# Hack-filled at the moment.
+
+UPDATE, CLONE, COMMIT, LOG, DIFF = range(5)
+scm_cmds = {
+ 'git' : ('update', 'clone', 'log', 'diff'),
+ 'hg' : ('update', 'clone', 'log', 'diff'),
+ 'cvs' : ('update', 'checkout', 'log', 'diff'),
+}
+scms = {
+ 'cvs.fedoraproject.org' : 'cvs -d :ext:cvs.fedoraproject.org:/cvs/pkgs %(command)s %(module)s',
+ 'git.fedorahosted.org' : 'git %(command)s ssh+git://git.fedorahosted.org/git/%(module)s',
+ 'hg.fedorahosted.org' : 'hg %(command)s ssh://hg.fedorahosted.org//hg/%(module)s',
+}
+
+
+class CannotFindPackage(Exception):
+ pass
+
+#FIXME: use this?
+class SCM:
+ cmds = dict(update='update', clone='clone', log='log', diff='diff')
+
+class Package(object):
+
+ def __init__(self, name, branch='devel'):
+ self.name = name
+ self.branch = branch
+ self.scm = None
+ self.__path = None
+ self.__checkout()
+
+ def __set_path(self, p):
+ """ Set our path and make it our current working directory """
+ if isdir(join(p, self.branch)):
+ p = join(p, self.branch)
+ print p
+ self.__path = p
+ os.chdir(p)
+
+ def __get_path(self):
+ return self.__path
+
+ path = property(__get_path, __set_path)
+
+ def __checkout(self):
+ """ Find where this package lives """
+
+ # Look in FEDORA_DIR/<scm>/<pkg>
+ for scm in scms.keys():
+ scmdir = join(FEDORA_DIR, scm, self.name)
+ if isdir(scmdir):
+ self.scm = scm
+ self.path = scmdir
+ return
+
+ # Find this module in our scms
+ for scm in scms.keys():
+ scmdir = join(FEDORA_DIR, scm)
+ if not isdir(scmdir):
+ print "Creating %s" % scmdir
+ os.mkdir(scmdir)
+ os.chdir(scmdir)
+ cmd = scms[scm] % {
+ 'command' : scm_cmds[scm.split('.')[0]][CLONE],
+ 'module' : self.name
+ }
+ print "Running %s" % cmd
+ status, output = commands.getstatusoutput(cmd)
+ if status == 0:
+ self.scm = scm
+ self.path = join(scmdir, self.name)
+ return
+
+ raise CannotFindPackage
+
+ def spec(self):
+ """ View the RPM spec file for this project """
+ editor = os.getenv('EDITOR', 'vi')
+ os.system("%s %s.spec" % (editor, self.name))
+
+ def sh(self):
+ """ Drop into a shell """
+ os.system("bash")
+
+ def update(self):
+ self.scm.update()
+ cmd = scms[self.scm] % {
+ 'command' : scm_cmds[self.scm.split('.')[0]][UPDATE],
+ 'module' : ''
+ }
+ print "Executing `%s`" % cmd
+ status, output = commands.getstatusoutput(cmd)
+ print output
+
+ def log(self, item=''):
+ """ Show the history of this package """
+ cmd = scms[self.scm] % {
+ 'command' : scm_cmds[self.scm.split('.')[0]][LOG],
+ 'module' : item
+ }
+ print "Executing `%s | less`" % cmd
+ os.system("%s | less" % cmd)
+
+ def diff(self, item=''):
+ cmd = scms[self.scm] % {
+ 'command' : scm_cmds[self.scm.split('.')[0]][DIFF],
+ 'module' : item
+ }
+ print "Executing `%s | colordiff | less -R`" % cmd
+ os.system("%s | colordiff | less -R" % cmd)
+
+ def build(self):
+ raise NotImplementedError
+
+ def srpm(self):
+ raise NotImplementedError
+
+ def qa(self):
+ raise NotImplementedError
+
+ def audit(self):
+ raise NotImplementedError
+
+ def bugs(self):
+ raise NotImplementedError
diff --git a/ports.py b/ports.py
new file mode 100755
index 0000000..d4d5005
--- /dev/null
+++ b/ports.py
@@ -0,0 +1,20 @@
+#!/usr/bin/python -tt
+# Fedora Developer Shell
+#
+# 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; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Library General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# Authors: Yaakov M. Nemoy <ynemoy@redhat.com>
+#
+
+
diff --git a/rebuild-scripts/CVS/Entries b/rebuild-scripts/CVS/Entries
new file mode 100644
index 0000000..d2d53df
--- /dev/null
+++ b/rebuild-scripts/CVS/Entries
@@ -0,0 +1,12 @@
+/add_owner/1.1.1.1/Fri Oct 6 22:22:02 2006//
+/buildcheck/1.1.1.1/Fri Oct 6 22:22:02 2006//
+/buildcheck-extras-development.repo/1.1.1.1/Fri Oct 6 22:22:02 2006//
+/bumpspecfile.py/1.1.1.1/Fri Oct 6 22:22:02 2006//
+/check_rebuild/1.1.1.1/Fri Oct 6 22:22:02 2006//
+/check_rebuild2/1.1.1.1/Fri Oct 6 22:22:02 2006//
+/check_release/1.1.1.1/Fri Oct 6 22:22:02 2006//
+/gen_nr_2/1.1.1.1/Fri Oct 6 22:22:02 2006//
+/gen_rebuild_lst/1.1.1.1/Fri Oct 6 22:22:02 2006//
+/rm_noarch/1.1.1.1/Fri Oct 6 22:22:02 2006//
+/semi_auto_rebuild.txt/1.1.1.1/Fri Oct 6 22:22:02 2006//
+D
diff --git a/rebuild-scripts/CVS/Repository b/rebuild-scripts/CVS/Repository
new file mode 100644
index 0000000..2014fa1
--- /dev/null
+++ b/rebuild-scripts/CVS/Repository
@@ -0,0 +1 @@
+rebuild-scripts
diff --git a/rebuild-scripts/CVS/Root b/rebuild-scripts/CVS/Root
new file mode 100644
index 0000000..7c4b192
--- /dev/null
+++ b/rebuild-scripts/CVS/Root
@@ -0,0 +1 @@
+:ext:cvs.fedora.redhat.com:/cvs/fedora
diff --git a/rebuild-scripts/add_owner b/rebuild-scripts/add_owner
new file mode 100755
index 0000000..e419d42
--- /dev/null
+++ b/rebuild-scripts/add_owner
@@ -0,0 +1,28 @@
+#!/usr/bin/env perl
+# $Id: add_owner,v 1.1.1.1 2006/10/06 22:22:02 c4chris Exp $
+use strict;
+local *IN;
+my %OWN;
+open IN, "/home/chris/src/isrec/fedora/owners/owners.list"
+ or die "Couldn't open owners.list: $!";
+while ( <IN> ) {
+ next if /^#/;
+ s/\s+$//;
+ my @F = split /\|/;
+ next if $F[1] eq "";
+ $OWN{$F[1]} = \@F;
+}
+close IN;
+while ( <> ) {
+ s/\s+$//;
+ my @F = split;
+ my $name = $F[5];
+ my $e = $OWN{$name};
+ if (defined $e) {
+ push @F, $$e[3];
+ } else {
+ push @F, "Unknown";
+ }
+ print join(" ", @F), "\n";
+}
+exit 0;
diff --git a/rebuild-scripts/buildcheck b/rebuild-scripts/buildcheck
new file mode 100755
index 0000000..be2bba4
--- /dev/null
+++ b/rebuild-scripts/buildcheck
@@ -0,0 +1,58 @@
+#!/bin/bash
+
+# if this one is rebuild again it will confuse the script:
+PACKAGESUPTO=recode
+byebye()
+{
+ [[ -e "${TMPDIR}" ]] && rm -f "${TMPDIR}/owners.list" "${TMPDIR}/repoquery" "${TMPDIR}/repoquery-noarch" "${TMPDIR}/result"
+ [[ -e "${TMPDIR}" ]] && rmdir "${TMPDIR}"
+ local return=${1}
+ shift
+ [[ "${1}" ]] && echo $@
+ exit ${return}
+}
+
+
+
+if ! TMPDIR="$(mktemp -d)"
+then
+ byebye 1 Could not create TMPDIR
+fi
+echo "TMPDIR is $TMPDIR"
+
+if ! wget --quiet -O ${TMPDIR}/owners.list http://cvs.fedora.redhat.com/viewcvs/*checkout*/owners/owners.list?root=extras
+then
+ byebye 2 Failed to get owners.list
+fi
+
+if ! repoquery -a --repoid=buildcheck-extras-development-sources --repoid=buildcheck-extras-development-buildsys --qf='%{buildtime} %{name} %{version}-%{release}' *.src | sort | grep -B 9999 ${PACKAGESUPTO} | head -n -1 > ${TMPDIR}/repoquery
+then
+ byebye 3 Repoquery failed
+fi
+
+if ! repoquery -a --repoid=buildcheck-extras-development-x86 --repoid=buildcheck-extras-development-x64 --repoid=buildcheck-extras-development-ppc --repoid=buildcheck-extras-development-buildsys --qf='%{buildtime} %{name} %{arch} %{version}-%{release}' | sort | grep ' noarch ' | awk '{print $2}' > ${TMPDIR}/repoquery-noarch
+then
+ byebye 3 Repoquery failed
+fi
+
+
+
+while read buildtime name verrel
+do
+ if ownerstring="$(grep \|${name}\| ${TMPDIR}/owners.list)"
+ then
+ echo "${ownerstring}" | while IFS='|' read ignoredone ignoredtwo ignoredthree emailone emailtwo emailthree emailfour alsoignored
+ do
+ echo ${emailone} ${name} ${verrel} | sed 's|@|_AT_|' >> ${TMPDIR}/result
+ done
+ else
+ echo No owner found for "${name}" >&2
+ fi
+done < ${TMPDIR}/repoquery
+
+sort < ${TMPDIR}/result | uniq | column -t > extras-tobuild
+sort < ${TMPDIR}/result | uniq | column -t | grep -f ${TMPDIR}/repoquery-noarch > extras-tobuild-noarch
+sort < ${TMPDIR}/result | uniq | column -t | grep -v -f ${TMPDIR}/repoquery-noarch > extras-tobuild-arch
+
+
+byebye 0
diff --git a/rebuild-scripts/buildcheck-extras-development.repo b/rebuild-scripts/buildcheck-extras-development.repo
new file mode 100644
index 0000000..0e6ffc6
--- /dev/null
+++ b/rebuild-scripts/buildcheck-extras-development.repo
@@ -0,0 +1,12 @@
+[buildcheck-extras-development-source]
+name=Fedora Extras - Development - Source
+baseurl=http://fedoraproject.org/extras/development/SRPMS/
+enabled=0
+gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-fedora-extras
+gpgcheck=1
+
+[buildcheck-extras-buildsys-source]
+name=Fedora Extras - Development - Source
+baseurl=http://buildsys.fedoraproject.org/plague-results/fedora-development-extras/
+enabled=0
+gpgcheck=1
diff --git a/rebuild-scripts/bumpspecfile.py b/rebuild-scripts/bumpspecfile.py
new file mode 100755
index 0000000..9054266
--- /dev/null
+++ b/rebuild-scripts/bumpspecfile.py
@@ -0,0 +1,116 @@
+#!/usr/bin/python -t
+# -*- mode: Python; indent-tabs-mode: nil; -*-
+
+import fcntl
+import os, sys
+import rpmUtils
+import shutil
+import string
+import re
+import time
+
+EXIT_ON_WARN = False
+
+class SpecFile:
+ def __init__(self,filename):
+ self.filename = filename
+ file=open(filename,"r")
+ self.lines=file.readlines()
+ file.close()
+
+ def bumpRelease(self):
+ bump_patterns=[(re.compile(r"^Release:(\s*)(\d+.*)",re.I), self.increase),
+ (re.compile(r"^%define\s+rel\s+(\d+.*)"), self.increase2),
+ (re.compile(r"^%define\s+release\s+(\d+.*)"), self.increase3),
+ (re.compile(r"^%define\s+RELEASE\s+(\d+.*)"), self.increase4),
+ (re.compile(r"^Release:\s+%release_func\s+(\d+.*)"), self.increase5)
+ ]
+ skip_pattern=re.compile(r"\$Revision:")
+ for i in range(len(self.lines)):
+ if skip_pattern.search(self.lines[i]): continue
+ for bumpit, bumpit_func in bump_patterns:
+ self.lines[i]=bumpit.sub(bumpit_func,self.lines[i])
+
+ def addChangelogEntry(self,entry,email):
+ versionre=re.compile(r"^Version:\s*(\S+)")
+ changematch=re.compile(r"^%changelog")
+ date=time.strftime("%a %b %d %Y", time.localtime(time.time()))
+ for i in range(len(self.lines)):
+ versionmatch=versionre.search(self.lines[i])
+ if(versionmatch):
+ version=versionmatch.group(1)
+ if(changematch.match(self.lines[i])):
+ newchangelogentry="%changelog\n* "+date+" "+email+" "+version+"-"+self.newrelease+"\n"+entry+"\n\n"
+ self.lines[i]=newchangelogentry
+ break
+
+ def increaseMain(self,release):
+ relre = re.compile(r'(?P<pre>0\.)?(?P<rel>\d+)(?P<post>.*)',re.I)
+ relmatch = relre.search(release)
+
+ pre = relmatch.group('pre')
+ value = int(relmatch.group('rel'))
+ self.newrelease = `value+1`
+ post = relmatch.group('post')
+
+ old = ''
+ if pre != None:
+ old += pre
+ old += relmatch.group('rel')+post
+
+ if pre == None:
+ if post.find('rc')>=0:
+ print 'CRUCIAL WARNING: Bad pre-release versioning scheme!'
+ print self.filename
+ if EXIT_ON_WARN:
+ sys.exit(1)
+ new = `value+1`+post
+ if True or post != '%{?dist}' and len(post):
+ self.debugdiff(old,new)
+ else:
+ if value == None or value > 10000:
+ print 'CRUCIAL WARNING: Bad pre-release versioning scheme!'
+ print self.filename
+ if EXIT_ON_WARN:
+ sys.exit(1)
+ new = '0.'+`value+1`+post
+ self.debugdiff(old,new)
+ return new
+
+ def increase(self,match):
+ return 'Release:' + match.group(1) + self.increaseMain(match.group(2))
+
+ def increase2(self,match):
+ return '%define rel ' + self.increaseMain(match.group(1))
+
+ def increase3(self,match):
+ return '%define release ' + self.increaseMain(match.group(1))
+
+ def increase4(self,match):
+ return '%define RELEASE ' + self.increaseMain(match.group(1))
+
+ def increase5(self,match):
+ return 'Release: %release_func ' + self.increaseMain(match.group(1))
+
+ def writeFile(self,filename):
+ file=open(filename,"w")
+ file.writelines(self.lines)
+ file.close()
+
+ def debugdiff(self,old,new):
+ print '-%s' % old
+ print '+%s\n' % new
+
+if __name__=="__main__":
+ if len(sys.argv) < 2:
+ print 'SYNTAX: %s <specfile> [specfile]...' % sys.argv[0]
+ sys.exit(22)
+
+ userstring = "You <Your.Address@your.domain>"
+ for aspec in sys.argv[1:]:
+ s=SpecFile(aspec)
+ s.bumpRelease()
+ s.addChangelogEntry(" - rebuilt for unwind info generation, broken in gcc-4.1.1-21", userstring)
+ s.writeFile(aspec)
+
+sys.exit(0)
diff --git a/rebuild-scripts/check_rebuild b/rebuild-scripts/check_rebuild
new file mode 100755
index 0000000..863bbf3
--- /dev/null
+++ b/rebuild-scripts/check_rebuild
@@ -0,0 +1,17 @@
+#!/usr/bin/env perl
+# $Id: check_rebuild,v 1.1.1.1 2006/10/06 22:22:02 c4chris Exp $
+use strict;
+my %B;
+my $base_time = 1156678565;
+while ( <> ) {
+ my @F = split;
+ my $name = $F[1];
+ $name =~ s/-[^-]+-[^-]+\.src\.rpm$//;
+ if ($F[0] >= $base_time) {
+ $B{$name} = 1;
+ next;
+ }
+ next if defined $B{$name};
+ print;
+}
+exit 0;
diff --git a/rebuild-scripts/check_rebuild2 b/rebuild-scripts/check_rebuild2
new file mode 100755
index 0000000..c71c25a
--- /dev/null
+++ b/rebuild-scripts/check_rebuild2
@@ -0,0 +1,20 @@
+#!/usr/bin/env perl
+# $Id: check_rebuild2,v 1.1.1.1 2006/10/06 22:22:02 c4chris Exp $
+use strict;
+my %B;
+my $cur = <>;
+while ( $cur ) {
+ my @F = split /\s+/, $cur;
+ last if $F[1] eq "Sep" and $F[2] == 26;
+ $B{$F[5]} = 1;
+ $cur = <>;
+}
+while ( $cur ) {
+ my @F = split /\s+/, $cur;
+ last if $F[1] eq "Sep" and $F[2] == 17;
+ unless (defined $B{$F[5]}) {
+ print $cur;
+ }
+ $cur = <>;
+}
+exit 0;
diff --git a/rebuild-scripts/check_release b/rebuild-scripts/check_release
new file mode 100755
index 0000000..74b9999
--- /dev/null
+++ b/rebuild-scripts/check_release
@@ -0,0 +1,12 @@
+#!/usr/bin/env perl
+# $Id: check_release,v 1.1.1.1 2006/10/06 22:22:02 c4chris Exp $
+use strict;
+while ( <> ) {
+ s/\s+$//;
+ my @F = split;
+ my ($r) = $F[6] =~ /-([^-]+)$/;
+ $r =~ s/\.fc6//;
+ next if $r =~ /^\d+$/;
+ print "$_\n";
+}
+exit 0;
diff --git a/rebuild-scripts/gen_nr_2 b/rebuild-scripts/gen_nr_2
new file mode 100755
index 0000000..343b968
--- /dev/null
+++ b/rebuild-scripts/gen_nr_2
@@ -0,0 +1,26 @@
+#!/usr/bin/env perl
+# $Id: gen_nr_2,v 1.1.1.1 2006/10/06 22:22:02 c4chris Exp $
+use strict;
+local *IN;
+my %OWN;
+open IN, "/home/chris/src/isrec/fedora/owners/owners.list"
+ or die "Couldn't open owners.list: $!";
+while ( <IN> ) {
+ next if /^#/;
+ s/\s+$//;
+ my @F = split /\|/;
+ next if $F[1] eq "";
+ $OWN{$F[1]} = \@F;
+}
+close IN;
+while ( <> ) {
+ my @F = split;
+ my $name = $F[0];
+ my $e = $OWN{$name};
+ my $o = "UNKNOWN";
+ if (defined $e) {
+ $o = $$e[3];
+ }
+ print "$o ", join(" ", @F), "\n";
+}
+exit 0;
diff --git a/rebuild-scripts/gen_rebuild_lst b/rebuild-scripts/gen_rebuild_lst
new file mode 100755
index 0000000..c3fab75
--- /dev/null
+++ b/rebuild-scripts/gen_rebuild_lst
@@ -0,0 +1,26 @@
+#!/usr/bin/env perl
+# $Id: gen_rebuild_lst,v 1.1.1.1 2006/10/06 22:22:02 c4chris Exp $
+use strict;
+local *IN;
+my %OWN;
+open IN, "/home/chris/src/isrec/fedora/owners/owners.list"
+ or die "Couldn't open owners.list: $!";
+while ( <IN> ) {
+ next if /^#/;
+ s/\s+$//;
+ my @F = split /\|/;
+ next if $F[1] eq "";
+ $OWN{$F[1]} = \@F;
+}
+close IN;
+while ( <> ) {
+ my @F = split;
+ my $name = $F[1];
+ my $e = $OWN{$name};
+ if (defined $e) {
+ print "$$e[3]|$name\n";
+ next;
+ }
+ print STDERR "No owner for $name\n";
+}
+exit 0;
diff --git a/rebuild-scripts/rm_noarch b/rebuild-scripts/rm_noarch
new file mode 100755
index 0000000..317c6fe
--- /dev/null
+++ b/rebuild-scripts/rm_noarch
@@ -0,0 +1,21 @@
+#!/usr/bin/env perl
+# $Id: rm_noarch,v 1.1.1.1 2006/10/06 22:22:02 c4chris Exp $
+use strict;
+my %B;
+local *IN;
+open IN, "pkg_noarch.txt" or die "Couldn't open pkg_noarch.txt: $!";
+while ( <IN> ) {
+ chop;
+ my @F = split;
+ my $name = $F[4];
+ $name =~ s/-[^-]+-[^-]+\.src\.rpm$//;
+ $B{$name} = 1;
+}
+close IN;
+while ( <> ) {
+ my @F = split;
+ my $name = $F[5];
+ next if defined $B{$name};
+ print;
+}
+exit 0;
diff --git a/rebuild-scripts/semi_auto_rebuild.txt b/rebuild-scripts/semi_auto_rebuild.txt
new file mode 100644
index 0000000..e258cb8
--- /dev/null
+++ b/rebuild-scripts/semi_auto_rebuild.txt
@@ -0,0 +1,67 @@
+# Log of things done for the last semi-mass rebuild
+# $Id: semi_auto_rebuild.txt,v 1.1.1.1 2006/10/06 22:22:02 c4chris Exp $
+
+
+# Grab list of noarch packages
+repoquery -a --repoid=extras-development \
+ --qf='%{buildtime} %{name} %{arch} %{version}-%{release} %{sourcerpm}' \
+ | sort | grep ' noarch ' > pkg_noarch.txt
+
+# Grab list of source packages in the repo, with their build time
+repoquery -a --repoid=buildcheck-extras-development-source \
+ --qf='%{buildtime} %{name} %{version}-%{release}' \*.src \
+ | sort -nr > lst.txt
+
+# Turn the time in a readable form
+perl -ane '$F[0] = localtime($F[0]); print join(" ", @F), "\n"' \
+ lst.txt > lst2.txt
+
+# Apply script to determine which ones need a rebuild
+./check_rebuild2 lst2.txt > lst3.txt
+
+# Remove the noarch packages from the list
+./rm_noarch lst3.txt >lst4.txt
+
+# Produce a list of package names to include in a mail
+perl -ane 'print "$F[5]\n"' lst4.txt|sort >~/to_rebuild.txt
+
+# Add package owner email field in the list of packages to rebuild
+./add_owner lst4.txt >lst5.txt
+
+# Edit list to hand-remove packages that other people said they'd handle
+# themselves
+vi lst5.txt
+
+# Mark out packages that do not have a simple numeric release field
+./check_release lst5.txt > lst_noauto.txt
+
+# Extract the list of simple packages
+diff lst5.txt lst_noauto.txt |grep '^<'|sed 's/^..//' >lst_auto.txt
+
+# Make sure we have the latest version of all packages in our CVS checkout
+pushd /export/scratch/extras/
+cvs update
+popd
+
+# Do the automated mass rebuild for the simple packages
+for f in `awk '{print $6}' lst_auto.txt`; do
+ echo $f
+ ./bumpspecfile.py /export/scratch/extras/$f/devel/$f.spec
+ pushd /export/scratch/extras/$f/devel
+ cvs commit -m 'automated bump and rebuild' && make tag && make build
+ popd
+done
+
+# Now do the rest of the packages (repeat for each package...)
+ for f in `head -1 lst_noauto.txt | awk '{print $6}'`; do
+ echo $f
+ ./bumpspecfile.py /export/scratch/extras/$f/devel/$f.spec
+ pushd /export/scratch/extras/$f/devel
+ cvs diff
+ done
+ vi <package>.spec
+ cvs diff
+ cvs commit -m 'automated bump and rebuild' && make tag && make build
+ popd
+ vi lst_noauto.txt # To remove the first line
+# Done...