1
0
mirror of https://github.com/openSUSE/osc.git synced 2025-02-22 18:22:12 +01:00

Fix possibility to overwrite special files in .osc (CVE-2024-22034 boo#1225911)

Source files are now stored in the 'sources' subdirectory which prevents
name collisons. This requires changing version of '.osc' store to 2.0.
This commit is contained in:
Daniel Mach 2024-07-18 10:36:20 +02:00
parent 48baf9c84f
commit 56c08df3d6
9 changed files with 176 additions and 86 deletions

View File

@ -8868,14 +8868,12 @@ Please submit there instead, or use --nodevelproject to force direct submission.
store_write_string(destdir, '_linkrepair', '') store_write_string(destdir, '_linkrepair', '')
pac = Package(destdir) pac = Package(destdir)
storedir = os.path.join(destdir, store)
for name in sorted(entries.keys()): for name in sorted(entries.keys()):
md5_old = entries_old.get(name, '') md5_old = entries_old.get(name, '')
md5_new = entries_new.get(name, '') md5_new = entries_new.get(name, '')
md5_oldpatched = entries_oldpatched.get(name, '') md5_oldpatched = entries_oldpatched.get(name, '')
if md5_new != '': if md5_new != '':
self.download(name, md5_new, dir_new, os.path.join(storedir, name)) self.download(name, md5_new, dir_new, store_sources_get_path(destdir, name))
if md5_old == md5_new: if md5_old == md5_new:
if md5_oldpatched == '': if md5_oldpatched == '':
pac.put_on_deletelist(name) pac.put_on_deletelist(name)
@ -8887,17 +8885,17 @@ Please submit there instead, or use --nodevelproject to force direct submission.
if md5_new == '': if md5_new == '':
continue continue
print(statfrmt('U', name)) print(statfrmt('U', name))
shutil.copy2(os.path.join(storedir, name), os.path.join(destdir, name)) shutil.copy2(store_sources_get_path(destdir, name), os.path.join(destdir, name))
continue continue
if md5_new == md5_oldpatched: if md5_new == md5_oldpatched:
if md5_new == '': if md5_new == '':
continue continue
print(statfrmt('G', name)) print(statfrmt('G', name))
shutil.copy2(os.path.join(storedir, name), os.path.join(destdir, name)) shutil.copy2(store_sources_get_path(destdir, name), os.path.join(destdir, name))
continue continue
self.download(name, md5_oldpatched, dir_oldpatched, os.path.join(destdir, name + '.mine')) self.download(name, md5_oldpatched, dir_oldpatched, os.path.join(destdir, name + '.mine'))
if md5_new != '': if md5_new != '':
shutil.copy2(os.path.join(storedir, name), os.path.join(destdir, name + '.new')) shutil.copy2(store_sources_get_path(destdir, name), os.path.join(destdir, name + '.new'))
else: else:
self.download(name, md5_new, dir_new, os.path.join(destdir, name + '.new')) self.download(name, md5_new, dir_new, os.path.join(destdir, name + '.new'))
self.download(name, md5_old, dir_old, os.path.join(destdir, name + '.old')) self.download(name, md5_old, dir_old, os.path.join(destdir, name + '.old'))

View File

@ -13,7 +13,7 @@ __version__ = git_version.get_version('0.182.1')
# __store_version__ is to be incremented when the format of the working copy # __store_version__ is to be incremented when the format of the working copy
# "store" changes in an incompatible way. Please add any needed migration # "store" changes in an incompatible way. Please add any needed migration
# functionality to check_store_version(). # functionality to check_store_version().
__store_version__ = '1.0' __store_version__ = '2.0'
import locale import locale
import os import os
@ -1213,16 +1213,13 @@ class Package:
if self.scm_url: if self.scm_url:
return dirty_files return dirty_files
for fname in self.filenamelist: for fname in self.filenamelist:
if not os.path.exists(os.path.join(self.storedir, fname)) and not fname in self.skipped: if not store_sources_is_file(self.absdir, fname) and fname not in self.skipped:
dirty_files.append(fname) dirty_files.append(fname)
for fname in Package.REQ_STOREFILES: for fname in Package.REQ_STOREFILES:
if not os.path.isfile(os.path.join(self.storedir, fname)): if not os.path.isfile(os.path.join(self.storedir, fname)):
dirty_files.append(fname) dirty_files.append(fname)
for fname in os.listdir(self.storedir): for fname in store_sources_list_files(self.absdir):
if fname in Package.REQ_STOREFILES or fname in Package.OPT_STOREFILES or \ if fname in self.filenamelist and fname in self.skipped:
fname.startswith('_build'):
continue
elif fname in self.filenamelist and fname in self.skipped:
dirty_files.append(fname) dirty_files.append(fname)
elif not fname in self.filenamelist: elif not fname in self.filenamelist:
dirty_files.append(fname) dirty_files.append(fname)
@ -1248,18 +1245,20 @@ class Package:
# all files which are present in the filelist have to exist in the storedir # all files which are present in the filelist have to exist in the storedir
for f in self.filelist: for f in self.filelist:
# XXX: should we also check the md5? # XXX: should we also check the md5?
if not os.path.exists(os.path.join(self.storedir, f.name)) and not f.name in self.skipped: if not store_sources_is_file(self.absdir, f.name) and f.name not in self.skipped:
# if get_source_file fails we're screwed up... # if get_source_file fails we're screwed up...
get_source_file(self.apiurl, self.prjname, self.name, f.name, get_source_file(self.apiurl, self.prjname, self.name, f.name,
targetfilename=os.path.join(self.storedir, f.name), revision=self.rev, targetfilename=store_sources_get_path(self.absdir, f.name), revision=self.rev,
mtime=f.mtime) mtime=f.mtime)
for fname in os.listdir(self.storedir): for fname in os.listdir(self.storedir):
if fname in Package.REQ_STOREFILES or fname in Package.OPT_STOREFILES or \ if fname in Package.REQ_STOREFILES or fname in Package.OPT_STOREFILES or \
fname.startswith('_build'): fname.startswith('_build'):
continue continue
elif not fname in self.filenamelist or fname in self.skipped:
for fname in store_sources_list_files(self.absdir):
if fname not in self.filenamelist or fname in self.skipped:
# this file does not belong to the storedir so remove it # this file does not belong to the storedir so remove it
os.unlink(os.path.join(self.storedir, fname)) os.unlink(store_sources_get_path(self.absdir, fname))
for fname in self.to_be_deleted[:]: for fname in self.to_be_deleted[:]:
if not fname in self.filenamelist: if not fname in self.filenamelist:
self.to_be_deleted.remove(fname) self.to_be_deleted.remove(fname)
@ -1279,11 +1278,9 @@ class Package:
raise oscerr.OscIOError(None, 'error: file \'%s\' does not exist' % n) raise oscerr.OscIOError(None, 'error: file \'%s\' does not exist' % n)
if n in self.to_be_deleted: if n in self.to_be_deleted:
self.to_be_deleted.remove(n) self.to_be_deleted.remove(n)
# self.delete_storefile(n)
self.write_deletelist() self.write_deletelist()
elif n in self.filenamelist or n in self.to_be_added: elif n in self.filenamelist or n in self.to_be_added:
raise oscerr.PackageFileConflict(self.prjname, self.name, n, 'osc: warning: \'%s\' is already under version control' % n) raise oscerr.PackageFileConflict(self.prjname, self.name, n, 'osc: warning: \'%s\' is already under version control' % n)
# shutil.copyfile(os.path.join(self.dir, n), os.path.join(self.storedir, n))
if self.dir != '.': if self.dir != '.':
pathname = os.path.join(self.dir, n) pathname = os.path.join(self.dir, n)
else: else:
@ -1348,7 +1345,7 @@ class Package:
if n in self.in_conflict: if n in self.in_conflict:
filename = os.path.join(self.dir, n) filename = os.path.join(self.dir, n)
storefilename = os.path.join(self.storedir, n) storefilename = store_sources_get_path(self.absdir, n)
myfilename = os.path.join(self.dir, n + '.mine') myfilename = os.path.join(self.dir, n + '.mine')
upfilename = os.path.join(self.dir, n + '.new') upfilename = os.path.join(self.dir, n + '.new')
@ -1392,7 +1389,7 @@ class Package:
def delete_source_file(self, n): def delete_source_file(self, n):
"""delete local a source file""" """delete local a source file"""
self.delete_localfile(n) self.delete_localfile(n)
self.delete_storefile(n) store_sources_delete_file(self.absdir, n)
def delete_remote_source_file(self, n): def delete_remote_source_file(self, n):
"""delete a remote source file (e.g. from the server)""" """delete a remote source file (e.g. from the server)"""
@ -1415,7 +1412,7 @@ class Package:
def __commit_update_store(self, tdir): def __commit_update_store(self, tdir):
"""move files from transaction directory into the store""" """move files from transaction directory into the store"""
for filename in os.listdir(tdir): for filename in os.listdir(tdir):
os.rename(os.path.join(tdir, filename), os.path.join(self.storedir, filename)) os.rename(os.path.join(tdir, filename), store_sources_get_path(self.absdir, filename))
def __generate_commitlist(self, todo_send): def __generate_commitlist(self, todo_send):
root = ET.Element('directory') root = ET.Element('directory')
@ -1549,7 +1546,7 @@ class Package:
# in sha256sums. # in sha256sums.
# The storefile is guaranteed to exist (since we have a # The storefile is guaranteed to exist (since we have a
# pulled/linkrepair wc, the file cannot have state 'S') # pulled/linkrepair wc, the file cannot have state 'S')
storefile = os.path.join(self.storedir, filename) storefile = store_sources_get_path(self.absdir, filename)
sha256sums[filename] = sha256_dgst(storefile) sha256sums[filename] = sha256_dgst(storefile)
if not force and not real_send and not todo_delete and not self.islinkrepair() and not self.ispulled(): if not force and not real_send and not todo_delete and not self.islinkrepair() and not self.ispulled():
@ -1629,7 +1626,7 @@ class Package:
store_write_string(self.absdir, '_files', ET.tostring(sfilelist, encoding=ET_ENCODING) + '\n') store_write_string(self.absdir, '_files', ET.tostring(sfilelist, encoding=ET_ENCODING) + '\n')
for filename in todo_delete: for filename in todo_delete:
self.to_be_deleted.remove(filename) self.to_be_deleted.remove(filename)
self.delete_storefile(filename) store_sources_delete_file(self.absdir, filename)
self.write_deletelist() self.write_deletelist()
self.write_addlist() self.write_addlist()
self.update_datastructs() self.update_datastructs()
@ -1670,7 +1667,7 @@ class Package:
def updatefile(self, n, revision, mtime=None): def updatefile(self, n, revision, mtime=None):
filename = os.path.join(self.dir, n) filename = os.path.join(self.dir, n)
storefilename = os.path.join(self.storedir, n) storefilename = store_sources_get_path(self.absdir, n)
origfile_tmp = os.path.join(self.storedir, '_in_update', '%s.copy' % n) origfile_tmp = os.path.join(self.storedir, '_in_update', '%s.copy' % n)
origfile = os.path.join(self.storedir, '_in_update', n) origfile = os.path.join(self.storedir, '_in_update', n)
if os.path.isfile(filename): if os.path.isfile(filename):
@ -1690,7 +1687,7 @@ class Package:
def mergefile(self, n, revision, mtime=None): def mergefile(self, n, revision, mtime=None):
filename = os.path.join(self.dir, n) filename = os.path.join(self.dir, n)
storefilename = os.path.join(self.storedir, n) storefilename = store_sources_get_path(self.absdir, n)
myfilename = os.path.join(self.dir, n + '.mine') myfilename = os.path.join(self.dir, n + '.mine')
upfilename = os.path.join(self.dir, n + '.new') upfilename = os.path.join(self.dir, n + '.new')
origfile_tmp = os.path.join(self.storedir, '_in_update', '%s.copy' % n) origfile_tmp = os.path.join(self.storedir, '_in_update', '%s.copy' % n)
@ -1966,7 +1963,7 @@ class Package:
known_by_meta = True known_by_meta = True
if os.path.exists(localfile): if os.path.exists(localfile):
exists = True exists = True
if os.path.exists(os.path.join(self.storedir, n)): if store_sources_is_file(self.absdir, n):
exists_in_store = True exists_in_store = True
if n in self.to_be_deleted: if n in self.to_be_deleted:
@ -2040,7 +2037,7 @@ class Package:
b_revision = self.rev.encode() b_revision = self.rev.encode()
diff.append(b'--- %s\t(revision %s)\n' % (fname.encode(), b_revision)) diff.append(b'--- %s\t(revision %s)\n' % (fname.encode(), b_revision))
diff.append(b'+++ %s\t(working copy)\n' % fname.encode()) diff.append(b'+++ %s\t(working copy)\n' % fname.encode())
fname = os.path.join(self.storedir, fname) fname = store_sources_get_path(self.absdir, fname)
try: try:
if revision is not None and not add: if revision is not None and not add:
@ -2376,8 +2373,8 @@ rev: %s
raise oscerr.PackageInternalError(self.prjname, self.name, 'too many files in \'_in_update\' dir') raise oscerr.PackageInternalError(self.prjname, self.name, 'too many files in \'_in_update\' dir')
tmp = rfiles[:] tmp = rfiles[:]
for f in tmp: for f in tmp:
if os.path.exists(os.path.join(self.storedir, f.name)): if store_sources_is_file(self.absdir, f.name):
if dgst(os.path.join(self.storedir, f.name)) == f.md5: if dgst(store_sources_get_path(self.absdir, f.name)) == f.md5:
if f in kept: if f in kept:
kept.remove(f) kept.remove(f)
elif f in added: elif f in added:
@ -2419,10 +2416,10 @@ rev: %s
# if the storefile doesn't exist we're resuming an aborted update: # if the storefile doesn't exist we're resuming an aborted update:
# the file was already deleted but we cannot know this # the file was already deleted but we cannot know this
# OR we're processing a _service: file (simply keep the file) # OR we're processing a _service: file (simply keep the file)
if os.path.isfile(os.path.join(self.storedir, f.name)) and self.status(f.name) not in ('M', 'C'): if store_sources_is_file(self.absdir, f.name) and self.status(f.name) not in ('M', 'C'):
# if self.status(f.name) != 'M': # if self.status(f.name) != 'M':
self.delete_localfile(f.name) self.delete_localfile(f.name)
self.delete_storefile(f.name) store_sources_delete_file(self.absdir, f.name)
print(statfrmt('D', os.path.join(pathn, f.name))) print(statfrmt('D', os.path.join(pathn, f.name)))
if f.name in self.to_be_deleted: if f.name in self.to_be_deleted:
self.to_be_deleted.remove(f.name) self.to_be_deleted.remove(f.name)
@ -2446,7 +2443,7 @@ rev: %s
print('Restored \'%s\'' % os.path.join(pathn, f.name)) print('Restored \'%s\'' % os.path.join(pathn, f.name))
elif state == 'C': elif state == 'C':
get_source_file(self.apiurl, self.prjname, self.name, f.name, get_source_file(self.apiurl, self.prjname, self.name, f.name,
targetfilename=os.path.join(self.storedir, f.name), revision=rev, targetfilename=store_sources_get_path(self.absdir, f.name), revision=rev,
progress_obj=self.progress_obj, mtime=f.mtime, meta=self.meta) progress_obj=self.progress_obj, mtime=f.mtime, meta=self.meta)
print('skipping \'%s\' (this is due to conflicts)' % f.name) print('skipping \'%s\' (this is due to conflicts)' % f.name)
elif state == 'D' and self.findfilebyname(f.name).md5 != f.md5: elif state == 'D' and self.findfilebyname(f.name).md5 != f.md5:
@ -2506,11 +2503,11 @@ rev: %s
raise oscerr.OscIOError(None, 'file \'%s\' is not under version control' % filename) raise oscerr.OscIOError(None, 'file \'%s\' is not under version control' % filename)
elif filename in self.skipped: elif filename in self.skipped:
raise oscerr.OscIOError(None, 'file \'%s\' is marked as skipped and cannot be reverted' % filename) raise oscerr.OscIOError(None, 'file \'%s\' is marked as skipped and cannot be reverted' % filename)
if filename in self.filenamelist and not os.path.exists(os.path.join(self.storedir, filename)): if filename in self.filenamelist and not store_sources_is_file(self.absdir, filename):
raise oscerr.PackageInternalError('file \'%s\' is listed in filenamelist but no storefile exists' % filename) raise oscerr.PackageInternalError('file \'%s\' is listed in filenamelist but no storefile exists' % filename)
state = self.status(filename) state = self.status(filename)
if not (state == 'A' or state == '!' and filename in self.to_be_added): if not (state == 'A' or state == '!' and filename in self.to_be_added):
shutil.copyfile(os.path.join(self.storedir, filename), os.path.join(self.absdir, filename)) shutil.copyfile(store_sources_get_path(self.absdir, filename), os.path.join(self.absdir, filename))
if state == 'D': if state == 'D':
self.to_be_deleted.remove(filename) self.to_be_deleted.remove(filename)
self.write_deletelist() self.write_deletelist()
@ -3483,12 +3480,43 @@ def check_store_version(dir):
raise oscerr.NoWorkingCopy(msg) raise oscerr.NoWorkingCopy(msg)
if v != __store_version__: if v != __store_version__:
migrated = False
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', '0.99']: 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', '0.99']:
# version is fine, no migration needed # no migration needed, only change metadata version to 1.0
f = open(versionfile, 'w') v = "1.0"
f.write(__store_version__ + '\n') with open(versionfile, 'w') as f:
f.close() f.write(v + '\n')
migrated = True
if v == "1.0":
store_dir = os.path.join(dir, store)
sources_dir = os.path.join(dir, store, "sources")
os.makedirs(sources_dir, exist_ok=True)
if is_package_dir(dir) and not store_read_scmurl(dir):
scm_files = [i.name for i in store_read_files(dir)]
for fn in os.listdir(store_dir):
old_path = os.path.join(store_dir, fn)
new_path = os.path.join(sources_dir, fn)
if not os.path.isfile(old_path):
continue
if fn in Package.REQ_STOREFILES or fn in Package.OPT_STOREFILES:
continue
if fn.startswith("_") and fn not in scm_files:
continue
if os.path.isfile(old_path):
os.rename(old_path, new_path)
v = "2.0"
with open(versionfile, 'w') as f:
f.write(v + '\n')
migrated = True
if migrated:
return return
msg = 'The osc metadata of your working copy "%s"' % dir msg = 'The osc metadata of your working copy "%s"' % dir
msg += '\nhas __store_version__ = %s, but it should be %s' % (v, __store_version__) msg += '\nhas __store_version__ = %s, but it should be %s' % (v, __store_version__)
msg += '\nPlease do a fresh checkout or update your client. Sorry about the inconvenience.' msg += '\nPlease do a fresh checkout or update your client. Sorry about the inconvenience.'
@ -4889,7 +4917,7 @@ def get_source_file_diff(dir, filename, rev, oldfilename = None, olddir = None,
oldfilename = filename oldfilename = filename
if not olddir: if not olddir:
olddir = os.path.join(dir, store) olddir = os.path.join(dir, store, "sources")
if not origfilename: if not origfilename:
origfilename = filename origfilename = filename
@ -6796,6 +6824,70 @@ def store_write_initial_packages(dir, project, subelements):
root.append(elem) root.append(elem)
ET.ElementTree(root).write(fname) ET.ElementTree(root).write(fname)
def store_read_files(dir):
files_tree = read_filemeta(dir)
files_tree_root = files_tree.getroot()
result = []
for node in files_tree_root.findall('entry'):
f = File(
node.get('name'),
node.get('md5'),
int(node.get('size')),
int(node.get('mtime')),
)
if node.get('skipped'):
f.skipped = True
result.append(f)
return result
def store_sources_get_path(dir, file_name):
if "/" in file_name:
raise ValueError("Plain file name expected: %s" % file_name)
result = os.path.join(dir, store, "sources", file_name)
try:
os.makedirs(os.path.dirname(result))
except FileExistsError:
pass
return result
def store_sources_list_files(dir):
result = []
invalid = []
topdir = os.path.join(dir, store, "sources")
if not os.path.isdir(topdir):
return []
for fn in os.listdir(topdir):
if store_sources_is_file(dir, fn):
result.append(fn)
else:
invalid.append(fn)
if invalid:
msg = ".osc/sources contains entries other than regular files"
project = store_read_project(dir)
package = store_read_package(dir)
raise oscerr.WorkingCopyInconsistent(project, package, invalid, msg)
return result
def store_sources_is_file(dir, file_name):
return os.path.isfile(store_sources_get_path(dir, file_name))
def store_sources_delete_file(dir, file_name):
try:
os.unlink(store_sources_get_path(dir, file_name))
except:
pass
def get_osc_version(): def get_osc_version():
return __version__ return __version__

View File

@ -239,8 +239,8 @@ class OscTestCase(unittest.TestCase):
for i in root.findall('entry'): for i in root.findall('entry'):
if i.get('name') in skipfiles: if i.get('name') in skipfiles:
continue continue
self.assertTrue(os.path.exists(os.path.join('.osc', i.get('name')))) self.assertTrue(os.path.exists(os.path.join('.osc', 'sources', i.get('name'))))
self.assertEqual(osc.core.dgst(os.path.join('.osc', i.get('name'))), i.get('md5')) self.assertEqual(osc.core.dgst(os.path.join('.osc', 'sources', i.get('name'))), i.get('md5'))
def assertXMLEqual(self, act, exp): def assertXMLEqual(self, act, exp):
if xml_equal(act, exp): if xml_equal(act, exp):

View File

@ -21,7 +21,7 @@ class TestAddFiles(OscTestCase):
p.addfile('toadd1') p.addfile('toadd1')
exp = 'A toadd1\n' exp = 'A toadd1\n'
self.assertEqual(sys.stdout.getvalue(), exp) self.assertEqual(sys.stdout.getvalue(), exp)
self.assertFalse(os.path.exists(os.path.join('.osc', 'toadd1'))) self.assertFalse(os.path.exists(os.path.join('.osc', 'sources', 'toadd1')))
self._check_status(p, 'toadd1', 'A') self._check_status(p, 'toadd1', 'A')
self._check_addlist('toadd1\n') self._check_addlist('toadd1\n')
@ -33,8 +33,8 @@ class TestAddFiles(OscTestCase):
p.addfile('toadd2') p.addfile('toadd2')
exp = 'A toadd1\nA toadd2\n' exp = 'A toadd1\nA toadd2\n'
self.assertEqual(sys.stdout.getvalue(), exp) self.assertEqual(sys.stdout.getvalue(), exp)
self.assertFalse(os.path.exists(os.path.join('.osc', 'toadd1'))) self.assertFalse(os.path.exists(os.path.join('.osc', 'sources', 'toadd1')))
self.assertFalse(os.path.exists(os.path.join('.osc', 'toadd2'))) self.assertFalse(os.path.exists(os.path.join('.osc', 'sources', 'toadd2')))
self._check_status(p, 'toadd1', 'A') self._check_status(p, 'toadd1', 'A')
self._check_status(p, 'toadd2', 'A') self._check_status(p, 'toadd2', 'A')
self._check_addlist('toadd1\ntoadd2\n') self._check_addlist('toadd1\ntoadd2\n')
@ -55,7 +55,7 @@ class TestAddFiles(OscTestCase):
self.assertRaises(osc.oscerr.PackageFileConflict, p.addfile, 'toadd1') self.assertRaises(osc.oscerr.PackageFileConflict, p.addfile, 'toadd1')
exp = 'A toadd1\n' exp = 'A toadd1\n'
self.assertEqual(sys.stdout.getvalue(), exp) self.assertEqual(sys.stdout.getvalue(), exp)
self.assertFalse(os.path.exists(os.path.join('.osc', 'toadd1'))) self.assertFalse(os.path.exists(os.path.join('.osc', 'sources', 'toadd1')))
self._check_status(p, 'toadd1', 'A') self._check_status(p, 'toadd1', 'A')
self._check_addlist('toadd1\n') self._check_addlist('toadd1\n')
@ -67,8 +67,8 @@ class TestAddFiles(OscTestCase):
p.addfile('foo') p.addfile('foo')
exp = 'A foo\n' exp = 'A foo\n'
self.assertEqual(sys.stdout.getvalue(), exp) self.assertEqual(sys.stdout.getvalue(), exp)
self.assertTrue(os.path.exists(os.path.join('.osc', 'foo'))) self.assertTrue(os.path.exists(os.path.join('.osc', 'sources', 'foo')))
self.assertNotEqual(open(os.path.join('.osc', 'foo'), 'r').read(), 'replaced file\n') self.assertNotEqual(open(os.path.join('.osc', 'sources', 'foo'), 'r').read(), 'replaced file\n')
self.assertFalse(os.path.exists(os.path.join('.osc', '_to_be_deleted'))) self.assertFalse(os.path.exists(os.path.join('.osc', '_to_be_deleted')))
self._check_status(p, 'foo', 'R') self._check_status(p, 'foo', 'R')
self._check_addlist('foo\n') self._check_addlist('foo\n')

View File

@ -47,7 +47,7 @@ class TestCommit(OscTestCase):
self.assertEqual(sys.stdout.getvalue(), exp) self.assertEqual(sys.stdout.getvalue(), exp)
self._check_digests('testSimple_cfilesremote') self._check_digests('testSimple_cfilesremote')
self.assertTrue(os.path.exists('nochange')) self.assertTrue(os.path.exists('nochange'))
self.assertEqual(open('nochange', 'r').read(), open(os.path.join('.osc', 'nochange'), 'r').read()) self.assertEqual(open('nochange', 'r').read(), open(os.path.join('.osc', 'sources', 'nochange'), 'r').read())
self._check_status(p, 'nochange', ' ') self._check_status(p, 'nochange', ' ')
self._check_status(p, 'foo', ' ') self._check_status(p, 'foo', ' ')
self._check_status(p, 'merge', ' ') self._check_status(p, 'merge', ' ')
@ -71,7 +71,7 @@ class TestCommit(OscTestCase):
self.assertEqual(sys.stdout.getvalue(), exp) self.assertEqual(sys.stdout.getvalue(), exp)
self._check_digests('testAddfile_cfilesremote') self._check_digests('testAddfile_cfilesremote')
self.assertTrue(os.path.exists('add')) self.assertTrue(os.path.exists('add'))
self.assertEqual(open('add', 'r').read(), open(os.path.join('.osc', 'add'), 'r').read()) self.assertEqual(open('add', 'r').read(), open(os.path.join('.osc', 'sources', 'add'), 'r').read())
self.assertFalse(os.path.exists(os.path.join('.osc', '_to_be_added'))) self.assertFalse(os.path.exists(os.path.join('.osc', '_to_be_added')))
self._check_status(p, 'add', ' ') self._check_status(p, 'add', ' ')
self._check_status(p, 'foo', ' ') self._check_status(p, 'foo', ' ')
@ -93,7 +93,7 @@ class TestCommit(OscTestCase):
self.assertEqual(sys.stdout.getvalue(), exp) self.assertEqual(sys.stdout.getvalue(), exp)
self._check_digests('testDeletefile_cfilesremote') self._check_digests('testDeletefile_cfilesremote')
self.assertFalse(os.path.exists('nochange')) self.assertFalse(os.path.exists('nochange'))
self.assertFalse(os.path.exists(os.path.join('.osc', 'nochange'))) self.assertFalse(os.path.exists(os.path.join('.osc', 'sources', 'nochange')))
self.assertFalse(os.path.exists(os.path.join('.osc', '_to_be_deleted'))) self.assertFalse(os.path.exists(os.path.join('.osc', '_to_be_deleted')))
self._check_status(p, 'foo', ' ') self._check_status(p, 'foo', ' ')
self._check_status(p, 'merge', ' ') self._check_status(p, 'merge', ' ')
@ -148,8 +148,8 @@ class TestCommit(OscTestCase):
self._check_digests('testMultiple_cfilesremote') self._check_digests('testMultiple_cfilesremote')
self.assertFalse(os.path.exists(os.path.join('.osc', '_to_be_added'))) self.assertFalse(os.path.exists(os.path.join('.osc', '_to_be_added')))
self.assertFalse(os.path.exists(os.path.join('.osc', '_to_be_deleted'))) self.assertFalse(os.path.exists(os.path.join('.osc', '_to_be_deleted')))
self.assertFalse(os.path.exists(os.path.join('.osc', 'foo'))) self.assertFalse(os.path.exists(os.path.join('.osc', 'sources', 'foo')))
self.assertFalse(os.path.exists(os.path.join('.osc', 'merge'))) self.assertFalse(os.path.exists(os.path.join('.osc', 'sources', 'merge')))
self.assertRaises(osc.oscerr.OscIOError, p.status, 'foo') self.assertRaises(osc.oscerr.OscIOError, p.status, 'foo')
self.assertRaises(osc.oscerr.OscIOError, p.status, 'merge') self.assertRaises(osc.oscerr.OscIOError, p.status, 'merge')
self._check_status(p, 'add', ' ') self._check_status(p, 'add', ' ')
@ -225,7 +225,7 @@ class TestCommit(OscTestCase):
self.assertFalse(os.path.exists(os.path.join('.osc', '_to_be_added'))) self.assertFalse(os.path.exists(os.path.join('.osc', '_to_be_added')))
self.assertFalse(os.path.exists(os.path.join('.osc', '_to_be_deleted'))) self.assertFalse(os.path.exists(os.path.join('.osc', '_to_be_deleted')))
self.assertFalse(os.path.exists('foo')) self.assertFalse(os.path.exists('foo'))
self.assertFalse(os.path.exists(os.path.join('.osc', 'foo'))) self.assertFalse(os.path.exists(os.path.join('.osc', 'sources', 'foo')))
self._check_status(p, 'add', ' ') self._check_status(p, 'add', ' ')
self._check_status(p, 'nochange', ' ') self._check_status(p, 'nochange', ' ')
self._check_status(p, 'merge', '!') self._check_status(p, 'merge', '!')
@ -248,7 +248,7 @@ class TestCommit(OscTestCase):
self.assertEqual(sys.stdout.getvalue(), exp) self.assertEqual(sys.stdout.getvalue(), exp)
self._check_digests('testAddfile_cfilesremote') self._check_digests('testAddfile_cfilesremote')
self.assertTrue(os.path.exists('add')) self.assertTrue(os.path.exists('add'))
self.assertEqual(open('add', 'r').read(), open(os.path.join('.osc', 'add'), 'r').read()) self.assertEqual(open('add', 'r').read(), open(os.path.join('.osc', 'sources', 'add'), 'r').read())
self.assertFalse(os.path.exists(os.path.join('.osc', '_to_be_added'))) self.assertFalse(os.path.exists(os.path.join('.osc', '_to_be_added')))
self._check_status(p, 'add', ' ') self._check_status(p, 'add', ' ')
self._check_status(p, 'foo', ' ') self._check_status(p, 'foo', ' ')
@ -348,7 +348,7 @@ class TestCommit(OscTestCase):
self.assertEqual(sys.stdout.getvalue(), exp) self.assertEqual(sys.stdout.getvalue(), exp)
self._check_digests('testSimple_cfilesremote') self._check_digests('testSimple_cfilesremote')
self.assertTrue(os.path.exists('nochange')) self.assertTrue(os.path.exists('nochange'))
self.assertEqual(open('nochange', 'r').read(), open(os.path.join('.osc', 'nochange'), 'r').read()) self.assertEqual(open('nochange', 'r').read(), open(os.path.join('.osc', 'sources', 'nochange'), 'r').read())
self._check_status(p, 'nochange', ' ') self._check_status(p, 'nochange', ' ')
self._check_status(p, 'foo', ' ') self._check_status(p, 'foo', ' ')
self._check_status(p, 'merge', ' ') self._check_status(p, 'merge', ' ')

View File

@ -20,7 +20,7 @@ class TestDeleteFiles(OscTestCase):
ret = p.delete_file('foo') ret = p.delete_file('foo')
self.__check_ret(ret, True, ' ') self.__check_ret(ret, True, ' ')
self.assertFalse(os.path.exists('foo')) self.assertFalse(os.path.exists('foo'))
self.assertTrue(os.path.exists(os.path.join('.osc', 'foo'))) self.assertTrue(os.path.exists(os.path.join('.osc', 'sources', 'foo')))
self._check_deletelist('foo\n') self._check_deletelist('foo\n')
self._check_status(p, 'foo', 'D') self._check_status(p, 'foo', 'D')
@ -31,7 +31,7 @@ class TestDeleteFiles(OscTestCase):
ret = p.delete_file('nochange') ret = p.delete_file('nochange')
self.__check_ret(ret, False, 'M') self.__check_ret(ret, False, 'M')
self.assertTrue(os.path.exists('nochange')) self.assertTrue(os.path.exists('nochange'))
self.assertTrue(os.path.exists(os.path.join('.osc', 'nochange'))) self.assertTrue(os.path.exists(os.path.join('.osc', 'sources', 'nochange')))
self.assertFalse(os.path.exists(os.path.join('.osc', '_to_be_deleted'))) self.assertFalse(os.path.exists(os.path.join('.osc', '_to_be_deleted')))
self._check_status(p, 'nochange', 'M') self._check_status(p, 'nochange', 'M')
@ -73,7 +73,7 @@ class TestDeleteFiles(OscTestCase):
ret = p.delete_file('foo') ret = p.delete_file('foo')
self.__check_ret(ret, False, 'C') self.__check_ret(ret, False, 'C')
self.assertTrue(os.path.exists('foo')) self.assertTrue(os.path.exists('foo'))
self.assertTrue(os.path.exists(os.path.join('.osc', 'foo'))) self.assertTrue(os.path.exists(os.path.join('.osc', 'sources', 'foo')))
self.assertFalse(os.path.exists(os.path.join('.osc', '_to_be_deleted'))) self.assertFalse(os.path.exists(os.path.join('.osc', '_to_be_deleted')))
self._check_conflictlist('foo\n') self._check_conflictlist('foo\n')
self._check_status(p, 'foo', 'C') self._check_status(p, 'foo', 'C')
@ -85,7 +85,7 @@ class TestDeleteFiles(OscTestCase):
ret = p.delete_file('nochange', force=True) ret = p.delete_file('nochange', force=True)
self.__check_ret(ret, True, 'M') self.__check_ret(ret, True, 'M')
self.assertFalse(os.path.exists('nochange')) self.assertFalse(os.path.exists('nochange'))
self.assertTrue(os.path.exists(os.path.join('.osc', 'nochange'))) self.assertTrue(os.path.exists(os.path.join('.osc', 'sources', 'nochange')))
self._check_deletelist('nochange\n') self._check_deletelist('nochange\n')
self._check_status(p, 'nochange', 'D') self._check_status(p, 'nochange', 'D')
@ -117,7 +117,7 @@ class TestDeleteFiles(OscTestCase):
ret = p.delete_file('merge', force=True) ret = p.delete_file('merge', force=True)
self.__check_ret(ret, True, 'R') self.__check_ret(ret, True, 'R')
self.assertFalse(os.path.exists('merge')) self.assertFalse(os.path.exists('merge'))
self.assertTrue(os.path.exists(os.path.join('.osc', 'merge'))) self.assertTrue(os.path.exists(os.path.join('.osc', 'sources', 'merge')))
self._check_deletelist('merge\n') self._check_deletelist('merge\n')
self._check_addlist('toadd1\n') self._check_addlist('toadd1\n')
self._check_status(p, 'merge', 'D') self._check_status(p, 'merge', 'D')
@ -131,7 +131,7 @@ class TestDeleteFiles(OscTestCase):
self.assertFalse(os.path.exists('foo')) self.assertFalse(os.path.exists('foo'))
self.assertTrue(os.path.exists('foo.r2')) self.assertTrue(os.path.exists('foo.r2'))
self.assertTrue(os.path.exists('foo.mine')) self.assertTrue(os.path.exists('foo.mine'))
self.assertTrue(os.path.exists(os.path.join('.osc', 'foo'))) self.assertTrue(os.path.exists(os.path.join('.osc', 'sources', 'foo')))
self._check_deletelist('foo\n') self._check_deletelist('foo\n')
self.assertFalse(os.path.exists(os.path.join('.osc', '_in_conflict'))) self.assertFalse(os.path.exists(os.path.join('.osc', '_in_conflict')))
self._check_status(p, 'foo', 'D') self._check_status(p, 'foo', 'D')
@ -146,8 +146,8 @@ class TestDeleteFiles(OscTestCase):
self.__check_ret(ret, True, ' ') self.__check_ret(ret, True, ' ')
self.assertFalse(os.path.exists('foo')) self.assertFalse(os.path.exists('foo'))
self.assertFalse(os.path.exists('merge')) self.assertFalse(os.path.exists('merge'))
self.assertTrue(os.path.exists(os.path.join('.osc', 'foo'))) self.assertTrue(os.path.exists(os.path.join('.osc', 'sources', 'foo')))
self.assertTrue(os.path.exists(os.path.join('.osc', 'merge'))) self.assertTrue(os.path.exists(os.path.join('.osc', 'sources', 'merge')))
self._check_deletelist('foo\nmerge\n') self._check_deletelist('foo\nmerge\n')
def testDeleteAlreadyDeleted(self): def testDeleteAlreadyDeleted(self):
@ -157,7 +157,7 @@ class TestDeleteFiles(OscTestCase):
ret = p.delete_file('foo') ret = p.delete_file('foo')
self.__check_ret(ret, True, 'D') self.__check_ret(ret, True, 'D')
self.assertFalse(os.path.exists('foo')) self.assertFalse(os.path.exists('foo'))
self.assertTrue(os.path.exists(os.path.join('.osc', 'foo'))) self.assertTrue(os.path.exists(os.path.join('.osc', 'sources', 'foo')))
self._check_deletelist('foo\n') self._check_deletelist('foo\n')
self._check_status(p, 'foo', 'D') self._check_status(p, 'foo', 'D')
@ -171,7 +171,7 @@ class TestDeleteFiles(OscTestCase):
ret = p.delete_file('toadd1') ret = p.delete_file('toadd1')
self.__check_ret(ret, True, '!') self.__check_ret(ret, True, '!')
self.assertFalse(os.path.exists('toadd1')) self.assertFalse(os.path.exists('toadd1'))
self.assertFalse(os.path.exists(os.path.join('.osc', 'toadd1'))) self.assertFalse(os.path.exists(os.path.join('.osc', 'sources', 'toadd1')))
self._check_deletelist('foo\n') self._check_deletelist('foo\n')
self.assertFalse(os.path.exists(os.path.join('.osc', '_to_be_added'))) self.assertFalse(os.path.exists(os.path.join('.osc', '_to_be_added')))

View File

@ -53,7 +53,7 @@ class TestRepairWC(OscTestCase):
self.assertRaises(osc.oscerr.WorkingCopyInconsistent, osc.core.Package, '.') self.assertRaises(osc.oscerr.WorkingCopyInconsistent, osc.core.Package, '.')
p = osc.core.Package('.', wc_check=False) p = osc.core.Package('.', wc_check=False)
p.wc_repair() p.wc_repair()
self.assertTrue(os.path.exists(os.path.join('.osc', 'foo'))) self.assertTrue(os.path.exists(os.path.join('.osc', 'sources', 'foo')))
self._check_deletelist('foo\n') self._check_deletelist('foo\n')
self._check_status(p, 'foo', 'D') self._check_status(p, 'foo', 'D')
self._check_status(p, 'nochange', 'M') self._check_status(p, 'nochange', 'M')
@ -68,7 +68,7 @@ class TestRepairWC(OscTestCase):
self.assertRaises(osc.oscerr.WorkingCopyInconsistent, osc.core.Package, '.') self.assertRaises(osc.oscerr.WorkingCopyInconsistent, osc.core.Package, '.')
p = osc.core.Package('.', wc_check=False) p = osc.core.Package('.', wc_check=False)
p.wc_repair() p.wc_repair()
self.assertFalse(os.path.exists(os.path.join('.osc', 'somefile'))) self.assertFalse(os.path.exists(os.path.join('.osc', 'sources', 'somefile')))
self._check_deletelist('foo\n') self._check_deletelist('foo\n')
self._check_status(p, 'foo', 'D') self._check_status(p, 'foo', 'D')
self._check_status(p, 'nochange', 'M') self._check_status(p, 'nochange', 'M')
@ -78,12 +78,12 @@ class TestRepairWC(OscTestCase):
self.__assertNotRaises(osc.oscerr.WorkingCopyInconsistent, osc.core.Package, '.') self.__assertNotRaises(osc.oscerr.WorkingCopyInconsistent, osc.core.Package, '.')
def test_simple3(self): def test_simple3(self):
"""toadd1 has state 'A' and a file .osc/toadd1 exists""" """toadd1 has state 'A' and a file .osc/sources/toadd1 exists"""
self._change_to_pkg('simple3') self._change_to_pkg('simple3')
self.assertRaises(osc.oscerr.WorkingCopyInconsistent, osc.core.Package, '.') self.assertRaises(osc.oscerr.WorkingCopyInconsistent, osc.core.Package, '.')
p = osc.core.Package('.', wc_check=False) p = osc.core.Package('.', wc_check=False)
p.wc_repair() p.wc_repair()
self.assertFalse(os.path.exists(os.path.join('.osc', 'toadd1'))) self.assertFalse(os.path.exists(os.path.join('.osc', 'sources', 'toadd1')))
self._check_deletelist('foo\n') self._check_deletelist('foo\n')
self._check_status(p, 'foo', 'D') self._check_status(p, 'foo', 'D')
self._check_status(p, 'nochange', 'M') self._check_status(p, 'nochange', 'M')
@ -132,7 +132,7 @@ class TestRepairWC(OscTestCase):
self.assertRaises(osc.oscerr.WorkingCopyInconsistent, osc.core.Package, '.') self.assertRaises(osc.oscerr.WorkingCopyInconsistent, osc.core.Package, '.')
p = osc.core.Package('.', wc_check=False) p = osc.core.Package('.', wc_check=False)
p.wc_repair() p.wc_repair()
self.assertTrue(os.path.exists(os.path.join('.osc', 'foo'))) self.assertTrue(os.path.exists(os.path.join('.osc', 'sources', 'foo')))
self._check_deletelist('foo\n') self._check_deletelist('foo\n')
self._check_status(p, 'foo', 'D') self._check_status(p, 'foo', 'D')
self._check_status(p, 'nochange', 'M') self._check_status(p, 'nochange', 'M')
@ -154,7 +154,7 @@ class TestRepairWC(OscTestCase):
self.assertRaises(osc.oscerr.WorkingCopyInconsistent, osc.core.Package, '.') self.assertRaises(osc.oscerr.WorkingCopyInconsistent, osc.core.Package, '.')
p = osc.core.Package('.', wc_check=False) p = osc.core.Package('.', wc_check=False)
p.wc_repair() p.wc_repair()
self.assertFalse(os.path.exists(os.path.join('.osc', 'skipped'))) self.assertFalse(os.path.exists(os.path.join('.osc', 'sources', 'skipped')))
self._check_deletelist('foo\n') self._check_deletelist('foo\n')
self._check_status(p, 'foo', 'D') self._check_status(p, 'foo', 'D')
self._check_status(p, 'nochange', 'M') self._check_status(p, 'nochange', 'M')
@ -177,8 +177,8 @@ class TestRepairWC(OscTestCase):
self.assertRaises(osc.oscerr.WorkingCopyInconsistent, osc.core.Package, '.') self.assertRaises(osc.oscerr.WorkingCopyInconsistent, osc.core.Package, '.')
p = osc.core.Package('.', wc_check=False) p = osc.core.Package('.', wc_check=False)
p.wc_repair() p.wc_repair()
self.assertTrue(os.path.exists(os.path.join('.osc', 'foo'))) self.assertTrue(os.path.exists(os.path.join('.osc', 'sources', 'foo')))
self.assertFalse(os.path.exists(os.path.join('.osc', 'unknown_file'))) self.assertFalse(os.path.exists(os.path.join('.osc', 'sources', 'unknown_file')))
self._check_deletelist('foo\n') self._check_deletelist('foo\n')
self._check_status(p, 'foo', 'D') self._check_status(p, 'foo', 'D')
self._check_status(p, 'nochange', 'C') self._check_status(p, 'nochange', 'C')

View File

@ -87,7 +87,7 @@ class TestRevertFiles(OscTestCase):
self.assertRaises(osc.oscerr.OscIOError, p.revert, 'skipped') self.assertRaises(osc.oscerr.OscIOError, p.revert, 'skipped')
def __check_file(self, fname): def __check_file(self, fname):
storefile = os.path.join('.osc', fname) storefile = os.path.join('.osc', 'sources', fname)
self.assertTrue(os.path.exists(fname)) self.assertTrue(os.path.exists(fname))
self.assertTrue(os.path.exists(storefile)) self.assertTrue(os.path.exists(storefile))
self.assertEqual(open(fname, 'r').read(), open(storefile, 'r').read()) self.assertEqual(open(fname, 'r').read(), open(storefile, 'r').read())

View File

@ -51,7 +51,7 @@ class TestUpdate(OscTestCase):
self.assertEqual(sys.stdout.getvalue(), exp) self.assertEqual(sys.stdout.getvalue(), exp)
self._check_digests('testUpdateDeletedFile_files') self._check_digests('testUpdateDeletedFile_files')
self.assertFalse(os.path.exists('foo')) self.assertFalse(os.path.exists('foo'))
self.assertFalse(os.path.exists(os.path.join('.osc', 'foo'))) self.assertFalse(os.path.exists(os.path.join('.osc', 'sources', 'foo')))
@GET('http://localhost/source/osctest/simple?rev=2', file='testUpdateUpstreamModifiedFile_files') @GET('http://localhost/source/osctest/simple?rev=2', file='testUpdateUpstreamModifiedFile_files')
@GET('http://localhost/source/osctest/simple/foo?rev=2', file='testUpdateUpstreamModifiedFile_foo') @GET('http://localhost/source/osctest/simple/foo?rev=2', file='testUpdateUpstreamModifiedFile_foo')
@ -111,7 +111,7 @@ class TestUpdate(OscTestCase):
self.assertEqual(sys.stdout.getvalue(), exp) self.assertEqual(sys.stdout.getvalue(), exp)
self._check_deletelist('foo\n') self._check_deletelist('foo\n')
self._check_conflictlist('merge\n') self._check_conflictlist('merge\n')
self.assertEqual(open('foo', 'r').read(), open(os.path.join('.osc', 'foo'), 'r').read()) self.assertEqual(open('foo', 'r').read(), open(os.path.join('.osc', 'sources', 'foo'), 'r').read())
self._check_digests('testUpdateLocalDeletions_files') self._check_digests('testUpdateLocalDeletions_files')
@GET('http://localhost/source/osctest/restore?rev=latest', file='testUpdateRestore_files') @GET('http://localhost/source/osctest/restore?rev=latest', file='testUpdateRestore_files')
@ -136,7 +136,7 @@ class TestUpdate(OscTestCase):
osc.core.Package('.').update(size_limit=50) osc.core.Package('.').update(size_limit=50)
exp = 'D bigfile\nAt revision 2.\n' exp = 'D bigfile\nAt revision 2.\n'
self.assertEqual(sys.stdout.getvalue(), exp) self.assertEqual(sys.stdout.getvalue(), exp)
self.assertFalse(os.path.exists(os.path.join('.osc', 'bigfile'))) self.assertFalse(os.path.exists(os.path.join('.osc', 'sources', 'bigfile')))
self.assertFalse(os.path.exists('bigfile')) self.assertFalse(os.path.exists('bigfile'))
self._check_digests('testUpdateLimitSizeNoChange_files', 'bigfile') self._check_digests('testUpdateLimitSizeNoChange_files', 'bigfile')
@ -152,8 +152,8 @@ class TestUpdate(OscTestCase):
p.update() p.update()
exp = 'D bigfile\nD merge\nAt revision 2.\n' exp = 'D bigfile\nD merge\nAt revision 2.\n'
self.assertEqual(sys.stdout.getvalue(), exp) self.assertEqual(sys.stdout.getvalue(), exp)
self.assertFalse(os.path.exists(os.path.join('.osc', 'bigfile'))) self.assertFalse(os.path.exists(os.path.join('.osc', 'sources', 'bigfile')))
self.assertFalse(os.path.exists(os.path.join('.osc', 'merge'))) self.assertFalse(os.path.exists(os.path.join('.osc', 'sources', 'merge')))
self.assertFalse(os.path.exists('bigfile')) self.assertFalse(os.path.exists('bigfile'))
self._check_digests('testUpdateLocalLimitSizeNoChange_files', 'bigfile', 'merge') self._check_digests('testUpdateLocalLimitSizeNoChange_files', 'bigfile', 'merge')
self._check_status(p, 'bigfile', 'S') self._check_status(p, 'bigfile', 'S')
@ -174,11 +174,11 @@ class TestUpdate(OscTestCase):
osc.core.Package('.').update(size_limit=10) osc.core.Package('.').update(size_limit=10)
exp = 'A exists\nD bigfile\nD foo\nD merge\nD nochange\nAt revision 2.\n' exp = 'A exists\nD bigfile\nD foo\nD merge\nD nochange\nAt revision 2.\n'
self.assertEqual(sys.stdout.getvalue(), exp) self.assertEqual(sys.stdout.getvalue(), exp)
self.assertFalse(os.path.exists(os.path.join('.osc', 'bigfile'))) self.assertFalse(os.path.exists(os.path.join('.osc', 'sources', 'bigfile')))
self.assertFalse(os.path.exists('bigfile')) self.assertFalse(os.path.exists('bigfile'))
self.assertFalse(os.path.exists(os.path.join('.osc', 'foo'))) self.assertFalse(os.path.exists(os.path.join('.osc', 'sources', 'foo')))
self.assertFalse(os.path.exists('foo')) self.assertFalse(os.path.exists('foo'))
self.assertFalse(os.path.exists(os.path.join('.osc', 'merge'))) self.assertFalse(os.path.exists(os.path.join('.osc', 'sources', 'merge')))
self.assertFalse(os.path.exists('merge')) self.assertFalse(os.path.exists('merge'))
# exists because local version is modified # exists because local version is modified
self.assertTrue(os.path.exists('nochange')) self.assertTrue(os.path.exists('nochange'))
@ -214,9 +214,9 @@ class TestUpdate(OscTestCase):
osc.core.Package('.').update() osc.core.Package('.').update()
exp = 'A bigfile\nD _service:exists\nAt revision 2.\n' exp = 'A bigfile\nD _service:exists\nAt revision 2.\n'
self.assertEqual(sys.stdout.getvalue(), exp) self.assertEqual(sys.stdout.getvalue(), exp)
self.assertFalse(os.path.exists(os.path.join('.osc', '_service:bar'))) self.assertFalse(os.path.exists(os.path.join('.osc', 'sources', '_service:bar')))
self.assertFalse(os.path.exists('_service:bar')) self.assertFalse(os.path.exists('_service:bar'))
self.assertFalse(os.path.exists(os.path.join('.osc', '_service:foo'))) self.assertFalse(os.path.exists(os.path.join('.osc', 'sources', '_service:foo')))
self.assertFalse(os.path.exists('_service:foo')) self.assertFalse(os.path.exists('_service:foo'))
self.assertTrue(os.path.exists('_service:exists')) self.assertTrue(os.path.exists('_service:exists'))
self._check_digests('testUpdateServiceFilesAddDelete_files', '_service:foo', '_service:bar') self._check_digests('testUpdateServiceFilesAddDelete_files', '_service:foo', '_service:bar')
@ -280,7 +280,7 @@ class TestUpdate(OscTestCase):
self.assertEqual(sys.stdout.getvalue(), exp) self.assertEqual(sys.stdout.getvalue(), exp)
self.assertFalse(os.path.exists(os.path.join('.osc', '_in_update'))) self.assertFalse(os.path.exists(os.path.join('.osc', '_in_update')))
self.assertFalse(os.path.exists('added')) self.assertFalse(os.path.exists('added'))
self.assertFalse(os.path.exists(os.path.join('.osc', 'added'))) self.assertFalse(os.path.exists(os.path.join('.osc', 'sources', 'added')))
self._check_digests('testUpdateResumeDeletedFile_files') self._check_digests('testUpdateResumeDeletedFile_files')
if __name__ == '__main__': if __name__ == '__main__':