diff --git a/TODO b/TODO index 3af5205a..05399c5a 100644 --- a/TODO +++ b/TODO @@ -1,12 +1,6 @@ MAJOR: - - new meta command, replacing usermeta, edituser, editprj, editmeta, ... [2] - (poeml has started to work on this one) - - See http://lists.opensuse.org/opensuse-buildservice/2007-05/msg00202.html - and the two followups. - - thereby, implement editing of project configuration (already works in api & backend) - - commit message handling, and source revision handling. This affects the commands co, up, log, ci, diff. (Checking out or diffing against old revivions, committing with commit messages, and reviewing the commit log) @@ -35,6 +29,8 @@ NORMAL: - add support for local build of packages which do not exist / have not been created yet in the buildservice + - add switches to the meta command for easy adding of other maintainers + (like 'osc meta prj --add-maintainer foo') - write howto for plugin-izing subcommand implementation - split functionality that needs prj/pac as commandline arguments into a seperate tool (oscremote? osc -r?) - status: implement -u option as in svn [3] diff --git a/osc/commandline.py b/osc/commandline.py index be937fe8..363d80a1 100755 --- a/osc/commandline.py +++ b/osc/commandline.py @@ -132,11 +132,11 @@ class Osc(cmdln.Cmdln): print '\n'.join(l) - @cmdln.option('-e', '--edit', action='store_true', - help='edit metadata') @cmdln.option('-F', '--file', metavar='FILE', help='read metadata from FILE, instead of opening an editor. ' '\'-\' denotes standard input. ') + @cmdln.option('-e', '--edit', action='store_true', + help='edit metadata') def do_meta(self, subcmd, opts, *args): """${cmd_name}: Show meta information, or edit it @@ -154,14 +154,17 @@ class Osc(cmdln.Cmdln): With the --edit switch, the metadata can be edited. Per default, osc opens the program specified by the environmental variable EDITOR with a temporary file. Alternatively, content to be saved can be supplied via - the --file switch. + the --file switch. If the argument is '-', input is taken from stdin: + osc meta prjconf home:poeml | sed ... | osc meta prjconf home:poeml -F - The --create switch is subject to discussion and not implemented. The current behaviour is to create a non-existing resource implicitely, if while it is edited. usage: - osc meta [-e|--edit [-f|--file] [-c|--create]] ARGS... + osc meta ARGS... + osc meta -e|--edit [-c|--create] ARGS... + osc meta -F|--file ARGS... ${cmd_option_list} """ @@ -185,51 +188,106 @@ class Osc(cmdln.Cmdln): print >>sys.stderr, 'Too many arguments.' return 2 - # prj + # specific arguments if cmd == 'prj': project = args[0] - if not opts.edit: - sys.stdout.write(''.join(show_project_meta(conf.config['apiurl'], project))) - else: - edit_meta(metatype='prj', - path_args = quote_plus(project), - template_args = (project, conf.config['user'])) - - # pkg elif cmd == 'pkg': project, package = args[0:2] - if not opts.edit: - sys.stdout.write(''.join(show_package_meta(conf.config['apiurl'], project, package))) - else: - edit_meta(metatype='pkg', - path_args = (quote_plus(project), quote_plus(package)), - template_args = (package, conf.config['user'])) - - # prjconf elif cmd == 'prjconf': project = args[0] - if not opts.edit: - sys.stdout.write(''.join(show_project_conf(conf.config['apiurl'], project))) - else: - edit_meta(metatype='prjconf', - path_args = quote_plus(project), - template_args = None) - - # user elif cmd == 'user': user = args[0] - if not opts.edit: + + # show + if not opts.edit: + if cmd == 'prj': + sys.stdout.write(''.join(show_project_meta(conf.config['apiurl'], project))) + elif cmd == 'pkg': + sys.stdout.write(''.join(show_package_meta(conf.config['apiurl'], project, package))) + elif cmd == 'prjconf': + sys.stdout.write(''.join(show_project_conf(conf.config['apiurl'], project))) + elif cmd == 'user': r = get_user_meta(conf.config['apiurl'], user) if r: sys.stdout.write(''.join(r)) - else: + + # edit + if opts.edit and not opts.file: + if cmd == 'prj': + edit_meta(metatype='prj', + edit=True, + path_args=quote_plus(project), + template_args=(project, conf.config['user'])) + elif cmd == 'pkg': + edit_meta(metatype='pkg', + edit=True, + path_args=(quote_plus(project), quote_plus(package)), + template_args=(package, conf.config['user'])) + elif cmd == 'prjconf': + edit_meta(metatype='prjconf', + edit=True, + path_args=quote_plus(project), + template_args=None) + elif cmd == 'user': edit_meta(metatype='user', - path_args = (quote_plus(user)), - template_args = (user, user)) + edit=True, + path_args=(quote_plus(user)), + template_args=(user, user)) + + # upload file + if opts.file: + + if opts.file == '-': + f = sys.stdin.read() + else: + try: + f = open(opts.file).read() + except: + sys.exit('could not open file \'%s\'.' % opts.file) + + if cmd == 'prj': + edit_meta(metatype='prj', + data=f, + edit=opts.edit, + path_args=quote_plus(project)) + elif cmd == 'pkg': + edit_meta(metatype='pkg', + data=f, + edit=opts.edit, + path_args=(quote_plus(project), quote_plus(package))) + elif cmd == 'prjconf': + edit_meta(metatype='prjconf', + data=f, + edit=opts.edit, + path_args=quote_plus(project)) + elif cmd == 'user': + edit_meta(metatype='user', + data=f, + edit=opts.edit, + path_args=(quote_plus(user))) + # editmeta and its aliases are all depracated + @cmdln.alias("editprj") + @cmdln.alias("createprj") + @cmdln.alias("editpac") + @cmdln.alias("createpac") + @cmdln.alias("edituser") + @cmdln.alias("usermeta") + def do_editmeta(self, subcmd, opts, *args): + """${cmd_name}: + + Obsolete command to edit metadata. Use 'meta' now. + See the help output of 'meta'. + + """ + + print >>sys.stderr, 'This command is obsolete. Use \'osc meta ...\'.' + print >>sys.stderr, 'See \'osc help meta\'.' + #self.do_help([None, 'meta']) + return 2 # @cmdln.alias("createpac") # def do_editpac(self, subcmd, opts, project, package): @@ -257,52 +315,6 @@ class Osc(cmdln.Cmdln): # edit_meta(project, None) -# def do_editmeta(self, subcmd, opts, *args): -# """${cmd_name}: Edit project/package meta information -# -# If the named project or package does not exist, it will be created. -# -# Examples: -# osc editmeta Apache # edit meta of project 'Apache' -# osc editmeta Apache apache2 # edit meta of package 'apache2' -# -# ${cmd_usage} -# ${cmd_option_list} -# """ -# -# args = slash_split(args) -# -# if not args: -# print >>sys.stderr, 'Missing argument.' -# self.do_help([None, 'editmeta']) -# return 2 -# -# if len(args) == 2: -# project = args[0] -# package = args[1] -# edit_meta(project, package) -# -# elif len(args) == 1: -# project = args[0] -# edit_meta(project, None) - - -# def do_edituser(self, subcmd, opts, *args): -# """${cmd_name}: Edit user meta information -# -# If the named user id does not exist, it will be created. -# -# ${cmd_usage} -# ${cmd_option_list} -# """ -# -# if not args or len(args) != 1: -# user = conf.config['user'] -# else: -# user = args[0] -# edit_user_meta(user) - - def do_linkpac(self, subcmd, opts, *args): """${cmd_name}: "Link" a package to another package @@ -1032,20 +1044,6 @@ class Osc(cmdln.Cmdln): p.clear_from_conflictlist(filename) -# def do_usermeta(self, subcmd, opts, name): -# """${cmd_name}: Shows user metadata -# -# Shows metadata about the buildservice user with the id NAME. -# -# ${cmd_usage} -# ${cmd_option_list} -# """ -# -# r = get_user_meta(conf.config['apiurl'], name) -# if r: -# print ''.join(r) - - def do_platforms(self, subcmd, opts, *args): """${cmd_name}: Shows available platforms diff --git a/osc/core.py b/osc/core.py index 58ede396..de48c44d 100755 --- a/osc/core.py +++ b/osc/core.py @@ -904,30 +904,16 @@ def show_package_meta(apiurl, prj, pac): class metafile: """metafile that can be manipulated and is stored back after manipulation.""" - def __init__(self, metatype, path, template, change_is_required=True): + def __init__(self, url, input, change_is_required=False): import tempfile + self.url = url self.change_is_required = change_is_required - (fd, self.filename) = tempfile.mkstemp(prefix = 'osc_editmeta.', suffix = '.xml', dir = '/tmp') - - self.url = makeurl(conf.config['apiurl'], [path]) - try: - m = http_GET(self.url).readlines() - # when testing this offline: <-- what did I mean with that?? - #except urllib2.URLError, e: - # m = template - except urllib2.HTTPError, e: - if e.code == 404: - m = template - else: - print >>sys.stderr, 'error getting metadata for type \'%s\', path \'%s\':' \ - % (metatype, self.url) - print >>sys.stderr, e - sys.exit(1) + (fd, self.filename) = tempfile.mkstemp(prefix = 'osc_metafile.', suffix = '.xml', dir = '/tmp') f = os.fdopen(fd, 'w') - f.write(''.join(m)) + f.write(''.join(input)) f.close() self.hash_orig = dgst(self.filename) @@ -976,29 +962,57 @@ metatypes = { 'prj': { 'path': 'source/%s/_meta', }, } -def edit_meta(metatype, path_args, template_args, change_is_required=True): +def edit_meta(metatype, + path_args=None, + data=None, + template_args=None, + edit=False, + change_is_required=False): + + if metatype not in metatypes.keys(): + sys.exit('unknown metatype %s' % metatype) + path = metatypes[metatype]['path'] - template = metatypes[metatype]['template'] if path_args: path = path % path_args - if template_args: - template = template % template_args - f=metafile(metatype, path, template, change_is_required) + url = makeurl(conf.config['apiurl'], [path]) - editor = os.getenv('EDITOR', default='vim') - while 1: - os.system('%s %s' % (editor, f.filename)) - if change_is_required == True: - if not f.sync(): - input = raw_input('Try again? (yY = Yes - nN = No): ') - if input != 'y' and input != 'Y': + if not data: + try: + data = http_GET(url).readlines() + except urllib2.HTTPError, e: + if e.code == 404: + data = metatypes[metatype]['template'] + if template_args: + data = data % template_args + else: + print >>sys.stderr, 'error getting metadata for type \'%s\' at URL \'%s\':' \ + % (metatype, url) + print >>sys.stderr, e + sys.exit(1) + + if edit: + change_is_required = True + + f=metafile(url, data, change_is_required) + + if edit: + editor = os.getenv('EDITOR', default='vim') + while 1: + os.system('%s %s' % (editor, f.filename)) + if change_is_required == True: + if not f.sync(): + input = raw_input('Try again? (yY = Yes - nN = No): ') + if input != 'y' and input != 'Y': + break + else: break else: + f.sync() break - else: - f.sync() - break + else: + f.sync() def show_files_meta(apiurl, prj, pac, revision=None): @@ -1215,7 +1229,11 @@ def link_pac(src_project, src_package, dst_project, dst_package): tree.write(buf) src_meta = buf.getvalue() - edit_meta(dst_project, dst_package, template=src_meta, change_is_required=False) + #edit_meta(dst_project, dst_package, template=src_meta) + edit_meta('pkg', + input=src_meta, + path_args=(dst_project, dst_package), + template_args=(dst_package, conf.config['user'])) # create the _link file # but first, make sure not to overwrite an existing one