summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjkeating@localhost.localdomain <jkeating@localhost.localdomain>2009-08-04 15:57:16 -0700
committerjkeating@localhost.localdomain <jkeating@localhost.localdomain>2009-08-04 15:57:16 -0700
commitf1b8a0aae2ee64069a208b388b1478c6948775af (patch)
treeaec41a22e4bbf75e4c915acf34c386b565ab81fd
parentb7acb66a65c58ef0e50288e233e3bf2cf1b9a4b5 (diff)
downloadfedora-packager-f1b8a0aae2ee64069a208b388b1478c6948775af.tar.gz
fedora-packager-f1b8a0aae2ee64069a208b388b1478c6948775af.tar.xz
fedora-packager-f1b8a0aae2ee64069a208b388b1478c6948775af.zip
Add fedora-hosted
fedora-hosted is a command line tool to ineract with Fedora Hosted's Trac server via xmlrpc. It requires the offtrac python library as indicated in the spec file.
-rw-r--r--ChangeLog2
-rw-r--r--Makefile.am9
-rw-r--r--NEWS3
-rw-r--r--configure.ac2
-rw-r--r--fedora-packager.spec7
-rwxr-xr-xsrc/fedora-hosted242
6 files changed, 261 insertions, 4 deletions
diff --git a/ChangeLog b/ChangeLog
index 1ad9626..7dc8386 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,5 @@
+* Jesse Keating <jkeating@redhat.com> - 0.3.8
+- add fedora-hosted
* Dennis Gilmore <dennis@ausil.us> - 0.3.7
- make sure user_cert is defined before refrencing it in fedora-cvs.py
* Dennis Gilmore <dennis@ausil.us> - 0.3.6
diff --git a/Makefile.am b/Makefile.am
index f694402..2f4ffdf 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,6 +1,6 @@
-bin_SCRIPTS = fedora-cvs fedora-packager-setup fedoradev-pkgowners fedora-cert fedora-getsvn rpmbuild-md5
+bin_SCRIPTS = fedora-cvs fedora-packager-setup fedoradev-pkgowners fedora-cert fedora-getsvn fedora-hosted rpmbuild-md5
CLEANFILES = $(bin_SCRIPTS)
-EXTRA_DIST = src/fedora-cvs.py src/fedora-packager-setup.py src/fedoradev-pkgowners src/fedora-cert.py src/fedora-getsvn src/rpmbuild-md5
+EXTRA_DIST = src/fedora-cvs.py src/fedora-packager-setup.py src/fedoradev-pkgowners src/fedora-cert.py src/fedora-getsvn fedora-hosted src/rpmbuild-md5
fedora-cvs: $(srcdir)/src/fedora-cvs.py
rm -f fedora-cvs
@@ -27,6 +27,11 @@ fedora-getsvn: $(srcdir)/src/fedora-getsvn
cp -p $(srcdir)/src/fedora-getsvn fedora-getsvn
chmod ugo+x fedora-getsvn
+fedora-hosted: $(srcdir)/src/fedora-hosted
+ rm -f fedora-hosted
+ cp -p $(srcdir)/src/fedora-getsvn fedora-hosted
+ chmod ugo+x fedora-hosted
+
rpmbuild-md5: $(srcdir)/src/rpmbuild-md5
rm -f rpmbuild-md5
cp -p $(srcdir)/src/rpmbuild-md5 rpmbuild-md5
diff --git a/NEWS b/NEWS
index 6dd9604..916363d 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,6 @@
+Aug 04 2009
+add fedora-hosted, a cli interface to our Trac setup
+
Jul 13 2009
add rpmbuild-md5 it creates rpms with old style hashes
diff --git a/configure.ac b/configure.ac
index c4fcc49..918c051 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,4 +1,4 @@
-AC_INIT([fedora-packager], [0.3.7])
+AC_INIT([fedora-packager], [0.3.8])
AM_INIT_AUTOMAKE([dist-bzip2 no-dist-gzip])
AC_PATH_PROGS(PYTHON, python)
AC_PATH_PROGS(BASH, sh bash)
diff --git a/fedora-packager.spec b/fedora-packager.spec
index 4f14fae..f1007c4 100644
--- a/fedora-packager.spec
+++ b/fedora-packager.spec
@@ -1,5 +1,5 @@
Name: fedora-packager
-Version: 0.3.7
+Version: 0.3.8
Release: 1%{?dist}
Summary: Tools for setting up a fedora maintainer environment
@@ -14,6 +14,7 @@ Requires: rpm-build rpmdevtools rpmlint
Requires: mock cvs curl wget
Requires: pyOpenSSL python-pycurl
Requires: redhat-rpm-config
+Requires: offtrac
BuildArch: noarch
@@ -45,10 +46,14 @@ rm -rf $RPM_BUILD_ROOT
%{_bindir}/fedoradev-pkgowners
%{_bindir}/fedora-cert
%{_bindir}/fedora-getsvn
+%{_bindir}/fedora-hosted
%{_bindir}/rpmbuild-md5
%changelog
+* Tue Aug 04 2009 Jesse Keating <jkeating@redhat.com> - 0.3.8-1
+- Add fedora-hosted and require offtrac
+
* Thu Jul 30 2009 Dennis Gilmore <dennis@ausil.us> - 0.3.7-1
- define user_cert in fedora-cvs before refrencing it
diff --git a/src/fedora-hosted b/src/fedora-hosted
new file mode 100755
index 0000000..c58a20a
--- /dev/null
+++ b/src/fedora-hosted
@@ -0,0 +1,242 @@
+#!/usr/bin/python
+# fedora-hosted - a commandline frontend for the Fedora Hosted Projects Trac
+#
+# Copyright (C) 2008 Red Hat Inc.
+# Author: 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.
+
+# TODO: this file should probably go away and be far more generic
+# And we should load specific things like url structure from a config
+# store of some sort.
+
+import getpass
+import optparse
+import offtrac
+import sys
+import time
+
+# Define some constants
+BASEURL = 'fedorahosted.org/'
+
+# List currently available commands
+cmdlist = ('list-tickets', 'list-milestones', 'ticket-info', 'milestone-info',
+ 'new-ticket', 'new-milestone', 'update-ticket')
+
+# Define some functions
+def setup_action_parser(action):
+ """Setup parsers for the various action types"""
+
+ usage = "usage: %%prog %s [options]" % action
+ p = optparse.OptionParser(usage = usage)
+
+ if action == "list-tickets":
+ p.add_option("--owner", "-o")
+ p.add_option("--status", "-s", default="!=closed",
+ help="Query string for status, default is '!=closed'")
+ p.add_option("--component", "-c")
+ p.add_option("--type", "-t")
+
+# elif action == "list-milestones":
+# p.add_option("--name", "-n",
+# help="Show information about a particular milestone")
+# p.add_option("--all", "-a", action="store_true",
+# help="Show all milestones, otherwise only show active.")
+
+ elif action == "ticket-info":
+ p.set_usage("usage: %%prog %s [ticket numbers]" % action)
+
+ elif action == "milestone_info":
+ p.set_usage("usage: %%prog %s [milestones]" % action)
+
+ elif action == "new-ticket":
+ p.add_option("--summary", "-s", help="REQUIRED!")
+ p.add_option("--description", "-d", help="REQUIRED!")
+ p.add_option("--type", "-t", default=None)
+ p.add_option("--priority", "-p", default=None)
+ p.add_option("--milestone", "-m", default=None)
+ p.add_option("--component", "-C", default=None)
+ p.add_option("--version", "-v", default=None)
+ p.add_option("--keyword", "-k", action="append",
+ help="Keyword to add, can be used multiple times.")
+ p.add_option("--assignee", "-a", default=None)
+ p.add_option("--cc", action="append",
+ help="Carbon Copy address, can be used multiple times.")
+ # This one is a little backwards. The rpc call is actually notify,
+ # and defaults to false, but we want to default to true.
+ p.add_option("--stealth", action="store_false", default=True,
+ help="Suppress initial notification of this ticket.")
+
+ elif action == "update-ticket":
+ p.add_option("--ticket", "-n", help="Ticket number. REQUIRED!")
+ p.add_option("--comment", "-c", default='')
+ p.add_option("--summary", "-s", default=None)
+ p.add_option("--description", "-d", default=None)
+ p.add_option("--type", "-t", default=None)
+ p.add_option("--priority", "-p", default=None)
+ p.add_option("--milestone", "-m", default=None)
+ p.add_option("--component", "-C", default=None)
+ p.add_option("--version", "-v", default=None)
+ p.add_option("--keyword", "-k", action="append",
+ help="Keyword to add, can be used multiple times.")
+ p.add_option("--assignee", "-a", default=None)
+ p.add_option("--cc", action="append",
+ help="Carbon Copy address, can be used multiple times.")
+ p.add_option("--status", "-S", default=None)
+ p.add_option("--resolution", "-r", default=None)
+ # This one is a little backwards. The rpc call is actually notify,
+ # and defaults to false, but we want to default to true.
+ p.add_option("--stealth", action="store_false", default=True,
+ help="Suppress notification of this update.")
+
+ elif action == "new-milestone":
+ p.add_option("--name", "-n", help="REQUIRED!")
+ p.add_option("--description", "-d", default=None)
+ p.add_option("--due", "-D", default=None,
+ help="Due date in MM-DD-YY format.")
+
+ return p
+
+
+# get command line options
+usage = "usage: %prog [global options] COMMAND [options]"
+usage += "\nCommands: %s" % ', '.join(cmdlist)
+parser = optparse.OptionParser(usage=usage)
+parser.disable_interspersed_args()
+
+# TODO: Try to get this info from fedora config files
+parser.add_option("--user", "-u")
+parser.add_option("--password", "-p")
+parser.add_option("--project", "-P")
+
+# Parse our global options
+(opts, args) = parser.parse_args()
+
+# See if we got a command
+if len(args) and args[0] in cmdlist:
+ action = args.pop(0)
+else:
+ parser.print_help()
+ sys.exit(1)
+
+# Parse the command
+action_parser = setup_action_parser(action)
+(actopt, actargs) = action_parser.parse_args(args)
+
+if not opts.user:
+ opts.user=raw_input('Username: ')
+
+if not opts.password:
+ opts.password=getpass.getpass('Password for %s: ' % opts.user)
+
+if not opts.project:
+ opts.project=raw_input('Project space: ')
+
+
+# Create the TracServ object
+uri = 'https://%s:%s@%s/%s/login/xmlrpc' % (opts.user,
+ opts.password,
+ BASEURL,
+ opts.project)
+trac = offtrac.TracServer(uri)
+
+# Try to do something
+if action == "list-tickets":
+ # setup the query string
+ query = "status%s" % actopt.status
+ if actopt.owner:
+ query += "&owner=%s" % actopt.owner
+ if actopt.component:
+ query += "&component=%s" % actopt.component
+ if actopt.type:
+ query += "&type=%s" % actopt.type
+
+ results = trac.query_tickets(query)
+ print results
+
+elif action == "list-milestones":
+ results = trac.list_milestones()
+ print results
+
+elif action == "ticket-info":
+ if not actargs: # FIXME, this isn't working
+ action_parser.print_help()
+ sys.exit(1)
+ # Setup the trac object for multicall
+ trac.setup_multicall()
+ for number in actargs:
+ trac.get_ticket(number)
+ # Do the multicall and print out the results
+ for result in trac.do_multicall():
+ print result
+
+elif action == "milestone-info":
+ if not actargs: # FIXME, this isn't working
+ action_parser.print_help()
+ sys.exit(1)
+ trac.setup_multicall()
+ for milestone in actargs:
+ trac.get_milestone(milestone)
+ for result in trac.do_multicall():
+ print result
+
+elif action == "new-ticket":
+ # Check to make sure we got all we need
+ if actopt.summary and actopt.description:
+ pass
+ else:
+ action_parser.print_help()
+ sys.exit(1)
+ # Wrap up our keywords and cc into one string, if any
+ keywords = None
+ ccs = None
+ if actopt.keyword:
+ keywords = ' '.join(actopt.keyword)
+ if actopt.cc:
+ ccs = ' '.join(actopt.cc)
+
+ result = trac.create_ticket(actopt.summary, actopt.description,
+ actopt.type, actopt.priority, actopt.milestone,
+ actopt.component, actopt.version, keywords,
+ actopt.assignee, ccs, actopt.stealth)
+ print result
+
+elif action == "update-ticket":
+ # Check to make sure we got all we need
+ if actopt.ticket:
+ pass
+ else:
+ action_parser.print_help()
+ sys.exit(1)
+ # Wrap up our keywords and cc into one string, if any
+ keywords = None
+ ccs = None
+ if actopt.keyword:
+ keywords = ' '.join(actopt.keyword)
+ if actopt.cc:
+ ccs = ' '.join(actopt.cc)
+
+ result = trac.update_ticket(actopt.ticket, actopt.comment, actopt.summary,
+ actopt.type, actopt.description,
+ actopt.priority, actopt.milestone,
+ actopt.component, actopt.version, keywords,
+ ccs, actopt.status, actopt.resolution,
+ actopt.assignee, actopt.stealth)
+ print result
+
+elif action == "new-milestone":
+ if not actopt.name:
+ action_parser.print_help()
+ sys.exit(1)
+ # Convert due date to seconds if needed
+ due = None
+ if actopt.due:
+ due = int(time.mktime(time.strptime(actopt.due, "%m-%d-%y")))
+
+ result = trac.create_milestone(actopt.name, actopt.description, due)
+ print result # The result here is "0" if successful, printing isn't fun
+