diff --git a/osc/commandline.py b/osc/commandline.py
index e69f0600..da0633fd 100755
--- a/osc/commandline.py
+++ b/osc/commandline.py
@@ -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 (
and ).
- 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)
diff --git a/osc/core.py b/osc/core.py
index ab58b98d..408eb64c 100755
--- a/osc/core.py
+++ b/osc/core.py
@@ -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)