summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichal Čihař <nijel@debian.org>2018-01-23 09:42:35 +0100
committerMichal Čihař <nijel@debian.org>2018-01-23 09:42:35 +0100
commit54f377d3c23ee1cb0039cd01a37905924bb7fa34 (patch)
tree76b807cefb2b28dfb815169703b93dc6d3fc5749
parentcae51dac0d62e19b87eb5fe0b76cbac61dd38987 (diff)
parentc5352d22f1aa5993aeb7c8ffd9458df8e967dd0c (diff)
Update upstream source from tag 'upstream/0.162.1'
Update to upstream version '0.162.1' with Debian dir 758e669adee84719856030fb7f9f86b016d32289
-rw-r--r--NEWS7
-rw-r--r--osc/build.py2
-rw-r--r--osc/commandline.py81
-rw-r--r--osc/conf.py33
-rw-r--r--osc/core.py67
-rw-r--r--osc/util/debquery.py26
-rw-r--r--tests/commit_fixtures/testAddedMissing_lfilelistwithSHA1
-rw-r--r--tests/commit_fixtures/testAddedMissing_missingfilelistwithSHA3
-rw-r--r--tests/commit_fixtures/testAddedMissing_missingfilelistwithSHAsum3
-rw-r--r--tests/commit_fixtures/testSimple_lfilelistwithSHA1
-rw-r--r--tests/commit_fixtures/testSimple_missingfilelistwithSHA3
-rw-r--r--tests/commit_fixtures/testSimple_missingfilelistwithSHAsum3
-rw-r--r--tests/test_commit.py70
13 files changed, 246 insertions, 54 deletions
diff --git a/NEWS b/NEWS
index 10e395e..cab05e8 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,10 @@
+0.162.1
+ - Send sha256 hashes for tracked files if the wc is pulled/linkrepair
+
+0.162
+ - Additional file content check with SHA256 when using OBS 2.9
+ - support deb format with control.tar.xz
+
0.161.1
- Fix python 2.6 SyntaxError (multiple context expressions)
diff --git a/osc/build.py b/osc/build.py
index 28d4307..665bfac 100644
--- a/osc/build.py
+++ b/osc/build.py
@@ -491,7 +491,7 @@ def check_trusted_projects(apiurl, projects):
print("Note that malicious packages can compromise the build result or even your system.")
r = raw_input(trustprompt % { 'project': prj })
if r == '1':
- print("adding '%s' to ~/.oscrc: ['%s']['trusted_prj']" % (prj, apiurl))
+ print("adding '%s' to oscrc: ['%s']['trusted_prj']" % (prj, apiurl))
trusted.append(prj)
elif r != '2':
print("Well, good good bye then :-)")
diff --git a/osc/commandline.py b/osc/commandline.py
index 03ad391..c12061b 100644
--- a/osc/commandline.py
+++ b/osc/commandline.py
@@ -802,7 +802,7 @@ class Osc(cmdln.Cmdln):
osc meta <prj|pkg|prjconf|user|group|pattern> [-m|--message TEXT] -e|--edit ARGS...
osc meta <prj|pkg|prjconf|user|group|pattern> [-m|--message TEXT] -F|--file ARGS...
osc meta pattern --delete PRJ PATTERN
- osc meta attribute PRJ [PKG [SUBPACKAGE]] [--attribute ATTRIBUTE] [--create|--delete|--set [value_list]]
+ osc meta attribute PRJ [PKG [SUBPACKAGE]] [--attribute ATTRIBUTE] [--create [--set <value_list>]|--delete|--set <value_list>]
${cmd_option_list}
"""
@@ -4737,6 +4737,8 @@ Please submit there instead, or use --nodevelproject to force direct submission.
help='update to specified revision (this option will be ignored '
'if you are going to update the complete project or more than '
'one package)')
+ @cmdln.option('', '--linkrev', metavar='REV',
+ help='revision of the link target that is used during link expansion')
@cmdln.option('-u', '--unexpand-link', action='store_true',
help='if a package is an expanded link, update to the raw _link file')
@cmdln.option('-e', '--expand-link', action='store_true',
@@ -4774,11 +4776,10 @@ Please submit there instead, or use --nodevelproject to force direct submission.
${cmd_option_list}
"""
- if (opts.expand_link and opts.unexpand_link) \
- or (opts.expand_link and opts.revision) \
- or (opts.unexpand_link and opts.revision):
- raise oscerr.WrongOptions('Sorry, the options --expand-link, --unexpand-link and '
- '--revision are mutually exclusive.')
+ if opts.expand_link and opts.unexpand_link:
+ raise oscerr.WrongOptions('Sorry, the options --expand-link and '
+ '--unexpand-link and are mutually '
+ 'exclusive.')
args = parseargs(args)
arg_list = args[:]
@@ -4809,6 +4810,28 @@ Please submit there instead, or use --nodevelproject to force direct submission.
if not checkRevision(pacs[0].prjname, pacs[0].name, rev, pacs[0].apiurl):
print('Revision \'%s\' does not exist' % rev, file=sys.stderr)
sys.exit(1)
+ if opts.expand_link or opts.unexpand_link:
+ meta = show_files_meta(pacs[0].apiurl, pacs[0].prjname,
+ pacs[0].name, revision=rev,
+ linkrev=opts.linkrev,
+ expand=opts.server_side_source_service_files)
+ directory = ET.fromstring(meta)
+ li_node = directory.find('linkinfo')
+ if li_node is None:
+ print('Revision \'%s\' is no link' % rev, file=sys.stderr)
+ sys.exit(1)
+ li = Linkinfo()
+ li.read(li_node)
+ if li.haserror() and opts.expand_link:
+ raise oscerr.LinkExpandError(pacs[0].prjname, pacs[0].name,
+ li.error)
+ rev = li.lsrcmd5
+ if opts.expand_link:
+ rev = li.xsrcmd5
+ if rev is None:
+ # 2 cases: a) unexpand and passed rev has linkerror
+ # b) expand and passed rev is already expanded
+ rev = directory.get('srcmd5')
else:
rev = None
@@ -5631,7 +5654,7 @@ Please submit there instead, or use --nodevelproject to force direct submission.
The arguments REPOSITORY and ARCH are optional. They can be taken from
the first two columns of the 'osc repos' output. If not specified,
- REPOSITORY defaults to the 'build_repositoy' config entry in your '.oscrc'
+ REPOSITORY defaults to the 'build_repositoy' config entry in your 'oscrc'
and ARCH defaults to your host architecture.
usage:
@@ -5846,13 +5869,17 @@ Please submit there instead, or use --nodevelproject to force direct submission.
if subcmd == 'repos_only':
for repo in get_repositories_of_project(apiurl, project):
- if (disabled is None) or ((disabled is not None) and (repo not in disabled)):
+ if (disabled is None) or ((disabled is not None) and (repo not in [d['repo'] for d in disabled])):
print(repo)
else:
data = []
for repo in get_repos_of_project(apiurl, project):
- if (disabled is None) or ((disabled is not None) and (repo.name not in disabled)):
- data += [repo.name, repo.arch]
+ if disabled is not None:
+ if ({'repo': repo.name, 'arch': repo.arch} in disabled
+ or repo.name in [d['repo'] for d in disabled if d['arch'] is None]
+ or repo.arch in [d['arch'] for d in disabled if d['repo'] is None]):
+ continue
+ data += [repo.name, repo.arch]
for row in build_table(2, data, width=2):
print(row)
@@ -6014,7 +6041,7 @@ Please submit there instead, or use --nodevelproject to force direct submission.
@cmdln.option('--nochecks', '--no-checks', action='store_true',
help='Do not run build checks on the resulting packages.')
@cmdln.option('--no-verify', '--noverify', action='store_true',
- help='Skip signature verification (via pgp keys) of packages used for build. (Global config in .oscrc: no_verify)')
+ help='Skip signature verification (via pgp keys) of packages used for build. (Global config in oscrc: no_verify)')
@cmdln.option('--noservice', '--no-service', action='store_true',
help='Skip run of local source services as specified in _service file.')
@cmdln.option('-p', '--prefer-pkgs', metavar='DIR', action='append',
@@ -6099,8 +6126,8 @@ Please submit there instead, or use --nodevelproject to force direct submission.
Debian dsc file.
The command honours packagecachedir, build-root and build-uid
- settings in .oscrc, if present. You may want to set su-wrapper = 'sudo'
- in .oscrc, and configure sudo with option NOPASSWD for /usr/bin/build.
+ settings in oscrc, if present. You may want to set su-wrapper = 'sudo'
+ in oscrc, and configure sudo with option NOPASSWD for /usr/bin/build.
If neither --clean nor --noinit is given, build will reuse an existing
build-root again, removing unneeded packages and add missing ones. This
@@ -6421,11 +6448,15 @@ Please submit there instead, or use --nodevelproject to force direct submission.
suargs = ' '.join(suwrapper.split()[1:])
if suwrapper.startswith('su '):
mntproc = [sucmd, '%s mount -n -tproc none %s/proc' % (suargs, buildroot)]
+ mntsys = [sucmd, '%s mount -n -tsysfs none %s/sys' % (suargs, buildroot)]
umntproc = [sucmd, '%s umount %s/proc' % (suargs, buildroot)]
+ umntsys = [sucmd, '%s umount %s/sys' % (suargs, buildroot)]
cmd = [sucmd, '%s chroot "%s" su - %s' % (suargs, buildroot, user)]
else:
mntproc = [sucmd, 'mount', '-n', '-tproc' , 'none', '%s/proc' % buildroot]
+ mntsys = [sucmd, 'mount', '-n', '-tsysfs' , 'none', '%s/sys' % buildroot]
umntproc = [sucmd, 'umount', '%s/proc' % buildroot]
+ umntsys = [sucmd, 'umount', '%s/sys' % buildroot]
cmd = [sucmd, 'chroot', buildroot, 'su', '-', user]
if suargs:
mntproc[1:1] = suargs.split()
@@ -6433,25 +6464,31 @@ Please submit there instead, or use --nodevelproject to force direct submission.
cmd[1:1] = suargs.split()
#signal handler for chroot procfs umount
- def umount_proc(signum = None, frame = None, ret=1):
+ def umount_handle(signum = None, frame = None, ret=1):
subprocess.call(umntproc)
+ subprocess.call(umntsys)
sys.exit(ret)
for sig in [signal.SIGTERM, signal.SIGINT, signal.SIGHUP, signal.SIGQUIT]:
- signal.signal(sig, umount_proc)
+ signal.signal(sig, umount_handle)
print('mounting proc: %s' % ' '.join(mntproc))
+ print('mounting sys: %s' % ' '.join(mntsys))
mount_err = -1
- mount_err = subprocess.call(mntproc)
- if mount_err > 0:
+ proc_mount_err = subprocess.call(mntproc)
+ sys_mount_err = subprocess.call(mntsys)
+ if proc_mount_err > 0:
print('There was an error mounting proc. Please check mountpoints in chroot')
+ if sys_mount_err > 0:
+ print('There was an error mounting sys. Please check mountpoints in chroot')
print('running: %s' % ' '.join(cmd))
retval = 0
try:
retval = subprocess.call(cmd)
finally:
- if not mount_err or mount_err == 32:
- print('unmounting %s/proc ...' % buildroot)
- umount_proc(ret=retval)
+ if ((not proc_mount_err or proc_mount_err == 32) and
+ (not sys_mount_err or sys_mount_err == 32)):
+ print('unmounting %s/proc and %s/sys ...' % (buildroot, buildroot))
+ umount_handle(ret=retval)
@cmdln.option('', '--csv', action='store_true',
@@ -8073,7 +8110,7 @@ Please submit there instead, or use --nodevelproject to force direct submission.
apiurl = self.get_api_url()
if len(usernames) < 1:
if 'user' not in conf.config['api_host_options'][apiurl]:
- raise oscerr.WrongArgs('your .oscrc does not have your user name.')
+ raise oscerr.WrongArgs('your oscrc does not have your user name.')
usernames = (conf.config['api_host_options'][apiurl]['user'],)
for name in usernames:
user = get_user_data(apiurl, name, 'login', 'realname', 'email')
@@ -8593,7 +8630,7 @@ Please submit there instead, or use --nodevelproject to force direct submission.
be in the cwd or in path.
The email address used in .changes file is read from BuildService
- instance, or should be defined in ~/.oscrc
+ instance, or should be defined in oscrc
[https://api.opensuse.org/]
user = login
pass = password
diff --git a/osc/conf.py b/osc/conf.py
index 9829f9b..f53cc6c 100644
--- a/osc/conf.py
+++ b/osc/conf.py
@@ -7,12 +7,12 @@ from __future__ import print_function
"""Read osc configuration and store it in a dictionary
-This module reads and parses ~/.oscrc. The resulting configuration is stored
+This module reads and parses oscrc. The resulting configuration is stored
for later usage in a dictionary named 'config'.
-The .oscrc is kept mode 0600, so that it is not publically readable.
+The oscrc is kept mode 0600, so that it is not publically readable.
This gives no real security for storing passwords.
If in doubt, use your favourite keyring.
-Password is stored on ~/.oscrc as bz2 compressed and base64 encoded, so that is fairly
+Password is stored on ~/.config/osc/oscrc as bz2 compressed and base64 encoded, so that is fairly
large and not to be recognized or remembered easily by an occasional spectator.
If information is missing, it asks the user questions.
@@ -638,7 +638,9 @@ def get_configParser(conffile=None, force_read=False):
ConfigParser object is stored in a method attribute and this attribute
is returned unless you pass force_read=True.
"""
- conffile = conffile or os.environ.get('OSC_CONFIG', '~/.oscrc')
+ if not conffile:
+ conffile = identify_conf()
+
conffile = os.path.expanduser(conffile)
if 'conffile' not in get_configParser.__dict__:
get_configParser.conffile = conffile
@@ -654,6 +656,8 @@ def write_config(fname, cp):
if os.path.exists(fname) and not os.path.isfile(fname):
# only write to a regular file
return
+ if not os.path.exists(os.path.dirname(fname)):
+ os.makedirs(os.path.dirname(fname), mode=0o700)
with open(fname + '.new', 'w') as f:
cp.write(f, comments=True)
try:
@@ -818,14 +822,17 @@ def get_config(override_conffile=None,
"""do the actual work (see module documentation)"""
global config
- conffile = override_conffile or os.environ.get('OSC_CONFIG', '~/.oscrc')
- conffile = os.path.expanduser(conffile)
+ if not override_conffile:
+ conffile = identify_conf()
+ else:
+ conffile = override_conffile
+ conffile = os.path.expanduser(conffile)
if not os.path.exists(conffile):
raise oscerr.NoConfigfile(conffile, \
account_not_configured_text % conffile)
- # okay, we made sure that .oscrc exists
+ # okay, we made sure that oscrc exists
# make sure it is not world readable, it may contain a password.
os.chmod(conffile, 0o600)
@@ -997,7 +1004,7 @@ def get_config(override_conffile=None,
scheme = config.get('scheme', 'https')
config['apiurl'] = urljoin(scheme, apisrv)
if 'apisrc' in config or 'scheme' in config:
- print('Warning: Use of the \'scheme\' or \'apisrv\' in ~/.oscrc is deprecated!\n' \
+ print('Warning: Use of the \'scheme\' or \'apisrv\' in oscrc is deprecated!\n' \
'Warning: See README for migration details.', file=sys.stderr)
if 'build_platform' in config:
print('Warning: Use of \'build_platform\' config option is deprecated! (use \'build_repository\' instead)', file=sys.stderr)
@@ -1037,5 +1044,15 @@ def get_config(override_conffile=None,
# finally, initialize urllib2 for to use the credentials for Basic Authentication
init_basicauth(config, os.stat(conffile).st_mtime)
+def identify_conf():
+ # needed for compat reasons(users may have their oscrc still in ~
+ if 'OSC_CONFIG' in os.environ:
+ return os.environ.get('OSC_CONFIG')
+ if os.path.exists(os.path.expanduser('~/.oscrc')):
+ conffile = '~/.oscrc'
+ else:
+ conffile = os.environ.get('XDG_CONFIG_HOME', '~/.config') + '/osc/oscrc'
+
+ return conffile
# vim: sw=4 et
diff --git a/osc/core.py b/osc/core.py
index 66aaf76..16909e5 100644
--- a/osc/core.py
+++ b/osc/core.py
@@ -5,7 +5,7 @@
from __future__ import print_function
-__version__ = '0.161.1'
+__version__ = '0.162.1'
# __store_version__ is to be incremented when the format of the working copy
# "store" changes in an incompatible way. Please add any needed migration
@@ -22,6 +22,7 @@ import re
import socket
import errno
import shlex
+import hashlib
try:
from urllib.parse import urlsplit, urlunsplit, urlparse, quote_plus, urlencode, unquote
@@ -1393,7 +1394,7 @@ class Package:
todo.append(n.get('name'))
return todo
- def __send_commitlog(self, msg, local_filelist):
+ def __send_commitlog(self, msg, local_filelist, validate=False):
"""send the commitlog and the local filelist to the server"""
query = {}
if self.islink() and self.isexpanded():
@@ -1405,6 +1406,8 @@ class Package:
query['linkrev'] = self.get_pulled_srcmd5()
if self.islinkrepair():
query['repairlink'] = '1'
+ if validate:
+ query['withvalidate'] = '1'
return self.commit_filelist(self.apiurl, self.prjname, self.name,
local_filelist, msg, **query)
@@ -1444,6 +1447,7 @@ class Package:
todo_send = {}
todo_delete = []
real_send = []
+ sha256sums = {}
for filename in self.filenamelist + [i for i in self.to_be_added if not i in self.filenamelist]:
if filename.startswith('_service:') or filename.startswith('_service_'):
continue
@@ -1454,6 +1458,7 @@ class Package:
elif filename in self.todo:
if st in ('A', 'R', 'M'):
todo_send[filename] = dgst(os.path.join(self.absdir, filename))
+ sha256sums[filename] = sha256_dgst(os.path.join(self.absdir, filename))
real_send.append(filename)
print(statfrmt('Sending', os.path.join(pathn, filename)))
elif st in (' ', '!', 'S'):
@@ -1479,6 +1484,15 @@ class Package:
'error: file \'%s\' with state \'%s\' is not known by meta' \
% (filename, st))
todo_send[filename] = f.md5
+ if ((self.ispulled() or self.islinkrepair()) and st != 'A'
+ and filename not in sha256sums):
+ # Ignore files with state 'A': if we should consider it,
+ # it would have been in pac.todo, which implies that it is
+ # in sha256sums.
+ # The storefile is guaranteed to exist (since we have a
+ # pulled/linkrepair wc, the file cannot have state 'S')
+ storefile = os.path.join(self.storedir, filename)
+ sha256sums[filename] = sha256_dgst(storefile)
if not force and not real_send and not todo_delete and not self.islinkrepair() and not self.ispulled():
print('nothing to do for package %s' % self.name)
@@ -1486,7 +1500,21 @@ class Package:
print('Transmitting file data', end=' ')
filelist = self.__generate_commitlist(todo_send)
- sfilelist = self.__send_commitlog(msg, filelist)
+ sfilelist = self.__send_commitlog(msg, filelist, validate=True)
+ if sfilelist.get('error') and sfilelist.findall('.//entry[@hash]'):
+ name2elem = dict([(e.get('name'), e) for e in filelist.findall('entry')])
+ for entry in sfilelist.findall('.//entry[@hash]'):
+ filename = entry.get('name')
+ fileelem = name2elem.get(filename)
+ if filename not in sha256sums:
+ msg = 'There is no sha256 sum for file %s.\n' \
+ 'This could be due to an outdated working copy.\n' \
+ 'Please update your working copy with osc update and\n' \
+ 'commit again afterwards.'
+ print(msg % filename)
+ return 1
+ fileelem.set('hash', 'sha256:%s' % sha256sums[filename])
+ sfilelist = self.__send_commitlog(msg, filelist)
send = self.commit_get_missing(sfilelist)
real_send = [i for i in real_send if not i in send]
# abort after 3 tries
@@ -3554,7 +3582,12 @@ def show_package_disabled_repos(apiurl, prj, pac):
try:
root = ET.fromstring(''.join(m))
elm = root.find('build')
- r = [ node.get('repository') for node in elm.findall('disable')]
+ r = []
+ for node in elm.findall('disable'):
+ repo = node.get('repository')
+ arch = node.get('arch')
+ dis_r = {'repo': repo, 'arch': arch}
+ r.append(dis_r)
return r
except:
return None
@@ -4621,9 +4654,21 @@ def dgst(file):
buf = f.read(BUFSIZE)
if not buf: break
s.update(buf)
- return s.hexdigest()
f.close()
+ return s.hexdigest()
+
+def sha256_dgst(file):
+ global BUFSIZE
+
+ f = open(file, 'rb')
+ s = hashlib.sha256()
+ while True:
+ buf = f.read(BUFSIZE)
+ if not buf: break
+ s.update(buf)
+ f.close()
+ return s.hexdigest()
def binary(s):
"""return true if a string is binary data using diff's heuristic"""
@@ -7182,7 +7227,7 @@ def request_interactive_review(apiurl, request, initial_cmd='', group=None,
print('Type %s:' % action.type)
disabled = show_package_disabled_repos(apiurl, action.src_project, action.src_package)
for repo in get_repos_of_project(apiurl, action.src_project):
- if disabled is None or repo.name not in disabled:
+ if (disabled is None) or (repo.name not in [d['repo'] for d in disabled]):
lintlog_entry = {
'proj': action.src_project,
'pkg': action.src_package,
@@ -7567,6 +7612,16 @@ def return_external(filename, *args, **kwargs):
cmd = filename
try:
+ # backward compatibility for python 2.6
+ if 'check_output' not in dir(subprocess):
+ process = subprocess.Popen(cmd, stdout=subprocess.PIPE)
+ output, errstr = process.communicate()
+ retcode = process.poll()
+ if retcode:
+ error = subprocess.CalledProcessError(retcode, cmd)
+ error.output = output
+ raise error
+ return output
return subprocess.check_output(cmd, **kwargs)
except OSError as e:
if e.errno != errno.ENOENT:
diff --git a/osc/util/debquery.py b/osc/util/debquery.py
index 4b1a823..7d3c754 100644
--- a/osc/util/debquery.py
+++ b/osc/util/debquery.py
@@ -5,8 +5,15 @@ from . import ar
import os.path
import re
import tarfile
+import StringIO
from . import packagequery
+HAVE_LZMA = True
+try:
+ import lzma
+except ImportError:
+ HAVE_LZMA = False
+
class DebError(packagequery.PackageError):
pass
@@ -30,10 +37,18 @@ class DebQuery(packagequery.PackageQuery, packagequery.PackageQueryResult):
if debbin.read() != '2.0\n':
raise DebError(self.__path, 'invalid debian binary format')
control = arfile.get_file('control.tar.gz')
- if control is None:
- raise DebError(self.__path, 'missing control.tar.gz')
- # XXX: python2.4 relies on a name
- tar = tarfile.open(name = 'control.tar.gz', fileobj = control)
+ if control is not None:
+ # XXX: python2.4 relies on a name
+ tar = tarfile.open(name='control.tar.gz', fileobj=control)
+ else:
+ control = arfile.get_file('control.tar.xz')
+ if control is None:
+ raise DebError(self.__path, 'missing control.tar')
+ if not HAVE_LZMA:
+ raise DebError(self.__path, 'can\'t open control.tar.xz without python-lzma')
+ decompressed = lzma.decompress(control.read())
+ tar = tarfile.open(name="control.tar.xz",
+ fileobj=StringIO.StringIO(decompressed))
try:
name = './control'
# workaround for python2.4's tarfile module
@@ -41,7 +56,8 @@ class DebQuery(packagequery.PackageQuery, packagequery.PackageQueryResult):
name = 'control'
control = tar.extractfile(name)
except KeyError:
- raise DebError(self.__path, 'missing \'control\' file in control.tar.gz')
+ raise DebError(self.__path,
+ 'missing \'control\' file in control.tar')
self.__parse_control(control, all_tags, self_provides, *extra_tags)
return self
diff --git a/tests/commit_fixtures/testAddedMissing_lfilelistwithSHA b/tests/commit_fixtures/testAddedMissing_lfilelistwithSHA
new file mode 100644
index 0000000..408146c
--- /dev/null
+++ b/tests/commit_fixtures/testAddedMissing_lfilelistwithSHA
@@ -0,0 +1 @@
+<directory><entry hash="sha256:aec070645fe53ee3b3763059376134f058cc337247c978add178b6ccdfb0019f" md5="14758f1afd44c09b7992073ccf00b43d" name="bar" /><entry md5="0d62ceea6020d75154078a20d8c9f9ba" name="foo" /></directory> \ No newline at end of file
diff --git a/tests/commit_fixtures/testAddedMissing_missingfilelistwithSHA b/tests/commit_fixtures/testAddedMissing_missingfilelistwithSHA
new file mode 100644
index 0000000..4895b5e
--- /dev/null
+++ b/tests/commit_fixtures/testAddedMissing_missingfilelistwithSHA
@@ -0,0 +1,3 @@
+<directory error="missing" name="added_missing">
+ <entry md5="14758f1afd44c09b7992073ccf00b43d" name="bar" hash="new"/>
+</directory>
diff --git a/tests/commit_fixtures/testAddedMissing_missingfilelistwithSHAsum b/tests/commit_fixtures/testAddedMissing_missingfilelistwithSHAsum
new file mode 100644
index 0000000..13a2553
--- /dev/null
+++ b/tests/commit_fixtures/testAddedMissing_missingfilelistwithSHAsum
@@ -0,0 +1,3 @@
+<directory error="missing" name="added_missing">
+ <entry md5="14758f1afd44c09b7992073ccf00b43d" name="bar" hash="sha256:aec070645fe53ee3b3763059376134f058cc337247c978add178b6ccdfb0019f"/>
+</directory>
diff --git a/tests/commit_fixtures/testSimple_lfilelistwithSHA b/tests/commit_fixtures/testSimple_lfilelistwithSHA
new file mode 100644
index 0000000..aac9cf3
--- /dev/null
+++ b/tests/commit_fixtures/testSimple_lfilelistwithSHA
@@ -0,0 +1 @@
+<directory><entry md5="0d62ceea6020d75154078a20d8c9f9ba" name="foo" /><entry md5="17b9e9e1a032ed44e7a584dc6303ffa8" name="merge" /><entry hash="sha256:a531b3f2e3bb545ad9396dcfbb9973385b22e67bad2ac4c2bdf8f62ca05ecb02" md5="382588b92f5976de693f44c4d6df27b7" name="nochange" /></directory> \ No newline at end of file
diff --git a/tests/commit_fixtures/testSimple_missingfilelistwithSHA b/tests/commit_fixtures/testSimple_missingfilelistwithSHA
new file mode 100644
index 0000000..1a7a99b
--- /dev/null
+++ b/tests/commit_fixtures/testSimple_missingfilelistwithSHA
@@ -0,0 +1,3 @@
+<directory error="missing" name="simple">
+ <entry hash="missing" md5="c4eaea5dcaff13418e38e7fea151dd49" name="nochange" />
+</directory>
diff --git a/tests/commit_fixtures/testSimple_missingfilelistwithSHAsum b/tests/commit_fixtures/testSimple_missingfilelistwithSHAsum
new file mode 100644
index 0000000..077cd51
--- /dev/null
+++ b/tests/commit_fixtures/testSimple_missingfilelistwithSHAsum
@@ -0,0 +1,3 @@
+<directory error="missing" name="simple">
+ <entry hash="sha256:a531b3f2e3bb545ad9396dcfbb9973385b22e67bad2ac4c2bdf8f62ca05ecb02" md5="c4eaea5dcaff13418e38e7fea151dd49" name="nochange" />
+</directory>
diff --git a/tests/test_commit.py b/tests/test_commit.py
index 02baa85..349fc4b 100644
--- a/tests/test_commit.py
+++ b/tests/test_commit.py
@@ -25,7 +25,7 @@ class TestCommit(OscTestCase):
@GET('http://localhost/source/osctest/simple?rev=latest', file='testSimple_filesremote')
@POST('http://localhost/source/osctest/simple?cmd=getprojectservices',
exp='', text='<services />')
- @POST('http://localhost/source/osctest/simple?comment=&cmd=commitfilelist&user=Admin',
+ @POST('http://localhost/source/osctest/simple?comment=&cmd=commitfilelist&user=Admin&withvalidate=1',
file='testSimple_missingfilelist', expfile='testSimple_lfilelist')
@PUT('http://localhost/source/osctest/simple/nochange?rev=repository',
exp='This file didn\'t change but\nis modified.\n', text=rev_dummy)
@@ -48,7 +48,7 @@ class TestCommit(OscTestCase):
@GET('http://localhost/source/osctest/add?rev=latest', file='testAddfile_filesremote')
@POST('http://localhost/source/osctest/add?cmd=getprojectservices',
exp='', text='<services />')
- @POST('http://localhost/source/osctest/add?comment=&cmd=commitfilelist&user=Admin',
+ @POST('http://localhost/source/osctest/add?comment=&cmd=commitfilelist&user=Admin&withvalidate=1',
file='testAddfile_missingfilelist', expfile='testAddfile_lfilelist')
@PUT('http://localhost/source/osctest/add/add?rev=repository',
exp='added file\n', text=rev_dummy)
@@ -73,7 +73,7 @@ class TestCommit(OscTestCase):
@GET('http://localhost/source/osctest/delete?rev=latest', file='testDeletefile_filesremote')
@POST('http://localhost/source/osctest/delete?cmd=getprojectservices',
exp='', text='<services />')
- @POST('http://localhost/source/osctest/delete?comment=&cmd=commitfilelist&user=Admin',
+ @POST('http://localhost/source/osctest/delete?comment=&cmd=commitfilelist&user=Admin&withvalidate=1',
file='testDeletefile_cfilesremote', expfile='testDeletefile_lfilelist')
def test_deletefile(self):
"""delete a file"""
@@ -120,7 +120,7 @@ class TestCommit(OscTestCase):
@GET('http://localhost/source/osctest/multiple?rev=latest', file='testMultiple_filesremote')
@POST('http://localhost/source/osctest/multiple?cmd=getprojectservices',
exp='', text='<services />')
- @POST('http://localhost/source/osctest/multiple?comment=&cmd=commitfilelist&user=Admin',
+ @POST('http://localhost/source/osctest/multiple?comment=&cmd=commitfilelist&user=Admin&withvalidate=1',
file='testMultiple_missingfilelist', expfile='testMultiple_lfilelist')
@PUT('http://localhost/source/osctest/multiple/nochange?rev=repository', exp='This file did change.\n', text=rev_dummy)
@PUT('http://localhost/source/osctest/multiple/add?rev=repository', exp='added file\n', text=rev_dummy)
@@ -149,7 +149,7 @@ class TestCommit(OscTestCase):
@GET('http://localhost/source/osctest/multiple?rev=latest', file='testPartial_filesremote')
@POST('http://localhost/source/osctest/multiple?cmd=getprojectservices',
exp='', text='<services />')
- @POST('http://localhost/source/osctest/multiple?comment=&cmd=commitfilelist&user=Admin',
+ @POST('http://localhost/source/osctest/multiple?comment=&cmd=commitfilelist&user=Admin&withvalidate=1',
file='testPartial_missingfilelist', expfile='testPartial_lfilelist')
@PUT('http://localhost/source/osctest/multiple/add?rev=repository', exp='added file\n', text=rev_dummy)
@PUT('http://localhost/source/osctest/multiple/nochange?rev=repository', exp='This file did change.\n', text=rev_dummy)
@@ -176,7 +176,7 @@ class TestCommit(OscTestCase):
@GET('http://localhost/source/osctest/simple?rev=latest', file='testSimple_filesremote')
@POST('http://localhost/source/osctest/simple?cmd=getprojectservices',
exp='', text='<services />')
- @POST('http://localhost/source/osctest/simple?comment=&cmd=commitfilelist&user=Admin',
+ @POST('http://localhost/source/osctest/simple?comment=&cmd=commitfilelist&user=Admin&withvalidate=1',
file='testSimple_missingfilelist', expfile='testSimple_lfilelist')
@PUT('http://localhost/source/osctest/simple/nochange?rev=repository', exp='This file didn\'t change but\nis modified.\n',
exception=IOError('test exception'), text=rev_dummy)
@@ -194,7 +194,7 @@ class TestCommit(OscTestCase):
@GET('http://localhost/source/osctest/allstates?rev=latest', file='testPartial_filesremote')
@POST('http://localhost/source/osctest/allstates?cmd=getprojectservices',
exp='', text='<services />')
- @POST('http://localhost/source/osctest/allstates?comment=&cmd=commitfilelist&user=Admin',
+ @POST('http://localhost/source/osctest/allstates?comment=&cmd=commitfilelist&user=Admin&withvalidate=1',
file='testAllStates_missingfilelist', expfile='testAllStates_lfilelist')
@PUT('http://localhost/source/osctest/allstates/add?rev=repository', exp='added file\n', text=rev_dummy)
@PUT('http://localhost/source/osctest/allstates/missing?rev=repository', exp='replaced\n', text=rev_dummy)
@@ -224,7 +224,7 @@ class TestCommit(OscTestCase):
@GET('http://localhost/source/osctest/add?rev=latest', file='testAddfile_filesremote')
@POST('http://localhost/source/osctest/add?cmd=getprojectservices',
exp='', text='<services />')
- @POST('http://localhost/source/osctest/add?comment=&cmd=commitfilelist&user=Admin',
+ @POST('http://localhost/source/osctest/add?comment=&cmd=commitfilelist&user=Admin&withvalidate=1',
file='testAddfile_cfilesremote', expfile='testAddfile_lfilelist')
def test_remoteexists(self):
"""file 'add' should be committed but already exists on the server"""
@@ -245,7 +245,7 @@ class TestCommit(OscTestCase):
@GET('http://localhost/source/osctest/branch?rev=latest', file='testExpand_filesremote')
@POST('http://localhost/source/osctest/branch?cmd=getprojectservices',
exp='', text='<services />')
- @POST('http://localhost/source/osctest/branch?comment=&cmd=commitfilelist&user=Admin&keeplink=1',
+ @POST('http://localhost/source/osctest/branch?comment=&cmd=commitfilelist&user=Admin&withvalidate=1&keeplink=1',
file='testExpand_missingfilelist', expfile='testExpand_lfilelist')
@PUT('http://localhost/source/osctest/branch/simple?rev=repository', exp='simple modified file.\n', text=rev_dummy)
@POST('http://localhost/source/osctest/branch?comment=&cmd=commitfilelist&user=Admin&keeplink=1',
@@ -277,7 +277,7 @@ class TestCommit(OscTestCase):
@GET('http://localhost/source/osctest/added_missing?rev=latest', file='testAddedMissing_filesremote')
@POST('http://localhost/source/osctest/added_missing?cmd=getprojectservices',
exp='', text='<services />')
- @POST('http://localhost/source/osctest/added_missing?comment=&cmd=commitfilelist&user=Admin',
+ @POST('http://localhost/source/osctest/added_missing?comment=&cmd=commitfilelist&user=Admin&withvalidate=1',
file='testAddedMissing_missingfilelist', expfile='testAddedMissing_lfilelist')
@PUT('http://localhost/source/osctest/added_missing/bar?rev=repository', exp='foobar\n', text=rev_dummy)
@POST('http://localhost/source/osctest/added_missing?comment=&cmd=commitfilelist&user=Admin',
@@ -296,7 +296,7 @@ class TestCommit(OscTestCase):
@GET('http://localhost/source/osctest/simple?rev=latest', file='testSimple_filesremote')
@POST('http://localhost/source/osctest/simple?cmd=getprojectservices',
exp='', text='<services />')
- @POST('http://localhost/source/osctest/simple?comment=&cmd=commitfilelist&user=Admin',
+ @POST('http://localhost/source/osctest/simple?comment=&cmd=commitfilelist&user=Admin&withvalidate=1',
file='testSimple_missingfilelist', expfile='testSimple_lfilelist')
@PUT('http://localhost/source/osctest/simple/nochange?rev=repository',
exp='This file didn\'t change but\nis modified.\n', text=rev_dummy)
@@ -312,6 +312,52 @@ class TestCommit(OscTestCase):
self.assertEqual(sys.stdout.getvalue(), exp)
self._check_status(p, 'nochange', 'M')
-if __name__ == '__main__':
+ @GET('http://localhost/source/osctest/simple?rev=latest', file='testSimple_filesremote')
+ @POST('http://localhost/source/osctest/simple?cmd=getprojectservices',
+ exp='', text='<services />')
+ @POST('http://localhost/source/osctest/simple?comment=&cmd=commitfilelist&user=Admin&withvalidate=1',
+ file='testSimple_missingfilelistwithSHA', expfile='testSimple_lfilelist')
+ @POST('http://localhost/source/osctest/simple?comment=&cmd=commitfilelist&user=Admin',
+ file='testSimple_missingfilelistwithSHAsum', expfile='testSimple_lfilelistwithSHA')
+ @PUT('http://localhost/source/osctest/simple/nochange?rev=repository',
+ exp='This file didn\'t change but\nis modified.\n', text=rev_dummy)
+ @POST('http://localhost/source/osctest/simple?comment=&cmd=commitfilelist&user=Admin',
+ file='testSimple_cfilesremote', expfile='testSimple_lfilelistwithSHA')
+ def test_simple_sha256(self):
+ """a simple commit (only one modified file)"""
+ self._change_to_pkg('simple')
+ p = osc.core.Package('.')
+ p.commit()
+ exp = 'Sending nochange\nTransmitting file data .\nCommitted revision 2.\n'
+ self.assertEqual(sys.stdout.getvalue(), exp)
+ self._check_digests('testSimple_cfilesremote')
+ self.assertTrue(os.path.exists('nochange'))
+ self.assertEqual(open('nochange', 'r').read(), open(os.path.join('.osc', 'nochange'), 'r').read())
+ self._check_status(p, 'nochange', ' ')
+ self._check_status(p, 'foo', ' ')
+ self._check_status(p, 'merge', ' ')
+
+ @GET('http://localhost/source/osctest/added_missing?rev=latest', file='testAddedMissing_filesremote')
+ @POST('http://localhost/source/osctest/added_missing?cmd=getprojectservices',
+ exp='', text='<services />')
+ @POST('http://localhost/source/osctest/added_missing?comment=&cmd=commitfilelist&user=Admin&withvalidate=1',
+ file='testAddedMissing_missingfilelistwithSHA', expfile='testAddedMissing_lfilelist')
+ @POST('http://localhost/source/osctest/added_missing?comment=&cmd=commitfilelist&user=Admin',
+ file='testAddedMissing_missingfilelistwithSHAsum', expfile='testAddedMissing_lfilelistwithSHA')
+ @PUT('http://localhost/source/osctest/added_missing/bar?rev=repository', exp='foobar\n', text=rev_dummy)
+ @POST('http://localhost/source/osctest/added_missing?comment=&cmd=commitfilelist&user=Admin',
+ file='testAddedMissing_cfilesremote', expfile='testAddedMissing_lfilelistwithSHA')
+ def test_added_missing2_sha256(self):
+ """commit an added file, another added file missing (but it's not part of the commit)"""
+ self._change_to_pkg('added_missing')
+ p = osc.core.Package('.')
+ p.todo = ['bar']
+ p.commit()
+ exp = 'Sending bar\nTransmitting file data .\nCommitted revision 2.\n'
+ self.assertEqual(sys.stdout.getvalue(), exp)
+ self._check_status(p, 'add', '!')
+ self._check_status(p, 'bar', ' ')
+
+if __name__ == '__main__':
import unittest
unittest.main()