mirror of
https://github.com/openSUSE/osc.git
synced 2025-03-03 14:42:11 +01:00
Merged revisions 3774-3775,3779,3781-3782,3787,3789-3793,3798,3802,3805,3817-3822,3827,3829-3830,3837-3839,3841-3842,3848-3850 via svnmerge from
https://forgesvn1.novell.com/svn/opensuse/branches/buildservice/osc-exception-handling ........ r3774 | poeml | 2008-04-22 17:39:45 +0200 (Tue, 22 Apr 2008) | 3 lines A first draft on implement systematic exception handling: Add errors.py with some exceptions defined, and babysitter.py to handle them ........ r3775 | poeml | 2008-04-22 22:34:12 +0200 (Tue, 22 Apr 2008) | 9 lines - new global options: --debugger jump into the debugger before executing anything --post-mortem jump into the debugger in case of errors -t, --traceback print call trace in case of errors - traceback and post_mortem can also be set in .oscrc. - catch more errors (HTTPError). - make config accessible from outside of the Osc instance, by making it a class attribute ........ r3779 | poeml | 2008-04-23 00:55:49 +0200 (Wed, 23 Apr 2008) | 5 lines - new global option: -d, --debug print info useful for debugging - catch some more errors (HTTPError), with OscHTTPError which isn't very advanced yet. ........ r3781 | Marcus_H | 2008-04-23 01:02:00 +0200 (Wed, 23 Apr 2008) | 2 lines - added OscConfigError class (just for testing). - small change in the signature of the OscBaseError constructor (actually we should get rid of the 'args' tuple because it will be deprecated sooner or later ........ r3782 | Marcus_H | 2008-04-23 02:02:13 +0200 (Wed, 23 Apr 2008) | 2 lines - access the prg.conf.config dict in a save way - this way we avoid AttributeErrors if the prg.conf.config dict doesn't exist - in case of an configparser error we have to use the prg.options object directly (this was removed in r3781 by accident) ........ r3787 | poeml | 2008-04-23 09:23:56 +0200 (Wed, 23 Apr 2008) | 4 lines - remove local exception handling from do_req - for HTTPError, print details (headers and response) when in debug mode - catch AttributeError ........ r3789 | poeml | 2008-04-23 16:23:14 +0200 (Wed, 23 Apr 2008) | 4 lines - errors: add two new classes named OscWrongOptionsError and OscWrongArgsError - commandline: raise instances of the new errors in a number of places - commandline: add get_cmd_help() to Osc instance which returns the formatted help of a subcommand ........ r3790 | Marcus_H | 2008-04-23 16:48:28 +0200 (Wed, 23 Apr 2008) | 4 lines - added 2 new exception classes: OscNoConfigfileError and OscIOError - added new method write_config() to the conf.py module: This method writes osc's configuration file - minor cleanups in the conf module ........ r3791 | poeml | 2008-04-23 17:11:07 +0200 (Wed, 23 Apr 2008) | 3 lines small compatibility fix for r3790: try-except-finally isn't supported in python-2.4.2, thus do the same as try-except inside a try-finally. ........ r3792 | poeml | 2008-04-23 17:37:53 +0200 (Wed, 23 Apr 2008) | 2 lines fix up the remaining places regarding handling of errors related to commandline parsing ........ r3793 | poeml | 2008-04-23 17:40:34 +0200 (Wed, 23 Apr 2008) | 3 lines raise a NoWorkingCopyError in osc.core.store_read_project() in case of an IOError ........ r3798 | Marcus_H | 2008-04-23 23:55:24 +0200 (Wed, 23 Apr 2008) | 1 line ported -r3797 from trunk ........ r3802 | Marcus_H | 2008-04-24 11:00:55 +0200 (Thu, 24 Apr 2008) | 1 line ported -r3801 from trunk ........ r3805 | poeml | 2008-04-24 12:52:30 +0200 (Thu, 24 Apr 2008) | 2 lines raise OscHTTPError in show_pattern_meta(), replacing local error handling ........ r3817 | poeml | 2008-04-24 20:21:32 +0200 (Thu, 24 Apr 2008) | 9 lines - remove errors.OscHTTPError again. it seems simpler to use urllib2.HTTPError instead (and just add a specific error text message where appropriate, and re-raise) - for 404s, check out _which_ part was not found it is very ugly, but may be considered Good for pragmatic reasons - removed local exception handling and workaround for returned 500's from delete_package() and delete_project(), thereby getting rid of 4 possible exit points. ........ r3818 | Marcus_H | 2008-04-24 22:36:17 +0200 (Thu, 24 Apr 2008) | 1 line - this check is superfluous because every HTTPError instance has a code attribute ........ r3819 | poeml | 2008-04-25 00:39:39 +0200 (Fri, 25 Apr 2008) | 1 line remove a forgotten debug line from core.delete_project() ........ r3820 | poeml | 2008-04-25 10:07:58 +0200 (Fri, 25 Apr 2008) | 2 lines - ditch local error handling from wipebinaries(), rebuild(), and abortbuild() ........ r3821 | poeml | 2008-04-25 10:56:38 +0200 (Fri, 25 Apr 2008) | 2 lines It is never needed to import the exception module. ........ r3822 | poeml | 2008-04-25 11:13:39 +0200 (Fri, 25 Apr 2008) | 4 lines - when going into the debugger with --post-mortem, always print a traceback before (thus implying -t) - do not jump into the debugger if not on a TTY, or working in interactive mode ........ r3827 | poeml | 2008-04-25 13:07:46 +0200 (Fri, 25 Apr 2008) | 9 lines - add errors.OscWorkingCopyOutdated, which takes a tuple with three args: path to working copy, current rev, expected rev - add handler for urllib2.URLError errors to the babysitter - simplify the OscWrongArgsError and OscWrongOptionsError handlers, by removing the extra line "Sorry, wrong ..." that was printed before the messages given when the error was raised. - remove one more errors.OscHTTPError which was still there, and raise urllib2.HTTPError instead (show_package_meta()) ........ r3829 | poeml | 2008-04-25 14:19:10 +0200 (Fri, 25 Apr 2008) | 11 lines - comment some methods in osc.core which are used by nearly all do_* methods in osc.commandline - improve "is not a package/project dir" error messages, by printing the absolute path tried, instead of '.' for the cwd - make core.store_read_package() raise a proper NoWorkingCopyError instead of terminating - give attribution to things in babysitter.py copied from mercurial - prefix HTTPError exceptions with 'Server returned an error:' - remove obsolete local error handling from do_prjresults(), do_importsrcpkg(), do_repos() ........ r3830 | poeml | 2008-04-25 14:29:35 +0200 (Fri, 25 Apr 2008) | 1 line catch IOError exceptions in the babysitter ........ r3837 | poeml | 2008-04-25 17:27:36 +0200 (Fri, 25 Apr 2008) | 5 lines - do_remotebuildlog: raise errors for wrong arguments, remove exits - raise AttributeError in make_meta_url() instead of exiting - delete unused method core.delete_server_files() - replace exit call inside make_meta_url() with an AttributeError ........ r3838 | poeml | 2008-04-25 17:49:18 +0200 (Fri, 25 Apr 2008) | 1 line simplify the check in do_checkout if a project exists, by using show_project_meta() instead of meta_exists ........ r3839 | poeml | 2008-04-25 18:31:26 +0200 (Fri, 25 Apr 2008) | 6 lines - commandline do_checkout(): change the order of the two checks, first do the (cheaper) check for existing directory - core.core checkout_package(): simplify the check in if the package exists, by using show_package_meta() instead of meta_exists Let it throw an exception, instead of using sys.exit(). ........ r3841 | Marcus_H | 2008-04-27 15:48:06 +0200 (Sun, 27 Apr 2008) | 5 lines - added 2 new exception classes: PackageError() and PackageExistsError. The PackageError() class is meant to be the base class for all subsequent package exceptions. - get rid of 2 sys.exit(1) calls - make the update() method of the Project() class safer: in any case we have to write the _packages file otherwise the package tracking will be screwed up. - minor fix in delPackage(): use getTransActPath() when printing out the filename ........ r3842 | Marcus_H | 2008-04-27 16:52:55 +0200 (Sun, 27 Apr 2008) | 3 lines - make the commit() method safe: in any case we have to write the _packages file otherwise the package tracking will be screwed up. - removed another sys.exit(1): raise an exception if a package is missing when doing a commit. For now we use the PackageExistsError() exception but this might change in the future (updated description of PackageExistsError() according to this change) ........ r3848 | poeml | 2008-04-28 12:46:45 +0200 (Mon, 28 Apr 2008) | 3 lines rename several error classes, dropping the "Osc" prefix, and "Error" suffix in cases where they don't really make sense. ........ r3849 | poeml | 2008-04-28 12:57:32 +0200 (Mon, 28 Apr 2008) | 3 lines - rename osc.errors module to osc.oscerr, to make it easier to import it from other programs and have a crystal clear namespace ........ r3850 | poeml | 2008-04-28 13:26:12 +0200 (Mon, 28 Apr 2008) | 2 lines split PackageExists exception class into PackageExists and PackageMissing ........
This commit is contained in:
parent
f8b35ba80a
commit
3018460596
@ -5,8 +5,12 @@
|
|||||||
|
|
||||||
import sys
|
import sys
|
||||||
from osc import commandline
|
from osc import commandline
|
||||||
|
from osc import babysitter
|
||||||
|
|
||||||
|
osccli = commandline.Osc()
|
||||||
|
|
||||||
|
r = babysitter.run(osccli)
|
||||||
|
sys.exit(r)
|
||||||
|
|
||||||
osc = commandline.Osc()
|
|
||||||
sys.exit( osc.main() )
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1 +1 @@
|
|||||||
__all__ = ['core', 'commandline', 'othermethods', 'build', 'fetch', 'meter']
|
__all__ = ['babysitter', 'core', 'commandline', 'oscerr', 'othermethods', 'build', 'fetch', 'meter']
|
||||||
|
145
osc/babysitter.py
Normal file
145
osc/babysitter.py
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
# Copyright (C) 2008 Peter Poeml / Novell Inc. All rights reserved.
|
||||||
|
# This program is free software; it may be used, copied, modified
|
||||||
|
# and distributed under the terms of the GNU General Public Licence,
|
||||||
|
# either version 2, or (at your option) any later version.
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import signal
|
||||||
|
from osc import oscerr
|
||||||
|
from urllib2 import URLError, HTTPError
|
||||||
|
|
||||||
|
# the good things are stolen from Matt Mackall's mercurial
|
||||||
|
|
||||||
|
def catchterm(*args):
|
||||||
|
raise oscerr.SignalInterrupt
|
||||||
|
|
||||||
|
for name in 'SIGBREAK', 'SIGHUP', 'SIGTERM':
|
||||||
|
num = getattr(signal, name, None)
|
||||||
|
if num: signal.signal(num, catchterm)
|
||||||
|
|
||||||
|
|
||||||
|
def run(prg):
|
||||||
|
|
||||||
|
try:
|
||||||
|
|
||||||
|
try:
|
||||||
|
if '--debugger' in sys.argv:
|
||||||
|
import pdb
|
||||||
|
pdb.set_trace()
|
||||||
|
|
||||||
|
# here we actually run the program:
|
||||||
|
return prg.main()
|
||||||
|
|
||||||
|
except:
|
||||||
|
# look for an option in the prg.options object and in the config dict
|
||||||
|
# print stack trace, if desired
|
||||||
|
if getattr(prg.options, 'traceback', None) or getattr(prg.conf, 'config', {}).get('traceback', None) or \
|
||||||
|
getattr(prg.options, 'post_mortem', None) or getattr(prg.conf, 'config', {}).get('post_mortem', None):
|
||||||
|
import traceback
|
||||||
|
traceback.print_exc(file=sys.stderr)
|
||||||
|
# we could use http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52215
|
||||||
|
|
||||||
|
# enter the debugger, if desired
|
||||||
|
if getattr(prg.options, 'post_mortem', None) or getattr(prg.conf, 'config', {}).get('post_mortem', None):
|
||||||
|
if sys.stdout.isatty() and not hasattr(sys, 'ps1'):
|
||||||
|
import pdb
|
||||||
|
pdb.post_mortem(sys.exc_info()[2])
|
||||||
|
else:
|
||||||
|
print >>sys.stderr, 'sys.stdout is not a tty. Not jumping into pdb.'
|
||||||
|
raise
|
||||||
|
|
||||||
|
except oscerr.SignalInterrupt:
|
||||||
|
print >>sys.stderr, 'killed!'
|
||||||
|
return 1
|
||||||
|
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
print >>sys.stderr, 'interrupted!'
|
||||||
|
return 1
|
||||||
|
|
||||||
|
except oscerr.UnreadableFile, e:
|
||||||
|
print >>sys.stderr, e.msg
|
||||||
|
return 1
|
||||||
|
|
||||||
|
except (oscerr.NoWorkingCopy, oscerr.WorkingCopyWrongVersion), e:
|
||||||
|
print >>sys.stderr, e
|
||||||
|
return 1
|
||||||
|
|
||||||
|
except HTTPError, e:
|
||||||
|
print >>sys.stderr, 'Server returned an error:', e
|
||||||
|
if hasattr(e, 'osc_msg'):
|
||||||
|
print >>sys.stderr, e.osc_msg
|
||||||
|
|
||||||
|
if getattr(prg.options, 'debug', None) or \
|
||||||
|
getattr(prg.conf, 'config', {}).get('debug', None):
|
||||||
|
print >>sys.stderr, e.hdrs
|
||||||
|
print >>sys.stderr, e.read()
|
||||||
|
|
||||||
|
# For 404s, check out _which_ part was not found
|
||||||
|
#
|
||||||
|
# It is very ugly, but may be Good for pragmatic reasons
|
||||||
|
#
|
||||||
|
# FIXME this can be obsoleted when the api returns a more specific error code
|
||||||
|
# like "project not found" right away
|
||||||
|
if e.code == 404:
|
||||||
|
import urlparse
|
||||||
|
scheme, netloc, path = urlparse.urlsplit(e.url)[0:3]
|
||||||
|
parts = path.split('/')
|
||||||
|
# we know how to do this for /source URLs. I don't know for others right now...
|
||||||
|
if len(parts) > 1 and parts[1] == 'source':
|
||||||
|
if len(parts) == 3:
|
||||||
|
# it was a request on /source/project
|
||||||
|
print >>sys.stderr, 'A project named \'%s\' does not exist.' % parts[2]
|
||||||
|
if len(parts) == 4:
|
||||||
|
# it was a request on /source/project/package
|
||||||
|
prjurl = urlparse.urlunsplit((scheme, netloc, '/'.join(parts[:3]), None, None))
|
||||||
|
import osc.core
|
||||||
|
try:
|
||||||
|
osc.core.http_GET(prjurl)
|
||||||
|
except:
|
||||||
|
print >>sys.stderr, 'A project named \'%s\' does not exist.' % parts[2]
|
||||||
|
else:
|
||||||
|
print >>sys.stderr, \
|
||||||
|
'A package named \'%s\' does not exist in project \'%s\'.' \
|
||||||
|
% (parts[3], parts[2])
|
||||||
|
else:
|
||||||
|
# not handled...
|
||||||
|
pass
|
||||||
|
|
||||||
|
return 1
|
||||||
|
|
||||||
|
except URLError, e:
|
||||||
|
print >>sys.stderr, 'Failed to reach a server:', e.reason
|
||||||
|
return 1
|
||||||
|
|
||||||
|
except (oscerr.ConfigError, oscerr.NoConfigfile), e:
|
||||||
|
print >>sys.stderr, e.msg
|
||||||
|
return 1
|
||||||
|
|
||||||
|
except oscerr.OscIOError, e:
|
||||||
|
print >>sys.stderr, e.msg
|
||||||
|
if getattr(prg.options, 'debug', None) or \
|
||||||
|
getattr(prg.conf, 'config', {}).get('debug', None):
|
||||||
|
print >>sys.stderr, e.e
|
||||||
|
return 1
|
||||||
|
|
||||||
|
except (oscerr.WrongOptions, oscerr.WrongArgs), e:
|
||||||
|
print >>sys.stderr, e
|
||||||
|
return 2
|
||||||
|
|
||||||
|
except oscerr.WorkingCopyOutdated, e:
|
||||||
|
print >>sys.stderr, e
|
||||||
|
return 1
|
||||||
|
|
||||||
|
except (oscerr.PackageExists, oscerr.PackageMissing), e:
|
||||||
|
print >>sys.stderr, e.msg
|
||||||
|
return 1
|
||||||
|
|
||||||
|
except IOError, e:
|
||||||
|
print >>sys.stderr, e
|
||||||
|
return 1
|
||||||
|
|
||||||
|
except AttributeError, e:
|
||||||
|
print >>sys.stderr, e
|
||||||
|
return 1
|
@ -9,6 +9,7 @@
|
|||||||
from core import *
|
from core import *
|
||||||
import cmdln
|
import cmdln
|
||||||
import conf
|
import conf
|
||||||
|
import oscerr
|
||||||
|
|
||||||
|
|
||||||
class Osc(cmdln.Cmdln):
|
class Osc(cmdln.Cmdln):
|
||||||
@ -26,6 +27,7 @@ class Osc(cmdln.Cmdln):
|
|||||||
* http://www.opensuse.org/Build_Service/CLI
|
* http://www.opensuse.org/Build_Service/CLI
|
||||||
"""
|
"""
|
||||||
name = 'osc'
|
name = 'osc'
|
||||||
|
conf = None
|
||||||
|
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
@ -37,8 +39,16 @@ class Osc(cmdln.Cmdln):
|
|||||||
"""this is the parser for "global" options (not specific to subcommand)"""
|
"""this is the parser for "global" options (not specific to subcommand)"""
|
||||||
|
|
||||||
optparser = cmdln.CmdlnOptionParser(self, version=get_osc_version())
|
optparser = cmdln.CmdlnOptionParser(self, version=get_osc_version())
|
||||||
|
optparser.add_option('--debugger', action='store_true',
|
||||||
|
help='jump into the debugger before executing anything')
|
||||||
|
optparser.add_option('--post-mortem', action='store_true',
|
||||||
|
help='jump into the debugger in case of errors')
|
||||||
|
optparser.add_option('-t', '--traceback', action='store_true',
|
||||||
|
help='print call trace in case of errors')
|
||||||
optparser.add_option('-H', '--http-debug', action='store_true',
|
optparser.add_option('-H', '--http-debug', action='store_true',
|
||||||
help='debug HTTP traffic')
|
help='debug HTTP traffic')
|
||||||
|
optparser.add_option('-d', '--debug', action='store_true',
|
||||||
|
help='print info useful for debugging')
|
||||||
optparser.add_option('-A', '--apisrv', dest='apisrv',
|
optparser.add_option('-A', '--apisrv', dest='apisrv',
|
||||||
metavar='URL',
|
metavar='URL',
|
||||||
help='specify URL to access API server at')
|
help='specify URL to access API server at')
|
||||||
@ -50,10 +60,41 @@ class Osc(cmdln.Cmdln):
|
|||||||
|
|
||||||
def postoptparse(self):
|
def postoptparse(self):
|
||||||
"""merge commandline options into the config"""
|
"""merge commandline options into the config"""
|
||||||
|
try:
|
||||||
|
conf.get_config(override_conffile = self.options.conffile,
|
||||||
|
override_apisrv = self.options.apisrv,
|
||||||
|
override_debug = self.options.debug,
|
||||||
|
override_http_debug = self.options.http_debug,
|
||||||
|
override_traceback = self.options.traceback,
|
||||||
|
override_post_mortem = self.options.post_mortem)
|
||||||
|
except oscerr.NoConfigfile, e:
|
||||||
|
print >>sys.stderr, e.msg
|
||||||
|
print >>sys.stderr, 'Creating osc configuration file %s ...' % e.file
|
||||||
|
import getpass
|
||||||
|
config = {}
|
||||||
|
config['user'] = raw_input('Username: ')
|
||||||
|
config['pass'] = getpass.getpass()
|
||||||
|
|
||||||
conf.get_config(override_conffile = self.options.conffile,
|
if conf.write_config(e.file, config):
|
||||||
override_http_debug = self.options.http_debug,
|
print >>sys.stderr, 'done'
|
||||||
override_apisrv = self.options.apisrv)
|
conf.get_config(override_conffile = self.options.conffile,
|
||||||
|
override_apisrv = self.options.apisrv,
|
||||||
|
override_debug = self.options.debug,
|
||||||
|
override_http_debug = self.options.http_debug,
|
||||||
|
override_traceback = self.options.traceback,
|
||||||
|
override_post_mortem = self.options.post_mortem)
|
||||||
|
else:
|
||||||
|
raise NoConfigfile(e.file, 'Unable to create osc\'s configuration file \
|
||||||
|
\'%s\'' % e.file)
|
||||||
|
self.conf = conf
|
||||||
|
|
||||||
|
|
||||||
|
def get_cmd_help(self, cmdname):
|
||||||
|
doc = self._get_cmd_handler(cmdname).__doc__
|
||||||
|
doc = self._help_reindent(doc)
|
||||||
|
doc = self._help_preprocess(doc, cmdname)
|
||||||
|
doc = doc.rstrip() + '\n' # trim down trailing space
|
||||||
|
return self._str(doc)
|
||||||
|
|
||||||
|
|
||||||
def do_init(self, subcmd, opts, project, package):
|
def do_init(self, subcmd, opts, project, package):
|
||||||
@ -117,15 +158,13 @@ class Osc(cmdln.Cmdln):
|
|||||||
package = args[1]
|
package = args[1]
|
||||||
|
|
||||||
if opts.binaries and (not opts.repo or not opts.arch):
|
if opts.binaries and (not opts.repo or not opts.arch):
|
||||||
sys.exit('missing options:\n'
|
raise oscerr.WrongOptions('Sorry, -r <repo> -a <arch> missing\n'
|
||||||
'-r <repo> -a <arch>\n'
|
'You can list repositories with: \'osc platforms <project>\'')
|
||||||
'list repositories with:\n'
|
|
||||||
'\'osc platforms %s\'' %project)
|
|
||||||
|
|
||||||
# list binaries
|
# list binaries
|
||||||
if opts.binaries:
|
if opts.binaries:
|
||||||
if not args:
|
if not args:
|
||||||
sys.exit('there are no binaries to list above project level.')
|
raise oscerr.WrongArgs('There are no binaries to list above project level.')
|
||||||
|
|
||||||
elif len(args) == 1:
|
elif len(args) == 1:
|
||||||
#if opts.verbose:
|
#if opts.verbose:
|
||||||
@ -144,7 +183,7 @@ class Osc(cmdln.Cmdln):
|
|||||||
|
|
||||||
elif len(args) == 1:
|
elif len(args) == 1:
|
||||||
if opts.verbose:
|
if opts.verbose:
|
||||||
sys.exit('The verbose option is not implemented for projects.')
|
raise oscerr.WrongOptions('Sorry, the --verbose option is not implemented for projects.')
|
||||||
|
|
||||||
print '\n'.join(meta_get_packagelist(conf.config['apiurl'], project))
|
print '\n'.join(meta_get_packagelist(conf.config['apiurl'], project))
|
||||||
|
|
||||||
@ -211,8 +250,8 @@ class Osc(cmdln.Cmdln):
|
|||||||
args = slash_split(args)
|
args = slash_split(args)
|
||||||
|
|
||||||
if not args or args[0] not in metatypes.keys():
|
if not args or args[0] not in metatypes.keys():
|
||||||
print >>sys.stderr, 'Unknown meta type. Choose one of %s.' % ', '.join(metatypes)
|
raise oscerr.WrongArgs('Unknown meta type. Choose one of %s.' \
|
||||||
return 2
|
% ', '.join(metatypes))
|
||||||
|
|
||||||
cmd = args[0]
|
cmd = args[0]
|
||||||
del args[0]
|
del args[0]
|
||||||
@ -224,11 +263,9 @@ class Osc(cmdln.Cmdln):
|
|||||||
else:
|
else:
|
||||||
min_args, max_args = 1, 1
|
min_args, max_args = 1, 1
|
||||||
if len(args) < min_args:
|
if len(args) < min_args:
|
||||||
print >>sys.stderr, 'Too few arguments.'
|
raise oscerr.WrongArgs('Too few arguments.')
|
||||||
return 2
|
|
||||||
if len(args) > max_args:
|
if len(args) > max_args:
|
||||||
print >>sys.stderr, 'Too many arguments.'
|
raise oscerr.WrongArgs('Too many arguments.')
|
||||||
return 2
|
|
||||||
|
|
||||||
# specific arguments
|
# specific arguments
|
||||||
if cmd == 'prj':
|
if cmd == 'prj':
|
||||||
@ -247,7 +284,7 @@ class Osc(cmdln.Cmdln):
|
|||||||
pattern = None
|
pattern = None
|
||||||
# enforce pattern argument if needed
|
# enforce pattern argument if needed
|
||||||
if opts.edit or opts.file:
|
if opts.edit or opts.file:
|
||||||
sys.exit('a pattern file argument is required.')
|
raise oscerr.WrongArgs('A pattern file argument is required.')
|
||||||
|
|
||||||
# show
|
# show
|
||||||
if not opts.edit and not opts.file and not opts.delete:
|
if not opts.edit and not opts.file and not opts.delete:
|
||||||
@ -395,8 +432,8 @@ class Osc(cmdln.Cmdln):
|
|||||||
|
|
||||||
cmds = ['create', 'list', 'show', 'decline', 'accept']
|
cmds = ['create', 'list', 'show', 'decline', 'accept']
|
||||||
if not args or args[0] not in cmds:
|
if not args or args[0] not in cmds:
|
||||||
print >>sys.stderr, 'Unknown submitreq action. Choose one of %s.' % ', '.join(cmds)
|
raise oscerr.WrongArgs('Unknown submitreq action. Choose one of %s.' \
|
||||||
return 2
|
% ', '.join(cmds))
|
||||||
|
|
||||||
cmd = args[0]
|
cmd = args[0]
|
||||||
del args[0]
|
del args[0]
|
||||||
@ -408,11 +445,9 @@ class Osc(cmdln.Cmdln):
|
|||||||
else:
|
else:
|
||||||
min_args, max_args = 1, 1
|
min_args, max_args = 1, 1
|
||||||
if len(args) < min_args:
|
if len(args) < min_args:
|
||||||
print >>sys.stderr, 'Too few arguments.'
|
raise oscerr.WrongArgs('Too few arguments.')
|
||||||
return 2
|
|
||||||
if len(args) > max_args:
|
if len(args) > max_args:
|
||||||
print >>sys.stderr, 'Too many arguments.'
|
raise oscerr.WrongArgs('Too many arguments.')
|
||||||
return 2
|
|
||||||
|
|
||||||
# collect specific arguments
|
# collect specific arguments
|
||||||
if cmd == 'create':
|
if cmd == 'create':
|
||||||
@ -459,7 +494,8 @@ class Osc(cmdln.Cmdln):
|
|||||||
r.dst_project, r.dst_package, None,
|
r.dst_project, r.dst_package, None,
|
||||||
r.src_project, r.src_package, r.src_md5)
|
r.src_project, r.src_package, r.src_md5)
|
||||||
except urllib2.HTTPError, e:
|
except urllib2.HTTPError, e:
|
||||||
print >>sys.stderr, 'Diff not possible:', e
|
e.osc_msg = 'Diff not possible'
|
||||||
|
raise
|
||||||
|
|
||||||
|
|
||||||
# decline
|
# decline
|
||||||
@ -521,9 +557,8 @@ class Osc(cmdln.Cmdln):
|
|||||||
args = slash_split(args)
|
args = slash_split(args)
|
||||||
|
|
||||||
if not args or len(args) < 3:
|
if not args or len(args) < 3:
|
||||||
print >>sys.stderr, 'Incorrect number of argument.'
|
raise oscerr.WrongArgs('Incorrect number of arguments.\n\n' \
|
||||||
self.do_help([None, 'linkpac'])
|
+ self.get_cmd_help('linkpac'))
|
||||||
return 2
|
|
||||||
|
|
||||||
src_project = args[0]
|
src_project = args[0]
|
||||||
src_package = args[1]
|
src_package = args[1]
|
||||||
@ -552,9 +587,8 @@ class Osc(cmdln.Cmdln):
|
|||||||
args = slash_split(args)
|
args = slash_split(args)
|
||||||
|
|
||||||
if not args or len(args) < 3:
|
if not args or len(args) < 3:
|
||||||
print >>sys.stderr, 'Incorrect number of argument.'
|
raise oscerr.WrongArgs('Incorrect number of arguments.\n\n' \
|
||||||
self.do_help([None, 'aggregatepac'])
|
+ self.get_cmd_help('aggregatepac'))
|
||||||
return 2
|
|
||||||
|
|
||||||
src_project = args[0]
|
src_project = args[0]
|
||||||
src_package = args[1]
|
src_package = args[1]
|
||||||
@ -595,9 +629,8 @@ class Osc(cmdln.Cmdln):
|
|||||||
args = slash_split(args)
|
args = slash_split(args)
|
||||||
|
|
||||||
if not args or len(args) < 3:
|
if not args or len(args) < 3:
|
||||||
print >>sys.stderr, 'Incorrect number of argument.'
|
raise oscerr.WrongArgs('Incorrect number of arguments.\n\n' \
|
||||||
self.do_help([None, 'copypac'])
|
+ self.get_cmd_help('copypac'))
|
||||||
return 2
|
|
||||||
|
|
||||||
src_project = args[0]
|
src_project = args[0]
|
||||||
src_package = args[1]
|
src_package = args[1]
|
||||||
@ -616,8 +649,7 @@ class Osc(cmdln.Cmdln):
|
|||||||
if src_project == dst_project and \
|
if src_project == dst_project and \
|
||||||
src_package == dst_package and \
|
src_package == dst_package and \
|
||||||
src_apiurl == dst_apiurl:
|
src_apiurl == dst_apiurl:
|
||||||
print >>sys.stderr, 'Error: source and destination are the same.'
|
raise oscerr.WrongArgs('Source and destination are the same.')
|
||||||
return 1
|
|
||||||
|
|
||||||
if src_apiurl != dst_apiurl:
|
if src_apiurl != dst_apiurl:
|
||||||
opts.client_side_copy = True
|
opts.client_side_copy = True
|
||||||
@ -679,7 +711,6 @@ class Osc(cmdln.Cmdln):
|
|||||||
specfile = None
|
specfile = None
|
||||||
pacs = findpacs(args)
|
pacs = findpacs(args)
|
||||||
for p in pacs:
|
for p in pacs:
|
||||||
|
|
||||||
p.read_meta_from_spec(specfile)
|
p.read_meta_from_spec(specfile)
|
||||||
p.update_package_meta()
|
p.update_package_meta()
|
||||||
|
|
||||||
@ -823,24 +854,22 @@ class Osc(cmdln.Cmdln):
|
|||||||
rev, expand_link=opts.expand_link, prj_dir=project)
|
rev, expand_link=opts.expand_link, prj_dir=project)
|
||||||
|
|
||||||
elif project:
|
elif project:
|
||||||
if not os.path.exists(project):
|
if os.path.exists(project):
|
||||||
if meta_exists(metatype='prj', path_args=quote_plus(project), create_new=False):
|
sys.exit('osc: project \'%s\' already exists' % project)
|
||||||
init_project_dir(conf.config['apiurl'], project, project)
|
|
||||||
print statfrmt('A', project)
|
# check if the project does exist (show_project_meta will throw an exception)
|
||||||
else:
|
show_project_meta(conf.config['apiurl'], project)
|
||||||
print >>sys.stderr, 'osc: project \'%s\' does not exist on the server' % project
|
|
||||||
sys.exit(1)
|
init_project_dir(conf.config['apiurl'], project, project)
|
||||||
else:
|
print statfrmt('A', project)
|
||||||
print >>sys.stderr, 'osc: project \'%s\' already exists' % project
|
|
||||||
sys.exit(1)
|
|
||||||
# all packages
|
# all packages
|
||||||
for package in meta_get_packagelist(conf.config['apiurl'], project):
|
for package in meta_get_packagelist(conf.config['apiurl'], project):
|
||||||
checkout_package(conf.config['apiurl'], project, package,
|
checkout_package(conf.config['apiurl'], project, package,
|
||||||
expand_link=opts.expand_link, prj_dir=project)
|
expand_link=opts.expand_link, prj_dir=project)
|
||||||
else:
|
else:
|
||||||
print >>sys.stderr, 'Missing argument.'
|
raise oscerr.WrongArgs('Missing argument.\n\n' \
|
||||||
self.do_help([None, 'checkout'])
|
+ self.get_cmd_help('checkout'))
|
||||||
return 2
|
|
||||||
|
|
||||||
|
|
||||||
@cmdln.option('-v', '--verbose', action='store_true',
|
@cmdln.option('-v', '--verbose', action='store_true',
|
||||||
@ -897,8 +926,8 @@ class Osc(cmdln.Cmdln):
|
|||||||
elif os.path.isfile(arg):
|
elif os.path.isfile(arg):
|
||||||
pacpaths.append(arg)
|
pacpaths.append(arg)
|
||||||
else:
|
else:
|
||||||
print >>sys.stderr, 'osc: error: \'%s\' is neither a project or a package directory' % arg
|
msg = '\'%s\' is neither a project or a package directory' % arg
|
||||||
return 1
|
raise oscerr.NoWorkingCopy, msg
|
||||||
lines = []
|
lines = []
|
||||||
# process single packages
|
# process single packages
|
||||||
lines = getStatus(findpacs(pacpaths), None, opts.verbose)
|
lines = getStatus(findpacs(pacpaths), None, opts.verbose)
|
||||||
@ -917,9 +946,8 @@ class Osc(cmdln.Cmdln):
|
|||||||
${cmd_option_list}
|
${cmd_option_list}
|
||||||
"""
|
"""
|
||||||
if not args:
|
if not args:
|
||||||
print >>sys.stderr, 'Missing argument.'
|
raise oscerr.WrongArgs('Missing argument.\n\n' \
|
||||||
self.do_help([None, 'add'])
|
+ self.get_cmd_help('add'))
|
||||||
return 2
|
|
||||||
|
|
||||||
filenames = parseargs(args)
|
filenames = parseargs(args)
|
||||||
#print filenames
|
#print filenames
|
||||||
@ -938,8 +966,8 @@ class Osc(cmdln.Cmdln):
|
|||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
if len(args) != 1:
|
if len(args) != 1:
|
||||||
print >>sys.stderr, 'wrong number of arguments!'
|
raise oscerr.WrongArgs('Wrong number of arguments.')
|
||||||
sys.exit(1)
|
|
||||||
createPackageDir(args[0])
|
createPackageDir(args[0])
|
||||||
|
|
||||||
|
|
||||||
@ -1098,8 +1126,8 @@ class Osc(cmdln.Cmdln):
|
|||||||
if (opts.expand_link and opts.unexpand_link) \
|
if (opts.expand_link and opts.unexpand_link) \
|
||||||
or (opts.expand_link and opts.revision) \
|
or (opts.expand_link and opts.revision) \
|
||||||
or (opts.unexpand_link and opts.revision):
|
or (opts.unexpand_link and opts.revision):
|
||||||
sys.exit('The options --expand-link, --unexpand-link and '
|
raise oscerr.WrongOptions('Sorry, the options --expand-link, --unexpand-link and '
|
||||||
'--revision are mutually exclusive')
|
'--revision are mutually exclusive.')
|
||||||
|
|
||||||
if opts.revision and ( len(args) == 1):
|
if opts.revision and ( len(args) == 1):
|
||||||
rev, dummy = parseRevisionOption(opts.revision)
|
rev, dummy = parseRevisionOption(opts.revision)
|
||||||
@ -1140,9 +1168,8 @@ class Osc(cmdln.Cmdln):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
if not args:
|
if not args:
|
||||||
print >>sys.stderr, 'Missing argument.'
|
raise oscerr.WrongArgs('Missing argument.\n\n' \
|
||||||
self.do_help([None, 'delete'])
|
+ self.get_cmd_help('delete'))
|
||||||
return 2
|
|
||||||
|
|
||||||
args = parseargs(args)
|
args = parseargs(args)
|
||||||
# check if args contains a package which was removed by
|
# check if args contains a package which was removed by
|
||||||
@ -1199,9 +1226,8 @@ class Osc(cmdln.Cmdln):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
if not args:
|
if not args:
|
||||||
print >>sys.stderr, 'Missing argument.'
|
raise oscerr.WrongArgs('Missing argument.\n\n' \
|
||||||
self.do_help([None, 'resolved'])
|
+ self.get_cmd_help('resolved'))
|
||||||
return 2
|
|
||||||
|
|
||||||
args = parseargs(args)
|
args = parseargs(args)
|
||||||
pacs = findpacs(args)
|
pacs = findpacs(args)
|
||||||
@ -1296,12 +1322,8 @@ class Osc(cmdln.Cmdln):
|
|||||||
else:
|
else:
|
||||||
wd = os.curdir
|
wd = os.curdir
|
||||||
|
|
||||||
try:
|
project = store_read_project(wd)
|
||||||
project = store_read_project(wd)
|
apiurl = store_read_apiurl(wd)
|
||||||
apiurl = store_read_apiurl(wd)
|
|
||||||
except:
|
|
||||||
print >>sys.stderr, '\'%s\' is neither an osc project or package directory' % wd
|
|
||||||
return 1
|
|
||||||
|
|
||||||
print '\n'.join(get_prj_results(apiurl, project, show_legend=opts.legend, csv=opts.csv))
|
print '\n'.join(get_prj_results(apiurl, project, show_legend=opts.legend, csv=opts.csv))
|
||||||
|
|
||||||
@ -1344,11 +1366,9 @@ class Osc(cmdln.Cmdln):
|
|||||||
"""
|
"""
|
||||||
args = slash_split(args)
|
args = slash_split(args)
|
||||||
if len(args) < 4:
|
if len(args) < 4:
|
||||||
print >>sys.stderr, "too few arguments"
|
raise oscerr.WrongArgs('Too few arguments.')
|
||||||
sys.exit(1)
|
|
||||||
elif len(args) > 4:
|
elif len(args) > 4:
|
||||||
print >>sys.stderr, "too many arguments"
|
raise oscerr.WrongArgs('Too many arguments.')
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
print_buildlog(conf.config['apiurl'], *args)
|
print_buildlog(conf.config['apiurl'], *args)
|
||||||
|
|
||||||
@ -1385,12 +1405,11 @@ class Osc(cmdln.Cmdln):
|
|||||||
apiurl = store_read_apiurl(wd)
|
apiurl = store_read_apiurl(wd)
|
||||||
|
|
||||||
if args is None or len(args) < 2:
|
if args is None or len(args) < 2:
|
||||||
print >>sys.stderr, 'Missing argument.'
|
|
||||||
print 'Valid arguments for this package are:'
|
print 'Valid arguments for this package are:'
|
||||||
print
|
print
|
||||||
self.do_repos(None, None)
|
self.do_repos(None, None)
|
||||||
print
|
print
|
||||||
return 2
|
raise oscerr.WrongArgs('Missing argument')
|
||||||
|
|
||||||
platform = args[0]
|
platform = args[0]
|
||||||
arch = args[1]
|
arch = args[1]
|
||||||
@ -1450,10 +1469,6 @@ class Osc(cmdln.Cmdln):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
args = parseargs(args)
|
args = parseargs(args)
|
||||||
for arg in args:
|
|
||||||
if not is_project_dir(arg) and not is_package_dir(arg):
|
|
||||||
print >>sys.stderr, '\'%s\' is neither a package dir nor a project dir' % arg
|
|
||||||
args.remove(arg)
|
|
||||||
|
|
||||||
for arg in args:
|
for arg in args:
|
||||||
for platform in get_repos_of_project(store_read_apiurl(arg), store_read_project(arg)):
|
for platform in get_repos_of_project(store_read_apiurl(arg), store_read_project(arg)):
|
||||||
@ -1532,25 +1547,22 @@ class Osc(cmdln.Cmdln):
|
|||||||
return 1
|
return 1
|
||||||
|
|
||||||
if len(args) == 2:
|
if len(args) == 2:
|
||||||
print >>sys.stderr, 'Missing argument: build description (spec of dsc file)'
|
raise oscerr.WrongArgs('Missing argument: build description (spec of dsc file)')
|
||||||
return 2
|
|
||||||
elif len(args) < 2:
|
elif len(args) < 2:
|
||||||
print
|
# we are going to raise an error for this, but first look up some helpful details:
|
||||||
print >>sys.stderr, 'Missing argument.'
|
msg= ['You have to choose a repo to build on.']
|
||||||
print 'Valid arguments are:'
|
msg.append('Possible repositories on this machine are:\n')
|
||||||
print 'you have to choose a repo to build on'
|
|
||||||
print 'possible repositories on this machine are:'
|
|
||||||
print
|
|
||||||
for platform in get_repos_of_project(store_read_apiurl(os.curdir),
|
for platform in get_repos_of_project(store_read_apiurl(os.curdir),
|
||||||
store_read_project(os.curdir)):
|
store_read_project(os.curdir)):
|
||||||
arch = platform.split()[1] # arch
|
arch = platform.split()[1] # arch
|
||||||
if arch == osc.build.hostarch or \
|
if arch == osc.build.hostarch or \
|
||||||
arch in osc.build.can_also_build.get(osc.build.hostarch, []):
|
arch in osc.build.can_also_build.get(osc.build.hostarch, []):
|
||||||
print platform.strip()
|
msg.append(platform.strip())
|
||||||
return 2
|
raise oscerr.WrongArgs('Missing argument.\n\n' + '\n'.join(msg))
|
||||||
|
|
||||||
elif len(args) > 3:
|
elif len(args) > 3:
|
||||||
print >>sys.stderr, 'too many arguments'
|
raise oscerr.WrongArgs('Too many arguments')
|
||||||
return 2
|
|
||||||
|
|
||||||
if opts.prefer_pkgs:
|
if opts.prefer_pkgs:
|
||||||
for d in opts.prefer_pkgs:
|
for d in opts.prefer_pkgs:
|
||||||
@ -1634,9 +1646,7 @@ class Osc(cmdln.Cmdln):
|
|||||||
args = slash_split(args)
|
args = slash_split(args)
|
||||||
|
|
||||||
if len(args) < 1:
|
if len(args) < 1:
|
||||||
print >>sys.stderr, 'Missing argument.'
|
raise oscerr.WrongArgs('Missing argument.')
|
||||||
#self.do_help([None, 'rebuildpac'])
|
|
||||||
return 2
|
|
||||||
|
|
||||||
package = repo = arch = code = None
|
package = repo = arch = code = None
|
||||||
project = args[0]
|
project = args[0]
|
||||||
@ -1687,8 +1697,7 @@ class Osc(cmdln.Cmdln):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
if len(args) < 1:
|
if len(args) < 1:
|
||||||
print >>sys.stderr, 'Missing <project> argument'
|
raise oscerr.WrongArgs('Missing <project> argument.')
|
||||||
return 2
|
|
||||||
|
|
||||||
if len(args) == 2:
|
if len(args) == 2:
|
||||||
package = args[1]
|
package = args[1]
|
||||||
@ -1722,8 +1731,7 @@ class Osc(cmdln.Cmdln):
|
|||||||
args = slash_split(args)
|
args = slash_split(args)
|
||||||
|
|
||||||
if len(args) < 1:
|
if len(args) < 1:
|
||||||
print >>sys.stderr, 'Missing <project> argument'
|
raise oscerr.WrongArgs('Missing <project> argument.')
|
||||||
return 2
|
|
||||||
|
|
||||||
if len(args) == 2:
|
if len(args) == 2:
|
||||||
package = args[1]
|
package = args[1]
|
||||||
@ -1773,11 +1781,9 @@ class Osc(cmdln.Cmdln):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
if len(args) > 1:
|
if len(args) > 1:
|
||||||
print >>sys.stderr, 'too many arguments'
|
raise oscerr.WrongArgs('Too many arguments.')
|
||||||
sys.exit(1)
|
|
||||||
elif len(args) < 1:
|
elif len(args) < 1:
|
||||||
print >>sys.stderr, 'too few arguments'
|
raise oscerr.WrongArgs('Too few arguments.')
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
search_list = []
|
search_list = []
|
||||||
search_for = []
|
search_for = []
|
||||||
@ -1872,14 +1878,10 @@ class Osc(cmdln.Cmdln):
|
|||||||
else:
|
else:
|
||||||
project_dir = os.curdir
|
project_dir = os.curdir
|
||||||
|
|
||||||
if not is_project_dir(project_dir):
|
if conf.config['do_package_tracking']:
|
||||||
print >>sys.stderr, 'project dir \'%s\' does not exist' % project_dir
|
project = Project(project_dir)
|
||||||
sys.exit(1)
|
|
||||||
else:
|
else:
|
||||||
if conf.config['do_package_tracking']:
|
project = store_read_project(project_dir)
|
||||||
project = Project(project_dir)
|
|
||||||
else:
|
|
||||||
project = store_read_project(project_dir)
|
|
||||||
|
|
||||||
rpm_data = data_from_rpm(srpm, 'Name:', 'Summary:', '%description')
|
rpm_data = data_from_rpm(srpm, 'Name:', 'Summary:', '%description')
|
||||||
if rpm_data:
|
if rpm_data:
|
||||||
@ -1999,34 +2001,13 @@ class Osc(cmdln.Cmdln):
|
|||||||
if opts.headers:
|
if opts.headers:
|
||||||
opts.headers = dict(opts.headers)
|
opts.headers = dict(opts.headers)
|
||||||
|
|
||||||
try:
|
r = http_request(opts.method,
|
||||||
r = http_request(opts.method,
|
url,
|
||||||
url,
|
data=opts.data,
|
||||||
data=opts.data,
|
file=opts.file,
|
||||||
file=opts.file,
|
headers=opts.headers)
|
||||||
headers=opts.headers)
|
|
||||||
|
|
||||||
except urllib2.HTTPError, e:
|
|
||||||
if e.code in [400, 404]:
|
|
||||||
print >>sys.stderr, e
|
|
||||||
print >>sys.stderr, e.read()
|
|
||||||
sys.exit(1)
|
|
||||||
elif e.code == 500:
|
|
||||||
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
|
|
||||||
if conf.config['http_debug']:
|
|
||||||
print >>sys.stderr, e.read()
|
|
||||||
sys.exit(1)
|
|
||||||
else:
|
|
||||||
sys.exit('unexpected error')
|
|
||||||
|
|
||||||
try:
|
|
||||||
out = r.read()
|
|
||||||
except:
|
|
||||||
sys.exit('failed to read from file object')
|
|
||||||
|
|
||||||
|
out = r.read()
|
||||||
sys.stdout.write(out)
|
sys.stdout.write(out)
|
||||||
|
|
||||||
|
|
||||||
@ -2060,7 +2041,7 @@ class Osc(cmdln.Cmdln):
|
|||||||
prj = args[0]
|
prj = args[0]
|
||||||
pac = args[1]
|
pac = args[1]
|
||||||
else:
|
else:
|
||||||
sys.exit('wrong argument count')
|
raise oscerr.WrongArgs('I need at least one argument.')
|
||||||
|
|
||||||
maintainers = []
|
maintainers = []
|
||||||
|
|
||||||
@ -2107,8 +2088,7 @@ class Osc(cmdln.Cmdln):
|
|||||||
|
|
||||||
args = slash_split(args)
|
args = slash_split(args)
|
||||||
if len(args) != 3:
|
if len(args) != 3:
|
||||||
print >>sys.stderr, 'error - incorrect number of arguments'
|
raise oscerr.WrongArgs('Wrong number of arguments.')
|
||||||
sys.exit(1)
|
|
||||||
rev, dummy = parseRevisionOption(opts.revision)
|
rev, dummy = parseRevisionOption(opts.revision)
|
||||||
|
|
||||||
import tempfile
|
import tempfile
|
||||||
|
83
osc/conf.py
83
osc/conf.py
@ -33,6 +33,7 @@ The configuration dictionary could look like this:
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import ConfigParser
|
import ConfigParser
|
||||||
|
from osc import oscerr
|
||||||
|
|
||||||
# being global to this module, this dict can be accessed from outside
|
# being global to this module, this dict can be accessed from outside
|
||||||
# it will hold the parsed configuration
|
# it will hold the parsed configuration
|
||||||
@ -55,12 +56,15 @@ DEFAULTS = { 'apisrv': 'https://api.opensuse.org/',
|
|||||||
'%(scheme)s://%(apisrv)s/build/%(project)s/%(repository)s/%(buildarch)s/_repository/%(name)s',
|
'%(scheme)s://%(apisrv)s/build/%(project)s/%(repository)s/%(buildarch)s/_repository/%(name)s',
|
||||||
],
|
],
|
||||||
|
|
||||||
|
'debug': '0',
|
||||||
'http_debug': '0',
|
'http_debug': '0',
|
||||||
|
'traceback': '0',
|
||||||
|
'post_mortem': '0',
|
||||||
'cookiejar': '~/.osc_cookiejar',
|
'cookiejar': '~/.osc_cookiejar',
|
||||||
# disable project tracking by default
|
# disable project tracking by default
|
||||||
'do_package_tracking': '0',
|
'do_package_tracking': '0',
|
||||||
}
|
}
|
||||||
boolean_opts = ['http_debug', 'do_package_tracking']
|
boolean_opts = ['debug', 'do_package_tracking', 'http_debug', 'post_mortem', 'traceback']
|
||||||
|
|
||||||
new_conf_template = """
|
new_conf_template = """
|
||||||
[general]
|
[general]
|
||||||
@ -80,9 +84,18 @@ new_conf_template = """
|
|||||||
# /srv/oscbuild/%%(repo)s-%%(arch)s
|
# /srv/oscbuild/%%(repo)s-%%(arch)s
|
||||||
#build-root = %(build-root)s
|
#build-root = %(build-root)s
|
||||||
|
|
||||||
|
# show info useful for debugging
|
||||||
|
#debug = 1
|
||||||
|
|
||||||
# show HTTP traffic useful for debugging
|
# show HTTP traffic useful for debugging
|
||||||
#http_debug = 1
|
#http_debug = 1
|
||||||
|
|
||||||
|
# jump into the debugger in case of errors
|
||||||
|
#post_mortem = 1
|
||||||
|
|
||||||
|
# print call traces in case of errors
|
||||||
|
#traceback = 1
|
||||||
|
|
||||||
[%(apisrv)s]
|
[%(apisrv)s]
|
||||||
user = %(user)s
|
user = %(user)s
|
||||||
pass = %(pass)s
|
pass = %(pass)s
|
||||||
@ -192,9 +205,42 @@ def get_configParser(conffile=None, force_read=False):
|
|||||||
return get_configParser.cp
|
return get_configParser.cp
|
||||||
|
|
||||||
|
|
||||||
|
def write_config(conffile, entries, custom_template = None, force = False):
|
||||||
|
"""
|
||||||
|
write osc's configuration file. entries is a dict which contains values
|
||||||
|
for the config file (e.g. { 'user' : 'username', 'pass' : 'password' } ).
|
||||||
|
custom_template is an optional configuration template. Use force=True if you
|
||||||
|
want to overwrite an existing configuration file.
|
||||||
|
"""
|
||||||
|
import os
|
||||||
|
conf_template = custom_template or new_conf_template
|
||||||
|
config = DEFAULTS.copy()
|
||||||
|
config.update(entries)
|
||||||
|
if force or not os.path.exists(conffile):
|
||||||
|
file = None
|
||||||
|
try:
|
||||||
|
file = open(conffile, 'w')
|
||||||
|
except IOError, e:
|
||||||
|
raise oscerr.OscIOError(e, 'cannot open configfile \'%s\'' % conffile)
|
||||||
|
try:
|
||||||
|
try:
|
||||||
|
os.chmod(conffile, 0600)
|
||||||
|
file.write(conf_template % config)
|
||||||
|
except IOError, e:
|
||||||
|
raise oscerr.OscIOError(e, 'cannot write configfile \'s\'' % conffile)
|
||||||
|
finally:
|
||||||
|
if file: file.close()
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
def get_config(override_conffile = None,
|
def get_config(override_conffile = None,
|
||||||
|
override_apisrv = None,
|
||||||
|
override_debug = None,
|
||||||
override_http_debug = None,
|
override_http_debug = None,
|
||||||
override_apisrv = None):
|
override_traceback = None,
|
||||||
|
override_post_mortem = None):
|
||||||
"""do the actual work (see module documentation)"""
|
"""do the actual work (see module documentation)"""
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
@ -223,23 +269,8 @@ def get_config(override_conffile = None,
|
|||||||
netrc.netrc().authenticators(netrc_host)
|
netrc.netrc().authenticators(netrc_host)
|
||||||
print >>sys.stderr, 'Read credentials from %s.' % os.path.expanduser('~/.netrc')
|
print >>sys.stderr, 'Read credentials from %s.' % os.path.expanduser('~/.netrc')
|
||||||
except (IOError, TypeError, netrc.NetrcParseError):
|
except (IOError, TypeError, netrc.NetrcParseError):
|
||||||
#
|
raise oscerr.NoConfigfile(conffile, \
|
||||||
# last resort... ask the user
|
account_not_configured_text % conffile)
|
||||||
#
|
|
||||||
import getpass
|
|
||||||
print >>sys.stderr, account_not_configured_text % conffile
|
|
||||||
config['user'] = raw_input('Username: ')
|
|
||||||
config['pass'] = getpass.getpass()
|
|
||||||
|
|
||||||
print >>sys.stderr, 'Creating osc configuration file %s ...' % conffile
|
|
||||||
fd = open(conffile, 'w')
|
|
||||||
os.chmod(conffile, 0600)
|
|
||||||
fd.write(new_conf_template % config)
|
|
||||||
fd.close()
|
|
||||||
print >>sys.stderr, 'done.'
|
|
||||||
#print >>sys.stderr, ('Now re-run the command.')
|
|
||||||
#sys.exit(0)
|
|
||||||
|
|
||||||
|
|
||||||
# okay, we made sure that .oscrc exists
|
# okay, we made sure that .oscrc exists
|
||||||
|
|
||||||
@ -247,9 +278,9 @@ def get_config(override_conffile = None,
|
|||||||
|
|
||||||
if not cp.has_section('general'):
|
if not cp.has_section('general'):
|
||||||
# FIXME: it might be sufficient to just assume defaults?
|
# FIXME: it might be sufficient to just assume defaults?
|
||||||
print >>sys.stderr, config_incomplete_text % conffile
|
msg = config_incomplete_text % conffile
|
||||||
print >>sys.stderr, new_conf_template % DEFAULTS
|
msg += new_conf_template % DEFAULTS
|
||||||
sys.exit(1)
|
raise oscerr.ConfigError(msg)
|
||||||
|
|
||||||
config = dict(cp.items('general', raw=1))
|
config = dict(cp.items('general', raw=1))
|
||||||
|
|
||||||
@ -263,7 +294,7 @@ def get_config(override_conffile = None,
|
|||||||
else:
|
else:
|
||||||
config[i] = False
|
config[i] = False
|
||||||
except:
|
except:
|
||||||
sys.exit('option %s requires an integer value' % i)
|
raise oscerr.ConfigError('option %s requires an integer value' % i)
|
||||||
|
|
||||||
packagecachedir = os.path.expanduser(config['packagecachedir'])
|
packagecachedir = os.path.expanduser(config['packagecachedir'])
|
||||||
|
|
||||||
@ -283,8 +314,14 @@ def get_config(override_conffile = None,
|
|||||||
config['auth_dict'] = auth_dict
|
config['auth_dict'] = auth_dict
|
||||||
|
|
||||||
# override values which we were called with
|
# override values which we were called with
|
||||||
|
if override_debug:
|
||||||
|
config['debug'] = override_debug
|
||||||
if override_http_debug:
|
if override_http_debug:
|
||||||
config['http_debug'] = override_http_debug
|
config['http_debug'] = override_http_debug
|
||||||
|
if override_traceback:
|
||||||
|
config['traceback'] = override_traceback
|
||||||
|
if override_post_mortem:
|
||||||
|
config['post_mortem'] = override_post_mortem
|
||||||
if override_apisrv:
|
if override_apisrv:
|
||||||
config['scheme'], config['apisrv'] = \
|
config['scheme'], config['apisrv'] = \
|
||||||
parse_apisrv_url(config['scheme'], override_apisrv)
|
parse_apisrv_url(config['scheme'], override_apisrv)
|
||||||
|
354
osc/core.py
354
osc/core.py
@ -14,6 +14,7 @@ from urllib import pathname2url, quote_plus, urlencode
|
|||||||
from urlparse import urlsplit, urlunsplit
|
from urlparse import urlsplit, urlunsplit
|
||||||
from cStringIO import StringIO
|
from cStringIO import StringIO
|
||||||
import shutil
|
import shutil
|
||||||
|
import oscerr
|
||||||
import conf
|
import conf
|
||||||
try:
|
try:
|
||||||
from xml.etree import cElementTree as ET
|
from xml.etree import cElementTree as ET
|
||||||
@ -252,8 +253,8 @@ class Project:
|
|||||||
|
|
||||||
if conf.config['do_package_tracking'] and pac in self.pacs_unvers:
|
if conf.config['do_package_tracking'] and pac in self.pacs_unvers:
|
||||||
# pac is not under version control but a local file/dir exists
|
# pac is not under version control but a local file/dir exists
|
||||||
print 'can\'t add package \'%s\': Object already exists' % pac
|
msg = 'can\'t add package \'%s\': Object already exists' % pac
|
||||||
sys.exit(1)
|
raise oscerr.PackageExists(self.name, pac, msg)
|
||||||
else:
|
else:
|
||||||
print 'checking out new package %s' % pac
|
print 'checking out new package %s' % pac
|
||||||
checkout_package(self.apiurl, self.name, pac, \
|
checkout_package(self.apiurl, self.name, pac, \
|
||||||
@ -318,7 +319,7 @@ class Project:
|
|||||||
self.new_package_entry(pac, 'A')
|
self.new_package_entry(pac, 'A')
|
||||||
self.write_packages()
|
self.write_packages()
|
||||||
# sometimes the new pac doesn't exist in the list because
|
# sometimes the new pac doesn't exist in the list because
|
||||||
# it would take too much time to update all data structs regulary
|
# it would take too much time to update all data structs regularly
|
||||||
if pac in self.pacs_unvers:
|
if pac in self.pacs_unvers:
|
||||||
self.pacs_unvers.remove(pac)
|
self.pacs_unvers.remove(pac)
|
||||||
return True
|
return True
|
||||||
@ -345,9 +346,7 @@ class Project:
|
|||||||
pac.delete_storefile(file)
|
pac.delete_storefile(file)
|
||||||
# this is not really necessary
|
# this is not really necessary
|
||||||
pac.put_on_deletelist(file)
|
pac.put_on_deletelist(file)
|
||||||
print statfrmt('D', os.path.join(pac.dir, file))
|
print statfrmt('D', getTransActPath(os.path.join(pac.dir, file)))
|
||||||
#print os.path.dirname(pac.dir)
|
|
||||||
# some black path vodoo
|
|
||||||
print statfrmt('D', getTransActPath(os.path.join(pac.dir, os.pardir, pac.name)))
|
print statfrmt('D', getTransActPath(os.path.join(pac.dir, os.pardir, pac.name)))
|
||||||
pac.write_deletelist()
|
pac.write_deletelist()
|
||||||
self.set_state(pac.name, 'D')
|
self.set_state(pac.name, 'D')
|
||||||
@ -372,105 +371,111 @@ class Project:
|
|||||||
for pac in pacs:
|
for pac in pacs:
|
||||||
Package(os.path.join(self.dir, pac)).update()
|
Package(os.path.join(self.dir, pac)).update()
|
||||||
else:
|
else:
|
||||||
# update complete project
|
# we need to make sure that the _packages file will be written (even if an exception
|
||||||
# packages which no longer exists upstream
|
# occurs)
|
||||||
upstream_del = [ pac for pac in self.pacs_have if not pac in self.pacs_available and self.get_state(pac) != 'A']
|
try:
|
||||||
|
# update complete project
|
||||||
|
# packages which no longer exists upstream
|
||||||
|
upstream_del = [ pac for pac in self.pacs_have if not pac in self.pacs_available and self.get_state(pac) != 'A']
|
||||||
|
|
||||||
for pac in upstream_del:
|
for pac in upstream_del:
|
||||||
p = Package(os.path.join(self.dir, pac))
|
|
||||||
self.delPackage(p, force = True)
|
|
||||||
delete_storedir(p.storedir)
|
|
||||||
try:
|
|
||||||
os.rmdir(pac)
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
self.pac_root.remove(self.get_package_node(p.name))
|
|
||||||
self.pacs_have.remove(pac)
|
|
||||||
|
|
||||||
for pac in self.pacs_have:
|
|
||||||
state = self.get_state(pac)
|
|
||||||
if pac in self.pacs_broken:
|
|
||||||
if self.get_state(pac) != 'A':
|
|
||||||
checkout_package(self.apiurl, self.name, pac,
|
|
||||||
pathname=getTransActPath(os.path.join(self.dir, pac)), prj_obj=self, prj_dir=self.dir)
|
|
||||||
elif state == ' ':
|
|
||||||
# do a simple update
|
|
||||||
p = Package(os.path.join(self.dir, pac))
|
p = Package(os.path.join(self.dir, pac))
|
||||||
rev = None
|
self.delPackage(p, force = True)
|
||||||
if expand_link and p.islink() and not p.isexpanded():
|
delete_storedir(p.storedir)
|
||||||
print 'Expanding to rev', p.linkinfo.xsrcmd5
|
try:
|
||||||
rev = p.linkinfo.xsrcmd5
|
os.rmdir(pac)
|
||||||
elif unexpand_link and p.islink() and p.isexpanded():
|
except:
|
||||||
print 'Unexpanding to rev', p.linkinfo.lsrcmd5
|
pass
|
||||||
rev = p.linkinfo.lsrcmd5
|
self.pac_root.remove(self.get_package_node(p.name))
|
||||||
elif p.islink() and p.isexpanded():
|
self.pacs_have.remove(pac)
|
||||||
rev = show_upstream_xsrcmd5(p.apiurl,
|
|
||||||
p.prjname, p.name)
|
|
||||||
p.update(rev)
|
|
||||||
elif state == 'D':
|
|
||||||
# TODO: Package::update has to fixed to behave like svn does
|
|
||||||
if pac in self.pacs_broken:
|
|
||||||
checkout_package(self.apiurl, self.name, pac,
|
|
||||||
pathname=getTransActPath(os.path.join(self.dir, pac)), prj_obj=self, prj_dir=self.dir)
|
|
||||||
else:
|
|
||||||
Package(os.path.join(self.dir, pac)).update()
|
|
||||||
elif state == 'A' and pac in self.pacs_available:
|
|
||||||
# file/dir called pac already exists and is under version control
|
|
||||||
print 'can\'t add package \'%s\': Object already exists' % pac
|
|
||||||
sys.exit(1)
|
|
||||||
elif state == 'A':
|
|
||||||
# do nothing
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
print 'unexpected state.. package \'%s\'' % pac
|
|
||||||
|
|
||||||
self.checkout_missing_pacs()
|
for pac in self.pacs_have:
|
||||||
self.write_packages()
|
state = self.get_state(pac)
|
||||||
|
if pac in self.pacs_broken:
|
||||||
|
if self.get_state(pac) != 'A':
|
||||||
|
checkout_package(self.apiurl, self.name, pac,
|
||||||
|
pathname=getTransActPath(os.path.join(self.dir, pac)), prj_obj=self, prj_dir=self.dir)
|
||||||
|
elif state == ' ':
|
||||||
|
# do a simple update
|
||||||
|
p = Package(os.path.join(self.dir, pac))
|
||||||
|
rev = None
|
||||||
|
if expand_link and p.islink() and not p.isexpanded():
|
||||||
|
print 'Expanding to rev', p.linkinfo.xsrcmd5
|
||||||
|
rev = p.linkinfo.xsrcmd5
|
||||||
|
elif unexpand_link and p.islink() and p.isexpanded():
|
||||||
|
print 'Unexpanding to rev', p.linkinfo.lsrcmd5
|
||||||
|
rev = p.linkinfo.lsrcmd5
|
||||||
|
elif p.islink() and p.isexpanded():
|
||||||
|
rev = show_upstream_xsrcmd5(p.apiurl,
|
||||||
|
p.prjname, p.name)
|
||||||
|
p.update(rev)
|
||||||
|
elif state == 'D':
|
||||||
|
# TODO: Package::update has to fixed to behave like svn does
|
||||||
|
if pac in self.pacs_broken:
|
||||||
|
checkout_package(self.apiurl, self.name, pac,
|
||||||
|
pathname=getTransActPath(os.path.join(self.dir, pac)), prj_obj=self, prj_dir=self.dir)
|
||||||
|
else:
|
||||||
|
Package(os.path.join(self.dir, pac)).update()
|
||||||
|
elif state == 'A' and pac in self.pacs_available:
|
||||||
|
# file/dir called pac already exists and is under version control
|
||||||
|
msg = 'can\'t add package \'%s\': Object already exists' % pac
|
||||||
|
raise oscerr.PackageExists(self.name, pac, msg)
|
||||||
|
elif state == 'A':
|
||||||
|
# do nothing
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
print 'unexpected state.. package \'%s\'' % pac
|
||||||
|
|
||||||
|
self.checkout_missing_pacs()
|
||||||
|
finally:
|
||||||
|
self.write_packages()
|
||||||
|
|
||||||
def commit(self, pacs = (), msg = '', files = {}):
|
def commit(self, pacs = (), msg = '', files = {}):
|
||||||
if len(pacs):
|
if len(pacs):
|
||||||
for pac in pacs:
|
try:
|
||||||
todo = []
|
for pac in pacs:
|
||||||
if files.has_key(pac):
|
todo = []
|
||||||
todo = files[pac]
|
if files.has_key(pac):
|
||||||
state = self.get_state(pac)
|
todo = files[pac]
|
||||||
if state == 'A':
|
state = self.get_state(pac)
|
||||||
self.commitNewPackage(pac, msg, todo)
|
if state == 'A':
|
||||||
elif state == 'D':
|
self.commitNewPackage(pac, msg, todo)
|
||||||
self.commitDelPackage(pac)
|
elif state == 'D':
|
||||||
elif state == ' ':
|
self.commitDelPackage(pac)
|
||||||
# display the correct dir when sending the changes
|
elif state == ' ':
|
||||||
if os.path.samefile(os.path.join(self.dir, pac), os.getcwd()):
|
# display the correct dir when sending the changes
|
||||||
p = Package('.')
|
if os.path.samefile(os.path.join(self.dir, pac), os.getcwd()):
|
||||||
else:
|
p = Package('.')
|
||||||
p = Package(os.path.join(self.dir, pac))
|
else:
|
||||||
p.todo = todo
|
p = Package(os.path.join(self.dir, pac))
|
||||||
p.commit(msg)
|
p.todo = todo
|
||||||
elif pac in self.pacs_unvers and not is_package_dir(os.path.join(self.dir, pac)):
|
p.commit(msg)
|
||||||
print 'osc: \'%s\' is not under version control' % pac
|
elif pac in self.pacs_unvers and not is_package_dir(os.path.join(self.dir, pac)):
|
||||||
elif pac in self.pacs_broken:
|
print 'osc: \'%s\' is not under version control' % pac
|
||||||
print 'osc: \'%s\' package not found' % pac
|
elif pac in self.pacs_broken:
|
||||||
elif state == None:
|
print 'osc: \'%s\' package not found' % pac
|
||||||
self.commitExtPackage(pac, msg, todo)
|
elif state == None:
|
||||||
|
self.commitExtPackage(pac, msg, todo)
|
||||||
|
finally:
|
||||||
|
self.write_packages()
|
||||||
else:
|
else:
|
||||||
# if we have packages marked as '!' we cannot commit
|
# if we have packages marked as '!' we cannot commit
|
||||||
for pac in self.pacs_broken:
|
for pac in self.pacs_broken:
|
||||||
if self.get_state(pac) != 'D':
|
if self.get_state(pac) != 'D':
|
||||||
print 'commit failed: package \'%s\' is missing' % pac
|
msg = 'commit failed: package \'%s\' is missing' % pac
|
||||||
sys.exit(1)
|
raise oscerr.PackageMissing(self.name, pac, msg)
|
||||||
for pac in self.pacs_have:
|
try:
|
||||||
state = self.get_state(pac)
|
for pac in self.pacs_have:
|
||||||
if state == ' ':
|
state = self.get_state(pac)
|
||||||
# do a simple commit
|
if state == ' ':
|
||||||
try:
|
# do a simple commit
|
||||||
Package(os.path.join(self.dir, pac)).commit(msg)
|
Package(os.path.join(self.dir, pac)).commit(msg)
|
||||||
except SystemExit:
|
elif state == 'D':
|
||||||
pass
|
self.commitDelPackage(pac)
|
||||||
elif state == 'D':
|
elif state == 'A':
|
||||||
self.commitDelPackage(pac)
|
self.commitNewPackage(pac, msg)
|
||||||
elif state == 'A':
|
finally:
|
||||||
self.commitNewPackage(pac, msg)
|
self.write_packages()
|
||||||
self.write_packages()
|
|
||||||
|
|
||||||
def commitNewPackage(self, pac, msg = '', files = []):
|
def commitNewPackage(self, pac, msg = '', files = []):
|
||||||
"""creates and commits a new package if it does not exist on the server"""
|
"""creates and commits a new package if it does not exist on the server"""
|
||||||
@ -677,10 +682,7 @@ class Package:
|
|||||||
else:
|
else:
|
||||||
upstream_rev = show_upstream_rev(self.apiurl, self.prjname, self.name)
|
upstream_rev = show_upstream_rev(self.apiurl, self.prjname, self.name)
|
||||||
if self.rev != upstream_rev:
|
if self.rev != upstream_rev:
|
||||||
print >>sys.stderr, 'Working copy \'%s\' is out of date (rev %s vs rev %s).' \
|
raise oscerr.WorkingCopyOutdated((self.absdir, self.rev, upstream_rev))
|
||||||
% (self.absdir, self.rev, upstream_rev)
|
|
||||||
print >>sys.stderr, 'Looks as if you need to update it first.'
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
if not self.todo:
|
if not self.todo:
|
||||||
self.todo = self.filenamelist_unvers + self.filenamelist
|
self.todo = self.filenamelist_unvers + self.filenamelist
|
||||||
@ -1247,6 +1249,8 @@ def slash_split(l):
|
|||||||
|
|
||||||
|
|
||||||
def findpacs(files):
|
def findpacs(files):
|
||||||
|
"""collect Package objects belonging to the given files
|
||||||
|
and make sure each Package is returned only once"""
|
||||||
pacs = []
|
pacs = []
|
||||||
for f in files:
|
for f in files:
|
||||||
p = filedir_to_pac(f)
|
p = filedir_to_pac(f)
|
||||||
@ -1287,13 +1291,21 @@ def read_inconflict(dir):
|
|||||||
|
|
||||||
|
|
||||||
def parseargs(list_of_args):
|
def parseargs(list_of_args):
|
||||||
if list_of_args:
|
"""Convenience method osc's commandline argument parsing.
|
||||||
return list(list_of_args)
|
|
||||||
else:
|
If called with an empty tuple (or list), return a list containing the current directory.
|
||||||
return [ os.curdir ]
|
Otherwise, return a list of the arguments."""
|
||||||
|
if list_of_args:
|
||||||
|
return list(list_of_args)
|
||||||
|
else:
|
||||||
|
return [os.curdir]
|
||||||
|
|
||||||
|
|
||||||
def filedir_to_pac(f):
|
def filedir_to_pac(f):
|
||||||
|
"""Takes a working copy path, or a path to a file inside a working copy,
|
||||||
|
and returns a Package object instance
|
||||||
|
|
||||||
|
If the argument was a filename, add it onto the "todo" list of the Package """
|
||||||
|
|
||||||
if os.path.isdir(f):
|
if os.path.isdir(f):
|
||||||
wd = f
|
wd = f
|
||||||
@ -1385,6 +1397,8 @@ def http_request(method, url, headers={}, data=None, file=None):
|
|||||||
else:
|
else:
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
if conf.config['debug']: print method, url
|
||||||
|
|
||||||
try:
|
try:
|
||||||
fd = urllib2.urlopen(req, data=data)
|
fd = urllib2.urlopen(req, data=data)
|
||||||
|
|
||||||
@ -1453,8 +1467,8 @@ def check_store_version(dir):
|
|||||||
v = ''
|
v = ''
|
||||||
|
|
||||||
if v == '':
|
if v == '':
|
||||||
print >>sys.stderr, 'error: "%s" is not an osc working copy' % dir
|
msg = 'Error: "%s" is not an osc working copy.' % os.path.abspath(dir)
|
||||||
sys.exit(1)
|
raise oscerr.NoWorkingCopy(msg)
|
||||||
|
|
||||||
if v != __version__:
|
if v != __version__:
|
||||||
if v in ['0.2', '0.3', '0.4', '0.5', '0.6', '0.7', '0.8', '0.9', '0.95', '0.96', '0.97', '0.98']:
|
if v in ['0.2', '0.3', '0.4', '0.5', '0.6', '0.7', '0.8', '0.9', '0.95', '0.96', '0.97', '0.98']:
|
||||||
@ -1463,12 +1477,10 @@ def check_store_version(dir):
|
|||||||
f.write(__version__ + '\n')
|
f.write(__version__ + '\n')
|
||||||
f.close()
|
f.close()
|
||||||
return
|
return
|
||||||
print >>sys.stderr
|
msg = 'The osc metadata of your working copy "%s"' % dir
|
||||||
print >>sys.stderr, 'the osc metadata of your working copy "%s"' % dir
|
msg += '\nhas the wrong version (%s), should be %s' % (v, __version__)
|
||||||
print >>sys.stderr, 'has the wrong version (%s), should be %s' % (v, __version__)
|
msg += '\nPlease do a fresh checkout'
|
||||||
print >>sys.stderr, 'please do a fresh checkout'
|
raise oscerr.WorkingCopyWrongVersion, msg
|
||||||
print >>sys.stderr
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
|
|
||||||
def meta_get_packagelist(apiurl, prj):
|
def meta_get_packagelist(apiurl, prj):
|
||||||
@ -1523,22 +1535,23 @@ def show_project_conf(apiurl, prj):
|
|||||||
|
|
||||||
|
|
||||||
def show_package_meta(apiurl, prj, pac):
|
def show_package_meta(apiurl, prj, pac):
|
||||||
|
url = makeurl(apiurl, ['source', prj, pac, '_meta'])
|
||||||
try:
|
try:
|
||||||
url = makeurl(apiurl, ['source', prj, pac, '_meta'])
|
|
||||||
f = http_GET(url)
|
f = http_GET(url)
|
||||||
|
return f.readlines()
|
||||||
except urllib2.HTTPError, e:
|
except urllib2.HTTPError, e:
|
||||||
print >>sys.stderr, 'error getting meta for project \'%s\' package \'%s\'' % (prj, pac)
|
e.osc_msg = 'Error getting meta for project \'%s\' package \'%s\'' % (prj, pac)
|
||||||
print >>sys.stderr, e
|
raise
|
||||||
if e.code == 500:
|
|
||||||
print >>sys.stderr, '\nDebugging output follows.\nurl:\n%s\nresponse:\n%s' % (url, e.read())
|
|
||||||
sys.exit(1)
|
|
||||||
return f.readlines()
|
|
||||||
|
|
||||||
|
|
||||||
def show_pattern_metalist(apiurl, prj):
|
def show_pattern_metalist(apiurl, prj):
|
||||||
url = makeurl(apiurl, ['source', prj, '_pattern'])
|
url = makeurl(apiurl, ['source', prj, '_pattern'])
|
||||||
f = http_GET(url)
|
try:
|
||||||
tree = ET.parse(f)
|
f = http_GET(url)
|
||||||
|
tree = ET.parse(f)
|
||||||
|
except urllib2.HTTPError, e:
|
||||||
|
e.osc_msg = 'show_pattern_metalist: Error getting pattern list for project \'%s\'' % prj
|
||||||
|
raise
|
||||||
r = [ node.get('name') for node in tree.getroot() ]
|
r = [ node.get('name') for node in tree.getroot() ]
|
||||||
r.sort()
|
r.sort()
|
||||||
return r
|
return r
|
||||||
@ -1548,11 +1561,10 @@ def show_pattern_meta(apiurl, prj, pattern):
|
|||||||
url = makeurl(apiurl, ['source', prj, '_pattern', pattern])
|
url = makeurl(apiurl, ['source', prj, '_pattern', pattern])
|
||||||
try:
|
try:
|
||||||
f = http_GET(url)
|
f = http_GET(url)
|
||||||
|
return f.readlines()
|
||||||
except urllib2.HTTPError, e:
|
except urllib2.HTTPError, e:
|
||||||
print >>sys.stderr, 'error getting pattern \'%s\' for project \'%s\'' % (pattern, prj)
|
e.osc_msg = 'show_pattern_meta: Error getting pattern \'%s\' for project \'%s\'' % (pattern, prj)
|
||||||
print >>sys.stderr, e
|
raise
|
||||||
sys.exit(1)
|
|
||||||
return f.readlines()
|
|
||||||
|
|
||||||
|
|
||||||
class metafile:
|
class metafile:
|
||||||
@ -1650,7 +1662,7 @@ def make_meta_url(metatype, path_args=None, apiurl=None):
|
|||||||
if not apiurl:
|
if not apiurl:
|
||||||
apiurl = conf.config['apiurl']
|
apiurl = conf.config['apiurl']
|
||||||
if metatype not in metatypes.keys():
|
if metatype not in metatypes.keys():
|
||||||
sys.exit('unknown metatype %s' % metatype)
|
raise AttributeError('make_meta_url(): Unknown meta type \'%s\'' % metatype)
|
||||||
path = metatypes[metatype]['path']
|
path = metatypes[metatype]['path']
|
||||||
|
|
||||||
if path_args:
|
if path_args:
|
||||||
@ -1742,8 +1754,8 @@ def read_meta_from_spec(specfile, *args):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
if not os.path.isfile(specfile):
|
if not os.path.isfile(specfile):
|
||||||
print 'file \'%s\' is not a readable file' % specfile
|
msg = 'File \'%s\' is not a readable file' % specfile
|
||||||
sys.exit(1)
|
raise oscerr.UnreadableFile, msg
|
||||||
|
|
||||||
try:
|
try:
|
||||||
lines = codecs.open(specfile, 'r', locale.getpreferredencoding()).readlines()
|
lines = codecs.open(specfile, 'r', locale.getpreferredencoding()).readlines()
|
||||||
@ -2192,10 +2204,9 @@ def checkout_package(apiurl, project, package,
|
|||||||
if not pathname:
|
if not pathname:
|
||||||
pathname = getTransActPath(os.path.join(prj_dir, package))
|
pathname = getTransActPath(os.path.join(prj_dir, package))
|
||||||
|
|
||||||
path = (quote_plus(project), quote_plus(package))
|
# before we create directories and stuff, check if the package actually
|
||||||
if meta_exists(metatype='pkg', path_args=path, create_new=False, apiurl=apiurl) == None:
|
# exists
|
||||||
print >>sys.stderr, 'error 404 - project or package does not exist'
|
show_package_meta(apiurl, project, package)
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
if expand_link:
|
if expand_link:
|
||||||
# try to read from the linkinfo
|
# try to read from the linkinfo
|
||||||
@ -2348,30 +2359,12 @@ def copy_pac(src_apiurl, src_project, src_package,
|
|||||||
|
|
||||||
def delete_package(apiurl, prj, pac):
|
def delete_package(apiurl, prj, pac):
|
||||||
u = makeurl(apiurl, ['source', prj, pac])
|
u = makeurl(apiurl, ['source', prj, pac])
|
||||||
try:
|
http_DELETE(u)
|
||||||
http_DELETE(u)
|
|
||||||
except urllib2.HTTPError, e:
|
|
||||||
if e.code == 404:
|
|
||||||
print >>sys.stderr, 'Package \'%s\' does not exist' % pac
|
|
||||||
sys.exit(1)
|
|
||||||
else:
|
|
||||||
print >>sys.stderr, 'an unexpected error occured while deleting ' \
|
|
||||||
'\'%s\'' % pac
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
|
|
||||||
def delete_project(apiurl, prj):
|
def delete_project(apiurl, prj):
|
||||||
u = makeurl(apiurl, ['source', prj])
|
u = makeurl(apiurl, ['source', prj])
|
||||||
try:
|
http_DELETE(u)
|
||||||
http_DELETE(u)
|
|
||||||
except urllib2.HTTPError, e:
|
|
||||||
if e.code == 404:
|
|
||||||
print >>sys.stderr, 'Package \'%s\' does not exist' % pac
|
|
||||||
sys.exit(1)
|
|
||||||
else:
|
|
||||||
print >>sys.stderr, 'an unexpected error occured while deleting ' \
|
|
||||||
'\'%s\'' % pac
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
|
|
||||||
def get_platforms(apiurl):
|
def get_platforms(apiurl):
|
||||||
@ -2660,10 +2653,8 @@ def rebuild(apiurl, prj, package, repo, arch, code=None):
|
|||||||
try:
|
try:
|
||||||
f = http_POST(u)
|
f = http_POST(u)
|
||||||
except urllib2.HTTPError, e:
|
except urllib2.HTTPError, e:
|
||||||
print >>sys.stderr, 'could not trigger rebuild for project \'%s\' package \'%s\'' % (prj, package)
|
e.osc_msg = 'could not trigger rebuild for project \'%s\' package \'%s\'' % (prj, package)
|
||||||
print >>sys.stderr, u
|
raise
|
||||||
print >>sys.stderr, e
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
root = ET.parse(f).getroot()
|
root = ET.parse(f).getroot()
|
||||||
return root.get('code')
|
return root.get('code')
|
||||||
@ -2673,9 +2664,8 @@ def store_read_project(dir):
|
|||||||
try:
|
try:
|
||||||
p = open(os.path.join(dir, store, '_project')).readlines()[0].strip()
|
p = open(os.path.join(dir, store, '_project')).readlines()[0].strip()
|
||||||
except IOError:
|
except IOError:
|
||||||
print >>sys.stderr, 'error: \'%s\' is not an osc project dir ' \
|
raise oscerr.NoWorkingCopy('Error: \'%s\' is not an osc project dir ' \
|
||||||
'or working copy' % dir
|
'or working copy.' % os.path.abspath(dir))
|
||||||
sys.exit(1)
|
|
||||||
return p
|
return p
|
||||||
|
|
||||||
|
|
||||||
@ -2683,8 +2673,8 @@ def store_read_package(dir):
|
|||||||
try:
|
try:
|
||||||
p = open(os.path.join(dir, store, '_package')).readlines()[0].strip()
|
p = open(os.path.join(dir, store, '_package')).readlines()[0].strip()
|
||||||
except IOError:
|
except IOError:
|
||||||
print >>sys.stderr, 'error: \'%s\' is not an osc working copy' % dir
|
raise oscerr.NoWorkingCopy('error: \'%s\' is not an osc working copy' \
|
||||||
sys.exit(1)
|
% os.path.abspath(dir))
|
||||||
return p
|
return p
|
||||||
|
|
||||||
def store_read_apiurl(dir):
|
def store_read_apiurl(dir):
|
||||||
@ -2727,17 +2717,15 @@ def abortbuild(apiurl, project, package=None, arch=None, repo=None):
|
|||||||
try:
|
try:
|
||||||
f = http_POST(u)
|
f = http_POST(u)
|
||||||
except urllib2.HTTPError, e:
|
except urllib2.HTTPError, e:
|
||||||
err_str = 'abortion failed for project %s' % project
|
e.osc_msg = 'abortion failed for project %s' % project
|
||||||
if package:
|
if package:
|
||||||
err_str += ' package %s' % package
|
e.osc_msg += ' package %s' % package
|
||||||
if arch:
|
if arch:
|
||||||
err_str += ' arch %s' % arch
|
e.osc_msg += ' arch %s' % arch
|
||||||
if repo:
|
if repo:
|
||||||
err_str += ' repo %s' % repo
|
e.osc_msg += ' repo %s' % repo
|
||||||
print >> sys.stderr, err_str
|
raise
|
||||||
print >> sys.stderr, u
|
|
||||||
print >> sys.stderr, e
|
|
||||||
sys.exit(1)
|
|
||||||
root = ET.parse(f).getroot()
|
root = ET.parse(f).getroot()
|
||||||
return root.get('code')
|
return root.get('code')
|
||||||
|
|
||||||
@ -2757,19 +2745,17 @@ def wipebinaries(apiurl, project, package=None, arch=None, repo=None, code=None)
|
|||||||
try:
|
try:
|
||||||
f = http_POST(u)
|
f = http_POST(u)
|
||||||
except urllib2.HTTPError, e:
|
except urllib2.HTTPError, e:
|
||||||
err_str = 'wipe binary rpms failed for project %s' % project
|
e.osc_msg = 'wipe binary rpms failed for project %s' % project
|
||||||
if package:
|
if package:
|
||||||
err_str += ' package %s' % package
|
e.osc_msg += ' package %s' % package
|
||||||
if arch:
|
if arch:
|
||||||
err_str += ' arch %s' % arch
|
e.osc_msg += ' arch %s' % arch
|
||||||
if repo:
|
if repo:
|
||||||
err_str += ' repository %s' % repo
|
e.osc_msg += ' repository %s' % repo
|
||||||
if code:
|
if code:
|
||||||
err_str += ' code=%s' % code
|
e.osc_msg += ' code=%s' % code
|
||||||
print >> sys.stderr, err_str
|
raise
|
||||||
print >> sys.stderr, u
|
|
||||||
print >> sys.stderr, e
|
|
||||||
sys.exit(1)
|
|
||||||
root = ET.parse(f).getroot()
|
root = ET.parse(f).getroot()
|
||||||
return root.get('code')
|
return root.get('code')
|
||||||
|
|
||||||
@ -3061,22 +3047,6 @@ def is_srcrpm(f):
|
|||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def delete_server_files(apiurl, prj, pac, files):
|
|
||||||
"""
|
|
||||||
This method deletes the given filelist on the
|
|
||||||
server. No local data will be touched.
|
|
||||||
"""
|
|
||||||
|
|
||||||
for file in files:
|
|
||||||
try:
|
|
||||||
u = makeurl(apiurl, ['source', prj, pac, file])
|
|
||||||
http_DELETE(u)
|
|
||||||
except:
|
|
||||||
# we do not handle all exceptions here - we need another solution
|
|
||||||
# see bug #280034
|
|
||||||
print >>sys.stderr, 'error while deleting file \'%s\'' % file
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
def addMaintainer(apiurl, prj, pac, user):
|
def addMaintainer(apiurl, prj, pac, user):
|
||||||
""" add a new maintainer to a package or project """
|
""" add a new maintainer to a package or project """
|
||||||
path = quote_plus(prj),
|
path = quote_plus(prj),
|
||||||
|
91
osc/oscerr.py
Normal file
91
osc/oscerr.py
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
# Copyright (C) 2008 Peter Poeml / Novell Inc. All rights reserved.
|
||||||
|
# This program is free software; it may be used, copied, modified
|
||||||
|
# and distributed under the terms of the GNU General Public Licence,
|
||||||
|
# either version 2, or (at your option) any later version.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class OscBaseError(Exception):
|
||||||
|
def __init__(self, args=()):
|
||||||
|
Exception.__init__(self)
|
||||||
|
self.args = args
|
||||||
|
|
||||||
|
class ConfigError(OscBaseError):
|
||||||
|
"""Exception raised when there is an error in the config file"""
|
||||||
|
def __init__(self, msg):
|
||||||
|
OscBaseError.__init__(self)
|
||||||
|
self.msg = msg
|
||||||
|
|
||||||
|
class NoConfigfile(OscBaseError):
|
||||||
|
"""Exception raised when osc's configfile cannot be found"""
|
||||||
|
def __init__(self, fname, msg):
|
||||||
|
OscBaseError.__init__(self)
|
||||||
|
self.file = fname
|
||||||
|
self.msg = msg
|
||||||
|
|
||||||
|
class WrongArgs(OscBaseError):
|
||||||
|
"""Exception raised by the cli for wrong arguments usage"""
|
||||||
|
|
||||||
|
class WrongOptions(OscBaseError):
|
||||||
|
"""Exception raised by the cli for wrong option usage"""
|
||||||
|
#def __str__(self):
|
||||||
|
# s = 'Sorry, wrong options.'
|
||||||
|
# if self.args:
|
||||||
|
# s += '\n' + self.args
|
||||||
|
# return s
|
||||||
|
|
||||||
|
class NoWorkingCopy(OscBaseError):
|
||||||
|
"""Exception raised when directory is neither a project dir nor a package dir"""
|
||||||
|
|
||||||
|
class WorkingCopyWrongVersion(OscBaseError):
|
||||||
|
"""Exception raised when working copy's .osc/_osclib_version doesn't match"""
|
||||||
|
|
||||||
|
class WorkingCopyOutdated(OscBaseError):
|
||||||
|
"""Exception raised when the working copy is outdated.
|
||||||
|
It takes a tuple with three arguments: path to wc,
|
||||||
|
revision that it has, revision that it should have.
|
||||||
|
"""
|
||||||
|
def __str__(self):
|
||||||
|
return ('Working copy \'%s\' is out of date (rev %s vs rev %s).\n'
|
||||||
|
'Looks as if you need to update it first.' \
|
||||||
|
% (self[0], self[1], self[2]))
|
||||||
|
|
||||||
|
|
||||||
|
class UnreadableFile(OscBaseError):
|
||||||
|
def __init__(self, msg):
|
||||||
|
OscBaseError.__init__(self)
|
||||||
|
self.msg = msg
|
||||||
|
|
||||||
|
class OscIOError(OscBaseError):
|
||||||
|
def __init__(self, e, msg):
|
||||||
|
OscBaseError.__init__(self)
|
||||||
|
self.e = e
|
||||||
|
self.msg = msg
|
||||||
|
|
||||||
|
class SignalInterrupt(Exception):
|
||||||
|
"""Exception raised on SIGTERM and SIGHUP."""
|
||||||
|
|
||||||
|
class PackageError(OscBaseError):
|
||||||
|
"""Base class for all Package related exceptions"""
|
||||||
|
def __init__(self, prj, pac):
|
||||||
|
OscBaseError.__init__(self)
|
||||||
|
self.prj = prj
|
||||||
|
self.pac = pac
|
||||||
|
|
||||||
|
class PackageExists(PackageError):
|
||||||
|
"""
|
||||||
|
Exception raised when a local object already exists
|
||||||
|
"""
|
||||||
|
def __init__(self, prj, pac, msg):
|
||||||
|
PackageError.__init__(self, prj, pac)
|
||||||
|
self.msg = msg
|
||||||
|
|
||||||
|
class PackageMissing(PackageError):
|
||||||
|
"""
|
||||||
|
Exception raised when a local object doesn't exist
|
||||||
|
"""
|
||||||
|
def __init__(self, prj, pac, msg):
|
||||||
|
PackageError.__init__(self, prj, pac)
|
||||||
|
self.msg = msg
|
Loading…
x
Reference in New Issue
Block a user