mirror of
https://github.com/openSUSE/osc.git
synced 2024-12-25 17:36:13 +01:00
All in one go.
0.121.jw02 - made rresults an alias for results. python decorators are a strange concept... - asserting that ~/.oscrc remains mode 0600 - no more plain text passwords in ~/.oscrc, we store now as bz2+base64 - added verbosity control -v -q. To be used in guess_proj_pack() - added 'll' and 'ls -l' as shorthand to 'list -v' - started to change to explicit dual license GPLv2 or GPLv3 to conform to Novell policy. - added revision parameter to show_upstream_srcmd5(), so that it can be used in do_cat later. - allowed both integer and srcmd5 revisions in meta_get_filelist() - added 'lL', 'LL': allowed -e and -v together in do_list(). Was an internal error before. - added cat -e, to cat a file through a link. 'cat -e -r 3' expands through the third revision of the _link. - added subcmd bco as alias for branch -c - added default project to branch subcommand. .oscrc:branch_project = OpenSUSE:Factory - added primitive experimental support for .oscrc:checkout_no_colon = 1 - suggest using svn when .svn found. - alias submitpac submitrequest - osc bco now continues to checkout after branch target exists error. - added .oscrc:plaintext_passwd=1 for backwards compatibility - moved core.py:exclude_stuff to .oscrc:exclude_glob and expand it to catch *.orig etc. - allowed req as alias for request. - bugfix get_request_list: use 'or' with multiple states, not 'and'. - added osc req list -s all; a shorthand for enumerating all states - osc req list no longer confuses creator with approver. - osc req list -D nnn limit to requests nnn days old. - osc req list now also shows requests from the the given package, not only to. - improved help texts with repairlink to point to osc resolved. - improved passx code when creating oscrc. - osc sr -l is now a shortcut for 'osc req list -M -a -t submit -D 0'
This commit is contained in:
parent
090e79964c
commit
83b1b5ca59
1
AUTHORS
1
AUTHORS
@ -19,4 +19,5 @@ Susanne Oberhauser
|
||||
Tom Patzig
|
||||
Werner Fink
|
||||
Will Stephenson
|
||||
Juergen Weigert
|
||||
Jan-Simon Möller
|
||||
|
31
NEWS
31
NEWS
@ -1,3 +1,34 @@
|
||||
0.121.jw02
|
||||
- made rresults an alias for results. python decorators are a strange concept...
|
||||
- asserting that ~/.oscrc remains mode 0600
|
||||
- no more plain text passwords in ~/.oscrc, we store now as bz2+base64
|
||||
- added verbosity control -v -q. To be used in guess_proj_pack()
|
||||
- added 'll' and 'ls -l' as shorthand to 'list -v'
|
||||
- started to change to explicit dual license GPLv2 or GPLv3 to conform to Novell policy.
|
||||
- added revision parameter to show_upstream_srcmd5(), so that it can be used in do_cat later.
|
||||
- allowed both integer and srcmd5 revisions in meta_get_filelist()
|
||||
- added 'lL', 'LL': allowed -e and -v together in do_list(). Was an internal error before.
|
||||
- added cat -e, to cat a file through a link.
|
||||
'cat -e -r 3' expands through the third revision of the _link.
|
||||
- added subcmd bco as alias for branch -c
|
||||
- added default project to branch subcommand. .oscrc:branch_project = OpenSUSE:Factory
|
||||
- added primitive experimental support for .oscrc:checkout_no_colon = 1
|
||||
- suggest using svn when .svn found.
|
||||
- alias submitpac submitrequest
|
||||
- osc bco now continues to checkout after branch target exists error.
|
||||
- added .oscrc:plaintext_passwd=1 for backwards compatibility
|
||||
- moved core.py:exclude_stuff to .oscrc:exclude_glob and expand it to catch *.orig etc.
|
||||
- allowed req as alias for request.
|
||||
- bugfix get_request_list: use 'or' with multiple states, not 'and'.
|
||||
- added osc req list -s all; a shorthand for enumerating all states
|
||||
- osc req list no longer confuses creator with approver.
|
||||
- osc req list -D nnn limit to requests nnn days old.
|
||||
- osc req list now also shows requests from the the given package, not only to.
|
||||
- improved help texts with repairlink to point to osc resolved.
|
||||
- improved passx code when creating oscrc.
|
||||
- osc sr -l is now a shortcut for 'osc req list -M -a -t submit -D 0'
|
||||
|
||||
|
||||
0.121:
|
||||
- osc metafromspec allows editing before send
|
||||
- allow handling of other roles than "maintainer" with maintainer command
|
||||
|
58
TODO
58
TODO
@ -1,3 +1,34 @@
|
||||
CRITICAL:
|
||||
- there is no way to list my old requests, regardless of their state,
|
||||
the online help is misleading about comma seperated lists.
|
||||
osc request list -s revoked,revoked openSUSE:Tools -> lists 37
|
||||
osc request list -s accecpted openSUSE:Tools -> lists 113
|
||||
osc request list -s accecpted,revoked openSUSE:Tools -> lists 0
|
||||
|
||||
- hitting the wrong build service is a legal risk.
|
||||
osc has no guard against forgetting -A. Add automatic pickup from current path.
|
||||
|
||||
- webpage can create a _link in a fully populated package.
|
||||
Need to prevent his somehow.
|
||||
|
||||
- cat -E <srcmd5> -r 3 <file> should expand through the third revision of the link to a
|
||||
named md5sum revision of the file. Or is this nonsense???
|
||||
|
||||
- canonical option parser.
|
||||
-A, -e, -u, -E <n>, should be univeral to all subconmmands that work on prj/pkg objects.
|
||||
With all subcommands that work on prj/pkg, the following should all be synonyms:
|
||||
-A apiurl prj pkg
|
||||
-A apiurl --project prj --package=pkg
|
||||
-A apiurl prj/pkg
|
||||
-A apiurl prj:pkg
|
||||
apiurl/source/prj/pkg
|
||||
The current working directory or its descendants should provide defaults
|
||||
for apiurl, prj and/or pkg.
|
||||
|
||||
- checkout working directories should be real directories. No more colons.
|
||||
A prj / package nameing collision shall be resolved by renaming the project to
|
||||
have a .prj suffix
|
||||
|
||||
|
||||
MAJOR:
|
||||
|
||||
@ -21,11 +52,6 @@ NORMAL:
|
||||
and put it into the spec file... otherwise clients won't regard the copied package as newer
|
||||
- commit: check if errors during PUT are handled sensibly, so the change is
|
||||
not committed to localmeta
|
||||
- store password base64 hashed, so it is not directly visible in plaintext
|
||||
when opening .oscrc and someone is looking over the shoulder
|
||||
- use http://code.google.com/p/iniparse/ instead of ConfigParser, with
|
||||
write capability, for the change
|
||||
- or implement Juergen Weigert's idea of a on-demand password agent
|
||||
- add switch to commit to change repository options, like to e.g. disable publishing?
|
||||
- implement optional logging to .osc/log, which could be useful for debugging bugs like
|
||||
the one where api.opensuse.org sends empty replies (a hard-to-catch one)
|
||||
@ -47,13 +73,9 @@ MINOR:
|
||||
this can peruse the new get_binarylist() and get_binary_file() functions
|
||||
- adjust zsh completion to work with cmdln.py implementation
|
||||
- add support for adding tags to packages?
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
- evaluate password storage alternatives
|
||||
- use http://code.google.com/p/iniparse/ instead of ConfigParser, with
|
||||
write capability, for the change
|
||||
|
||||
|
||||
|
||||
@ -67,3 +89,15 @@ MINOR:
|
||||
15:20 < DuDE> mt: das ist gut, dann sollte osc kein "try again" anbieten, sondern die Meldung rueberbringen
|
||||
|
||||
|
||||
JW:
|
||||
FIXME: osc co overwrites local changes without warning.
|
||||
FIXME: when branching, the user should be added to bugowner, for the branch project.
|
||||
FIXME: 'osc req' shall default to 'osc req list -M -B -s all',
|
||||
where -B shows requests related to packages where I am the bugowner.
|
||||
FIXME: 'osc log openSUSE:Factory PKG' should also point to the bsdevelproject
|
||||
|
||||
osc addrepo - obsolete zypper ar
|
||||
osc install - obsolete zypper in
|
||||
-
|
||||
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
# Copyright (C) 2006 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.
|
||||
# either version 2, or version 3 (at your option).
|
||||
|
||||
|
||||
from core import *
|
||||
@ -58,6 +58,11 @@ class Osc(cmdln.Cmdln):
|
||||
name = 'osc'
|
||||
conf = None
|
||||
|
||||
## FIXME: not sure, if it is possible in python to
|
||||
## fetch conf.config['request_list_days'] from
|
||||
## oscrc instead of an ugly pointer string hre.
|
||||
request_list_days = 'oscrc:request_list_days'
|
||||
|
||||
man_header = MAN_HEADER
|
||||
man_footer = MAN_FOOTER
|
||||
|
||||
@ -90,6 +95,10 @@ class Osc(cmdln.Cmdln):
|
||||
help='specify alternate configuration file')
|
||||
optparser.add_option('--no-gnome-keyring', action='store_true',
|
||||
help='disable usage of GNOME Keyring')
|
||||
optparser.add_option('-v', '--verbose', dest='verbose', action='count', default=0,
|
||||
help='increase verbosity')
|
||||
optparser.add_option('-q', '--quiet', dest='verbose', action='store_const', const=-1,
|
||||
help='be quiet, not verbose')
|
||||
return optparser
|
||||
|
||||
|
||||
@ -102,7 +111,8 @@ class Osc(cmdln.Cmdln):
|
||||
override_http_debug = self.options.http_debug,
|
||||
override_traceback = self.options.traceback,
|
||||
override_post_mortem = self.options.post_mortem,
|
||||
override_no_gnome_keyring = self.options.no_gnome_keyring)
|
||||
override_no_gnome_keyring = self.options.no_gnome_keyring,
|
||||
override_verbose = self.options.verbose)
|
||||
except oscerr.NoConfigfile, e:
|
||||
print >>sys.stderr, e.msg
|
||||
print >>sys.stderr, 'Creating osc configuration file %s ...' % e.file
|
||||
@ -125,6 +135,11 @@ class Osc(cmdln.Cmdln):
|
||||
if try_again: self.postoptparse(try_again = False)
|
||||
|
||||
self.conf = conf
|
||||
self.options.verbose = conf.config['verbose']
|
||||
conf.exclude_glob = conf.config['exclude_glob'].split()
|
||||
#if conf.config['version']:
|
||||
# print "osc-%s" % __version__
|
||||
# exit
|
||||
|
||||
|
||||
def get_cmd_help(self, cmdname):
|
||||
@ -166,6 +181,9 @@ class Osc(cmdln.Cmdln):
|
||||
|
||||
|
||||
@cmdln.alias('ls')
|
||||
@cmdln.alias('ll')
|
||||
@cmdln.alias('lL')
|
||||
@cmdln.alias('LL')
|
||||
@cmdln.option('-a', '--arch', metavar='ARCH',
|
||||
help='specify architecture')
|
||||
@cmdln.option('-R', '--revision', metavar='REVISION',
|
||||
@ -176,6 +194,8 @@ class Osc(cmdln.Cmdln):
|
||||
help='list built binaries, instead of sources')
|
||||
@cmdln.option('-v', '--verbose', action='store_true',
|
||||
help='print extra information')
|
||||
@cmdln.option('-l', '--long', action='store_true', dest='verbose',
|
||||
help='print extra information')
|
||||
@cmdln.option('-e', '--expand', action='store_true',
|
||||
help='expand linked package')
|
||||
def do_list(self, subcmd, opts, *args):
|
||||
@ -192,6 +212,9 @@ class Osc(cmdln.Cmdln):
|
||||
ls Apache apache2 # list source files of package of a project
|
||||
ls Apache apache2 <file> # list <file> if this file exists
|
||||
ls -v Apache apache2 # verbosely list source files of package
|
||||
ls -l Apache apache2 # verbosely list source files of package
|
||||
ll Apache apache2 # verbosely list source files of package
|
||||
LL Apache apache2 # verbosely list source files of expanded link
|
||||
|
||||
With --verbose, the following fields will be shown for each item:
|
||||
MD5 hash of file
|
||||
@ -204,6 +227,8 @@ class Osc(cmdln.Cmdln):
|
||||
"""
|
||||
|
||||
args = slash_split(args)
|
||||
if (subcmd == 'll'): opts.verbose = True;
|
||||
if (subcmd == 'lL' or subcmd == 'LL'): opts.verbose = True; opts.expand = True;
|
||||
|
||||
if len(args) == 1:
|
||||
project = args[0]
|
||||
@ -246,7 +271,8 @@ class Osc(cmdln.Cmdln):
|
||||
|
||||
elif len(args) == 1:
|
||||
if opts.verbose:
|
||||
raise oscerr.WrongOptions('Sorry, the --verbose option is not implemented for projects.')
|
||||
if self.options.verbose:
|
||||
print >>sys.stderr, 'Sorry, the --verbose option is not implemented for projects.'
|
||||
if opts.expand:
|
||||
raise oscerr.WrongOptions('Sorry, the --expand option is not implemented for projects.')
|
||||
|
||||
@ -260,7 +286,7 @@ class Osc(cmdln.Cmdln):
|
||||
expand=opts.expand,
|
||||
revision=opts.revision)
|
||||
if opts.verbose:
|
||||
out = [ '%s %7d %9d %s %s' % (i.md5, i.rev, i.size, shorttime(i.mtime), i.name) \
|
||||
out = [ '%s %7s %9d %s %s' % (i.md5, i.rev, i.size, shorttime(i.mtime), i.name) \
|
||||
for i in l if not fname or fname == i.name ]
|
||||
if len(out) == 0:
|
||||
if fname:
|
||||
@ -475,8 +501,11 @@ class Osc(cmdln.Cmdln):
|
||||
'(primary project where a package is developed)')
|
||||
@cmdln.option('-d', '--diff', action='store_true',
|
||||
help='show diff only instead of creating the actual request')
|
||||
@cmdln.option('-l', '--list', action='store_true',
|
||||
help='show submitrequests. Same as \'osc req list -M -s all -t submit -D 0\'')
|
||||
@cmdln.alias("sr")
|
||||
@cmdln.alias("submitreq")
|
||||
@cmdln.alias("submitpac")
|
||||
def do_submitrequest(self, subcmd, opts, *args):
|
||||
"""${cmd_name}: Create request to submit source into another Project
|
||||
|
||||
@ -492,16 +521,26 @@ class Osc(cmdln.Cmdln):
|
||||
${cmd_option_list}
|
||||
"""
|
||||
|
||||
if opts.list:
|
||||
opts.state = "all"
|
||||
opts.user = ""
|
||||
opts.all = True
|
||||
opts.type = "submit"
|
||||
opts.mine = True
|
||||
return self.do_request('list', opts, *args)
|
||||
|
||||
args = slash_split(args)
|
||||
|
||||
# remove this block later again
|
||||
oldcmds = ['create', 'list', 'log', 'show', 'decline', 'accept', 'delete', 'revoke']
|
||||
if args and args[0] in oldcmds:
|
||||
print "****************************************************************"
|
||||
print "* WARNING: It looks that you are using this command with a *"
|
||||
print "* deprecated syntax (maybe) ! *"
|
||||
print "* Please run \"osc sr --help\" to see the new syntax. *"
|
||||
print "****************************************************************"
|
||||
print "***********************************************************************"
|
||||
print "* WARNING: It looks that you are using this command with a *"
|
||||
print "* deprecated syntax (maybe) ! *"
|
||||
print "* Please run \"osc sr --help\" and \"osc req --help\" *"
|
||||
print "* to see the new syntax. *"
|
||||
print "* E.g. \"osc sr -l\" is shortcut for \"osc req list -M -s all -t submit\" *"
|
||||
print "***********************************************************************"
|
||||
if args[0] == 'create':
|
||||
args.pop(0)
|
||||
else:
|
||||
@ -671,7 +710,6 @@ Please submit there instead, or use --nodevelproject to force direct submission.
|
||||
print result
|
||||
|
||||
|
||||
|
||||
@cmdln.option('-d', '--diff', action='store_true',
|
||||
help='generate a diff')
|
||||
@cmdln.option('-u', '--unified', action='store_true',
|
||||
@ -681,16 +719,19 @@ Please submit there instead, or use --nodevelproject to force direct submission.
|
||||
@cmdln.option('-t', '--type', metavar='TEXT',
|
||||
help='limit to requests which contain a given action type (submit/delete/change_devel)')
|
||||
@cmdln.option('-a', '--all', action='store_true',
|
||||
help='all states')
|
||||
@cmdln.option('-s', '--state', default='new',
|
||||
help='only list requests in one of the comma separated given states (new/accepted/rejected/revoked/declined) [default=new]')
|
||||
help='all states. Same as\'-s all\'')
|
||||
@cmdln.option('-s', '--state', default='', # default is 'all' if no args given, 'new' otherwise
|
||||
help='only list requests in one of the comma separated given states (new/accepted/rejected/revoked/declined) or "all" [default=new, or all, if no args given]')
|
||||
@cmdln.option('-D', '--days', default='%s' % request_list_days, metavar='DAYS',
|
||||
help='only list requests created or changed in the last DAYS. [default=%s]' % request_list_days)
|
||||
@cmdln.option('-U', '--user', metavar='USER',
|
||||
help='same as -M, but for the specified USER')
|
||||
@cmdln.option('-b', '--brief', action='store_true', default=False,
|
||||
help='print output in list view as list subcommand')
|
||||
@cmdln.option('-M', '--mine', action='store_true',
|
||||
help='only show requests created by yourself')
|
||||
@cmdln.alias("rq")
|
||||
# may support it later, but lets fail for people used the api call before
|
||||
# @cmdln.alias("req")
|
||||
@cmdln.alias("req")
|
||||
def do_request(self, subcmd, opts, *args):
|
||||
"""${cmd_name}: Show and modify requests
|
||||
|
||||
@ -705,7 +746,9 @@ Please submit there instead, or use --nodevelproject to force direct submission.
|
||||
|
||||
This command has the following sub commands:
|
||||
|
||||
"list" lists open requests attached to a project or package.
|
||||
"list" lists open requests attached to a project or package or person.
|
||||
Uses the project/package of the current directory if none of
|
||||
-M, -U USER, project/package are given.
|
||||
|
||||
"log" will show the history of the given ID
|
||||
|
||||
@ -726,7 +769,7 @@ Please submit there instead, or use --nodevelproject to force direct submission.
|
||||
|
||||
|
||||
usage:
|
||||
osc request list [-M] [-s state] [-t type] [PRJ [PKG]]
|
||||
osc request list [-M] [-U USER] [-s state] [-D DAYS] [-t type] [PRJ [PKG]]
|
||||
osc request log ID
|
||||
osc request show [-d] [-b] ID
|
||||
osc request accept [-m TEXT] ID
|
||||
@ -738,8 +781,20 @@ Please submit there instead, or use --nodevelproject to force direct submission.
|
||||
|
||||
args = slash_split(args)
|
||||
|
||||
# 'req' defaults to 'req list -M -s all'
|
||||
if not args:
|
||||
args = [ 'list' ]
|
||||
opts.mine = 1
|
||||
if opts.state == '':
|
||||
opts.state = 'all'
|
||||
|
||||
if opts.state == '':
|
||||
opts.state = 'new'
|
||||
|
||||
cmds = ['list', 'log', 'show', 'decline', 'accept', 'wipe', 'revoke']
|
||||
if not args or args[0] not in cmds:
|
||||
if subcmd == 'req':
|
||||
print >>sys.stderr, 'You may want to try "osc api" instead of "osc req".'
|
||||
raise oscerr.WrongArgs('Unknown request action. Choose one of %s.' \
|
||||
% ', '.join(cmds))
|
||||
|
||||
@ -780,20 +835,50 @@ Please submit there instead, or use --nodevelproject to force direct submission.
|
||||
|
||||
# list
|
||||
if cmd == 'list':
|
||||
states = ('new', 'accepted', 'rejected', 'revoked', 'declined')
|
||||
state_list = opts.state.split(',')
|
||||
if opts.state == 'all':
|
||||
state_list = []
|
||||
for s in state_list:
|
||||
if not s in states:
|
||||
print >>sys.stderr, "Unknown state %s, try one of %s" % (s, ','.join(states))
|
||||
who = ''
|
||||
if opts.mine:
|
||||
who = conf.get_apiurl_usr(apiurl)
|
||||
if opts.user:
|
||||
who = opts.user
|
||||
if opts.all:
|
||||
state_list = ('new', 'accepted', 'declined', 'revoked', 'rejected')
|
||||
state_list = []
|
||||
|
||||
results = get_request_list(apiurl,
|
||||
project, package, who, state_list, opts.type)
|
||||
|
||||
results.sort(reverse=True)
|
||||
import time
|
||||
try:
|
||||
## ugly hack needed, as as the -D decorator constructs its default before osrcrc is loaded.
|
||||
if opts.days == self.request_list_days:
|
||||
opts.days = conf.config['request_list_days']
|
||||
int(opts.days)
|
||||
except:
|
||||
opts.days = '0'
|
||||
if int(opts.days) > 0:
|
||||
since = time.strftime('%Y-%m-%dT%H:%M:%S',time.localtime(time.time()-int(opts.days)*24*3600))
|
||||
|
||||
|
||||
skipped = 0
|
||||
## bs has received 2009-09-20 a new xquery compare() function
|
||||
## which allows us to limit the list inside of get_request_list
|
||||
## That would be much faster for coolo. But counting the remainder
|
||||
## is not possible with current xquery implementation.
|
||||
for result in results:
|
||||
print result.list_view()
|
||||
if int(opts.days) == 0 or result.state.when > since:
|
||||
print result.list_view()
|
||||
else:
|
||||
skipped += 1
|
||||
if skipped:
|
||||
print "There are %d requests older than %s days.\n" % (skipped,opts.days)
|
||||
|
||||
|
||||
elif cmd == 'log':
|
||||
for l in get_request_log(conf.config['apiurl'], reqid):
|
||||
@ -1031,7 +1116,7 @@ Please submit there instead, or use --nodevelproject to force direct submission.
|
||||
@cmdln.option('-d', '--keep-develproject', action='store_true',
|
||||
help='keep develproject tag in the package metadata')
|
||||
@cmdln.option('-r', '--revision', metavar='rev',
|
||||
help='link the specified revision.')
|
||||
help='link the specified revision.')
|
||||
@cmdln.option('-t', '--to-apiurl', metavar='URL',
|
||||
help='URL of destination api server. Default is the source api server.')
|
||||
@cmdln.option('-m', '--message', metavar='TEXT',
|
||||
@ -1090,7 +1175,7 @@ Please submit there instead, or use --nodevelproject to force direct submission.
|
||||
if opts.message:
|
||||
comment = opts.message
|
||||
else:
|
||||
if not rev:
|
||||
if not rev:
|
||||
rev = show_upstream_rev(src_apiurl, src_project, src_package);
|
||||
comment = 'osc copypac from project:%s package:%s revision:%s' % ( src_project, src_package, rev )
|
||||
|
||||
@ -1105,11 +1190,16 @@ Please submit there instead, or use --nodevelproject to force direct submission.
|
||||
print r
|
||||
|
||||
|
||||
@cmdln.alias('branch_co')
|
||||
@cmdln.alias('branchco')
|
||||
@cmdln.alias('bco')
|
||||
@cmdln.alias('getpac')
|
||||
@cmdln.option('--nodevelproject', action='store_true',
|
||||
help='do not follow a defined devel project ' \
|
||||
'(primary project where a package is developed)')
|
||||
@cmdln.option('-c', '--checkout', action='store_true',
|
||||
help='Checkout branched package afterwards ' )
|
||||
help='Checkout branched package afterwards ' \
|
||||
'(\'osc bco\' is a shorthand for this option)' )
|
||||
@cmdln.option('-r', '--revision', metavar='rev',
|
||||
help='branch against a specific revision')
|
||||
def do_branch(self, subcmd, opts, *args):
|
||||
@ -1125,15 +1215,31 @@ Please submit there instead, or use --nodevelproject to force direct submission.
|
||||
home:USERNAME:branches:PROJECT/PACKAGE
|
||||
if nothing else specified.
|
||||
|
||||
The branched package will come from
|
||||
openSUSE:Factory
|
||||
if nothing else specified.
|
||||
|
||||
usage:
|
||||
osc branch SOURCEPACKAGE
|
||||
osc branch SOURCEPROJECT SOURCEPACKAGE
|
||||
osc branch SOURCEPROJECT SOURCEPACKAGE TARGETPROJECT
|
||||
osc branch SOURCEPROJECT SOURCEPACKAGE TARGETPROJECT TARGETPACKAGE
|
||||
osc bco ...
|
||||
${cmd_option_list}
|
||||
"""
|
||||
|
||||
# FIXME: how can we interpolate conf.config['branch_project'] in the above message?
|
||||
|
||||
if (subcmd == 'branch_co' or subcmd == 'branchco' or subcmd == 'bco'): opts.checkout = True
|
||||
args = slash_split(args)
|
||||
tproject = tpackage = None
|
||||
|
||||
if (len(args) == 1):
|
||||
print >>sys.stderr, "defaulting to %s/%s" % (conf.config['branch_project'],args[0])
|
||||
# python has no args.unshift ???
|
||||
args = [ conf.config['branch_project'] , args[0] ]
|
||||
|
||||
|
||||
if not (len(args) >= 2 and len(args) <= 4):
|
||||
raise oscerr.WrongArgs('Wrong number of arguments.')
|
||||
if len(args) >= 3:
|
||||
@ -1142,9 +1248,16 @@ Please submit there instead, or use --nodevelproject to force direct submission.
|
||||
tpackage = args[3]
|
||||
|
||||
r = branch_pkg(conf.config['apiurl'], args[0], args[1],
|
||||
nodevelproject=opts.nodevelproject, rev=opts.revision, target_project=tproject, target_package=tpackage)
|
||||
nodevelproject=opts.nodevelproject, rev=opts.revision,
|
||||
target_project=tproject, target_package=tpackage,
|
||||
return_existing=opts.checkout)
|
||||
|
||||
expected = 'home:%s:branches:%s' % (conf.config['user'], args[0])
|
||||
|
||||
if r[0] is None:
|
||||
r = expected = r[1]
|
||||
print >>sys.stderr, 'Using existing branch project:', r, '\n'
|
||||
|
||||
if r != expected:
|
||||
devloc = r
|
||||
if 'branches:' in r:
|
||||
@ -1163,6 +1276,8 @@ Please submit there instead, or use --nodevelproject to force direct submission.
|
||||
if opts.checkout:
|
||||
checkout_package(conf.config['apiurl'], r, package,
|
||||
expand_link=True, prj_dir=r)
|
||||
if conf.config['verbose']:
|
||||
print 'Note: You can use "osc delete" or "osc submitpac" when done.\n'
|
||||
else:
|
||||
apiopt = ''
|
||||
if conf.get_configParser().get('general', 'apiurl') != conf.config['apiurl']:
|
||||
@ -1175,7 +1290,7 @@ Please submit there instead, or use --nodevelproject to force direct submission.
|
||||
|
||||
|
||||
@cmdln.option('-f', '--force', action='store_true',
|
||||
help='deletes a project and its packages')
|
||||
help='deletes a package or an empty project')
|
||||
def do_rdelete(self, subcmd, opts, *args):
|
||||
"""${cmd_name}: Delete a project or packages on the server.
|
||||
|
||||
@ -1341,6 +1456,19 @@ Please submit there instead, or use --nodevelproject to force direct submission.
|
||||
|
||||
print rdiff
|
||||
|
||||
def do_install(self, subcmd, opts, *args):
|
||||
"""${cmd_name}: install a package after build via zypper in -r
|
||||
|
||||
Not implemented yet. Use osc repourls,
|
||||
select the url you best like (standard),
|
||||
chop off after the last /, this should work with zypper.
|
||||
|
||||
${cmd_usage}
|
||||
${cmd_option_list}
|
||||
"""
|
||||
|
||||
print self.do_install.__doc__
|
||||
|
||||
|
||||
def do_repourls(self, subcmd, opts, *args):
|
||||
"""${cmd_name}: Shows URLs of .repo files
|
||||
@ -1621,14 +1749,17 @@ Please submit there instead, or use --nodevelproject to force direct submission.
|
||||
|
||||
p.todo = p.filenamelist + p.filenamelist_unvers
|
||||
|
||||
|
||||
for filename in p.todo:
|
||||
if os.path.isdir(filename):
|
||||
continue
|
||||
# ignore foo.rXX, foo.mine for files which are in 'C' state
|
||||
if os.path.splitext(filename)[0] in p.in_conflict:
|
||||
continue
|
||||
continue
|
||||
state = p.status(filename)
|
||||
|
||||
if state == '?':
|
||||
# TODO: should ignore typical backup files suffix ~ or .orig
|
||||
p.addfile(filename)
|
||||
print statfrmt('A', getTransActPath(os.path.join(p.dir, filename)))
|
||||
elif state == '!':
|
||||
@ -1962,8 +2093,17 @@ Please submit there instead, or use --nodevelproject to force direct submission.
|
||||
sys.exit(1)
|
||||
|
||||
@cmdln.hide(1)
|
||||
@cmdln.option('-l', '--last-build', action='store_true',
|
||||
help='show last build results (succeeded/failed/unknown)')
|
||||
@cmdln.option('-r', '--repo', action='append', default = [],
|
||||
help='Show results only for specified repo(s)')
|
||||
@cmdln.option('-a', '--arch', action='append', default = [],
|
||||
help='Show results only for specified architecture(s)')
|
||||
@cmdln.option('', '--xml', action='store_true',
|
||||
help='generate output in XML (former results_meta)')
|
||||
def do_rresults(self, subcmd, opts, *args):
|
||||
print "Command rresults is obsolete. Please use 'osc results'"
|
||||
print "Command rresults is obsolete. Running 'osc results' instead"
|
||||
self.do_results('results', opts, *args)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
@ -2004,10 +2144,10 @@ Please submit there instead, or use --nodevelproject to force direct submission.
|
||||
else:
|
||||
raise e
|
||||
|
||||
@cmdln.hide(1)
|
||||
def do_req(self, subcmd, opts, *args):
|
||||
print "Command req is obsolete. Please use 'osc api'"
|
||||
sys.exit(1)
|
||||
# @cmdln.hide(1)
|
||||
# def do_req(self, subcmd, opts, *args):
|
||||
# print "Command req is obsolete. Please use 'osc api'"
|
||||
# sys.exit(1)
|
||||
|
||||
@cmdln.alias('r')
|
||||
@cmdln.option('-l', '--last-build', action='store_true',
|
||||
@ -2029,6 +2169,7 @@ Please submit there instead, or use --nodevelproject to force direct submission.
|
||||
"""
|
||||
|
||||
args = slash_split(args)
|
||||
|
||||
apiurl = conf.config['apiurl']
|
||||
if len(args) == 0:
|
||||
wd = os.curdir
|
||||
@ -2786,6 +2927,9 @@ Please submit there instead, or use --nodevelproject to force direct submission.
|
||||
usage:
|
||||
osc search \'search term\' <options>
|
||||
${cmd_option_list}
|
||||
|
||||
osc search does not find binary rpm names. Use
|
||||
http://software.opensuse.org/search?q=binaryname
|
||||
"""
|
||||
|
||||
search_term = None
|
||||
@ -3144,6 +3288,8 @@ Please submit there instead, or use --nodevelproject to force direct submission.
|
||||
|
||||
@cmdln.option('-r', '--revision', metavar='rev',
|
||||
help='print out the specified revision')
|
||||
@cmdln.option('-e', '--expand', action='store_true',
|
||||
help='expand linked package')
|
||||
def do_cat(self, subcmd, opts, *args):
|
||||
"""${cmd_name}: Output the content of a file to standard output
|
||||
|
||||
@ -3160,9 +3306,11 @@ Please submit there instead, or use --nodevelproject to force direct submission.
|
||||
raise oscerr.WrongArgs('Wrong number of arguments.')
|
||||
rev, dummy = parseRevisionOption(opts.revision)
|
||||
|
||||
query = ''
|
||||
query = { }
|
||||
if opts.revision:
|
||||
query = 'rev=%s' % opts.revision
|
||||
query['rev'] = opts.revision
|
||||
if opts.expand:
|
||||
query['rev'] = show_upstream_srcmd5(conf.config['apiurl'], args[0], args[1], expand=True, revision=opts.revision)
|
||||
u = makeurl(conf.config['apiurl'], ['source', args[0], args[1], args[2]], query=query)
|
||||
for data in streamfile(u):
|
||||
sys.stdout.write(data)
|
||||
@ -3186,7 +3334,8 @@ Please submit there instead, or use --nodevelproject to force direct submission.
|
||||
|
||||
This command checks out a package with merged source changes. It uses
|
||||
a 3-way merge to resolve file conflicts. After reviewing/repairing
|
||||
the merge, 'osc ci' will re-create a working source link.
|
||||
the merge, use 'osc resolved ...' and 'osc ci' to re-create a
|
||||
working source link.
|
||||
|
||||
usage:
|
||||
* For merging conflicting changes of a checkout package:
|
||||
@ -3379,7 +3528,8 @@ Please submit there instead, or use --nodevelproject to force direct submission.
|
||||
pac.write_conflictlist()
|
||||
print
|
||||
print 'Please change into the \'%s\' directory,' % destdir
|
||||
print 'fix the conflicts, and commit the changes.'
|
||||
print 'fix the conflicts (files marked with \'C\' above),'
|
||||
print 'run \'osc resolved ...\', and commit the changes.'
|
||||
|
||||
@cmdln.option('-m', '--message',
|
||||
help='add MESSAGE to changes (not open an editor)')
|
||||
|
98
osc/conf.py
98
osc/conf.py
@ -1,12 +1,17 @@
|
||||
# Copyright (C) 2006 Novell Inc. All rights reserved.
|
||||
# Copyright (C) 2006-2009 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.
|
||||
# either version 2, or version 3 (at your option).
|
||||
|
||||
"""Read osc configuration and store it in a dictionary
|
||||
|
||||
This module reads and parses ~/.oscrc. The resulting configuration is stored
|
||||
for later usage in a dictionary named 'config'.
|
||||
The .oscrc is kept mode 0600, so that it is not publically readable.
|
||||
This gives no real security for storing passwords.
|
||||
If in doubt, use your favourite keyring.
|
||||
Password is stored on ~/.oscrc as bz2 compressed and base64 encoded, so that is fairly
|
||||
large and not to be recognized or remembered easily by an occasional spectator.
|
||||
|
||||
If information is missing, it asks the user questions.
|
||||
|
||||
@ -28,7 +33,6 @@ The configuration dictionary could look like this:
|
||||
}
|
||||
|
||||
"""
|
||||
|
||||
import OscConfigParser
|
||||
from osc import oscerr
|
||||
|
||||
@ -47,6 +51,7 @@ config = { }
|
||||
DEFAULTS = { 'apiurl': 'https://api.opensuse.org',
|
||||
'user': 'your_username',
|
||||
'pass': 'your_password',
|
||||
'passx': '',
|
||||
'packagecachedir': '/var/tmp/osbuild-packagecache',
|
||||
'su-wrapper': 'su -c',
|
||||
|
||||
@ -70,6 +75,20 @@ DEFAULTS = { 'apiurl': 'https://api.opensuse.org',
|
||||
'extra-pkgs': 'vim gdb strace',
|
||||
# default platform
|
||||
'build_platform': 'openSUSE_Factory',
|
||||
# default project for branch or bco
|
||||
'branch_project': 'openSUSE:Factory',
|
||||
# alternate filesystem layout: have multiple subdirs, where colons were.
|
||||
'checkout_no_colon': 0,
|
||||
# local files to ignore with status, addremove, ....
|
||||
'exclude_glob': '.osc CVS .svn .* _linkerror *~ #*# *.orig *.bak',
|
||||
# keep passwords in plaintext. If you see this comment, your osc
|
||||
# already uses the encrypted password, and only keeps them in plain text
|
||||
# for backwards compatibility. Default will change to 0 in future releases.
|
||||
'plaintext_passwd': 1,
|
||||
# limit the age of requests shown with 'osc req list'.
|
||||
# this is a default only, can be overridden by 'osc req list -D NNN'
|
||||
# Use 0 for unlimted.
|
||||
'request_list_days': 30,
|
||||
# check for unversioned/removed files before commit
|
||||
'check_filelist': '1',
|
||||
}
|
||||
@ -101,20 +120,41 @@ apiurl = %(apiurl)s
|
||||
#extra-pkgs = vim gdb strace
|
||||
|
||||
# build platform is used if the platform argument is omitted to osc build
|
||||
#build_platform = openSUSE_Factory
|
||||
#build_platform = %(build_platform)s
|
||||
|
||||
# show info useful for debugging
|
||||
# default project for branch or bco
|
||||
#branch_project = %(branch_project)s
|
||||
|
||||
# alternate filesystem layout: have multiple subdirs, where colons were.
|
||||
#checkout_no_colon = %(checkout_no_colon)s
|
||||
|
||||
# local files to ignore with status, addremove, ....
|
||||
#exclude_glob = %(exclude_glob)s
|
||||
|
||||
# keep passwords in plaintext. If you see this comment, your osc
|
||||
# already uses the encrypted password, and only keeps them in plain text
|
||||
# for backwards compatibility. Default will change to 0 in future releases.
|
||||
# You can remove the plaintext password without harm, if you do not need
|
||||
# backwards compatibility.
|
||||
#plaintext_passwd = %(plaintext_passwd)s
|
||||
|
||||
# limit the age of requests shown with 'osc req list'.
|
||||
# this is a default only, can be overridden by 'osc req list -D NNN'
|
||||
# Use 0 for unlimted.
|
||||
#request_list_days = %(request_list_days)s
|
||||
|
||||
# show info useful for debugging
|
||||
#debug = 1
|
||||
|
||||
# show HTTP traffic useful for debugging
|
||||
|
||||
# show HTTP traffic useful for debugging
|
||||
#http_debug = 1
|
||||
|
||||
|
||||
# jump into the debugger in case of errors
|
||||
#post_mortem = 1
|
||||
|
||||
|
||||
# print call traces in case of errors
|
||||
#traceback = 1
|
||||
|
||||
|
||||
# use GNOME keyring for credentials if available
|
||||
#gnome_keyring = 0
|
||||
|
||||
@ -124,10 +164,11 @@ apiurl = %(apiurl)s
|
||||
[%(apiurl)s]
|
||||
user = %(user)s
|
||||
pass = %(pass)s
|
||||
passx = %(passx)s
|
||||
# set aliases for this apiurl
|
||||
# aliases = foo, bar
|
||||
# email used in .changes, unless the one from osc meta prj <user> will be used
|
||||
# email =
|
||||
# email =
|
||||
# additional headers to pass to a request, e.g. for special authentication
|
||||
#http_headers = Host: foofoobar,
|
||||
# User: mumblegack
|
||||
@ -281,6 +322,7 @@ def write_initial_config(conffile, entries, custom_template = ''):
|
||||
conf_template = custom_template or new_conf_template
|
||||
config = DEFAULTS.copy()
|
||||
config.update(entries)
|
||||
config['passx'] = config['pass'].encode('bz2').encode('base64')
|
||||
if config['gnome_keyring'] and GNOME_KEYRING:
|
||||
protocol, host = \
|
||||
parse_apisrv_url(None, config['apiurl'])
|
||||
@ -291,6 +333,9 @@ def write_initial_config(conffile, entries, custom_template = ''):
|
||||
server = host)
|
||||
config['user'] = ''
|
||||
config['pass'] = ''
|
||||
config['passx'] = ''
|
||||
if not config['plaintext_passwd']:
|
||||
config['pass'] = ''
|
||||
sio = StringIO.StringIO(conf_template.strip() % config)
|
||||
cp = OscConfigParser.OscConfigParser(DEFAULTS)
|
||||
cp.readfp(sio)
|
||||
@ -331,7 +376,9 @@ def add_section(filename, url, user, passwd):
|
||||
cp.set(url, 'keyring', '1')
|
||||
else:
|
||||
cp.set(url, 'user', user)
|
||||
cp.set(url, 'pass', passwd)
|
||||
if not config['plaintext_passwd']:
|
||||
cp.remove_option(url, 'pass')
|
||||
cp.set(url, 'passx', passwd.encode('bz2').encode('base64'))
|
||||
file = open(filename, 'w')
|
||||
cp.write(file, True)
|
||||
if file: file.close()
|
||||
@ -343,7 +390,8 @@ def get_config(override_conffile = None,
|
||||
override_http_debug = None,
|
||||
override_traceback = None,
|
||||
override_post_mortem = None,
|
||||
override_no_gnome_keyring = None):
|
||||
override_no_gnome_keyring = None,
|
||||
override_verbose = None):
|
||||
"""do the actual work (see module documentation)"""
|
||||
import os
|
||||
import sys
|
||||
@ -359,6 +407,9 @@ def get_config(override_conffile = None,
|
||||
|
||||
# okay, we made sure that .oscrc exists
|
||||
|
||||
# make sure it is not world readable, it may contain a password.
|
||||
os.chmod(conffile, 0600)
|
||||
|
||||
cp = get_configParser(conffile)
|
||||
|
||||
if not cp.has_section('general'):
|
||||
@ -405,7 +456,7 @@ def get_config(override_conffile = None,
|
||||
|
||||
# override values which we were called with
|
||||
# This needs to be done before processing API sections as it might be already used there
|
||||
if override_no_gnome_keyring:
|
||||
if override_no_gnome_keyring:
|
||||
config['gnome_keyring'] = False
|
||||
|
||||
aliases = {}
|
||||
@ -432,6 +483,17 @@ def get_config(override_conffile = None,
|
||||
#from the general section.
|
||||
user = cp.get(url, 'user', raw=True) # need to set raw to prevent '%' expansion
|
||||
password = cp.get(url, 'pass', raw=True) # especially on password!
|
||||
passwordx = cp.get(url, 'passx', raw=True) # especially on password!
|
||||
if password is None or password == 'your_password':
|
||||
try:
|
||||
password = passwordx.decode('base64').decode('bz2');
|
||||
except:
|
||||
print "%s: no credentials known" % url
|
||||
password = 'your_password'
|
||||
else:
|
||||
if not passwordx:
|
||||
print "%s: rewriting from plain pass to encoded pass\n" % url
|
||||
add_section(conffile, url, user, password)
|
||||
if cp.has_option(url, 'keyring') and cp.get(url, 'keyring'):
|
||||
# This APIURL was configured to use keyring by
|
||||
continue
|
||||
@ -464,7 +526,11 @@ def get_config(override_conffile = None,
|
||||
config['api_host_options'] = api_host_options
|
||||
|
||||
# override values which we were called with
|
||||
if override_debug:
|
||||
if override_verbose:
|
||||
config['verbose'] = override_verbose + 1
|
||||
if not config.has_key('verbose') : config['verbose'] = 1;
|
||||
|
||||
if override_debug:
|
||||
config['debug'] = override_debug
|
||||
if override_http_debug:
|
||||
config['http_debug'] = override_http_debug
|
||||
@ -478,7 +544,7 @@ def get_config(override_conffile = None,
|
||||
parse_apisrv_url(None, apiurl)
|
||||
config['apiurl'] = apiurl
|
||||
|
||||
# XXX unless config['user'] goes away (and is replaced with a handy function, or
|
||||
# XXX unless config['user'] goes away (and is replaced with a handy function, or
|
||||
# config becomes an object, even better), set the global 'user' here as well,
|
||||
# provided that there _are_ credentials for the chosen apiurl:
|
||||
try:
|
||||
|
105
osc/core.py
105
osc/core.py
@ -3,9 +3,9 @@
|
||||
# Copyright (C) 2006 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.
|
||||
# either version 2, or version 3 (at your option).
|
||||
|
||||
__version__ = '0.120.90'
|
||||
__version__ = '0.121.jw02'
|
||||
# __store_version__ is to be incremented when the format of the working copy
|
||||
# "store" changes in an incompatible way. Please add any needed migration
|
||||
# functionality to check_store_version().
|
||||
@ -15,7 +15,7 @@ import os
|
||||
import os.path
|
||||
import sys
|
||||
import urllib2
|
||||
from urllib import pathname2url, quote_plus, urlencode
|
||||
from urllib import pathname2url, quote_plus, urlencode, unquote
|
||||
from urlparse import urlsplit, urlunsplit
|
||||
from cStringIO import StringIO
|
||||
import shutil
|
||||
@ -33,8 +33,6 @@ except ImportError:
|
||||
|
||||
BUFSIZE = 1024*1024
|
||||
store = '.osc'
|
||||
exclude_stuff = [store, 'CVS', '*~', '#*#', '.*', '_linkerror']
|
||||
|
||||
|
||||
new_project_templ = """\
|
||||
<project name="%(name)s">
|
||||
@ -286,7 +284,7 @@ class Project:
|
||||
self.pac_root = self.read_packages().getroot()
|
||||
self.pacs_have = [ pac.get('name') for pac in self.pac_root.findall('package') ]
|
||||
self.pacs_excluded = [ i for i in os.listdir(self.dir)
|
||||
for j in exclude_stuff
|
||||
for j in conf.exclude_glob
|
||||
if fnmatch.fnmatch(i, j) ]
|
||||
self.pacs_unvers = [ i for i in os.listdir(self.dir) if i not in self.pacs_have and i not in self.pacs_excluded ]
|
||||
# store all broken packages (e.g. packages which where removed by a non-osc cmd)
|
||||
@ -365,7 +363,7 @@ class Project:
|
||||
|
||||
def addPackage(self, pac):
|
||||
import fnmatch
|
||||
for i in exclude_stuff:
|
||||
for i in conf.exclude_glob:
|
||||
if fnmatch.fnmatch(pac, i):
|
||||
return False
|
||||
state = self.get_state(pac)
|
||||
@ -957,7 +955,7 @@ class Package:
|
||||
|
||||
# gather unversioned files, but ignore some stuff
|
||||
self.excluded = [ i for i in os.listdir(self.dir)
|
||||
for j in exclude_stuff
|
||||
for j in conf.exclude_glob
|
||||
if fnmatch.fnmatch(i, j) ]
|
||||
self.filenamelist_unvers = [ i for i in os.listdir(self.dir)
|
||||
if i not in self.excluded
|
||||
@ -1431,7 +1429,7 @@ class Request:
|
||||
)
|
||||
|
||||
def list_view(self):
|
||||
ret = '%6d State:%-7s Creator:%-12s When:%-12s' % (self.reqid, self.state.name, self.state.who, self.state.when)
|
||||
ret = '%6d State:%-7s By:%-12s When:%-12s' % (self.reqid, self.state.name, self.state.who, self.state.when)
|
||||
|
||||
for a in self.actions:
|
||||
dst = "%s/%s" % (a.dst_project, a.dst_package)
|
||||
@ -1448,8 +1446,14 @@ class Request:
|
||||
ret += '\n %s: %-50s %-20s ' % \
|
||||
(a.type, sr_source, dst)
|
||||
|
||||
if self.statehistory and self.statehistory[0]:
|
||||
who = []
|
||||
for h in self.statehistory:
|
||||
who.append("%s(%s)" % (h.who,h.name))
|
||||
who.reverse()
|
||||
ret += "\n From: %s" % (' -> '.join(who))
|
||||
if self.descr:
|
||||
ret += "\n Comment: %s" % (repr(self.descr))
|
||||
ret += "\n Descr: %s" % (repr(self.descr))
|
||||
ret += "\n"
|
||||
|
||||
return ret
|
||||
@ -1733,10 +1737,14 @@ def http_DELETE(*args, **kwargs): return http_request('DELETE', *args, **kwargs)
|
||||
|
||||
def init_project_dir(apiurl, dir, project):
|
||||
if not os.path.exists(dir):
|
||||
os.mkdir(dir)
|
||||
if conf.config['checkout_no_colon']:
|
||||
os.makedirs(dir) # helpful with checkout_no_colon
|
||||
else:
|
||||
os.mkdir(dir)
|
||||
if not os.path.exists(os.path.join(dir, store)):
|
||||
os.mkdir(os.path.join(dir, store))
|
||||
|
||||
# print 'project=',project,' dir=',dir
|
||||
store_write_project(dir, project)
|
||||
store_write_apiurl(dir, apiurl)
|
||||
if conf.config['do_package_tracking']:
|
||||
@ -1780,6 +1788,8 @@ def check_store_version(dir):
|
||||
|
||||
if v == '':
|
||||
msg = 'Error: "%s" is not an osc working copy.' % os.path.abspath(dir)
|
||||
if os.path.exists(os.path.join(dir, '.svn')):
|
||||
msg = msg + '\nTry svn instead of osc.'
|
||||
raise oscerr.NoWorkingCopy(msg)
|
||||
|
||||
if v != __store_version__:
|
||||
@ -1824,7 +1834,8 @@ def meta_get_filelist(apiurl, prj, package, verbose=False, expand=False, revisio
|
||||
|
||||
else:
|
||||
l = []
|
||||
rev = int(root.get('rev'))
|
||||
# rev = int(root.get('rev')) # don't force int. also allow srcmd5 here.
|
||||
rev = root.get('rev')
|
||||
for node in root.findall('entry'):
|
||||
f = File(node.get('name'),
|
||||
node.get('md5'),
|
||||
@ -2069,8 +2080,8 @@ def show_files_meta(apiurl, prj, pac, revision=None, expand=False, linkrev=None,
|
||||
return f.readlines()
|
||||
|
||||
|
||||
def show_upstream_srcmd5(apiurl, prj, pac, expand=False):
|
||||
m = show_files_meta(apiurl, prj, pac, expand=expand)
|
||||
def show_upstream_srcmd5(apiurl, prj, pac, expand=False, revision=None):
|
||||
m = show_files_meta(apiurl, prj, pac, expand=expand, revision=revision)
|
||||
return ET.parse(StringIO(''.join(m))).getroot().get('srcmd5')
|
||||
|
||||
|
||||
@ -2323,10 +2334,12 @@ def get_request_list(apiurl, project, package, req_who='', req_state=('new',), r
|
||||
m = match
|
||||
if project:
|
||||
if len(m): m += '%20and%20'
|
||||
m += '%s/target/@project=\'%s\'' % (what, quote_plus(project))
|
||||
m += '(%s/target/@project=\'%s\'%%20or%%20' % (what, quote_plus(project))
|
||||
m += '%s/source/@project=\'%s\')' % (what, quote_plus(project))
|
||||
if package:
|
||||
if len(m): m += '%20and%20'
|
||||
m += '%s/target/@package=\'%s\'' % (what, quote_plus(package))
|
||||
m += '(%s/target/@package=\'%s\'%%20or%%20' % (what, quote_plus(package))
|
||||
m += '%s/source/@package=\'%s\')' % (what, quote_plus(package))
|
||||
if req_type:
|
||||
if len(m): m += '%20and%20'
|
||||
m += '%s/@type=\'%s\'' % (what, quote_plus(req_type))
|
||||
@ -2336,6 +2349,8 @@ def get_request_list(apiurl, project, package, req_who='', req_state=('new',), r
|
||||
matches.append(match)
|
||||
|
||||
for match in matches:
|
||||
if conf.config['verbose'] > 1:
|
||||
print "[",match,"]"
|
||||
u = makeurl(apiurl, ['search', 'request'], ['match=%s' % match])
|
||||
f = http_GET(u)
|
||||
collection = ET.parse(f).getroot()
|
||||
@ -2696,10 +2711,31 @@ def make_dir(apiurl, project, package, pathname=None, prj_dir=None):
|
||||
The optional 'prj_dir' parameter specifies the path to the project dir (default: 'project').
|
||||
"""
|
||||
prj_dir = prj_dir or project
|
||||
|
||||
# FIXME: carefully test each patch component of prj_dir,
|
||||
# if we have a .osc/_files entry at that level.
|
||||
# -> if so, we have a package/project clash,
|
||||
# and should rename this path component by appending '.proj'
|
||||
# and give user a warning message, to discourage such clashes
|
||||
|
||||
pathname = pathname or getTransActPath(os.path.join(prj_dir, package))
|
||||
if not os.path.exists(prj_dir):
|
||||
if os.path.exists(os.path.join(prj_dir,store,'_files')):
|
||||
# we want this to become a project directory,
|
||||
# but it already is a package directory.
|
||||
e.osc_msg = 'checkout_package: package/project clash. Moving myself away not implemented'
|
||||
raise
|
||||
|
||||
if not os.path.exists(os.path.join(prj_dir,store,'_packages')):
|
||||
# this directory could exist as a parent direory for one of our earlier
|
||||
# checked out sub-projects. in this case, we still need to initialize it.
|
||||
print statfrmt('A', prj_dir)
|
||||
init_project_dir(apiurl, prj_dir, project)
|
||||
if os.path.exists(os.path.join(prj_dir, package, store, '_packages')):
|
||||
# the thing exists, but is a project directory and not a package directory
|
||||
# FIXME: this should be a warning message to discourage package/project clashes
|
||||
e.osc_msg = 'checkout_package: package/project clash. Moving project away not implemented'
|
||||
raise
|
||||
|
||||
if not os.path.exists(os.path.join(prj_dir, package)):
|
||||
print statfrmt('A', pathname)
|
||||
os.mkdir(os.path.join(prj_dir, package))
|
||||
@ -2724,6 +2760,9 @@ def checkout_package(apiurl, project, package,
|
||||
else:
|
||||
if sys.platform[:3] == 'win':
|
||||
prj_dir = prj_dir[:2] + prj_dir[2:].replace(':', ';')
|
||||
else:
|
||||
if conf.config['checkout_no_colon']:
|
||||
prj_dir = prj_dir.replace(':', '/')
|
||||
|
||||
if not pathname:
|
||||
pathname = getTransActPath(os.path.join(prj_dir, package))
|
||||
@ -2873,7 +2912,7 @@ def aggregate_pac(src_project, src_package, dst_project, dst_package, repo_map =
|
||||
http_PUT(u, data=aggregate_template)
|
||||
print 'Done.'
|
||||
|
||||
def branch_pkg(apiurl, src_project, src_package, nodevelproject=False, rev=None, target_project=None, target_package=None):
|
||||
def branch_pkg(apiurl, src_project, src_package, nodevelproject=False, rev=None, target_project=None, target_package=None, return_existing=False):
|
||||
"""
|
||||
Branch a package (via API call)
|
||||
"""
|
||||
@ -2887,7 +2926,20 @@ def branch_pkg(apiurl, src_project, src_package, nodevelproject=False, rev=None,
|
||||
if target_package:
|
||||
query['target_package'] = target_package
|
||||
u = makeurl(apiurl, ['source', src_project, src_package], query=query)
|
||||
f = http_POST(u)
|
||||
try:
|
||||
f = http_POST(u)
|
||||
except urllib2.HTTPError, e:
|
||||
if not return_existing:
|
||||
raise
|
||||
msg = ''.join(e.readlines())
|
||||
msg = msg.split('<summary>')[1]
|
||||
msg = msg.split('</summary>')[0]
|
||||
m = re.match(r"branch target package already exists: (\S+)/", msg)
|
||||
if not m:
|
||||
e.msg += '\n' + msg
|
||||
raise
|
||||
return (None, m.group(1))
|
||||
|
||||
r = f.read()
|
||||
r = r.split('targetproject">')[1]
|
||||
r = r.split('</data>')[0]
|
||||
@ -3387,8 +3439,12 @@ def store_read_project(dir):
|
||||
try:
|
||||
p = open(os.path.join(dir, store, '_project')).readlines()[0].strip()
|
||||
except IOError:
|
||||
if os.path.exists(os.path.join(dir, '.svn')):
|
||||
svn = '\nTry svn instead of osc.'
|
||||
else:
|
||||
svn = ''
|
||||
raise oscerr.NoWorkingCopy('Error: \'%s\' is not an osc project dir ' \
|
||||
'or working copy.' % os.path.abspath(dir))
|
||||
'or working copy.'+svn % os.path.abspath(dir))
|
||||
return p
|
||||
|
||||
|
||||
@ -3396,7 +3452,11 @@ def store_read_package(dir):
|
||||
try:
|
||||
p = open(os.path.join(dir, store, '_package')).readlines()[0].strip()
|
||||
except IOError:
|
||||
raise oscerr.NoWorkingCopy('error: \'%s\' is not an osc working copy' \
|
||||
if os.path.exists(os.path.join(dir, '.svn')):
|
||||
svn = '\nTry svn instead of osc.'
|
||||
else:
|
||||
svn = ''
|
||||
raise oscerr.NoWorkingCopy('error: \'%s\' is not an osc working copy'+svn \
|
||||
% os.path.abspath(dir))
|
||||
return p
|
||||
|
||||
@ -3609,6 +3669,7 @@ def search(apiurl, search_list, kind, search_term, verbose = False, exact_matche
|
||||
|
||||
predicate = build_xpath_predicate(search_list, search_term, exact_matches)
|
||||
u = makeurl(apiurl, ['search', kind], ['match=%s' % quote_plus(''.join(predicate))])
|
||||
if conf.config['verbose']: print '>>', unquote(u), '<<'
|
||||
f = http_GET(u)
|
||||
root = ET.parse(f).getroot()
|
||||
result = []
|
||||
@ -3934,6 +3995,8 @@ def createPackageDir(pathname, prj_obj=None):
|
||||
return False
|
||||
else:
|
||||
print '\'%s\' is not a working copy' % prj_dir
|
||||
if os.path.exists(os.path.join(prj_dir, '.svn')):
|
||||
print 'try svn instead of osc.'
|
||||
return False
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user