mirror of
https://github.com/openSUSE/osc.git
synced 2024-12-26 09:56:13 +01:00
- reimplement 'osc pull' so that iw works like intended, i.e. still works if the link is broken
This commit is contained in:
parent
60c3b45194
commit
0cb7afbfdf
@ -4389,16 +4389,102 @@ Please submit there instead, or use --nodevelproject to force direct submission.
|
||||
raise oscerr.WrongArgs('osc pull only works on linked packages.')
|
||||
elif not p.isexpanded():
|
||||
raise oscerr.WrongArgs('osc pull only works on expanded links.')
|
||||
linkinfo = p.linkinfo
|
||||
baserev = linkinfo.baserev
|
||||
if baserev == None:
|
||||
raise oscerr.WrongArgs('osc pull only works on links containing a base revision.')
|
||||
|
||||
# hack
|
||||
conf.config['linkcontrol'] = 0
|
||||
# do the update
|
||||
pulledrev=p.latest_rev()
|
||||
if pulledrev == p.rev:
|
||||
raise oscerr.WrongArgs('Already up-to-date.')
|
||||
p.update(rev=pulledrev)
|
||||
store_write_string(p.absdir, '_pulled', '')
|
||||
# get revisions we need
|
||||
query = { 'expand': 1, 'emptylink': 1 }
|
||||
u = makeurl(p.apiurl, ['source', p.prjname, p.name], query=query)
|
||||
f = http_GET(u)
|
||||
meta = f.readlines()
|
||||
root_new = ET.fromstring(''.join(meta))
|
||||
linkinfo_new = root_new.find('linkinfo')
|
||||
if linkinfo_new == None:
|
||||
raise oscerr.APIError('link is not a really a link?')
|
||||
if linkinfo_new.get('error') != None:
|
||||
raise oscerr.APIError('link target is broken')
|
||||
if linkinfo_new.get('srcmd5') == baserev:
|
||||
print "Already up-to-date."
|
||||
return
|
||||
dir_new = { 'apiurl': p.apiurl, 'project': p.prjname, 'package': p.name }
|
||||
dir_new['srcmd5'] = root_new.get('srcmd5')
|
||||
dir_new['entries'] = [[n.get('name'), n.get('md5')] for n in root_new.findall('entry')]
|
||||
|
||||
dir_oldpatched = { 'apiurl': p.apiurl, 'project': p.prjname, 'package': p.name, 'srcmd5': p.srcmd5 }
|
||||
dir_oldpatched['entries'] = map(lambda f: [f.name, f.md5], p.filelist)
|
||||
|
||||
query = { 'rev': linkinfo.srcmd5 }
|
||||
u = makeurl(p.apiurl, ['source', linkinfo.project, linkinfo.package], query=query)
|
||||
f = http_GET(u)
|
||||
root_old = ET.parse(f).getroot()
|
||||
dir_old = { 'apiurl': p.apiurl, 'project': linkinfo.project, 'package': linkinfo.package, 'srcmd5': linkinfo.srcmd5 }
|
||||
dir_old['entries'] = [[n.get('name'), n.get('md5')] for n in root_old.findall('entry')]
|
||||
|
||||
# now do 3-way merge
|
||||
entries_old = dict(dir_old['entries'])
|
||||
entries_oldpatched = dict(dir_oldpatched['entries'])
|
||||
entries_new = dict(dir_new['entries'])
|
||||
entries = {}
|
||||
entries.update(entries_old)
|
||||
entries.update(entries_oldpatched)
|
||||
entries.update(entries_new)
|
||||
for name in sorted(entries.keys()):
|
||||
md5_old = entries_old.get(name, '')
|
||||
md5_new = entries_new.get(name, '')
|
||||
md5_oldpatched = entries_oldpatched.get(name, '')
|
||||
if md5_old == md5_new or md5_oldpatched == md5_new:
|
||||
continue
|
||||
if md5_old == md5_oldpatched:
|
||||
if md5_new == '':
|
||||
print statfrmt('D', name)
|
||||
p.put_on_deletelist(name)
|
||||
os.unlink(name)
|
||||
else:
|
||||
print statfrmt('U', name)
|
||||
self.download(name, md5_new, dir_new, name)
|
||||
continue
|
||||
# need diff3 to resolve issue
|
||||
if md5_oldpatched == '':
|
||||
open(name, 'w').write('')
|
||||
os.rename(name, name + '.mine')
|
||||
self.download(name, md5_new, dir_new, name + '.new')
|
||||
self.download(name, md5_old, dir_old, name + '.old')
|
||||
if binary_file(name + '.mine') or binary_file(name + '.old') or binary_file(name + '.new'):
|
||||
shutil.copy2(name + '.new', name)
|
||||
print statfrmt('C', name)
|
||||
p.put_on_conflictlist(name)
|
||||
continue
|
||||
|
||||
o = open(name, 'wb')
|
||||
code = subprocess.call(['diff3', '-m',
|
||||
'-L', '.mine', name + '.mine',
|
||||
'-L', '.old', name + '.old',
|
||||
'-L', '.new', name + '.new',
|
||||
], stdout=o)
|
||||
if code == 0:
|
||||
print statfrmt('G', name)
|
||||
os.unlink(name + '.mine')
|
||||
os.unlink(name + '.old')
|
||||
os.unlink(name + '.new')
|
||||
elif code == 1:
|
||||
print statfrmt('C', name)
|
||||
p.put_on_conflictlist(name)
|
||||
else:
|
||||
print statfrmt('?', name)
|
||||
p.put_on_conflictlist(name)
|
||||
p.write_deletelist()
|
||||
p.write_conflictlist()
|
||||
# store new linkrev
|
||||
store_write_string(p.absdir, '_pulled', linkinfo_new.get('srcmd5'))
|
||||
print
|
||||
if len(p.in_conflict):
|
||||
print 'Please fix the conflicts (files marked with \'C\' above),'
|
||||
print 'run \'osc resolved ...\', and commit the changes'
|
||||
print 'to update the link information.'
|
||||
else:
|
||||
print 'Please commit the changes to update the link information.'
|
||||
|
||||
@cmdln.option('--create', action='store_true', default=False,
|
||||
help='create new gpg signing key for this project')
|
||||
|
12
osc/core.py
12
osc/core.py
@ -276,6 +276,7 @@ class Linkinfo:
|
||||
self.srcmd5 = None
|
||||
self.error = None
|
||||
self.rev = None
|
||||
self.baserev = None
|
||||
|
||||
def read(self, linkinfo_node):
|
||||
"""read in the linkinfo metadata from the <linkinfo> element passed as
|
||||
@ -291,6 +292,7 @@ class Linkinfo:
|
||||
self.srcmd5 = linkinfo_node.get('srcmd5')
|
||||
self.error = linkinfo_node.get('error')
|
||||
self.rev = linkinfo_node.get('rev')
|
||||
self.baserev = linkinfo_node.get('baserev')
|
||||
|
||||
def islink(self):
|
||||
"""returns True if the linkinfo is not empty, otherwise False"""
|
||||
@ -745,7 +747,7 @@ class Package:
|
||||
filename = os.path.join(self.dir, n)
|
||||
storefilename = os.path.join(self.storedir, n)
|
||||
myfilename = os.path.join(self.dir, n + '.mine')
|
||||
if self.islinkrepair():
|
||||
if self.islinkrepair() or self.ispulled():
|
||||
upfilename = os.path.join(self.dir, n + '.new')
|
||||
else:
|
||||
upfilename = os.path.join(self.dir, n + '.r' + self.rev)
|
||||
@ -755,7 +757,7 @@ class Package:
|
||||
# the working copy may be updated, so the .r* ending may be obsolete...
|
||||
# then we don't care
|
||||
os.unlink(upfilename)
|
||||
if self.islinkrepair():
|
||||
if self.islinkrepair() or self.ispulled():
|
||||
os.unlink(os.path.join(self.dir, n + '.old'))
|
||||
except:
|
||||
pass
|
||||
@ -858,6 +860,12 @@ class Package:
|
||||
query['keeplink'] = '1'
|
||||
if conf.config['linkcontrol']:
|
||||
query['linkrev'] = self.linkinfo.srcmd5
|
||||
if self.ispulled():
|
||||
for line in open(os.path.join(self.storedir, '_pulled'), 'r'):
|
||||
pulledrev = line.strip()
|
||||
if pulledrev:
|
||||
query['repairlink'] = '1'
|
||||
query['linkrev'] = pulledrev
|
||||
if self.islinkrepair():
|
||||
query['repairlink'] = '1'
|
||||
u = makeurl(self.apiurl, ['source', self.prjname, self.name], query=query)
|
||||
|
Loading…
Reference in New Issue
Block a user