Mailinglist Archive: opensuse-commit (1003 mails)

< Previous Next >
commit osc
  • From: root@xxxxxxxxxxxxxxx (h_root)
  • Date: Thu, 14 Jun 2007 17:23:26 +0200
  • Message-id: <20070614152327.1095A6780D3@xxxxxxxxxxxxxxx>

Hello community,

here is the log from the commit of package osc
checked in at Thu Jun 14 17:23:26 CEST 2007.

--------
--- osc/osc.changes     2007-05-14 12:14:58.000000000 +0200
+++ /mounts/work_src_done/STABLE/osc/osc.changes        2007-06-14 16:32:13.000000000 +0200
@@ -1,0 +2,43 @@
+Thu Jun 14 16:31:30 CEST 2007 - poeml@xxxxxxx
+
+- update to r1733:
+  New features kindly implemented by Marcus Huewe:
+  - added wipebinaries command
+  - added abortbuild command
+  - improved handling of metadata editing if the server doesn't accept it
+
+-------------------------------------------------------------------
+Thu Jun 14 10:36:07 CEST 2007 - poeml@xxxxxxx
+
+- update to r1731:
+  - adjust for change in build.rpm, where /usr/lib/build/debsort
+    was removed.  Look for debtransform program instead in order to
+    determine if build.rpm is new enough.
+  - update cmdln.py to planned 1.0 version. The main changes are
+    related to points that were raised during employment in osc:
+      # v0.8.3
+      - Fix a bug where errors with passing an incorrect number of args to
+        functions in do_foo() implementations would be masked.
+      # v1.0.0
+      - [backward incompat] `Cmdln.main()` no longer takes an `optparser`
+        argument. Top-level option parsing has been changed so that top-level
+        options for a `Cmdln` subclass can more naturally be defined and
+        handled on the class definition. Changes:
+        - `Cmdln.main()` calls `self.get_optparser` to get an option handler.
+          Subclasses should overload this method for custom top-level options.
+        - After option parsing, but before sub-command handling, the
+          `self.postoptparse()` hook is called.
+      - Add a `version` attribute on `Cmdln` subclasses. If set, the default
+        top-level option parser will have a `--version` attribute.
+      - [backward incompat] Simplify the StopProcessing/opts.stop handling for
+        option handling in subcommands. The "opts" argument to "do_*"
+        sub-command functions will no longer have a "stop" value.
+        StopProcessing is now called StopOptionProcessing. This shouldn't
+        affect simple usage of cmdln.py.
+    - adjust osc.commandline for these changes.
+  - make startdir a module global
+  - add info about usage with the 'nosetests' test discovery tool
+  - add tests for commandline options
+  - results: remove obsolete code handling commandline arguments
+
+-------------------------------------------------------------------

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ osc.spec ++++++
--- /var/tmp/diff_new_pack.q12955/_old  2007-06-14 17:23:18.000000000 +0200
+++ /var/tmp/diff_new_pack.q12955/_new  2007-06-14 17:23:18.000000000 +0200
@@ -13,7 +13,7 @@
 Name:           osc
 BuildRequires:  python-devel
 Version:        0.96
-Release:        8
+Release:        24
 Group:          Development/Tools/Other
 License:        GNU General Public License (GPL)
 BuildRoot:      %{_tmppath}/%{name}-%{version}-build
@@ -63,6 +63,43 @@
 %doc README TODO NEWS
 
 %changelog
+* Thu Jun 14 2007 - poeml@xxxxxxx
+- update to r1733:
+  New features kindly implemented by Marcus Huewe:
+  - added wipebinaries command
+  - added abortbuild command
+  - improved handling of metadata editing if the server doesn't accept it
+* Thu Jun 14 2007 - poeml@xxxxxxx
+- update to r1731:
+  - adjust for change in build.rpm, where /usr/lib/build/debsort
+  was removed.  Look for debtransform program instead in order to
+  determine if build.rpm is new enough.
+  - update cmdln.py to planned 1.0 version. The main changes are
+  related to points that were raised during employment in osc:
+  [#] v0.8.3
+      - Fix a bug where errors with passing an incorrect number of args to
+  functions in do_foo() implementations would be masked.
+  [#] v1.0.0
+      - [backward incompat] `Cmdln.main()` no longer takes an `optparser`
+  argument. Top-level option parsing has been changed so that top-level
+  options for a `Cmdln` subclass can more naturally be defined and
+  handled on the class definition. Changes:
+        - `Cmdln.main()` calls `self.get_optparser` to get an option handler.
+  Subclasses should overload this method for custom top-level options.
+        - After option parsing, but before sub-command handling, the
+  `self.postoptparse()` hook is called.
+      - Add a `version` attribute on `Cmdln` subclasses. If set, the default
+  top-level option parser will have a `--version` attribute.
+      - [backward incompat] Simplify the StopProcessing/opts.stop handling for
+  option handling in subcommands. The "opts" argument to "do_*"
+  sub-command functions will no longer have a "stop" value.
+  StopProcessing is now called StopOptionProcessing. This shouldn't
+  affect simple usage of cmdln.py.
+    - adjust osc.commandline for these changes.
+  - make startdir a module global
+  - add info about usage with the 'nosetests' test discovery tool
+  - add tests for commandline options
+  - results: remove obsolete code handling commandline arguments
 * Mon May 14 2007 - poeml@xxxxxxx
 - update to r1657:
   - rebuildpac: fix mistyped repository parameter


++++++ osc-0.96.tar.gz ++++++
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/osc-0.96/CREDITS new/osc-0.96/CREDITS
--- old/osc-0.96/CREDITS        2007-05-03 17:54:40.000000000 +0200
+++ new/osc-0.96/CREDITS        2007-06-14 16:30:36.000000000 +0200
@@ -1,5 +1,6 @@
 There is a number of people who have helped:
 
+Marcus Huewe - wipebinaries command, abortbuild command, editmeta error handling
 Marcus Rueckert - help and countless suggestions
 Christoph Thiel - patch enabling build log following. 
 Adrian Schroeter - one-liner showing how to handle an error ;-)
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/osc-0.96/NEWS new/osc-0.96/NEWS
--- old/osc-0.96/NEWS   2007-05-10 16:33:43.000000000 +0200
+++ new/osc-0.96/NEWS   2007-06-14 16:30:36.000000000 +0200
@@ -1,4 +1,7 @@
 since 0.96:
+- new wipebinaries and abortbuild commands, by courtesy of Marcus Huewe
+- improved metadata error condition handling (thanks to Marcus Huewe)
+- build: add --userootforbuild option
 - build: implement -x/--extra-pkgs option (passed to backend and included in buildinfo result)
 - make filling out of username in templates work again
 - don't try to delete projects, as long it is not implemented in the backend
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/osc-0.96/osc/cmdln.py new/osc-0.96/osc/cmdln.py
--- old/osc-0.96/osc/cmdln.py   2007-05-04 23:51:15.000000000 +0200
+++ new/osc-0.96/osc/cmdln.py   2007-05-16 12:55:05.000000000 +0200
@@ -35,8 +35,8 @@
 details.
 """
 
-__revision__ = "$Id: cmdln.py 1087 2006-05-11 00:04:28Z trentm $"
-__version_info__ = (0, 8, 2)
+__revision__ = "$Id: cmdln.py 1666 2007-05-09 03:13:03Z trentm $"
+__version_info__ = (1, 0, 0)
 __version__ = '.'.join(map(str, __version_info__))
 
 import os
@@ -122,6 +122,7 @@
     """
     name = None      # if unset, defaults basename(sys.argv[0])
     prompt = None    # if unset, defaults to self.name+"> "
+    version = None   # if set, default top-level options include --version
 
     # Default messages for some 'help' command error cases.
     # They are interpolated with one arg: the command.
@@ -172,7 +173,31 @@
         self.completekey = completekey
         self.cmdlooping = False
 
-    def main(self, argv=None, optparser=_NOT_SPECIFIED, loop=LOOP_NEVER):
+    def get_optparser(self):
+        """Hook for subclasses to set the option parser for the
+        top-level command/shell.
+
+        This option parser is used retrieved and used by `.main()' to
+        handle top-level options.
+
+        The default implements a single '-h|--help' option. Sub-classes
+        can return None to have no options at the top-level. Typically
+        an instance of CmdlnOptionParser should be returned.
+        """
+        version = (self.version is not None 
+                    and "%s %s" % (self._name_str, self.version)
+                    or None)
+        return CmdlnOptionParser(self, version=version)
+
+    def postoptparse(self):
+        """Hook method executed just after `.main()' parses top-level
+        options.
+
+        When called `self.values' holds the results of the option parse.
+        """
+        pass
+
+    def main(self, argv=None, loop=LOOP_NEVER):
         """A possible mainline handler for a script, like so:
 
             import cmdln
@@ -192,13 +217,6 @@
                 It must be a sequence, where the first element is the
                 command name and subsequent elements the args for that
                 command.
-            "optparser" (optional) is a cmdln.CmdlnOptionParser instance
-                to process top-level options.  If left unspecified,
-                option parsing is done with a default option list: -h,
-                --help.  None can be given to disable top-level option
-                processing. If option processing is done, the 'options'
-                attribute is set to the resulting `optparse.Values`
-                instance.
             "loop" (optional, default LOOP_NEVER) is a constant
                 indicating if a command loop should be started (i.e. an
                 interactive shell). Valid values (constants on this module):
@@ -212,11 +230,8 @@
             argv = sys.argv
         else:
             argv = argv[:] # don't modify caller's list
-        optparser = self.optparser
-        if optparser is _NOT_SPECIFIED:
-            optparser = CmdlnOptionParser(self)
-        self.optparser = optparser
 
+        self.optparser = self.get_optparser()
         if self.optparser: # i.e. optparser=None means don't process for opts
             try:
                 self.options, args = self.optparser.parse_args(argv[1:])
@@ -226,10 +241,11 @@
                 self.stderr.write(self._str(msg))
                 self.stderr.flush()
                 return 1
-            if self.options.stop:
+            except StopOptionProcessing, ex:
                 return 0
         else:
             self.options, args = None, argv[1:]
+        self.postoptparse()
 
         if loop == LOOP_ALWAYS:
             if args:
@@ -828,6 +844,8 @@
     def _do_EOF(self, argv):
         # Default EOF handler
         # Note: an actual EOF is redirected to this command.
+        #TODO: separate name for this. Currently it is available from
+        #      command-line. Is that okay?
         self.stdout.write('\n')
         self.stdout.flush()
         self.stop = True
@@ -846,37 +864,26 @@
 # See the class _OptionParserEx docstring for details.
 #
 
-class StopProcessing(Exception):
+class StopOptionProcessing(Exception):
     """Indicate that option *and argument* processing should stop
-    cleanly.  This is not an error condition. It is similar in spirit to
-    StopIteration. This is raised by the default "help" and "version"
-    option actions and can be raised by custom option callbacks too.
+    cleanly. This is not an error condition. It is similar in spirit to
+    StopIteration. This is raised by _OptionParserEx's default "help"
+    and "version" option actions and can be raised by custom option
+    callbacks too.
     
-    A new boolean "stop" attribute on the optparse.Values instance
-    returned by parser.parse_args() indicates if StopProcessing was
-    encountered. Hence the typical CmdlnOptionParser usage is:
+    Hence the typical CmdlnOptionParser (a subclass of _OptionParserEx)
+    usage is:
 
         parser = CmdlnOptionParser(mycmd)
         parser.add_option("-f", "--force", dest="force")
         ...
-        parser.parse_args()
-        #XXX This is wrong: doesn't match current impl.
-        if parser.stop: # normal termination, "--help" was probably given
+        try:
+            opts, args = parser.parse_args()
+        except StopOptionProcessing:
+            # normal termination, "--help" was probably given
             sys.exit(0)
     """
 
-class _OptionEx(optparse.Option):
-    def take_action(self, action, dest, opt, value, values, parser):
-        if action == "help":
-            parser.print_help()
-            raise StopProcessing
-        elif action == "version":
-            parser.print_version()
-            raise StopProcessing
-        else:
-            return optparse.Option.take_action(self, action, dest, opt,
-                                               value, values, parser)
-
 class _OptionParserEx(optparse.OptionParser):
     """An optparse.OptionParser that uses exceptions instead of sys.exit.
 
@@ -884,10 +891,9 @@
     as follows:
     - Correct (IMO) the default OptionParser error handling to never
       sys.exit(). Instead OptParseError exceptions are passed through.
-    - Add the StopProcessing exception (a la StopIteration) to
-      indicate normal termination of option processing. Add the "stop"
-      boolean attribute to Values returned by .parse_args(). See
-      StopProcessing's docstring for details.
+    - Add the StopOptionProcessing exception (a la StopIteration) to
+      indicate normal termination of option processing.
+      See StopOptionProcessing's docstring for details.
 
     I'd also like to see the following in the core optparse.py, perhaps
     as a RawOptionParser which would serve as a base class for the more
@@ -899,62 +905,17 @@
         optparser.add_option("--version", action="version")
       These are good practices, just not valid defaults if they can
       get in the way.
-    - Something like the clear separation of user-error vs.
-      programmer-error in CmdlnOptionParser would be good: a new
-      OptParseUserError or something.
     """
-    #TODO: deal with older Python 2.3 optparse differences
-    def __init__(self, **kwargs):
-        if "option_class" in kwargs:
-            raise optparse.OptParseError(
-                "cannot specify 'option_class' on _OptionParserEx")
-        kwargs["option_class"] = _OptionEx
-        optparse.OptionParser.__init__(self, **kwargs)
-
     def error(self, msg):
         raise optparse.OptParseError(msg)
 
     def exit(self, status=0, msg=None):
-        # Proposed transition code would use deprecation warning.
-        #import warnings
-        #warnings.warn("OptionParser.exit() is deprecated")
-        raise optparse.OptParseError("_OptionParserEx.exit() is obsolete")
-
-    def parse_args(self, args=None, values=None):
-        """Override parse_args to properly handle StopProcessing.
-
-        Also changed: don't catch OptParseError's raised by
-        ._process_args() because we would just change them back to
-        exceptions in .error() anyway.
-        """
-        rargs = self._get_args(args)
-        if values is None:
-            values = self.get_default_values()
-
-        # for convenience of callbacks:
-        self.rargs = rargs
-        self.largs = largs = []
-        self.values = values
-
-        #TODO:
-        # - Should 'stop' be changed to a third return arg instead of
-        #   attr on Values? I think so, yes.
-        try:
-            self._process_args(largs, rargs, values)
-        except (optparse.BadOptionError, optparse.OptionValueError), ex:
-            self.error(ex.msg)
-        except StopProcessing:
-            values.stop = True
+        if status == 0:
+            raise StopOptionProcessing(msg)
         else:
-            values.stop = False
-        args = largs + rargs
-        return self.check_values(values, args)
-
-    def add_option(self, *args, **kwargs):
-        opt = optparse.OptionParser.add_option(self, *args, **kwargs)
-        if opt.dest == "stop":
-            raise optparse.OptionConflictError(
-                "option dest value of 'stop' is reserved")
+            #TODO: don't lose status info here
+            raise optparse.OptParseError(msg)
+
 
 
 #---- optparse.py-based option processing support
@@ -989,7 +950,7 @@
 
 class SubCmdOptionParser(_OptionParserEx):
     def set_cmdln_info(self, cmdln, subcmd):
-        """Called by CmdlnOpt to pass relevant info about itself needed
+        """Called by Cmdln to pass relevant info about itself needed
         for print_help().
         """
         self.cmdln = cmdln
@@ -1022,11 +983,6 @@
     return decorate
 
 
-#TODO: Could name these RawCmdln and Cmdln, the latter with optparse
-#      integration.
-#      Then *always* have an optparser (even empty)?
-#      TODO: check/test this *always* have an optparser case, even if
-#      no decorator is provided.
 class Cmdln(RawCmdln):
     """An improved (on cmd.Cmd) framework for building multi-subcommand
     scripts (think "svn" & "cvs") and simple shells (think "pdb" and
@@ -1079,6 +1035,8 @@
                 for arg in args:
                     bar(arg)
 
+        TODO: explain that "*args" can be other signatures as well.
+
         The `cmdln.option` decorator corresponds to an `add_option()`
         method call on an `optparse.OptionParser` instance.
 
@@ -1101,8 +1059,11 @@
                 optparser = handler.im_func.optparser = SubCmdOptionParser()
             assert isinstance(optparser, SubCmdOptionParser)
             optparser.set_cmdln_info(self, argv[0])
-            opts, args = optparser.parse_args(argv[1:])
-            if opts.stop:
+            try:
+                opts, args = optparser.parse_args(argv[1:])
+            except StopOptionProcessing:
+                #TODO: this doesn't really fly for a replacement of
+                #      optparse.py behaviour, does it?
                 return 0 # Normal command termination
 
             try:
@@ -1114,6 +1075,14 @@
                 #   do_foo() takes exactly 5 arguments (6 given)
                 # Raise CmdlnUserError for these with a suitably
                 # massaged error message.
+                import sys
+                tb = sys.exc_info()[2] # the traceback object
+                if tb.tb_next is not None:
+                    # If the traceback is more than one level deep, then the
+                    # TypeError do *not* happen on the "handler(...)" call
+                    # above. In that we don't want to handle it specially
+                    # here: it would falsely mask deeper code errors.
+                    raise
                 msg = ex.args[0]
                 match = _INCORRECT_NUM_ARGS_RE.search(msg)
                 if match:
@@ -1123,13 +1092,6 @@
                         msg[2] = msg[2].replace("arguments", "argument")
                     msg[3] = int(msg[3]) - 3
                     msg = ''.join(map(str, msg))
-
-                    # To debug errors which involve calling functions with
-                    # wrong number of arguments, uncomment the following line.
-                    # Otherwise, all errors of this kind are presented as
-                    # "incorrect usage" to the user:
-                    #raise
-
                     raise CmdlnUserError(msg)
                 else:
                     raise
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/osc-0.96/osc/commandline.py new/osc-0.96/osc/commandline.py
--- old/osc-0.96/osc/commandline.py     2007-05-14 10:29:50.000000000 +0200
+++ new/osc-0.96/osc/commandline.py     2007-06-14 16:30:36.000000000 +0200
@@ -12,7 +12,6 @@
 
 
 class Osc(cmdln.Cmdln):
-
     """usage:
         osc [GLOBALOPTS] SUBCOMMAND [OPTS] [ARGS...]
         osc help SUBCOMMAND
@@ -28,32 +27,34 @@
     """
     name = 'osc'
 
+
     def __init__(self, *args, **kwargs):
         cmdln.Cmdln.__init__(self, *args, **kwargs)
         cmdln.Cmdln.do_help.aliases.append('h')
 
         conf.get_config()
 
-        # set up and parse options before subcommand
-        self.optparser = cmdln.CmdlnOptionParser(self,
-                                                version=get_osc_version())
-        self.optparser.add_option('-H', '--http-debug', action='store_true',
+
+    def get_optparser(self):
+        """this is the parser for "global" options (not specific to subcommand)"""
+
+        optparser = cmdln.CmdlnOptionParser(self, version=get_osc_version())
+        optparser.add_option('-H', '--http-debug', action='store_true',
                       default=conf.config['http_debug'],
                       help='debug HTTP traffic')
-        self.optparser.add_option('-A', '--apisrv', dest='apisrv',
+        optparser.add_option('-A', '--apisrv', dest='apisrv',
                       metavar='URL',
                       help='specify URL to access API server at')
+        return optparser
 
-        (self.global_opts, self.myargs) = self.optparser.parse_args()
 
-        # XXX version is printed twice otherwise...
-        self.optparser.version = ''
+    def postoptparse(self):
+        """merge commandline options into the config"""
 
-        # merge commandline options into the config
-        conf.config['http_debug'] = self.global_opts.http_debug
-        if self.global_opts.apisrv:
+        conf.config['http_debug'] = self.options.http_debug
+        if self.options.apisrv:
             conf.config['scheme'], conf.config['apisrv'] = \
-                conf.parse_apisrv_url(conf.config['scheme'], self.global_opts.apisrv)
+                conf.parse_apisrv_url(conf.config['scheme'], self.options.apisrv)
         conf.config['apiurl'] = conf.config['scheme'] + '://' + conf.config['apisrv']
 
         # XXX unless config['user'] goes away (and is replaced with a handy function, or 
@@ -870,12 +871,8 @@
         ${cmd_option_list}
         """
 
-        try:
-            args = parseargs(args)
-            pacs = findpacs(args)
-        except:
-            print >>sys.stderr, '\'%s\' is not an osc package directory' % wd
-            return 1
+        args = parseargs(args)
+        pacs = findpacs(args)
 
         for pac in pacs:
             print '\n'.join(get_results(pac.apiurl, pac.prjname, pac.name))
@@ -1099,7 +1096,7 @@
 
         import osc.build
 
-        if not os.path.exists('/usr/lib/build/debsort'):
+        if not os.path.exists('/usr/lib/build/debtransform'):
             sys.stderr.write('Error: you need build.rpm with version 2006.6.14 or newer.\n')
             sys.stderr.write('See http://software.opensuse.org/download/openSUSE:/Tools/\n')
             return 1
@@ -1211,7 +1208,7 @@
         if opts.failed:
             code = 'failed'
 
-        print cmd_rebuild(conf.config['apiurl'], project, package, repo, arch, code)
+        print rebuild(conf.config['apiurl'], project, package, repo, arch, code)
 
 
     def do_info(self, subcmd, opts, *args):
@@ -1232,6 +1229,60 @@
             print p.info()
 
 
+    @cmdln.option('-a', '--arch', metavar='ARCH',
+                        help='Abort builds for a specific architecture')
+    @cmdln.option('-r', '--repo', metavar='REPO',
+                        help='Abort builds for a specific repository')
+    def do_abortbuild(self, subcmd, opts, *args):
+        """${cmd_name}: Aborts the build of a certain project/package
+        
+        With the optional argument <package> you can specify a certain package
+        otherwise all builds in the project will be cancelled.
+        
+        usage: 
+            osc abortbuild [OPTS] PROJECT [PACKAGE]
+        ${cmd_option_list}
+        """
+
+        if len(args) < 1:
+            print >>sys.stderr, 'Missing <project> argument'
+            return 2
+
+        if len(args) == 2:
+            package = args[1]
+        else:
+            package = None
+
+        print abortbuild(conf.config['apiurl'], args[0], package, opts.arch, opts.repo)
+
+
+    @cmdln.option('-a', '--arch', metavar='ARCH',
+                        help='Delete all binary package for a specific architecture')
+    @cmdln.option('-r', '--repo', metavar='REPO',
+                        help='Delete all binary packages for a specific repository')
+    def do_wipebinaries(self, subcmd, opts, *args):
+        """${cmd_name}: Delete all binary packages of a certain project/package
+
+        With the optional arguement <package> you can specify a certain package
+        otherwise all binary packages in the project will be deleted.
+
+        usage: 
+            osc wipebinaries [OPTS] PROJECT [PACKAGE]
+        ${cmd_option_list}
+        """
+        
+        if len(args) < 1:
+            print >>sys.stderr, 'Missing <project> argument'
+            return 2
+        
+        if len(args) == 2:
+            package = args[1]
+        else:
+            package = None
+        
+        print wipebinaries(conf.config['apiurl'], args[0], package, opts.arch, opts.repo)
+
+
 if __name__ == '__main__':
     osc = Osc()
     sys.exit(osc.main())
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/osc-0.96/osc/core.py new/osc-0.96/osc/core.py
--- old/osc-0.96/osc/core.py    2007-05-14 12:13:47.000000000 +0200
+++ new/osc-0.96/osc/core.py    2007-06-14 16:30:36.000000000 +0200
@@ -844,21 +844,43 @@
         if self.change_is_required == True and os.path.getmtime(self.filename) == self.timestamp:
             print 'File unchanged. Not saving.'
             os.unlink(self.filename)
+            return
 
-        else:
-            print 'Sending meta data...', 
+        try:
+            print 'Sending meta data...'
             http_PUT(self.url, file=self.filename)
             os.unlink(self.filename)
             print 'Done.'
+            return
+        except urllib2.HTTPError, e:
+            # internal server error (probably the xml file is incorrect)
+            if e.code == 500:
+                print >>sys.stderr, 'cannot save meta data - probably your xml file is incorrect'
+                print >>sys.stderr, e
+                # this may be unhelpful... because it may just print a big blob of uninteresting
+                # ichain html and javascript... however it could potentially be useful if the orign
+                # server returns an information body
+                #print >>sys.stderr, e.read()
+                return False
+            else:
+                print >> sys.stderr, 'cannot save meta data - an unexpected error occured'
+                return False
     
 def edit_meta(prj, pac, template=new_package_templ, change_is_required=True):
     f=metafile(prj, pac, template, change_is_required)
 
     editor = os.getenv('EDITOR', default='vim')
-    os.system('%s %s' % (editor, f.filename))
-
-    if change_is_required == True:
-        f.sync()
+    while 1:
+        os.system('%s %s' % (editor, f.filename))
+        if change_is_required == True:
+            if not f.sync():
+                input = raw_input('Try again? (yY = Yes - nN = No): ')
+                if input != 'y' and input != 'Y':
+                    break
+            else:
+                break
+        else:
+            break
 
 def edit_user_meta(user, change_is_required=True):
     import tempfile
@@ -1007,6 +1029,14 @@
             fromfile = '%s     (revision %s)' % (filename, rev), \
             tofile = '%s     (working copy)' % filename)
 
+        # if file doesn't end with newline, we need to append one in the diff result
+        d = list(d)
+        for i, line in enumerate(d):
+            if not line.endswith('\n'):
+                d[i] += '\n\\ No newline at end of file'
+                if i+1 != len(d):
+                    d[i] += '\n'
+
     return ''.join(d)
 
 
@@ -1316,7 +1346,7 @@
     return r
 
 
-def cmd_rebuild(apiurl, prj, package, repo, arch, code=None):
+def rebuild(apiurl, prj, package, repo, arch, code=None):
     query = []
     query.append('cmd=rebuild')
     if package:
@@ -1370,3 +1400,59 @@
 def get_osc_version():
     return __version__
 
+
+def abortbuild(apiurl, project, package=None, arch=None, repo=None):
+    query = []
+    query.append('cmd=abortbuild')
+    if package:
+        query.append('package=%s' % quote_plus(package))
+    if arch:
+        query.append('arch=%s' % quote_plus(arch))
+    if repo:
+        query.append('repository=%s' % quote_plus(repo))
+    u = makeurl(apiurl, ['build', project], query)
+    try:
+        f = http_POST(u)
+    except urllib2.HTTPError, e:
+        err_str = 'abortion failed for project %s' % project
+        if package:
+            err_str += ' package %s' % package
+        if arch:
+            err_str += ' arch %s' % arch
+        if repo:
+            err_str += ' repo %s' % repo
+        print >> sys.stderr, err_str
+        print >> sys.stderr, u
+        print >> sys.stderr, e
+        sys.exit(1)
+    root = ET.parse(f).getroot()
+    return root.get('code')
+
+
+def wipebinaries(apiurl, project, package=None, arch=None, repo=None):
+    query = []
+    query.append('cmd=wipe')
+    if package:
+        query.append('package=%s' % quote_plus(package))
+    if arch:
+        query.append('arch=%s' % quote_plus(arch))
+    if repo:
+        query.append('repository=%s' % quote_plus(repo))
+
+    u = makeurl(apiurl, ['build', project], query)
+    try:
+        f = http_POST(u)
+    except urllib2.HTTPError, e:
+        err_str = 'wipe binary rpms failed for project %s' % project
+        if package:
+            err_str += ' package %s' % package
+        if arch:
+            err_str += ' arch %s' % arch
+        if repo:
+            err_str += ' repository %s' % repo
+        print >> sys.stderr, err_str
+        print >> sys.stderr, u
+        print >> sys.stderr, e
+        sys.exit(1)
+    root = ET.parse(f).getroot()
+    return root.get('code')
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/osc-0.96/README new/osc-0.96/README
--- old/osc-0.96/README 2007-04-18 02:22:07.000000000 +0200
+++ new/osc-0.96/README 2007-05-16 12:57:38.000000000 +0200
@@ -148,3 +148,14 @@
 """
 
 chmod 0600 ~/.w3m/passwd
+
+
+NOTES about the testsuite
+
+It requires editing tests.py, for a user account / project to work with.
+I use my own project (home:poeml) for testing.
+Tests can be run as ./tests.py
+or, more powerful, with nosetests:
+  nosetests --exe
+To run a single test, you can use:
+  nosetests --exe tests:TestOsc.testCmdOptVersion
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/osc-0.96/tests.py new/osc-0.96/tests.py
--- old/osc-0.96/tests.py       2007-05-03 18:57:55.000000000 +0200
+++ new/osc-0.96/tests.py       2007-05-16 11:53:10.000000000 +0200
@@ -19,6 +19,7 @@
 PRJ = 'home:poeml'
 PAC = 'test'
 TESTPACDIR = os.path.join(PRJ, PAC)
+startdir = os.getcwd()
 
 
 def remove_revid(s):
@@ -346,6 +347,51 @@
 
 
 
+    #####################################################################
+
+    # test commandline options
+
+    def testCmdOptVersion(self):
+        self.out, self.err = runosc('--version')
+        self.assertEqual(self.err, '')
+        from osc.core import get_osc_version
+        self.assertEqual(self.out, '%s\n' % get_osc_version())
+
+    def testCmdOptHelp(self):
+        self.out, self.err = runosc('--help')
+        self.assertEqual(self.err, '')
+        self.assert_('OpenSUSE build service' in self.out)
+        self.assert_('additional information' in self.out)
+
+    def testCmdOptHelpCmd(self):
+        self.out, self.err = runosc('help')
+        self.assertEqual(self.err, '')
+        self.assert_('OpenSUSE build service' in self.out)
+        self.assert_('additional information' in self.out)
+
+    # a global option
+    def testCmdOptHelpOpt(self):
+        self.out, self.err = runosc('help')
+        self.assertEqual(self.err, '')
+        self.assert_('-H, --http-debug' in self.out)
+
+    # a subcommand option
+    def testCmdOptHelpBuild(self):
+        self.out, self.err = runosc('help build')
+        self.assertEqual(self.err, '')
+        self.assert_('build: Build a package' in self.out)
+        self.assert_('--clean' in self.out)
+
+    def testCmdOptDebugLs(self):
+        self.out, self.err = runosc('-H ls')
+        self.assertEqual(self.err, '')
+        self.assert_("send: 'GET /source" in self.out)
+
+    def testCmdOptApiOption(self):
+        self.out, self.err = runosc('-A https://api.opensuse.org -H ls')
+        self.assertEqual(self.err, '')
+        self.assert_("reply: 'HTTP/1.1 200 OK" in self.out)
+
 
 
 
@@ -373,6 +419,5 @@
 if __name__ == '__main__':
 
     #unittest.main()
-    startdir = os.getcwd()
     suite = unittest.makeSuite(TestOsc)
     unittest.TextTestRunner(verbosity=2).run(suite)



++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++



Remember to have fun...

---------------------------------------------------------------------
To unsubscribe, e-mail: opensuse-commit+unsubscribe@xxxxxxxxxxxx
For additional commands, e-mail: opensuse-commit+help@xxxxxxxxxxxx

< Previous Next >
This Thread