Hello community,
here is the log from the commit of package osc
checked in at Fri Nov 30 02:28:10 CET 2007.
--------
--- osc/osc.changes 2007-09-03 14:32:12.000000000 +0200
+++ /mounts/work_src_done/STABLE/osc/osc.changes 2007-11-30 02:02:16.000000000 +0100
@@ -1,0 +2,40 @@
+Fri Nov 30 01:50:24 CET 2007 - poeml@suse.de
+
+- update to r2685:
+ - rdiff: new command for server-side diffs between arbitrary
+ packages
+ - cat: new command to print a file on the standard output
+ - diff: reworked functionality to show newly added files, and
+ behaving more like svn when doing diff against a certain
+ revision
+ - bugfix in {link,aggregate,copy}_pac (<person> elements). Patch
+ from Michal Marek.
+ - checkout an empty project instead of doing nothing
+ - fix prjresults for newly added packages, where build status is
+ missing
+ - internal changes:
+ - copied init_project_dir() method from the
+ osc-package-tracking branch (just removed the
+ do_package_tracking stuff)
+ - changed the storedir attribut of the Package() class to an
+ absolute filename - normally this shouldn't have any impact
+ on existing methods, functionality etc.
+
+-------------------------------------------------------------------
+Tue Oct 30 12:47:13 CET 2007 - poeml@suse.de
+
+- update to r2467. Most work done by Marcus Huewe.
+ - version 0.99
+ - aggregatepac: new command, similar to linkpac. Patch from Pavol
+ Rusnak.
+ - wipebinaries: added --build-failed and --broken [#335498]
+ - deleteprj: enabled this command, as the backend now supports it
+ - maintainer:
+ - added --verbose option
+ - added functionality to add/remove users from a project/package
+ - print the list of URL to try, when in HTTP debug mode
+ - build: allow to use lbuild, a compatible replacement for build
+ - do not create dirs for non-existing packages during checkout
+ [#259711]
+
+-------------------------------------------------------------------
Old:
----
osc-0.98.tar.gz
New:
----
osc-0.99.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ osc.spec ++++++
--- /var/tmp/diff_new_pack.DA5603/_old 2007-11-30 02:27:28.000000000 +0100
+++ /var/tmp/diff_new_pack.DA5603/_new 2007-11-30 02:27:28.000000000 +0100
@@ -1,5 +1,5 @@
#
-# spec file for package osc (Version 0.98)
+# spec file for package osc (Version 0.99)
#
# Copyright (c) 2007 SUSE LINUX Products GmbH, Nuernberg, Germany.
# This file and all modifications and additions to the pristine
@@ -12,13 +12,13 @@
Name: osc
BuildRequires: python-devel
-Version: 0.98
+Version: 0.99
Release: 1
Group: Development/Tools/Other
License: GPL v2 or later
BuildRoot: %{_tmppath}/%{name}-%{version}-build
-URL: https://forgesvn1.novell.com/svn/opensuse/trunk/buildservice/src/clientlib/p...
-# v=0.98; svn export https://forgesvn1.novell.com/svn/opensuse/trunk/buildservice/src/clientlib/p... osc-$v; tar czf osc-$v.tar.gz osc-$v
+Url: https://forgesvn1.novell.com/svn/opensuse/trunk/buildservice/src/clientlib/p...
+# v=0.99; svn export https://forgesvn1.novell.com/svn/opensuse/trunk/buildservice/src/clientlib/p... osc-$v; tar czf osc-$v.tar.gz osc-$v
Source: osc-%{version}.tar.gz
Summary: openSUSE (build service) commander
Requires: python-urlgrabber
@@ -78,6 +78,40 @@
%doc README TODO NEWS
%changelog
+* Fri Nov 30 2007 - poeml@suse.de
+- update to r2685:
+ - rdiff: new command for server-side diffs between arbitrary
+ packages
+ - cat: new command to print a file on the standard output
+ - diff: reworked functionality to show newly added files, and
+ behaving more like svn when doing diff against a certain
+ revision
+ - bugfix in {link,aggregate,copy}_pac (<person> elements). Patch
+ from Michal Marek.
+ - checkout an empty project instead of doing nothing
+ - fix prjresults for newly added packages, where build status is
+ missing
+ - internal changes:
+ - copied init_project_dir() method from the
+ osc-package-tracking branch (just removed the
+ do_package_tracking stuff)
+ - changed the storedir attribut of the Package() class to an
+ absolute filename - normally this shouldn't have any impact
+ on existing methods, functionality etc.
+* Tue Oct 30 2007 - poeml@suse.de
+- update to r2467. Most work done by Marcus Huewe.
+ - version 0.99
+ - aggregatepac: new command, similar to linkpac. Patch from Pavol
+ Rusnak.
+ - wipebinaries: added --build-failed and --broken [#335498]
+ - deleteprj: enabled this command, as the backend now supports it
+ - maintainer:
+ - added --verbose option
+ - added functionality to add/remove users from a project/package
+ - print the list of URL to try, when in HTTP debug mode
+ - build: allow to use lbuild, a compatible replacement for build
+ - do not create dirs for non-existing packages during checkout
+ [#259711]
* Mon Sep 03 2007 - poeml@suse.de
- update to r2075:
- new 'maintainer' command, to list the maintainers of a project
++++++ debian.changelog ++++++
--- osc/debian.changelog 2007-09-03 12:50:23.000000000 +0200
+++ /mounts/work_src_done/STABLE/osc/debian.changelog 2007-11-30 02:03:02.000000000 +0100
@@ -1,3 +1,43 @@
+osc (0.99-2) unstable; urgency=high
+
+ - update to r2685:
+ - rdiff: new command for server-side diffs between arbitrary
+ packages
+ - cat: new command to print a file on the standard output
+ - diff: reworked functionality to show newly added files, and
+ behaving more like svn when doing diff against a certain
+ revision
+ - bugfix in {link,aggregate,copy}_pac (<person> elements). Patch
+ from Michal Marek.
+ - checkout an empty project instead of doing nothing
+ - fix prjresults for newly added packages, where build status is
+ missing
+ - internal changes:
+ - copied init_project_dir() method from the
+ osc-package-tracking branch (just removed the
+ do_package_tracking stuff)
+ - changed the storedir attribut of the Package() class to an
+ absolute filename - normally this shouldn't have any impact
+ on existing methods, functionality etc.
+
+ -- Peter Poeml Fri, 30 Nov 2007 00:00:00 +0200
+
+osc (0.99-1) unstable; urgency=high
+
+ - update to r2467. Most work done by Marcus Huewe.
+ - version 0.99
+ - wipebinaries: added --build-failed and --broken [#335498]
+ - deleteprj: enabled this command, as the backend now supports it
+ - maintainer:
+ - added --verbose option
+ - added functionality to add/remove users from a project/package
+ - print the list of URL to try, when in HTTP debug mode
+ - build: allow to use lbuild, a compatible replacement for build
+ - do not create dirs for non-existing packages during checkout
+ [#259711]
+
+ -- Peter Poeml Tue, 30 Oct 2007 00:00:00 +0200
+
osc (0.98-3) unstable; urgency=high
- update to r2075:
++++++ osc-0.98.tar.gz -> osc-0.99.tar.gz ++++++
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/osc-0.98/NEWS new/osc-0.99/NEWS
--- old/osc-0.98/NEWS 2007-09-03 12:50:02.000000000 +0200
+++ new/osc-0.99/NEWS 2007-11-30 02:00:14.000000000 +0100
@@ -1,3 +1,27 @@
+since 0.99:
+
+- rdiff: new command for server-side diffs between arbitrary packages
+- cat: new command to print a file on the standard output
+- diff: reworked functionality to show newly added files, and behaving more
+ like svn when doing diff against a certain revision
+- bugfix in {link,aggregate,copy}_pac (<person> elements)
+- checkout an empty project instead of doing nothing
+- fix prjresults for newly added packages, where build status is missing
+
+
+0.99:
+
+- aggregatepac: new command, similar to linkpac. Patch from Pavol Rusnak.
+- wipebinaries: added --build-failed and --broken [#335498]
+- deleteprj: enabled this command, as the backend now supports it
+- maintainer:
+ - added --verbose option
+ - added functionality to add/remove users from a project/package
+- print the list of URL to try, when in HTTP debug mode
+- build: allow to use lbuild, a compatible replacement for build
+- do not create dirs for non-existing packages during checkout [#259711]
+
+
0.98:
- new maintainer command, to list the maintainers of a project or package
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/osc-0.98/osc/build.py new/osc-0.99/osc/build.py
--- old/osc-0.98/osc/build.py 2007-09-03 12:25:18.000000000 +0200
+++ new/osc-0.99/osc/build.py 2007-09-10 14:22:13.000000000 +0200
@@ -281,7 +281,8 @@
print 'Updating cache of required packages'
fetcher = Fetcher(cachedir = config['packagecachedir'],
urllist = config['urllist'],
- auth_dict = config['auth_dict'])
+ auth_dict = config['auth_dict'],
+ http_debug = config['http_debug'])
# now update the package cache
fetcher.run(bi)
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/osc-0.98/osc/commandline.py new/osc-0.99/osc/commandline.py
--- old/osc-0.98/osc/commandline.py 2007-09-03 12:25:18.000000000 +0200
+++ new/osc-0.99/osc/commandline.py 2007-11-29 18:32:52.000000000 +0100
@@ -436,6 +436,36 @@
return 1
link_pac(src_project, src_package, dst_project, dst_package)
+ def do_aggregatepac(self, subcmd, opts, *args):
+ """${cmd_name}: "Aggregate" a package to another package
+
+ The DESTPAC name is optional; the source packages' name will be used if
+ DESTPAC is omitted.
+
+ usage:
+ osc aggregatepac SOURCEPRJ SOURCEPAC DESTPRJ [DESTPAC]
+ ${cmd_option_list}
+ """
+
+ args = slash_split(args)
+
+ if not args or len(args) < 3:
+ print >>sys.stderr, 'Incorrect number of argument.'
+ self.do_help([None, 'aggregatepac'])
+ return 2
+
+ src_project = args[0]
+ src_package = args[1]
+ dst_project = args[2]
+ if len(args) > 3:
+ dst_package = args[3]
+ else:
+ dst_package = src_package
+
+ if src_project == dst_project and src_package == dst_package:
+ print >>sys.stderr, 'Error: source and destination are the same.'
+ return 1
+ aggregate_pac(src_project, src_package, dst_project, dst_package)
@cmdln.option('-t', '--to-apiurl', metavar='URL',
help='URL of destination api server. Default is the source api server.')
@@ -493,27 +523,27 @@
delete_package(conf.config['apiurl'], project, package)
+ @cmdln.option('-f', '--force', action='store_true',
+ help='deletes a project and its packages')
def do_deleteprj(self, subcmd, opts, project):
"""${cmd_name}: Delete a project on the repository server
- As a safety measure, project must be empty (i.e., you first need to delete all
- packages first).
+ As a safety measure, project must be empty (i.e., you need to delete all
+ packages first). If you are sure that you want to remove this project and all
+ its packages use \'--force\' switch.
- NOTE: This command is not implemented yet. Please mail
- admin@opensuse.org in order to get projects deleted.
${cmd_usage}
${cmd_option_list}
"""
- if meta_get_packagelist(conf.config['apiurl'], project) != []:
- print >>sys.stderr, 'Project contains packages. It must be empty before deleting it.'
- return 1
-
- #delete_project(conf.config['apiurl'], project)
- print >>sys.stderr, 'Deleting projects is not yet implemented.'
- print >>sys.stderr, 'Please send a request to opensuse-buildservice@opensuse.org'
- print >>sys.stderr, 'or admin@opensuse.org.'
+ if len(meta_get_packagelist(conf.config['apiurl'], project)) >= 1 and not opts.force:
+ print >>sys.stderr, 'Project contains packages. It must be empty before deleting it. ' \
+ 'If you are sure that you want to remove this project and all its ' \
+ 'packages use the \'--force\' switch'
+ sys.exit(1)
+ else:
+ delete_project(conf.config['apiurl'], project)
@cmdln.option('', '--specfile', metavar='FILE',
@@ -561,98 +591,47 @@
args = parseargs(args)
pacs = findpacs(args)
- difference_found = False
- d = []
-
rev1, rev2 = parseRevisionOption(opts.revision)
- pac = pacs[0]
-
- if rev1 and rev2 and (len(pacs) == 1):
- # this is currently not implemented
- print >>sys.stderr, 'this feature isn\'t implemented yet'
- sys.exit(1)
- elif rev1 and (pac.rev != rev1) and (len(pacs) == 1):
- if not checkRevision(pac.prjname, pac.name, rev1):
- print >>sys.stderr, 'Revision \'%s\' does not exist' % rev1
- sys.exit(1)
- # make a temp dir for checking out the project
- import tempfile
- tmpdir = tempfile.mkdtemp(rev1, pac.name, '/tmp')
- curdir = os.getcwd()
- os.chdir(tmpdir)
- init_package_dir(conf.config['apiurl'], pac.prjname, pac.name, tmpdir, rev1)
- os.chdir(curdir)
- tmppac = Package(tmpdir)
-
- changed_files = []
- added_files = []
- removed_files = []
- if pac.todo:
- for file in pac.todo:
- if file in tmppac.filenamelist:
- if dgst(os.path.join(pac.dir, file)) != tmppac.findfilebyname(file).md5:
- changed_files.append(file)
- else:
- added_files.append(file)
- else:
- changed_files, added_files, removed_files = pac.comparePac(tmppac)
-
- for file in changed_files:
- tmppac.updatefile(file, rev1)
- d.append('Index: %s\n' % file)
- d.append('===================================================================\n')
- d.append(get_source_file_diff(pac.dir, file, rev1, file, tmppac.dir))
- tmppac.delete_localfile(file)
- tmppac.delete_storefile(file)
-
- # this tempfile is used as a dummy file for difflib
- (fd, filename) = tempfile.mkstemp(dir=tmppac.storedir)
-
- for file in added_files:
- d.append('Index: %s\n' % file)
- d.append('===================================================================\n')
- d.append(get_source_file_diff(pac.dir, file, rev1, \
- os.path.basename(filename), \
- tmppac.storedir, file))
-
- for file in removed_files:
- tmppac.updatefile(file, rev1)
- d.append('Index: %s\n' % file)
- d.append('===================================================================\n')
- d.append(get_source_file_diff(tmppac.storedir, \
- os.path.basename(filename), \
- rev1, file, tmppac.dir, file))
- tmppac.delete_localfile(file)
- tmppac.delete_storefile(file)
+ diff = ''
+ for pac in pacs:
+ diff += ''.join(make_diff(pac, rev1))
+ if len(diff) > 0:
+ print diff
- # clean up
- os.unlink(filename)
- for dir, dirnames, files in os.walk(tmppac.storedir):
- for file in files:
- os.unlink(os.path.join(dir, file))
- os.rmdir(tmppac.storedir)
- os.rmdir(tmppac.dir)
- else:
- for p in pacs:
- if p.todo == []:
- for i in p.filenamelist:
- s = p.status(i)
- if s == 'M' or s == 'C':
- p.todo.append(i)
-
- for filename in p.todo:
- d.append('Index: %s\n' % filename)
- d.append('===================================================================\n')
- d.append(get_source_file_diff(p.dir, filename, p.rev))
-
- if d:
- print ''.join(d)
- difference_found = True
+ @cmdln.option('--oldprj', metavar='OLDPRJ',
+ help='project to compare against')
+ @cmdln.option('--oldpkg', metavar='OLDPKG',
+ help='package to compare against')
+ @cmdln.option('-r', '--revision', metavar='N[:M]',
+ help='revision id, where N = old revision and M = new revision')
+ def do_rdiff(self, subcmd, opts, new_project, new_package):
+ """${cmd_name}: server-side "pretty" diff of two packages
+
+ If neither OLDPRJ nor OLDPKG are specified, the diff is against the
+ last revision, thus showing the latest change.
+
+ Note that this command doesn't reply a "normal" diff which can be
+ applied as patch, but a pretty diff, which also compares the content of
+ tarballs.
+
+
+ ${cmd_usage}
+ ${cmd_option_list}
+ """
+
+ old_revision = None
+ new_revision = None
+ if opts.revision:
+ old_revision, new_revision = parseRevisionOption(opts.revision)
+
+ rdiff = pretty_diff(conf.config['apiurl'],
+ opts.oldprj, opts.oldpkg, old_revision,
+ new_project, new_package, new_revision)
+
+ print rdiff
+
- if difference_found:
- return 1
-
def do_repourls(self, subcmd, opts, *args):
"""${cmd_name}: shows URLs of .repo files
@@ -719,6 +698,12 @@
checkout_package(conf.config['apiurl'], project, package, rev)
elif project:
+ if not os.path.exists(project):
+ init_project_dir(conf.config['apiurl'], project, project)
+ print statfrmt('A', project)
+ else:
+ print >>sys.stderr, 'osc: project \'%s\' already exists' % project
+ sys.exit(1)
# all packages
for package in meta_get_packagelist(conf.config['apiurl'], project):
checkout_package(conf.config['apiurl'], project, package)
@@ -1363,7 +1348,8 @@
import osc.build
- if not os.path.exists('/usr/lib/build/debtransform'):
+ if not os.path.exists('/usr/lib/build/debtransform') \
+ and not os.path.exists('/usr/lib/lbuild/debtransform'):
sys.stderr.write('Error: you need build.rpm with version 2007.3.12 or newer.\n')
sys.stderr.write('See http://download.opensuse.org/repositories/openSUSE:/Tools/\n')
return 1
@@ -1557,6 +1543,10 @@
help='Delete all binary packages for a specific repository')
@cmdln.option('--build-disabled', action='store_true',
help='Delete all binaries of packages for which the build is disabled')
+ @cmdln.option('--build-failed', action='store_true',
+ help='Delete all binaries of packages for which the build failed')
+ @cmdln.option('--broken', action='store_true',
+ help='Delete all binaries of packages for which the package source is bad')
def do_wipebinaries(self, subcmd, opts, *args):
"""${cmd_name}: Delete all binary packages of a certain project/package
@@ -1578,8 +1568,21 @@
package = args[1]
else:
package = None
-
- print wipebinaries(conf.config['apiurl'], args[0], package, opts.arch, opts.repo, opts.build_disabled)
+
+ codes = []
+ if opts.build_disabled:
+ codes.append('disabled')
+ if opts.build_failed:
+ codes.append('failed')
+ if opts.broken:
+ codes.append('broken')
+
+ if len(codes) == 0:
+ codes.append(None)
+
+ # make a new request for each code= parameter
+ for code in codes:
+ print wipebinaries(conf.config['apiurl'], args[0], package, opts.arch, opts.repo, code)
@cmdln.option('--repos-baseurl', action='store_true',
@@ -1832,23 +1835,33 @@
@cmdln.option('-e', '--email', action='store_true',
help='show email addresses instead of user names')
+ @cmdln.option('-v', '--verbose', action='store_true',
+ help='show more information')
+ @cmdln.option('-a', '--add', metavar='user',
+ help='add a new maintainer')
+ @cmdln.option('-d', '--delete', metavar='user',
+ help='delete a maintainer from a project or package')
def do_maintainer(self, subcmd, opts, *args):
"""${cmd_name}: Show maintainers of a project/package
To be used like this:
- osc maintainer PRJ
+ osc maintainer PRJ <options>
or
- osc maintainer PRJ PKG
+ osc maintainer PRJ PKG <options>
${cmd_usage}
${cmd_option_list}
"""
+ pac = None
if len(args) == 1:
m = show_project_meta(conf.config['apiurl'], args[0])
+ prj = args[0]
elif len(args) == 2:
m = show_package_meta(conf.config['apiurl'], args[0], args[1])
+ prj = args[0]
+ pac = args[1]
else:
sys.exit('wrong argument count')
@@ -1858,16 +1871,64 @@
for person in tree.findall('person'):
maintainers.append(person.get('userid'))
- if not opts.email:
- print ', '.join(maintainers)
- else:
+ if opts.email:
emails = []
for maintainer in maintainers:
- emails.append(get_user_email(conf.config['apiurl'], maintainer))
+ user = get_user_data(conf.config['apiurl'], maintainer, 'email')
+ if user != None:
+ emails.append(''.join(user))
print ', '.join(emails)
+ elif opts.verbose:
+ userdata = []
+ for maintainer in maintainers:
+ user = get_user_data(conf.config['apiurl'], maintainer, 'realname', 'login', 'email')
+ if user != None:
+ for itm in user:
+ userdata.append(itm)
+ for row in build_table(3, userdata, ['realname', 'userid', 'email\n']):
+ print row
+ elif opts.add:
+ addMaintainer(conf.config['apiurl'], prj, pac, opts.add)
+ elif opts.delete:
+ delMaintainer(conf.config['apiurl'], prj, pac, opts.delete)
+ else:
+ print ', '.join(maintainers)
+
+
+ def do_cat(self, subcmd, opts, *args):
+ """${cmd_name}: print file on the standard output
+ Examples:
+ osc cat project package file
+ osc cat project/package/file
+ ${cmd_usage}
+ ${cmd_option_list}
+ """
+ args = slash_split(args)
+ if len(args) != 3:
+ print >>sys.stderr, 'error - incorrect number of arguments'
+ sys.exit(1)
+ import tempfile
+ (fd, filename) = tempfile.mkstemp(prefix = 'osc_%s.' % args[2], dir = '/tmp')
+ get_source_file(conf.config['apiurl'], args[0], args[1], args[2], targetfilename=filename)
+ if binary(os.read(fd, 4098)):
+ print >>sys.stderr, 'error - cannot display binary file \'%s\'' % args[2]
+ else:
+ print '### Beginning of file: \'%s\' ###' % filename
+ while True:
+ buf = os.read(fd, BUFSIZE)
+ if not buf:
+ break
+ else:
+ print buf
+ print '### End of file ###'
+ try:
+ os.close(fd)
+ os.unlink(filename)
+ except:
+ pass
# fini!
###############################################################################
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/osc-0.98/osc/core.py new/osc-0.99/osc/core.py
--- old/osc-0.98/osc/core.py 2007-09-03 12:17:04.000000000 +0200
+++ new/osc-0.99/osc/core.py 2007-11-29 18:22:57.000000000 +0100
@@ -5,7 +5,7 @@
# and distributed under the terms of the GNU General Public Licence,
# either version 2, or (at your option) any later version.
-__version__ = '0.98'
+__version__ = '0.99'
import os
import sys
@@ -201,7 +201,7 @@
def __init__(self, workingdir):
self.dir = workingdir
self.absdir = os.path.abspath(self.dir)
- self.storedir = os.path.join(self.dir, store)
+ self.storedir = os.path.join(self.absdir, store)
check_store_version(self.dir)
@@ -498,7 +498,7 @@
exists_in_store = False
if n in self.filenamelist:
known_by_meta = True
- if os.path.exists(os.path.join(self.dir, n)):
+ if os.path.exists(os.path.join(self.absdir, n)):
exists = True
if os.path.exists(os.path.join(self.storedir, n)):
exists_in_store = True
@@ -512,7 +512,7 @@
state = 'C'
elif exists and exists_in_store and known_by_meta:
#print self.findfilebyname(n)
- if dgst(os.path.join(self.dir, n)) != self.findfilebyname(n).md5:
+ if dgst(os.path.join(self.absdir, n)) != self.findfilebyname(n).md5:
state = 'M'
else:
state = ' '
@@ -829,6 +829,13 @@
return fd
+def init_project_dir(apiurl, dir, project):
+ if not os.path.exists(dir):
+ os.mkdir(dir)
+ os.mkdir(os.path.join(dir, store))
+
+ store_write_project(dir, project)
+ store_write_apiurl(dir, apiurl)
def init_package_dir(apiurl, project, package, dir, revision=None):
if not os.path.isdir(store):
@@ -867,7 +874,7 @@
sys.exit(1)
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']:
+ 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']:
# version is fine, no migration needed
f = open(versionfile, 'w')
f.write(__version__ + '\n')
@@ -1182,14 +1189,25 @@
return None
-def get_user_email(apiurl, user):
- u = makeurl(apiurl, ['person', quote_plus(user)])
- try:
- f = http_GET(u)
- root = ET.parse(f).getroot()
- return root.find('email').text
- except urllib2.HTTPError:
- print 'user \'%s\' not found' % user
+def get_user_data(apiurl, user, *tags):
+ """get specified tags from the user meta"""
+ meta = get_user_meta(apiurl, user)
+ data = []
+ if meta != None:
+ root = ET.fromstring(meta)
+ for tag in tags:
+ try:
+ if root.find(tag).text != None:
+ data.append(root.find(tag).text)
+ else:
+ # tag is empty
+ data.append('-')
+ except AttributeError:
+ # this part is reached if the tags tuple contains an invalid tag
+ print 'The xml file for user \'%s\' seems to be broken' % user
+ return None
+ return data
+ else:
return None
@@ -1295,7 +1313,7 @@
if not origfilename:
origfilename = filename
-
+
file1 = os.path.join(olddir, oldfilename) # old/stored original
file2 = os.path.join(dir, filename) # working copy
@@ -1327,16 +1345,128 @@
return ''.join(d)
+def make_diff(wc, revision):
+ import tempfile
+ changed_files = []
+ added_files = []
+ removed_files = []
+ cmp_pac = None
+ diff_hdr = 'Index: %s\n'
+ diff_hdr += '===================================================================\n'
+ if not revision:
+ # normal diff
+ for file in wc.filenamelist+wc.filenamelist_unvers:
+ state = wc.status(file)
+ if state == 'M' or state == 'C':
+ changed_files.append(file)
+ elif state == 'A':
+ added_files.append(file)
+ elif state == 'D':
+ removed_files.append(file)
+ else:
+ olddir = os.getcwd()
+ tmpdir = tempfile.mkdtemp(revision, wc.name, '/tmp')
+ os.chdir(tmpdir)
+ init_package_dir(conf.config['apiurl'], wc.prjname, wc.name, tmpdir, revision)
+ cmp_pac = Package(tmpdir)
+ if wc.todo:
+ for file in wc.todo:
+ if file in cmp_pac.filenamelist:
+ changed_files.append(file)
+ # behave like svn
+ #else:
+ # added_files.append(file)
+ else:
+ for file in wc.filenamelist+wc.filenamelist_unvers:
+ state = wc.status(file)
+ if wc.status(file) == 'A' and (not file in cmp_pac.filenamelist):
+ added_files.append(file)
+ elif file in cmp_pac.filenamelist and wc.status(file) == 'D':
+ removed_files.append(file)
+ elif wc.status(file) == ' ' and not file in cmp_pac.filenamelist:
+ added_files.append(file)
+ elif file in cmp_pac.filenamelist and state != 'A' and state != '?':
+ if dgst(os.path.join(wc.absdir, file)) != cmp_pac.findfilebyname(file).md5:
+ changed_files.append(file)
+ for file in cmp_pac.filenamelist:
+ if not file in wc.filenamelist:
+ removed_files.append(file)
+
+ diff = []
+ for file in changed_files:
+ diff.append(diff_hdr % file)
+ if cmp_pac == None:
+ diff.append(get_source_file_diff(wc.absdir, file, wc.rev))
+ else:
+ cmp_pac.updatefile(file, revision)
+ diff.append(get_source_file_diff(wc.absdir, file, revision, file,
+ cmp_pac.absdir, file))
+ (fd, tmpfile) = tempfile.mkstemp(dir='/tmp')
+ for file in added_files:
+ diff.append(diff_hdr % file)
+ if cmp_pac == None:
+ diff.append(get_source_file_diff(wc.absdir, file, wc.rev, os.path.basename(tmpfile),
+ os.path.dirname(tmpfile), file))
+ else:
+ diff.append(get_source_file_diff(wc.absdir, file, revision, os.path.basename(tmpfile),
+ os.path.dirname(tmpfile), file))
+
+ # FIXME: this is ugly but it cannot be avoided atm
+ # if a file is deleted via "osc rm file" we should keep the storefile.
+ tmp_pac = None
+ if cmp_pac == None:
+ olddir = os.getcwd()
+ tmpdir = tempfile.mkdtemp(dir='/tmp')
+ os.chdir(tmpdir)
+ init_package_dir(conf.config['apiurl'], wc.prjname, wc.name, tmpdir, wc.rev)
+ tmp_pac = Package(tmpdir)
+ os.chdir(olddir)
+
+ for file in removed_files:
+ diff.append(diff_hdr % file)
+ if cmp_pac == None:
+ tmp_pac.updatefile(file, tmp_pac.rev)
+ diff.append(get_source_file_diff(os.path.dirname(tmpfile), os.path.basename(tmpfile),
+ wc.rev, file, tmp_pac.storedir, file))
+ else:
+ cmp_pac.updatefile(file, revision)
+ diff.append(get_source_file_diff(os.path.dirname(tmpfile), os.path.basename(tmpfile),
+ revision, file, cmp_pac.storedir, file))
+
+ os.chdir(olddir)
+ if cmp_pac != None:
+ delete_tmpdir(cmp_pac.absdir)
+ if tmp_pac != None:
+ delete_tmpdir(tmp_pac.absdir)
+ return diff
+
+
+def pretty_diff(apiurl,
+ old_project, old_package, old_revision,
+ new_project, new_package, new_revision):
+
+ query = []
+ query.append('cmd=diff')
+ if old_project:
+ query.append('oproject=%s' % quote_plus(old_project))
+ if old_package:
+ query.append('opackage=%s' % quote_plus(old_package))
+ if old_revision:
+ query.append('orev=%s' % quote_plus(old_revision))
+ if new_revision:
+ query.append('rev=%s' % quote_plus(new_revision))
+
+ u = makeurl(apiurl, ['source', new_project, new_package], query=query)
+
+ f = http_POST(u)
+ return f.read()
+
def make_dir(apiurl, project, package):
#print "creating directory '%s'" % project
if not os.path.exists(project):
print statfrmt('A', project)
- os.mkdir(project)
- os.mkdir(os.path.join(project, store))
-
- store_write_project(project, project)
- store_write_apiurl(project, apiurl)
+ init_project_dir(apiurl, project, project)
#print "creating directory '%s/%s'" % (project, package)
if not os.path.exists(os.path.join(project, package)):
@@ -1350,6 +1480,11 @@
def checkout_package(apiurl, project, package, revision=None):
olddir = os.getcwd()
+ path = (quote_plus(project), quote_plus(package))
+ if meta_exists(metatype='pkg', path_args=path, create_new=False) == None:
+ print >>sys.stderr, 'error 404 - package or package does not exist'
+ sys.exit(1)
+
os.chdir(make_dir(apiurl, project, package))
init_package_dir(apiurl, project, package, store, revision)
p = Package(os.curdir)
@@ -1361,6 +1496,20 @@
os.chdir(olddir)
+def replace_pkg_meta(pkgmeta, new_name, new_prj):
+ """
+ update pkgmeta with new new_name and new_prj and set calling user as the
+ only maintainer
+ """
+ root = ET.fromstring(''.join(pkgmeta))
+ root.set('name', new_name)
+ root.set('project', new_prj)
+ for person in root.findall('person'):
+ root.remove(person)
+ ET.SubElement(root, 'person',
+ userid = conf.config['user'], role = 'maintainer')
+ return ET.tostring(root)
+
def link_pac(src_project, src_package, dst_project, dst_package):
"""
create a linked package
@@ -1369,18 +1518,7 @@
"""
src_meta = show_package_meta(conf.config['apiurl'], src_project, src_package)
-
- # replace package name and username
- # using a string buffer
- # and create the package
- tree = ET.parse(StringIO(''.join(src_meta)))
- root = tree.getroot()
- root.set('name', dst_package)
- root.set('project', dst_project)
- tree.find('person').set('userid', conf.config['user'])
- buf = StringIO()
- tree.write(buf)
- src_meta = buf.getvalue()
+ src_meta = replace_pkg_meta(src_meta, dst_package, dst_project)
edit_meta('pkg',
path_args=(dst_project, dst_package),
@@ -1407,6 +1545,39 @@
http_PUT(u, data=link_template)
print 'Done.'
+def aggregate_pac(src_project, src_package, dst_project, dst_package):
+ """
+ aggregate package
+ - "src" is the original package
+ - "dst" is the "aggregate" package that we are creating here
+ """
+
+ src_meta = show_package_meta(conf.config['apiurl'], src_project, src_package)
+ src_meta = replace_pkg_meta(src_meta, dst_package, dst_project)
+
+ edit_meta('pkg',
+ path_args=(dst_project, dst_package),
+ data=src_meta)
+
+ # create the _aggregate file
+ # but first, make sure not to overwrite an existing one
+ if '_aggregate' in meta_get_filelist(conf.config['apiurl'], dst_project, dst_package):
+ print >>sys.stderr
+ print >>sys.stderr, '_aggregate file already exists...! Aborting'
+ sys.exit(1)
+
+ print 'Creating _aggregate...',
+ aggregate_template = """\
+<aggregatelist>
+ <aggregate project="%s">
+ <package>%s</package>
+ </aggregate>
+</aggregatelist>
+""" % (src_project, src_package)
+
+ u = makeurl(conf.config['apiurl'], ['source', dst_project, dst_package, '_aggregate'])
+ http_PUT(u, data=aggregate_template)
+ print 'Done.'
def copy_pac(src_apiurl, src_project, src_package,
dst_apiurl, dst_project, dst_package):
@@ -1417,17 +1588,7 @@
import tempfile
src_meta = show_package_meta(src_apiurl, src_project, src_package)
-
- # replace project and package name
- # using a string buffer
- # and create the package
- tree = ET.parse(StringIO(''.join(src_meta)))
- root = tree.getroot()
- root.set('name', dst_package)
- root.set('project', dst_project)
- buf = StringIO()
- tree.write(buf)
- src_meta = buf.getvalue()
+ src_meta = replace_pkg_meta(src_meta, dst_package, dst_project)
print 'Sending meta data...'
u = makeurl(dst_apiurl, ['source', dst_project, dst_package, '_meta'])
@@ -1609,6 +1770,8 @@
line = []
line.append(' ')
for pac in pacs[startpac:startpac+max_pacs]:
+ if not status.has_key(pac): # for newly added packages, status may be missing
+ status[pac] = '?'
line.append(status[pac])
line.append(' ')
line.append(' %s %s' % (target['repo'], target['arch']))
@@ -1804,7 +1967,7 @@
return root.get('code')
-def wipebinaries(apiurl, project, package=None, arch=None, repo=None, build_disabled=None):
+def wipebinaries(apiurl, project, package=None, arch=None, repo=None, code=None):
query = []
query.append('cmd=wipe')
if package:
@@ -1813,8 +1976,8 @@
query.append('arch=%s' % quote_plus(arch))
if repo:
query.append('repository=%s' % quote_plus(repo))
- if build_disabled:
- query.append('code=disabled')
+ if code:
+ query.append('code=%s' % quote_plus(code))
u = makeurl(apiurl, ['build', project], query)
try:
@@ -1827,8 +1990,8 @@
err_str += ' arch %s' % arch
if repo:
err_str += ' repository %s' % repo
- if build_disabled:
- err_str += ' code=disabled'
+ if code:
+ err_str += ' code=%s' % code
print >> sys.stderr, err_str
print >> sys.stderr, u
print >> sys.stderr, e
@@ -2118,3 +2281,61 @@
# see bug #280034
print >>sys.stderr, 'error while deleting file \'%s\'' % file
sys.exit(1)
+
+def addMaintainer(apiurl, prj, pac, user):
+ """ add a new maintainer to a package or project """
+ path = quote_plus(prj),
+ kind = 'prj'
+ if pac:
+ path = path + (quote_plus(pac),)
+ kind = 'pkg'
+ data = meta_exists(metatype=kind,
+ path_args=path,
+ template_args=None,
+ create_new=False)
+
+ if data and get_user_meta(apiurl, user) != None:
+ tree = ET.fromstring(''.join(data))
+ found = False
+ for person in tree.getiterator('person'):
+ if person.get('userid') == user:
+ found = True
+ print "user already exists"
+ break
+ if not found:
+ # the xml has a fixed structure
+ tree.insert(2, ET.Element('person', role='maintainer', userid=user))
+ print 'user \'%s\' added to \'%s\'' % (user, pac or prj)
+ edit_meta(metatype=kind,
+ path_args=path,
+ data=ET.tostring(tree))
+ else:
+ print "osc: an error occured"
+
+def delMaintainer(apiurl, prj, pac, user):
+ """ delete a maintainer from a package or project """
+ path = quote_plus(prj),
+ kind = 'prj'
+ if pac:
+ path = path + (quote_plus(pac), )
+ kind = 'pkg'
+ data = meta_exists(metatype=kind,
+ path_args=path,
+ template_args=None,
+ create_new=False)
+ if data:
+ tree = ET.fromstring(''.join(data))
+ found = False
+ for person in tree.getiterator('person'):
+ if person.get('userid') == user:
+ tree.remove(person)
+ found = True
+ print "user \'%s\' removed" % user
+ if found:
+ edit_meta(metatype=kind,
+ path_args=path,
+ data=ET.tostring(tree))
+ else:
+ print "user \'%s\' not found in \'%s\'" % (user, pac or prj)
+ else:
+ print "an error occured"
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/osc-0.98/osc/fetch.py new/osc-0.99/osc/fetch.py
--- old/osc-0.98/osc/fetch.py 2007-06-26 13:19:41.000000000 +0200
+++ new/osc-0.99/osc/fetch.py 2007-09-10 14:22:13.000000000 +0200
@@ -23,7 +23,7 @@
class Fetcher:
- def __init__(self, cachedir = '/tmp', auth_dict = {}, urllist = []):
+ def __init__(self, cachedir = '/tmp', auth_dict = {}, urllist = [], http_debug = False):
__version__ = '0.1'
__user_agent__ = 'osbuild/%s' % __version__
@@ -37,6 +37,7 @@
self.cachedir = cachedir
self.urllist = urllist
+ self.http_debug = http_debug
passmgr = urllib2.HTTPPasswordMgrWithDefaultRealm()
for host in auth_dict.keys():
@@ -67,6 +68,12 @@
MirrorGroup._join_url = join_url
mg = MirrorGroup(self.gr, pac.urllist)
+ if self.http_debug:
+ print
+ print 'URLs to try for package \'%s\':' % pac
+ print '\n'.join(pac.urllist)
+ print
+
try:
# it returns the filename
ret = mg.urlgrab(pac.filename,
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/osc-0.98/TODO new/osc-0.99/TODO
--- old/osc-0.98/TODO 2007-09-03 12:49:44.000000000 +0200
+++ new/osc-0.99/TODO 2007-10-25 15:53:46.000000000 +0200
@@ -8,6 +8,7 @@
- think about how to locally build "linked" packages
http://lists4.opensuse.org/opensuse-buildservice/2007-07/msg00043.html
https://bugzilla.novell.com/show_bug.cgi?id=212565
+ draft on source code branching: http://en.opensuse.org/Build_Service/Concepts
NORMAL:
@@ -26,6 +27,8 @@
- use urllib.urlencode for parameter encoding (or check if this is the case already?)
- _real_ SSL support, with certificate verification
- copypac: put the current release number into the spec file before sending it
+ - for this, it is required to scan all current binaries, pick the highest release number
+ 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
@@ -152,3 +155,34 @@
+
+ % osc importsrcpkg -n apache2-mod_memcache /tmp/apache-mod_memcache-0.1.0-2mdv2008.0.src.rpm
+warning: rpmts_HdrFromFdno: Header V3 DSA signature: NOKEY, key ID 26752624
+Traceback (most recent call last):
+ File "/suse/poeml/bin/osc", line 10, in ?
+ sys.exit( osc.main() )
+ File "/suse/poeml/osc/osc/cmdln.py", line 256, in main
+ return self.cmd(args)
+ File "/suse/poeml/osc/osc/cmdln.py", line 279, in cmd
+ retval = self.onecmd(argv)
+ File "/suse/poeml/osc/osc/cmdln.py", line 395, in onecmd
+ return self._dispatch_cmd(handler, argv)
+ File "/suse/poeml/osc/osc/cmdln.py", line 1070, in _dispatch_cmd
+ return handler(argv[0], opts, *args)
+ File "/suse/poeml/osc/osc/commandline.py", line 1714, in do_importsrcpkg
+ rpm_data = data_from_rpm(srpm, 'Name:', 'Summary:', '%description')
+ File "/suse/poeml/osc/osc/core.py", line 2128, in data_from_rpm
+ header = ts.hdrFromFdno(file.fileno())
+_rpm.error: public key not available
+
+
+15:16 < DuDE> mt: Projekte anlegen geht nur, wenn es ein Subprojekt ist von einem Projekt wo Du Schreibrechte hast
+15:16 < mt> DuDE: wofür?
+15:16 < DuDE> mt: dass jeder einfach so top-level-Projekte anlegen kann, war einmal. Chaos-Reduzierung
+15:17 < DuDE> mt: ueblich ist heutzutage ein Request auf opensuse-buildservice@
+15:18 < DuDE> mt: kannst Du das gleiche mal eben mit osc -H probieren? Mich wuerde mal interessieren, ob da eine sinnvollere Meldung im Body mitkommt
+15:19 < DuDE> mt: mit -H muesste osc den Response-Body anzeigen. Meist ist der unerwuenscht, weil er typischerweise dank iChain hauptsaechlich Javascript-Schlonz enthaelt.
+15:19 < mt> DuDE: reply: 'HTTP/1.1 403 Forbidden\r\n'
+15:20 < DuDE> mt: das ist gut, dann sollte osc kein "try again" anbieten, sondern die Meldung rueberbringen
+
+
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Remember to have fun...
---------------------------------------------------------------------
To unsubscribe, e-mail: opensuse-commit+unsubscribe@opensuse.org
For additional commands, e-mail: opensuse-commit+help@opensuse.org