1
0
mirror of https://github.com/openSUSE/osc.git synced 2025-03-03 14:42:11 +01:00

- rewrote addfile() and delete_file() methods from the Package class (for the details see below)

- addfile():
  * contains the complete logic for adding a file (=> simplified addFiles(...))
  * semantic fixes
- delete_file():
  * semantic fixes
- different handling of newly added/replaced files:
  * added/replaced files are tracked in the .osc/_to_be_added file
- introduced new file state 'R': 'R' == "replaced"
  * usecase: osc rm <file>; osc add <file> => new state is 'R'
  * conceptually 'R' is equal to 'A'
- adapted revert() to support the new state (+ some other minor fixes)
- added testcases for addfile() and delete_file()
This commit is contained in:
Marcus Huewe 2010-08-24 18:06:47 +02:00
parent e6b451596c
commit 88a961cae4
97 changed files with 684 additions and 29 deletions

View File

@ -796,8 +796,22 @@ class Package:
return r return r
def addfile(self, n): def addfile(self, n):
st = os.stat(os.path.join(self.dir, n)) if not os.path.exists(os.path.join(self.absdir, n)):
shutil.copyfile(os.path.join(self.dir, n), os.path.join(self.storedir, n)) raise IOError('error: file \'%s\' does not exist' % n)
if n in self.to_be_deleted:
self.to_be_deleted.remove(n)
# self.delete_storefile(n)
self.write_deletelist()
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)
# shutil.copyfile(os.path.join(self.dir, n), os.path.join(self.storedir, n))
if self.dir != '.':
pathname = os.path.join(self.dir, n)
else:
pathname = n
self.to_be_added.append(n)
self.write_addlist()
print statfrmt('A', pathname)
def delete_file(self, n, force=False): def delete_file(self, n, force=False):
"""deletes a file if possible and marks the file as deleted""" """deletes a file if possible and marks the file as deleted"""
@ -807,14 +821,20 @@ class Package:
except IOError, ioe: except IOError, ioe:
if not force: if not force:
raise ioe raise ioe
if state in ['?', 'A', 'M'] and not force: if state in ['?', 'A', 'M', 'R', 'C'] and not force:
return (False, state) return (False, state)
self.delete_localfile(n) self.delete_localfile(n)
if state != 'A': if state in ('A', 'R'):
self.to_be_added.remove(n)
self.write_addlist()
elif state == 'C':
# don't remove "merge files" (*.r, *.mine...)
# that's why we don't use clear_from_conflictlist
self.in_conflict.remove(n)
self.write_conflictlist()
if not state in ('A', '?'):
self.put_on_deletelist(n) self.put_on_deletelist(n)
self.write_deletelist() self.write_deletelist()
else:
self.delete_storefile(n)
return (True, state) return (True, state)
def delete_storefile(self, n): def delete_storefile(self, n):
@ -833,6 +853,10 @@ class Package:
if n not in self.in_conflict: if n not in self.in_conflict:
self.in_conflict.append(n) self.in_conflict.append(n)
def put_on_addlist(self, n):
if n not in self.to_be_added:
self.to_be_added.append(n)
def clear_from_conflictlist(self, n): def clear_from_conflictlist(self, n):
"""delete an entry from the file, and remove the file if it would be empty""" """delete an entry from the file, and remove the file if it would be empty"""
if n in self.in_conflict: if n in self.in_conflict:
@ -878,6 +902,9 @@ class Package:
else: else:
store_write_string(self.absdir, '_size_limit', self.size_limit) store_write_string(self.absdir, '_size_limit', self.size_limit)
def write_addlist(self):
self.__write_storelist('_to_be_added', self.to_be_added)
def write_deletelist(self): def write_deletelist(self):
self.__write_storelist('_to_be_deleted', self.to_be_deleted) self.__write_storelist('_to_be_deleted', self.to_be_deleted)
@ -901,6 +928,8 @@ class Package:
http_PUT(u, file = os.path.join(self.dir, n)) http_PUT(u, file = os.path.join(self.dir, n))
shutil.copyfile(os.path.join(self.dir, n), os.path.join(self.storedir, n)) shutil.copyfile(os.path.join(self.dir, n), os.path.join(self.storedir, n))
if n in self.to_be_added:
self.to_be_added.remove(n)
def commit(self, msg='', validators=None, verbose_validation=None): def commit(self, msg='', validators=None, verbose_validation=None):
todo_send = [] todo_send = []
@ -936,7 +965,7 @@ class Package:
for filename in self.todo: for filename in self.todo:
if not filename.startswith('_service:') and not filename.startswith('_service_'): if not filename.startswith('_service:') and not filename.startswith('_service_'):
st = self.status(filename) st = self.status(filename)
if st == 'A' or st == 'M': if st == 'A' or st == 'M' or st == 'R':
todo_send.append(filename) todo_send.append(filename)
print statfrmt('Sending', os.path.join(pathn, filename)) print statfrmt('Sending', os.path.join(pathn, filename))
elif st == 'D': elif st == 'D':
@ -1149,8 +1178,9 @@ class Package:
self.filelist.append(f) self.filelist.append(f)
self.filenamelist.append(f.name) self.filenamelist.append(f.name)
self.to_be_deleted = read_tobedeleted(self.dir) self.to_be_added = read_tobeadded(self.absdir)
self.in_conflict = read_inconflict(self.dir) self.to_be_deleted = read_tobedeleted(self.absdir)
self.in_conflict = read_inconflict(self.absdir)
self.linkrepair = os.path.isfile(os.path.join(self.storedir, '_linkrepair')) self.linkrepair = os.path.isfile(os.path.join(self.storedir, '_linkrepair'))
self.size_limit = read_sizelimit(self.dir) self.size_limit = read_sizelimit(self.dir)
self.meta = self.ismetamode() self.meta = self.ismetamode()
@ -1233,7 +1263,8 @@ class Package:
file storefile file present STATUS file storefile file present STATUS
exists exists in _files exists exists in _files
x x - 'A' x - - 'A' and listed in _to_be_added
x x - 'R' and listed in _to_be_added
x x x ' ' if digest differs: 'M' x x x ' ' if digest differs: 'M'
and if in conflicts file: 'C' and if in conflicts file: 'C'
x - - '?' x - - '?'
@ -1263,7 +1294,9 @@ class Package:
state = 'C' state = 'C'
elif n in self.skipped: elif n in self.skipped:
state = 'S' state = 'S'
elif exists and exists_in_store and not known_by_meta: elif n in self.to_be_added and exists_in_store:
state = 'R'
elif n in self.to_be_added:
state = 'A' state = 'A'
elif exists and exists_in_store and known_by_meta: elif exists and exists_in_store and known_by_meta:
if dgst(os.path.join(self.absdir, n)) != self.findfilebyname(n).md5: if dgst(os.path.join(self.absdir, n)) != self.findfilebyname(n).md5:
@ -1743,17 +1776,21 @@ rev: %s
raise ValueError("Empty filelist") raise ValueError("Empty filelist")
def revert(self, filename): def revert(self, filename):
if not filename in self.filenamelist: if not filename in self.filenamelist and not filename in self.to_be_added:
raise IOError('file \'%s\' is not under version control' % filename) raise IOError('file \'%s\' is not under version control' % filename)
if not os.path.exists(os.path.join(self.storedir, filename)): if filename in self.filenamelist and not os.path.exists(os.path.join(self.storedir, 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)
shutil.copyfile(os.path.join(self.storedir, filename), os.path.join(self.absdir, filename))
state = self.status(filename) state = self.status(filename)
if state != 'A':
shutil.copyfile(os.path.join(self.storedir, 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()
elif state == 'C': elif state == 'C':
self.clear_from_conflictlist(filename) self.clear_from_conflictlist(filename)
elif state == 'A' or state == 'R':
self.to_be_added.remove(filename)
self.write_addlist()
class ReviewState: class ReviewState:
"""for objects to represent the review state in a request""" """for objects to represent the review state in a request"""
@ -2148,6 +2185,9 @@ def store_readlist(dir, name):
r = [line.strip() for line in open(os.path.join(dir, store, name), 'r')] r = [line.strip() for line in open(os.path.join(dir, store, name), 'r')]
return r return r
def read_tobeadded(dir):
return store_readlist(dir, '_to_be_added')
def read_tobedeleted(dir): def read_tobedeleted(dir):
return store_readlist(dir, '_to_be_deleted') return store_readlist(dir, '_to_be_deleted')
@ -5042,21 +5082,6 @@ def addFiles(filenames, prj_obj = None):
if filename in pac.excluded: if filename in pac.excluded:
print >>sys.stderr, 'osc: warning: \'%s\' is excluded from a working copy' % filename print >>sys.stderr, 'osc: warning: \'%s\' is excluded from a working copy' % filename
continue continue
if filename in pac.filenamelist:
# check if this is a re-add after delete.
pac.to_be_deleted = read_tobedeleted(pac.dir)
try:
pac.to_be_deleted.remove(filename)
print >>sys.stderr, 'osc: Note: \'%s\' was deleted, is now re-added' % filename
pac.write_deletelist()
except:
print >>sys.stderr, 'osc: Warning: \'%s\' is already under version control' % filename
continue
if pac.dir != '.':
pathname = os.path.join(pac.dir, filename)
else:
pathname = filename
print statfrmt('A', pathname)
pac.addfile(filename) pac.addfile(filename)
def getPrjPacPaths(path): def getPrjPacPaths(path):

View File

@ -0,0 +1,104 @@
[general]
# URL to access API server, e.g. https://api.opensuse.org
# you also need a section [https://api.opensuse.org] with the credentials
apiurl = http://localhost
# Downloaded packages are cached here. Must be writable by you.
#packagecachedir = /var/tmp/osbuild-packagecache
# Wrapper to call build as root (sudo, su -, ...)
#su-wrapper = su -c
# rootdir to setup the chroot environment
# can contain %(repo)s, %(arch)s, %(project)s and %(package)s for replacement, e.g.
# /srv/oscbuild/%(repo)s-%(arch)s or
# /srv/oscbuild/%(repo)s-%(arch)s-%(project)s-%(package)s
#build-root = /var/tmp/build-root
# compile with N jobs (default: "getconf _NPROCESSORS_ONLN")
#build-jobs = N
# build-type to use - values can be (depending on the capabilities of the 'build' script)
# empty - chroot build
# kvm - kvm VM build (needs build-device, build-swap, build-memory)
# xen - xen VM build (needs build-device, build-swap, build-memory)
# experimental:
# qemu - qemu VM build
# lxc - lxc build
#build-type =
# build-device is the disk-image file to use as root for VM builds
# e.g. /var/tmp/FILE.root
#build-device = /var/tmp/FILE.root
# build-swap is the disk-image to use as swap for VM builds
# e.g. /var/tmp/FILE.swap
#build-swap = /var/tmp/FILE.swap
# build-memory is the amount of memory used in the VM
# value in MB - e.g. 512
#build-memory = 512
# build-vmdisk-rootsize is the size of the disk-image used as root in a VM build
# values in MB - e.g. 4096
#build-vmdisk-rootsize = 4096
# build-vmdisk-swapsize is the size of the disk-image used as swap in a VM build
# values in MB - e.g. 1024
#build-vmdisk-swapsize = 1024
# Numeric uid:gid to assign to the "abuild" user in the build-root
# or "caller" to use the current users uid:gid
# This is convenient when sharing the buildroot with ordinary userids
# on the host.
# This should not be 0
# build-uid =
# extra packages to install when building packages locally (osc build)
# this corresponds to osc build's -x option and can be overridden with that
# -x '' can also be given on the command line to override this setting, or
# you can have an empty setting here.
#extra-pkgs = vim gdb strace
# build platform is used if the platform argument is omitted to osc build
#build_repository = openSUSE_Factory
# default project for getpac or bco
#getpac_default_project = openSUSE:Factory
# alternate filesystem layout: have multiple subdirs, where colons were.
#checkout_no_colon = 0
# local files to ignore with status, addremove, ....
#exclude_glob = .osc CVS .svn .* _linkerror *~ #*# *.orig *.bak *.changes.*
# keep passwords in plaintext. If you see this comment, your osc
# already uses the encrypted password, and only keeps them in plain text
# for backwards compatibility. Default will change to 0 in future releases.
# You can remove the plaintext password without harm, if you do not need
# backwards compatibility.
#plaintext_passwd = 1
# limit the age of requests shown with 'osc req list'.
# this is a default only, can be overridden by 'osc req list -D NNN'
# Use 0 for unlimted.
#request_list_days = 0
# show info useful for debugging
#debug = 1
# show HTTP traffic useful for debugging
#http_debug = 1
# Skip signature verification of packages used for build.
#no_verify = 1
# jump into the debugger in case of errors
#post_mortem = 1
# print call traces in case of errors
#traceback = 1
# use KDE/Gnome/MacOS/Windows keyring for credentials if available
#use_keyring = 1
# check for unversioned/removed files before commit
#check_filelist = 1
# check for pending requests after executing an action (e.g. checkout, update, commit)
#check_for_request_on_action = 0
# what to do with the source package if the submitrequest has been accepted. If
# nothing is specified the API default is used
#submitrequest_on_accept_action = cleanup|update|noupdate
#review requests interactively (default: off)
#request_show_review = 1
# Directory with executables to validate sources, esp before committing
#source_validator_directory = /usr/lib/osc/source_validators
[http://localhost]
user = Admin
pass = opensuse
passx = QlpoOTFBWSZTWeTSblkAAAGBgAIBygAgADDACGNEHxaYXckU4UJDk0m5ZA==
# set aliases for this apiurl
# aliases = foo, bar
# email used in .changes, unless the one from osc meta prj <user> will be used
# email =
# additional headers to pass to a request, e.g. for special authentication
#http_headers = Host: foofoobar,
# User: mumblegack
# Force using of keyring for this API
#keyring = 1

View File

@ -0,0 +1 @@
http://localhost

View File

@ -0,0 +1 @@
<project name="osctest" />

View File

@ -0,0 +1 @@
osctest

View File

@ -0,0 +1 @@
http://localhost

View File

@ -0,0 +1,5 @@
<directory name="simple" rev="1" srcmd5="2df1eacfe03a3bec2112529e7f4dc39a" vrev="1">
<entry md5="0d62ceea6020d75154078a20d8c9f9ba" mtime="1282047302" name="foo" size="23" />
<entry md5="17b9e9e1a032ed44e7a584dc6303ffa8" mtime="1282047303" name="merge" size="48" />
<entry md5="7efa70f68983fad1cf487f69dedf93e9" mtime="1282047303" name="nochange" size="25" />
</directory>

View File

@ -0,0 +1 @@
1.0

View File

@ -0,0 +1 @@
simple

View File

@ -0,0 +1 @@
osctest

View File

@ -0,0 +1 @@
foo

View File

@ -0,0 +1 @@
This is a simple test.

View File

@ -0,0 +1,4 @@
Is it
possible to
merge this file?
I hope so...

View File

@ -0,0 +1 @@
This file didn't change.

View File

@ -0,0 +1,4 @@
Is it
possible to
merge this file?
I hope so...

View File

@ -0,0 +1,2 @@
This file didn't change but
is modified.

View File

@ -0,0 +1 @@
toadd1

View File

@ -0,0 +1 @@
toadd2

View File

@ -85,3 +85,11 @@ class OscTestCase(unittest.TestCase):
def _change_to_pkg(self, name): def _change_to_pkg(self, name):
os.chdir(os.path.join(self.tmpdir, 'osctest', name)) os.chdir(os.path.join(self.tmpdir, 'osctest', name))
def _check_list(self, fname, exp):
fname = os.path.join('.osc', fname)
self.assertTrue(os.path.exists(fname))
self.assertEqual(open(fname, 'r').read(), exp)
def _check_status(self, p, fname, exp):
self.assertEqual(p.status(fname), exp)

View File

@ -0,0 +1,104 @@
[general]
# URL to access API server, e.g. https://api.opensuse.org
# you also need a section [https://api.opensuse.org] with the credentials
apiurl = http://localhost
# Downloaded packages are cached here. Must be writable by you.
#packagecachedir = /var/tmp/osbuild-packagecache
# Wrapper to call build as root (sudo, su -, ...)
#su-wrapper = su -c
# rootdir to setup the chroot environment
# can contain %(repo)s, %(arch)s, %(project)s and %(package)s for replacement, e.g.
# /srv/oscbuild/%(repo)s-%(arch)s or
# /srv/oscbuild/%(repo)s-%(arch)s-%(project)s-%(package)s
#build-root = /var/tmp/build-root
# compile with N jobs (default: "getconf _NPROCESSORS_ONLN")
#build-jobs = N
# build-type to use - values can be (depending on the capabilities of the 'build' script)
# empty - chroot build
# kvm - kvm VM build (needs build-device, build-swap, build-memory)
# xen - xen VM build (needs build-device, build-swap, build-memory)
# experimental:
# qemu - qemu VM build
# lxc - lxc build
#build-type =
# build-device is the disk-image file to use as root for VM builds
# e.g. /var/tmp/FILE.root
#build-device = /var/tmp/FILE.root
# build-swap is the disk-image to use as swap for VM builds
# e.g. /var/tmp/FILE.swap
#build-swap = /var/tmp/FILE.swap
# build-memory is the amount of memory used in the VM
# value in MB - e.g. 512
#build-memory = 512
# build-vmdisk-rootsize is the size of the disk-image used as root in a VM build
# values in MB - e.g. 4096
#build-vmdisk-rootsize = 4096
# build-vmdisk-swapsize is the size of the disk-image used as swap in a VM build
# values in MB - e.g. 1024
#build-vmdisk-swapsize = 1024
# Numeric uid:gid to assign to the "abuild" user in the build-root
# or "caller" to use the current users uid:gid
# This is convenient when sharing the buildroot with ordinary userids
# on the host.
# This should not be 0
# build-uid =
# extra packages to install when building packages locally (osc build)
# this corresponds to osc build's -x option and can be overridden with that
# -x '' can also be given on the command line to override this setting, or
# you can have an empty setting here.
#extra-pkgs = vim gdb strace
# build platform is used if the platform argument is omitted to osc build
#build_repository = openSUSE_Factory
# default project for getpac or bco
#getpac_default_project = openSUSE:Factory
# alternate filesystem layout: have multiple subdirs, where colons were.
#checkout_no_colon = 0
# local files to ignore with status, addremove, ....
#exclude_glob = .osc CVS .svn .* _linkerror *~ #*# *.orig *.bak *.changes.*
# keep passwords in plaintext. If you see this comment, your osc
# already uses the encrypted password, and only keeps them in plain text
# for backwards compatibility. Default will change to 0 in future releases.
# You can remove the plaintext password without harm, if you do not need
# backwards compatibility.
#plaintext_passwd = 1
# limit the age of requests shown with 'osc req list'.
# this is a default only, can be overridden by 'osc req list -D NNN'
# Use 0 for unlimted.
#request_list_days = 0
# show info useful for debugging
#debug = 1
# show HTTP traffic useful for debugging
#http_debug = 1
# Skip signature verification of packages used for build.
#no_verify = 1
# jump into the debugger in case of errors
#post_mortem = 1
# print call traces in case of errors
#traceback = 1
# use KDE/Gnome/MacOS/Windows keyring for credentials if available
#use_keyring = 1
# check for unversioned/removed files before commit
#check_filelist = 1
# check for pending requests after executing an action (e.g. checkout, update, commit)
#check_for_request_on_action = 0
# what to do with the source package if the submitrequest has been accepted. If
# nothing is specified the API default is used
#submitrequest_on_accept_action = cleanup|update|noupdate
#review requests interactively (default: off)
#request_show_review = 1
# Directory with executables to validate sources, esp before committing
#source_validator_directory = /usr/lib/osc/source_validators
[http://localhost]
user = Admin
pass = opensuse
passx = QlpoOTFBWSZTWeTSblkAAAGBgAIBygAgADDACGNEHxaYXckU4UJDk0m5ZA==
# set aliases for this apiurl
# aliases = foo, bar
# email used in .changes, unless the one from osc meta prj <user> will be used
# email =
# additional headers to pass to a request, e.g. for special authentication
#http_headers = Host: foofoobar,
# User: mumblegack
# Force using of keyring for this API
#keyring = 1

View File

@ -0,0 +1 @@
http://localhost

View File

@ -0,0 +1 @@
<project name="osctest" />

View File

@ -0,0 +1 @@
osctest

View File

@ -0,0 +1 @@
http://localhost

View File

@ -0,0 +1,5 @@
<directory name="simple" rev="1" srcmd5="2df1eacfe03a3bec2112529e7f4dc39a" vrev="1">
<entry md5="0d62ceea6020d75154078a20d8c9f9ba" mtime="1282047302" name="foo" size="23" />
<entry md5="17b9e9e1a032ed44e7a584dc6303ffa8" mtime="1282047303" name="merge" size="48" />
<entry md5="7efa70f68983fad1cf487f69dedf93e9" mtime="1282047303" name="nochange" size="25" />
</directory>

View File

@ -0,0 +1 @@
simple

View File

@ -0,0 +1 @@
osctest

View File

@ -0,0 +1 @@
toadd1

View File

@ -0,0 +1 @@
This is a simple test.

View File

@ -0,0 +1,4 @@
Is it
possible to
merge this file?
I hope so...

View File

@ -0,0 +1 @@
This file didn't change.

View File

@ -0,0 +1,4 @@
Is it
possible to
merge this file?
I hope so...

View File

@ -0,0 +1,2 @@
This file didn't change but
is modified.

View File

@ -0,0 +1 @@
toadd1

View File

@ -0,0 +1 @@
toadd2

View File

@ -0,0 +1 @@
http://localhost

View File

@ -0,0 +1,5 @@
<directory name="conflict" rev="2" srcmd5="2df1eacfe03a3bec2112529e7f4dc39a" vrev="2">
<entry md5="0d62ceea6020d75154078a20d8c9f9ba" mtime="1282047302" name="foo" size="23" />
<entry md5="17b9e9e1a032ed44e7a584dc6303ffa8" mtime="1282047303" name="merge" size="48" />
<entry md5="7efa70f68983fad1cf487f69dedf93e9" mtime="1282047303" name="nochange" size="25" />
</directory>

View File

@ -0,0 +1 @@
foo

View File

@ -0,0 +1 @@
1.0

View File

@ -0,0 +1 @@
simple

View File

@ -0,0 +1 @@
osctest

View File

@ -0,0 +1 @@
toadd1

View File

@ -0,0 +1 @@
This is a simple test.

View File

@ -0,0 +1,4 @@
Is it
possible to
merge this file?
I hope so...

View File

@ -0,0 +1 @@
This file didn't change.

View File

@ -0,0 +1,5 @@
<<<<<<< foo.mine
This is no test.
=======
This is a simple test.
>>>>>>> foo.r2

View File

@ -0,0 +1 @@
This is no test.

View File

@ -0,0 +1 @@
This is a simple test.

View File

@ -0,0 +1,4 @@
Is it
possible to
merge this file?
I hope so...

View File

@ -0,0 +1,2 @@
This file didn't change but
is modified.

View File

@ -0,0 +1 @@
toadd1

View File

@ -0,0 +1 @@
toadd2

View File

@ -0,0 +1 @@
http://localhost

View File

@ -0,0 +1,5 @@
<directory name="simple" rev="1" srcmd5="2df1eacfe03a3bec2112529e7f4dc39a" vrev="1">
<entry md5="0d62ceea6020d75154078a20d8c9f9ba" mtime="1282047302" name="foo" size="23" />
<entry md5="17b9e9e1a032ed44e7a584dc6303ffa8" mtime="1282047303" name="merge" size="48" />
<entry md5="7efa70f68983fad1cf487f69dedf93e9" mtime="1282047303" name="nochange" size="25" />
</directory>

View File

@ -0,0 +1 @@
1.0

View File

@ -0,0 +1 @@
simple

View File

@ -0,0 +1 @@
osctest

View File

@ -0,0 +1 @@
foo

View File

@ -0,0 +1 @@
This is a simple test.

View File

@ -0,0 +1,4 @@
Is it
possible to
merge this file?
I hope so...

View File

@ -0,0 +1 @@
This file didn't change.

View File

@ -0,0 +1,4 @@
Is it
possible to
merge this file?
I hope so...

View File

@ -0,0 +1,2 @@
This file didn't change but
is modified.

View File

@ -0,0 +1 @@
toadd1

View File

@ -0,0 +1 @@
toadd2

View File

@ -0,0 +1 @@
http://localhost

View File

@ -0,0 +1,5 @@
<directory name="simple" rev="1" srcmd5="2df1eacfe03a3bec2112529e7f4dc39a" vrev="1">
<entry md5="0d62ceea6020d75154078a20d8c9f9ba" mtime="1282047302" name="foo" size="23" />
<entry md5="17b9e9e1a032ed44e7a584dc6303ffa8" mtime="1282047303" name="merge" size="48" />
<entry md5="7efa70f68983fad1cf487f69dedf93e9" mtime="1282047303" name="nochange" size="25" />
</directory>

View File

@ -0,0 +1 @@
1.0

View File

@ -0,0 +1 @@
simple

View File

@ -0,0 +1 @@
osctest

View File

@ -0,0 +1,2 @@
toadd1
merge

View File

@ -0,0 +1 @@
This is a simple test.

View File

@ -0,0 +1,4 @@
Is it
possible to
merge this file?
I hope so...

View File

@ -0,0 +1 @@
This file didn't change.

View File

@ -0,0 +1 @@
This is a simple test.

View File

@ -0,0 +1 @@
replaced

View File

@ -0,0 +1,2 @@
This file didn't change but
is modified.

View File

@ -0,0 +1 @@
toadd1

View File

@ -0,0 +1 @@
toadd2

View File

@ -0,0 +1 @@
http://localhost

View File

@ -0,0 +1,5 @@
<directory name="simple" rev="1" srcmd5="2df1eacfe03a3bec2112529e7f4dc39a" vrev="1">
<entry md5="0d62ceea6020d75154078a20d8c9f9ba" mtime="1282047302" name="foo" size="23" />
<entry md5="17b9e9e1a032ed44e7a584dc6303ffa8" mtime="1282047303" name="merge" size="48" />
<entry md5="7efa70f68983fad1cf487f69dedf93e9" mtime="1282047303" name="nochange" size="25" />
</directory>

View File

@ -0,0 +1 @@
1.0

View File

@ -0,0 +1 @@
simple

View File

@ -0,0 +1 @@
osctest

View File

@ -0,0 +1 @@
toadd1

View File

@ -0,0 +1 @@
This is a simple test.

View File

@ -0,0 +1,4 @@
Is it
possible to
merge this file?
I hope so...

View File

@ -0,0 +1 @@
This file didn't change.

View File

@ -0,0 +1 @@
This is a simple test.

View File

@ -0,0 +1,4 @@
Is it
possible to
merge this file?
I hope so...

View File

@ -0,0 +1,2 @@
This file didn't change but
is modified.

View File

@ -0,0 +1 @@
toadd1

View File

@ -0,0 +1 @@
toadd2

84
tests/test_addfiles.py Normal file
View File

@ -0,0 +1,84 @@
import osc.core
import osc.oscerr
import os
import sys
from common import GET, OscTestCase
FIXTURES_DIR = os.path.join(os.getcwd(), 'addfile_fixtures')
class TestAddFiles(OscTestCase):
def _get_fixtures_dir(self):
return FIXTURES_DIR
def testSimpleAdd(self):
"""add one file ('toadd1') to the wc"""
self._change_to_pkg('simple')
p = osc.core.Package('.')
p.addfile('toadd1')
exp = 'A toadd1\n'
self.assertEqual(sys.stdout.getvalue(), exp)
self.assertFalse(os.path.exists(os.path.join('.osc', 'toadd1')))
self._check_status(p, 'toadd1', 'A')
self.__check_addlist('toadd1\n')
def testSimpleMultipleAdd(self):
"""add multiple files ('toadd1', 'toadd2') to the wc"""
self._change_to_pkg('simple')
p = osc.core.Package('.')
p.addfile('toadd1')
p.addfile('toadd2')
exp = 'A toadd1\nA toadd2\n'
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', 'toadd2')))
self._check_status(p, 'toadd1', 'A')
self._check_status(p, 'toadd2', 'A')
self.__check_addlist('toadd1\ntoadd2\n')
def testAddVersionedFile(self):
"""add a versioned file"""
self._change_to_pkg('simple')
p = osc.core.Package('.')
self.assertRaises(osc.oscerr.PackageFileConflict, p.addfile, 'merge')
self.assertFalse(os.path.exists(os.path.join('.osc', '_to_be_added')))
self._check_status(p, 'merge', ' ')
def testAddUnversionedFileTwice(self):
"""add the same file twice"""
self._change_to_pkg('simple')
p = osc.core.Package('.')
p.addfile('toadd1')
self.assertRaises(osc.oscerr.PackageFileConflict, p.addfile, 'toadd1')
exp = 'A toadd1\n'
self.assertEqual(sys.stdout.getvalue(), exp)
self.assertFalse(os.path.exists(os.path.join('.osc', 'toadd1')))
self._check_status(p, 'toadd1', 'A')
self.__check_addlist('toadd1\n')
def testReplace(self):
"""replace a deleted file ('foo')"""
self._change_to_pkg('simple')
p = osc.core.Package('.')
open('foo', 'w').write('replaced file\n')
p.addfile('foo')
exp = 'A foo\n'
self.assertEqual(sys.stdout.getvalue(), exp)
self.assertTrue(os.path.exists(os.path.join('.osc', 'foo')))
self.assertNotEqual(open(os.path.join('.osc', 'foo'), 'r').read(), 'replaced file\n')
self.assertFalse(os.path.exists(os.path.join('.osc', '_to_be_deleted')))
self._check_status(p, 'foo', 'R')
self.__check_addlist('foo\n')
def testAddNonExistentFile(self):
"""add a non existent file"""
self._change_to_pkg('simple')
p = osc.core.Package('.')
self.assertRaises(IOError, p.addfile, 'doesnotexist')
self.assertFalse(os.path.exists(os.path.join('.osc', '_to_be_added')))
def __check_addlist(self, exp):
self._check_list('_to_be_added', exp)
if __name__ == '__main__':
import unittest
unittest.main()

171
tests/test_deletefiles.py Normal file
View File

@ -0,0 +1,171 @@
import osc.core
import osc.oscerr
import os
import sys
from common import GET, OscTestCase
FIXTURES_DIR = os.path.join(os.getcwd(), 'deletefile_fixtures')
class TestAddFiles(OscTestCase):
def _get_fixtures_dir(self):
return FIXTURES_DIR
def testSimpleRemove(self):
"""delete a file ('foo') from the wc"""
self._change_to_pkg('simple')
p = osc.core.Package('.')
ret = p.delete_file('foo')
self.__check_ret(ret, True, ' ')
self.assertFalse(os.path.exists('foo'))
self.assertTrue(os.path.exists(os.path.join('.osc', 'foo')))
self.__check_deletelist('foo\n')
self._check_status(p, 'foo', 'D')
def testDeleteModified(self):
"""delete modified file ('nochange') from the wc (without force)"""
self._change_to_pkg('simple')
p = osc.core.Package('.')
ret = p.delete_file('nochange')
self.__check_ret(ret, False, 'M')
self.assertTrue(os.path.exists('nochange'))
self.assertTrue(os.path.exists(os.path.join('.osc', 'nochange')))
self.assertFalse(os.path.exists(os.path.join('.osc', '_to_be_deleted')))
self._check_status(p, 'nochange', 'M')
def testDeleteUnversioned(self):
"""delete an unversioned file ('toadd2') from the wc"""
self._change_to_pkg('simple')
p = osc.core.Package('.')
ret = p.delete_file('toadd2')
self.__check_ret(ret, False, '?')
self.assertTrue(os.path.exists('toadd2'))
self.assertFalse(os.path.exists(os.path.join('.osc', '_to_be_deleted')))
self._check_status(p, 'toadd2', '?')
def testDeleteAdded(self):
"""delete an added file ('toadd1') from the wc (without force)"""
self._change_to_pkg('simple')
p = osc.core.Package('.')
ret = p.delete_file('toadd1')
self.__check_ret(ret, False, 'A')
self.assertTrue(os.path.exists('toadd1'))
self.assertFalse(os.path.exists(os.path.join('.osc', '_to_be_deleted')))
self._check_status(p, 'toadd1', 'A')
def testDeleteReplaced(self):
"""delete an added file ('merge') from the wc (without force)"""
self._change_to_pkg('replace')
p = osc.core.Package('.')
ret = p.delete_file('merge')
self.__check_ret(ret, False, 'R')
self.assertTrue(os.path.exists('merge'))
self.assertFalse(os.path.exists(os.path.join('.osc', '_to_be_deleted')))
self._check_list('_to_be_added', 'toadd1\nmerge\n')
self._check_status(p, 'merge', 'R')
def testDeleteConflict(self):
"""delete a file ('foo', state='C') from the wc (without force)"""
self._change_to_pkg('conflict')
p = osc.core.Package('.')
ret = p.delete_file('foo')
self.__check_ret(ret, False, 'C')
self.assertTrue(os.path.exists('foo'))
self.assertTrue(os.path.exists(os.path.join('.osc', 'foo')))
self.assertFalse(os.path.exists(os.path.join('.osc', '_to_be_deleted')))
self.assertTrue(os.path.exists(os.path.join('.osc', '_in_conflict')))
self._check_status(p, 'foo', 'C')
def testDeleteModifiedForce(self):
"""force deletion modified file ('nochange') from wc"""
self._change_to_pkg('simple')
p = osc.core.Package('.')
ret = p.delete_file('nochange', force=True)
self.__check_ret(ret, True, 'M')
self.assertFalse(os.path.exists('nochange'))
self.assertTrue(os.path.exists(os.path.join('.osc', 'nochange')))
self.__check_deletelist('nochange\n')
self._check_status(p, 'nochange', 'D')
def testDeleteUnversionedForce(self):
"""delete an unversioned file ('toadd2') from the wc (with force)"""
self._change_to_pkg('simple')
p = osc.core.Package('.')
ret = p.delete_file('toadd2', force=True)
self.__check_ret(ret, True, '?')
self.assertFalse(os.path.exists('toadd2'))
self.assertFalse(os.path.exists(os.path.join('.osc', '_to_be_deleted')))
self.assertRaises(IOError, p.status, 'toadd2')
def testDeleteAddedForce(self):
"""delete an added file ('toadd1') from the wc (with force)"""
self._change_to_pkg('simple')
p = osc.core.Package('.')
ret = p.delete_file('toadd1', force=True)
self.__check_ret(ret, True, 'A')
self.assertFalse(os.path.exists('toadd1'))
self.assertFalse(os.path.exists(os.path.join('.osc', '_to_be_deleted')))
self.assertFalse(os.path.exists(os.path.join('.osc', '_to_be_added')))
self.assertRaises(IOError, p.status, 'toadd1')
def testDeleteReplacedForce(self):
"""delete an added file ('merge') from the wc (with force)"""
self._change_to_pkg('replace')
p = osc.core.Package('.')
ret = p.delete_file('merge', force=True)
self.__check_ret(ret, True, 'R')
self.assertFalse(os.path.exists('merge'))
self.assertTrue(os.path.exists(os.path.join('.osc', 'merge')))
self.__check_deletelist('merge\n')
self._check_list('_to_be_added', 'toadd1\n')
self._check_status(p, 'merge', 'D')
def testDeleteConflictForce(self):
"""delete a file ('foo', state='C') from the wc (with force)"""
self._change_to_pkg('conflict')
p = osc.core.Package('.')
ret = p.delete_file('foo', force=True)
self.__check_ret(ret, True, 'C')
self.assertFalse(os.path.exists('foo'))
self.assertTrue(os.path.exists('foo.r2'))
self.assertTrue(os.path.exists('foo.mine'))
self.assertTrue(os.path.exists(os.path.join('.osc', 'foo')))
self.__check_deletelist('foo\n')
self.assertFalse(os.path.exists(os.path.join('.osc', '_in_conflict')))
self._check_status(p, 'foo', 'D')
def testDeleteMultiple(self):
"""delete mutliple files from the wc"""
self._change_to_pkg('simple')
p = osc.core.Package('.')
ret = p.delete_file('foo')
self.__check_ret(ret, True, ' ')
ret = p.delete_file('merge')
self.__check_ret(ret, True, ' ')
self.assertFalse(os.path.exists('foo'))
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', 'merge')))
self.__check_deletelist('foo\nmerge\n')
def testDeleteAlreadyDeleted(self):
"""delete already deleted file from the wc"""
self._change_to_pkg('already_deleted')
p = osc.core.Package('.')
ret = p.delete_file('foo')
self.__check_ret(ret, True, 'D')
self.assertFalse(os.path.exists('foo'))
self.assertTrue(os.path.exists(os.path.join('.osc', 'foo')))
self.__check_deletelist('foo\n')
self._check_status(p, 'foo', 'D')
def __check_ret(self, ret, exp1, exp2):
self.assertTrue(len(ret) == 2)
self.assertTrue(ret[0] == exp1)
self.assertTrue(ret[1] == exp2)
def __check_deletelist(self, exp):
self._check_list('_to_be_deleted', exp)
if __name__ == '__main__':
import unittest
unittest.main()