summaryrefslogtreecommitdiffstats
path: root/modules
diff options
context:
space:
mode:
authorYaakov Nemoy <loupgaroublond@gmail.com>2008-09-28 10:29:00 -0400
committerYaakov M. Nemoy <loupgaroublond@gmail.com>2008-09-28 10:29:00 -0400
commitd491ac3a2199cb1f3cdcd4f2f6b3d877b3a65a65 (patch)
tree9940bed9d7c8edd1d416659f23b5c56c929ef8c9 /modules
parent40119a669a625b839503d91aa5d40e112f7e46e2 (diff)
downloadfedora-devshell-d491ac3a2199cb1f3cdcd4f2f6b3d877b3a65a65.tar.gz
fedora-devshell-d491ac3a2199cb1f3cdcd4f2f6b3d877b3a65a65.tar.xz
fedora-devshell-d491ac3a2199cb1f3cdcd4f2f6b3d877b3a65a65.zip
Make the shell functions a bit more modular for scripting
Diffstat (limited to 'modules')
-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
5 files changed, 281 insertions, 0 deletions
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