← Back to team overview

arsenal-devel team mailing list archive

Re: Discussion: ArsenalApp class..

 

On Tue, Mar 30, 2010 at 07:19:58PM -0700, Brad Figg wrote:
> I've started using an ArsenalApp class for my development and
> I wanted to throw it out there for discussion to see if anyone
> else thinks it would be useful. It needs more work to make it
> flexible enough for every app. but has been working well.

This does look pretty cool.  I especially like how it wrappers up the
command line argument handling - I've been pondering about if there was
a general purpose way we could do that for some time.  Using class
derivation for adding more params is quite slick, I like.

I am thinking that we might actually move the load_project() routine
completely into this class from Arsenal.  The credentials stuff in the
Arsenal class duplicates some functionality that's now done in
launchpadlib itself and we could probably handle in ArsenalApp.  So I
think ultimately this let us pretty much get rid of the current Arsenal
class entirely.

Bryce
 
> Attached is the class file and an example app. which uses the
> distro version code that I just submitted. I used this app
> to test out the distro version code. Also attached is a _very_
> basic example.
> 
> Brad
> -- 
> Brad Figg brad.figg@xxxxxxxxxxxxx http://www.canonical.com

> #!/usr/bin/python
> 
> # The purpose of this script is to conduct the initial review of
> # incoming bugs and attempt to get them into a better shape for later
> # scripts to handle.
> #
> # We want to categorize the bugs as best we can, and request appropriate
> # information so later scripts can conduct their analysis.
> 
> from arsenal_lib       import *
> from arsenal_reply     import *
> from getopt import getopt, GetoptError
> 
> class ArsenalApp:
>     opt_dryrun      = True                    # The defalt is to not commit any changes
>     opt_source_pkgs = None
>     opt_bug_limit   = -1
>     opt_verbose     = False
>     opt_buglist     = []
>     reason          = ''
>     reason_tags     = []
> 
>     def __init__(self):
>         self.arsenal = Arsenal()
>         self.lp      = self.arsenal.launchpad
>         self.ubuntu  = self.arsenal.load_project("ubuntu")
>         self.canonical_kernel_team = self.lp.people['canonical-kernel-team']
> 
>     # cmdline_usage
>     #
>     # Prints out the help text which explains the command line options.
>     #
>     def cmdline_usage(self):
>         sys.stdout.write("""
>     Usage:
>         %s [--commit] [--verbose] [--limit=<n>] (--bug=<n> [<task-name(s)>] | <source-package(s)>)
> 
>     Options:
>         --help           Prints this text.
> 
>         --commit         Commit the appropriate changes to launchpad. The default
>                          is to run in "dryrun" mode which only reports what it would
>                          do and not commit any changes.
> 
>         --limit=<n>      Only process <n> number of bugs before exiting.
> 
>         --verbose        Give some feedback of what is happening while the script is
>                          running.
> 
>         --bugs=<bug-list>
>                          A comma separated list of bug ids. Only process the bugs
>                          specified here, on the command line.
> 
>     Examples:
>         %s --verbose --limit=2 alsa-driver
>         %s --verbose --bugs=367560 
> 
> """ % (sys.argv[0]))
> 
>     # cmdline_process
>     #
>     # As you can probably tell from the name, this method is responsible
>     # for calling the getopt function to process the command line. All
>     # parameters are processed into class variables for use by other
>     # methods.
>     #
>     def cmdline_process(self):
>         result = True
>         try:
>             optsShort = ''
>             optsLong  = ['help', 'commit', 'limit=', 'verbose', 'bugs=']
>             opts, args = getopt(sys.argv[1:], optsShort, optsLong)
> 
>             for opt, val in opts:
>                 if (opt == '--help'):
>                     result = False
>                     break
> 
>                 elif (opt == '--commit'):
>                     self.opt_dryrun = False
> 
>                 elif (opt == '--limit'):
>                     self.opt_bug_limit = int(val)
> 
>                 elif (opt == '--verbose'):
>                     self.opt_verbose = True
> 
>                 elif opt in ('--bugs'):
>                     self.opt_buglist = val.split(',')
> 
>             if result:
>                 if len(self.opt_buglist) == 0:
>                     if (len(args) != 0):
>                         self.opt_source_pkgs = args
>                     else:
>                         print("\n   Error: At least one source package must be specified.")
>                         result = False
>                 elif (len(args) != 0):
>                     self.opt_source_pkgs = args
> 
>         except GetoptError, error:
>             print(error)
>             result = False
> 
> 	return result
> 
>     # main
>     #
>     # Performs main sequencing through all the source packages specified and the
>     # associated bugs.
>     #
>     def main(self):
>         if (not self.cmdline_process()):
>             self.cmdline_usage()
>             return
> 
>         if (self.opt_verbose):
>             print("Current cmdline parameters:")
>             print("         dryrun: %s" % (self.opt_dryrun))
>             print("    source pkgs: %s" % (self.opt_source_pkgs))
>             print("          limit: %d" % (self.opt_bug_limit))   
>             print("        verbose: %s" % (self.opt_verbose))
>             print("")
> 
>         if self.opt_dryrun:
>             print('')
>             print("  ** Note: This is a 'dry run', no bugs will actually be modified!")
>             print('')
> 
>         total_count = 0
>         updated_count=0
>         
>         try:
>             examined_count = 0
> 
>             if len(self.opt_buglist) > 0:
>                 for bug in self.opt_buglist:
>                     abug = ArsenalBug(self.lp.bugs[bug], self.lp)
> 
>                     if self.opt_source_pkgs != None:
>                         for bugtask in abug.bug_tasks:
>                             #print(">> %s >> %s" % (bugtask.bug_target_name, bugtask.bug_target_display_name))
>                             if bugtask.bug_target_name in self.opt_source_pkgs:
>                                 self.bug_handler('', bugtask, abug)
>                     else:
>                         for bugtask in abug.bug_tasks:
>                             self.bug_handler('', bugtask, abug)
> 
>             else:
>                 # Go through all the source packages that were specified on the
>                 # command line.
>                 #
>                 for source_pkg in self.opt_source_pkgs:
>                     updated_count=0
>                     if self.opt_dryrun:
>                         print("\nProcessing %s" % (source_pkg))
> 
>                     # Go through all the bugs in one source package that are of a 
>                     # particular status.
>                     #
>                     pkg   = self.ubuntu.getSourcePackage(name = source_pkg)
>                     status_list = ['New', 'Incomplete', 'Confirmed', 'Triaged']
>                     tasks = pkg.searchTasks(status=status_list)
>                     for bugtask in tasks:
>                         self.reason  = ''
>                         if (self.opt_bug_limit != -1) and (examined_count >= self.opt_bug_limit):
>                             print("\n  ** Note: Hit max number of bugs to process, exiting.\n")
>                             break
>                         examined_count += 1
>      
>                         # Call the subclass's handler.
>                         #
>                         self.bug_handler(source_pkg, bugtask, ArsenalBug(bugtask.bug, self.lp))
> 
>                         updated_count += 1
> 
>                     if self.opt_verbose:
>                         print("%d bugs examined for %s" % (updated_count, source_pkg))
> 
>                     total_count += updated_count
>         
>         except KeyboardInterrupt:
>             # If the user presses <ctrl-C> then stop cleanly
>             pass
> 
>         except:
>             if (updated_count > 0) and (self.opt_verbose):
>                 print("%d bugs examined" % (updated_count))
>             raise
>         
>         if self.opt_verbose:
>             print("%d bugs examined in total" % (total_count))
> 
> # vi:set ts=4 sw=4 expandtab:

> #!/usr/bin/python
> 
> # The purpose of this script is to conduct the initial review of
> # incoming bugs and attempt to get them into a better shape for later
> # scripts to handle.
> #
> # We want to categorize the bugs as best we can, and request appropriate
> # information so later scripts can conduct their analysis.
> 
> from arsenal_app import *
> 
> class ProcessExampleApp(ArsenalApp):
>     debug = False
> 
>     def __init__(self):
>        ArsenalApp.__init__(self)
> 
>     # bug_handler
>     #
>     # Do the individual, bug specific work.
>     #
>     def bug_handler(self, source_pkg, bugtask, ars_bug):
>         if self.opt_verbose:
>             print("%s  %s" % (bugtask.status, str(ars_bug.title)))
>             print("           URL: https://bugs.launchpad.net/ubuntu/+bug/%d"; % (ars_bug.id))
> 
>         distro = determine_distro(ars_bug)
> 
>         if (distro != ''):
>             if self.opt_verbose:
>                 print("        Distro: %s" % (distro))
>             pass
>         else:
>             if self.opt_verbose:
>                 print("        Distro: unknown")
> 
>     def main(self):
>         ArsenalApp.main(self)
> 
> if __name__ == '__main__':
>     app = ProcessExampleApp()
>     app.main()
> 
> # vi:set ts=4 sw=4 expandtab:

> #!/usr/bin/python
> 
> # The purpose of this script is to conduct the initial review of
> # incoming bugs and attempt to get them into a better shape for later
> # scripts to handle.
> #
> # We want to categorize the bugs as best we can, and request appropriate
> # information so later scripts can conduct their analysis.
> 
> from arsenal_app import *
> 
> class ProcessExampleApp(ArsenalApp):
> 
>     def __init__(self):
>        ArsenalApps.__init__(self)
> 
>     # bug_handler
>     #
>     # Do the individual, bug specific work.
>     #
>     def bug_handler(self, source_pkg, bugtask, ars_bug):
>         if (self.opt_verbose):
>             print("%s  %s" % (bugtask.status, str(ars_bug.title)))
>             print("           URL: https://bugs.launchpad.net/ubuntu/+bug/%d"; % (ars_bug.id))
> 
> 
>     def main(self):
>         ArsenalApp.main(self)
> 
> if __name__ == '__main__':
>     app = ProcessExampleApp()
>     app.main()
> 
> # vi:set ts=4 sw=4 expandtab:

> _______________________________________________
> Mailing list: https://launchpad.net/~arsenal-devel
> Post to     : arsenal-devel@xxxxxxxxxxxxxxxxxxx
> Unsubscribe : https://launchpad.net/~arsenal-devel
> More help   : https://help.launchpad.net/ListHelp




References