1
0
mirror of https://github.com/openSUSE/osc.git synced 2025-01-13 17:16:23 +01:00

- some more work on importsrcpkg():

* by default the new files will be comitted
    (if it is a new package or if there are no
    source files on the server)
  * added --disable-commit option switch to
    import the package only locally
  * added --delete-old-files option switch to
    delete old files from the server.
- some changes in the Package class:
  * extended existing commit() method to do
    all the commit work (before it was done
    in the do_commit() method).
  * moved stuff from the constructor into a
    new method (update_datastructs()).
This commit is contained in:
Marcus Hüwe 2007-07-30 11:12:42 +00:00
parent 155d60cfa0
commit d6bdc3712f
2 changed files with 136 additions and 90 deletions

View File

@ -868,7 +868,6 @@ class Osc(cmdln.Cmdln):
conf.config['do_commits'] = True
for p in pacs:
if conf.config['do_commits']:
if opts.message:
msg = opts.message
@ -879,48 +878,7 @@ class Osc(cmdln.Cmdln):
sys.exit('could not open file \'%s\'.' % opts.file)
else:
msg = ''
# commit only if the upstream revision is the same as the working copy's
upstream_rev = show_upstream_rev(p.apiurl, p.prjname, p.name)
if p.rev != upstream_rev:
print >>sys.stderr, 'Working copy \'%s\' is out of date (rev %s vs rev %s).' \
% (p.absdir, p.rev, upstream_rev)
print >>sys.stderr, 'Looks as if you need to update it first.'
return 1
if not p.todo:
p.todo = p.filenamelist_unvers + p.filenamelist
for filename in p.todo:
st = p.status(filename)
if st == 'A' or st == 'M':
p.todo_send.append(filename)
print 'Sending %s' % filename
elif st == 'D':
p.todo_delete.append(filename)
print 'Deleting %s' % filename
if not p.todo_send and not p.todo_delete:
print 'nothing to do for package %s' % p.name
continue
print 'Transmitting file data ',
for filename in p.todo_delete:
p.delete_source_file(filename)
p.to_be_deleted.remove(filename)
for filename in p.todo_send:
sys.stdout.write('.')
sys.stdout.flush()
p.put_source_file(filename)
if conf.config['do_commits']:
p.rev = p.commit(msg=msg)
print
print 'Committed revision %s.' % p.rev
else:
print
p.update_local_filesmeta()
p.write_deletelist()
p.commit(msg)
@cmdln.option('-r', '--revision', metavar='rev',
@ -1666,6 +1624,10 @@ class Osc(cmdln.Cmdln):
help='set a title')
@cmdln.option('-d', '--description', metavar='description',
help='set the description of the package')
@cmdln.option('', '--delete-old-files', action='store_true',
help='delete existing files from the server')
@cmdln.option('', '--disable-commit', action='store_true',
help='do not commit the new files')
def do_importsrcpkg(self, subcmd, opts, srpm):
"""${cmd_name}: import a new package from a src.rpm
@ -1675,7 +1637,9 @@ class Osc(cmdln.Cmdln):
the package does not exist on the server it will be created
too otherwise the meta data of the existing package will be
updated (<title /> and <description />).
The src.rpm will be extracted into the package dir.
The src.rpm will be extracted into the package dir. If the
--disable-commit switch is not used all changes will be
committed.
SRPM is the path of the src.rpm in the local filesystem,
or an URL.
@ -1742,8 +1706,27 @@ class Osc(cmdln.Cmdln):
data = data)
init_package_dir(conf.config['apiurl'], project, pac, os.path.join(project, pac))
unpack_srcrpm(srpm, os.getcwd())
print 'Adding files to working copy...'
self.do_add(None, {}, *glob.glob('*'))
p = Package(os.getcwd())
if len(p.filenamelist) == 0 and not opts.disable_commit:
# TODO: moving this into the Package class
print 'Adding files to working copy...'
self.do_add(None, None, *glob.glob('*'))
p.commit()
elif not opts.disable_commit and opts.delete_old_files:
delete_server_files(conf.config['apiurl'], project, pac, p.filenamelist)
p.update_local_filesmeta()
# TODO: moving this into the Package class
print 'Adding files to working copy...'
self.do_add(None, None, *glob.glob('*'))
p.update_datastructs()
p.commit()
else:
print 'The package \'%s\' already exists on the server or the ' \
'\'--disable-commit\' switch was used. Please commit ' \
'this working copy manually or use the ' \
'\'--delete-old-files\' option.' % pac
print 'Package \'%s\' only imported locally' % pac
sys.exit(1)
else:
print >>sys.stderr, 'error - package already exists'
sys.exit(1)

View File

@ -199,7 +199,6 @@ class Project:
class Package:
"""represent a package (its directory) and read/keep/write its metadata"""
def __init__(self, workingdir):
import fnmatch
self.dir = workingdir
self.absdir = os.path.abspath(self.dir)
self.storedir = os.path.join(self.dir, store)
@ -210,41 +209,12 @@ class Package:
self.name = store_read_package(self.dir)
self.apiurl = store_read_apiurl(self.dir)
files_tree = read_filemeta(self.dir)
files_tree_root = files_tree.getroot()
self.rev = files_tree_root.get('rev')
self.srcmd5 = files_tree_root.get('srcmd5')
self.filenamelist = []
self.filelist = []
for node in files_tree_root.findall('entry'):
try:
f = File(node.get('name'),
node.get('md5'),
int(node.get('size')),
int(node.get('mtime')))
except:
# okay, a very old version of _files, which didn't contain any metadata yet...
f = File(node.get('name'), '', 0, 0)
self.filelist.append(f)
self.filenamelist.append(f.name)
self.to_be_deleted = read_tobedeleted(self.dir)
self.in_conflict = read_inconflict(self.dir)
self.update_datastructs()
self.todo = []
self.todo_send = []
self.todo_delete = []
# gather unversioned files, but ignore some stuff
self.excluded = [ i for i in os.listdir(self.dir)
for j in exclude_stuff
if fnmatch.fnmatch(i, j) ]
self.filenamelist_unvers = [ i for i in os.listdir(self.dir)
if i not in self.excluded
if i not in self.filenamelist ]
def info(self):
return info_templ % (self.dir, self.apiurl, self.srcmd5, self.rev)
@ -327,18 +297,57 @@ class Package:
shutil.copy2(os.path.join(self.dir, n), os.path.join(self.storedir, n))
def commit(self, msg=''):
query = []
query.append('cmd=commit')
query.append('rev=upload')
query.append('user=%s' % conf.config['user'])
query.append('comment=%s' % quote_plus(msg))
u = makeurl(self.apiurl, ['source', self.prjname, self.name], query=query)
#print u
f = http_POST(u)
root = ET.parse(f).getroot()
rev = int(root.get('rev'))
return rev
# commit only if the upstream revision is the same as the working copy's
upstream_rev = show_upstream_rev(self.apiurl, self.prjname, self.name)
if self.rev != upstream_rev:
print >>sys.stderr, 'Working copy \'%s\' is out of date (rev %s vs rev %s).' \
% (self.absdir, self.rev, upstream_rev)
print >>sys.stderr, 'Looks as if you need to update it first.'
sys.exit(1)
if not self.todo:
self.todo = self.filenamelist_unvers + self.filenamelist
for filename in self.todo:
st = self.status(filename)
if st == 'A' or st == 'M':
self.todo_send.append(filename)
print 'Sending %s' % filename
elif st == 'D':
self.todo_delete.append(filename)
print 'Deleting %s' % filename
if not self.todo_send and not self.todo_delete:
print 'nothing to do for package %s' % self.name
sys.exit(1)
print 'Transmitting file data ',
for filename in self.todo_delete:
self.delete_source_file(filename)
self.to_be_deleted.remove(filename)
for filename in self.todo_send:
sys.stdout.write('.')
sys.stdout.flush()
self.put_source_file(filename)
# all source files are committed - now comes the log
if conf.config['do_commits']:
query = []
query.append('cmd=commit')
query.append('rev=upload')
query.append('user=%s' % conf.config['user'])
query.append('comment=%s' % quote_plus(msg))
u = makeurl(self.apiurl, ['source', self.prjname, self.name], query=query)
#print u
f = http_POST(u)
root = ET.parse(f).getroot()
self.rev = int(root.get('rev'))
print
print 'Committed revision %s.' % self.rev
else:
print
self.update_local_filesmeta()
self.write_deletelist()
def write_conflictlist(self):
if len(self.in_conflict) == 0:
@ -416,7 +425,45 @@ class Package:
f = open(os.path.join(self.storedir, '_files'), 'w')
f.write(meta)
f.close()
def update_datastructs(self):
"""
Update the internal data structures if the local _files
file has changed (e.g. update_local_filesmeta() has been
called).
"""
import fnmatch
files_tree = read_filemeta(self.dir)
files_tree_root = files_tree.getroot()
self.rev = files_tree_root.get('rev')
self.srcmd5 = files_tree_root.get('srcmd5')
self.filenamelist = []
self.filelist = []
for node in files_tree_root.findall('entry'):
try:
f = File(node.get('name'),
node.get('md5'),
int(node.get('size')),
int(node.get('mtime')))
except:
# okay, a very old version of _files, which didn't contain any metadata yet...
f = File(node.get('name'), '', 0, 0)
self.filelist.append(f)
self.filenamelist.append(f.name)
self.to_be_deleted = read_tobedeleted(self.dir)
self.in_conflict = read_inconflict(self.dir)
# gather unversioned files, but ignore some stuff
self.excluded = [ i for i in os.listdir(self.dir)
for j in exclude_stuff
if fnmatch.fnmatch(i, j) ]
self.filenamelist_unvers = [ i for i in os.listdir(self.dir)
if i not in self.excluded
if i not in self.filenamelist ]
def update_local_pacmeta(self):
"""
Update the local _meta file in the store.
@ -1992,3 +2039,19 @@ def is_srcrpm(f):
return True
else:
return False
def delete_server_files(apiurl, prj, pac, files):
"""
This method deletes the given filelist on the
server. No local data will be touched.
"""
for file in files:
try:
u = makeurl(apiurl, ['source', prj, pac, file])
http_DELETE(u)
except:
# we do not handle all exceptions here - we need another solution
# see bug #280034
print >>sys.stderr, 'error while deleting file \'%s\'' % file
sys.exit(1)