Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package osc for openSUSE:Factory checked in at 2021-12-02 22:30:18 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/osc (Old) and /work/SRC/openSUSE:Factory/.osc.new.31177 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "osc" Thu Dec 2 22:30:18 2021 rev:158 rq:935127 version:0.175.0 Changes: -------- --- /work/SRC/openSUSE:Factory/osc/osc.changes 2021-07-21 19:07:51.007444770 +0200 +++ /work/SRC/openSUSE:Factory/.osc.new.31177/osc.changes 2021-12-02 22:31:14.634445112 +0100 @@ -1,0 +2,19 @@ +Thu Dec 2 08:18:20 UTC 2021 - Marco Strigl <marco.str...@suse.com> + +- 0.175.0: + * do not crash when running "osc search --binary --verbose foo" + * don't run source services when building outside of an OSC package working copy + * fix XDG_CONFIG_HOME + * offer a force ("f") choice in metafile.edit's error handling code path + * fix XPath used in search requests + * add support for creating a workflow token via "osc token" + * handle missing os.sysconf more gracefully + * detachbranch: remove _link when link target got removed + * improve error message in case of an URLError + * fix downloading from mirrors + * avoid sending entire projects on "osc mr" + * fix hdmrd5 check of local cached files + * improve logic for conffile mode handling + + +------------------------------------------------------------------- Old: ---- osc-0.174.0.tar.gz New: ---- osc-0.175.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ osc.spec ++++++ --- /var/tmp/diff_new_pack.3D82Eb/_old 2021-12-02 22:31:15.342442506 +0100 +++ /var/tmp/diff_new_pack.3D82Eb/_new 2021-12-02 22:31:15.342442506 +0100 @@ -27,7 +27,7 @@ %define use_python python %endif -%define version_unconverted 0.174.0 +%define version_unconverted 0.175.0 %define osc_plugin_dir %{_prefix}/lib/osc-plugins %define macros_file macros.osc %if ! %{defined _rpmmacrodir} @@ -35,7 +35,7 @@ %endif Name: osc -Version: 0.174.0 +Version: 0.175.0 Release: 0 Summary: Open Build Service Commander License: GPL-2.0-or-later ++++++ PKGBUILD ++++++ --- /var/tmp/diff_new_pack.3D82Eb/_old 2021-12-02 22:31:15.378442373 +0100 +++ /var/tmp/diff_new_pack.3D82Eb/_new 2021-12-02 22:31:15.378442373 +0100 @@ -1,5 +1,5 @@ pkgname=osc -pkgver=0.174.0 +pkgver=0.175.0 pkgrel=0 pkgdesc="Open Build Service client" arch=('x86_64') ++++++ _service ++++++ --- /var/tmp/diff_new_pack.3D82Eb/_old 2021-12-02 22:31:15.398442299 +0100 +++ /var/tmp/diff_new_pack.3D82Eb/_new 2021-12-02 22:31:15.398442299 +0100 @@ -1,7 +1,7 @@ <services> <service name="tar_scm" mode="disabled"> - <param name="version">0.174.0</param> - <param name="revision">0.174.0</param> + <param name="version">0.175.0</param> + <param name="revision">0.175.0</param> <param name="url">git://github.com/openSUSE/osc.git</param> <param name="scm">git</param> </service> ++++++ debian.changelog ++++++ --- /var/tmp/diff_new_pack.3D82Eb/_old 2021-12-02 22:31:15.438442152 +0100 +++ /var/tmp/diff_new_pack.3D82Eb/_new 2021-12-02 22:31:15.442442137 +0100 @@ -1,4 +1,4 @@ -osc (0.174.0-0) unstable; urgency=low +osc (0.175.0-0) unstable; urgency=low - Update to 0.174.0: - fix password deletion via "osc config -d <apiurl> pass" - support changing the password store via "osc config <apiurl> ++++++ osc-0.174.0.tar.gz -> osc-0.175.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/osc-0.174.0/NEWS new/osc-0.175.0/NEWS --- old/osc-0.174.0/NEWS 2021-07-21 10:43:53.000000000 +0200 +++ new/osc-0.175.0/NEWS 2021-12-02 08:48:19.000000000 +0100 @@ -1,3 +1,18 @@ +0.175.0 + - do not crash when running "osc search --binary --verbose foo" + - don't run source services when building outside of an OSC package working copy + - fix XDG_CONFIG_HOME + - offer a force ("f") choice in metafile.edit's error handling code path + - fix XPath used in search requests + - add support for creating a workflow token via "osc token" + - handle missing os.sysconf more gracefully + - detachbranch: remove _link when link target got removed + - improve error message in case of an URLError + - fix downloading from mirrors + - avoid sending entire projects on "osc mr" + - fix hdmrd5 check of local cached files + - improve logic for conffile mode handling + 0.174.0 - fix password deletion via "osc config -d <apiurl> pass" - support changing the password store via "osc config <apiurl> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/osc-0.174.0/osc/babysitter.py new/osc-0.175.0/osc/babysitter.py --- old/osc-0.174.0/osc/babysitter.py 2021-07-21 10:43:53.000000000 +0200 +++ new/osc-0.175.0/osc/babysitter.py 2021-12-02 08:48:19.000000000 +0100 @@ -139,7 +139,11 @@ except HTTPException as e: print(e, file=sys.stderr) except URLError as e: - print('Failed to reach a server:\n', e.reason, file=sys.stderr) + msg = 'Failed to reach a server' + if hasattr(e, '_osc_host_port'): + msg += ' (%s)' % e._osc_host_port + msg += ':\n' + print(msg, e.reason, file=sys.stderr) except IOError as e: # ignore broken pipe if e.errno != errno.EPIPE: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/osc-0.174.0/osc/build.py new/osc-0.175.0/osc/build.py --- old/osc-0.174.0/osc/build.py 2021-07-21 10:43:53.000000000 +0200 +++ new/osc-0.175.0/osc/build.py 2021-12-02 08:48:19.000000000 +0100 @@ -157,6 +157,7 @@ self.keys = [] self.prjkeys = [] self.pathes = [] + self.urls = {} self.modules = [] for node in root.findall('module'): self.modules.append(node.text) @@ -174,7 +175,12 @@ self.projects[p.project] = 1 self.deps.append(p) for node in root.findall('path'): + # old simple list for compatibility + # XXX: really old? This is currently used for kiwi builds self.pathes.append(node.get('project')+"/"+node.get('repository')) + # a hash providing the matching URL for specific repos for newer OBS instances + if node.get('url'): + self.urls[node.get('project')+"/"+node.get('repository')] = node.get('url') + '/%(arch)s/%(filename)s' self.vminstall_list = [ dep.name for dep in self.deps if dep.vminstall ] self.preinstall_list = [ dep.name for dep in self.deps if dep.preinstall ] @@ -790,6 +796,9 @@ if opts.noinit: buildargs.append('--noinit') + if not is_package_dir('.'): + opts.noservice = True + # check for source services if not opts.offline and not opts.noservice: p = osc.core.Package(os.curdir) @@ -1021,7 +1030,9 @@ else: urllist = config['urllist'] - # OBS 1.5 and before has no downloadurl defined in buildinfo + # OBS 1.5 and before has no downloadurl defined in buildinfo, but it is obsolete again meanwhile. + # we have now specific download repositories per repository. Could be removed IMHO, since the api fallback + # is there. In worst case it could fetch the wrong rpm... if bi.downloadurl: urllist.append(bi.downloadurl + '/%(extproject)s/%(extrepository)s/%(arch)s/%(filename)s') if opts.disable_cpio_bulk_download: @@ -1277,6 +1288,8 @@ for i in bi.deps: if i.hdrmd5: + if not i.name.startswith('container:') and i.pacsuffix != 'rpm': + continue from .util import packagequery if i.name.startswith('container:'): hdrmd5 = dgst(i.fullfilename) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/osc-0.174.0/osc/commandline.py new/osc-0.175.0/osc/commandline.py --- old/osc-0.174.0/osc/commandline.py 2021-07-21 10:43:53.000000000 +0200 +++ new/osc-0.175.0/osc/commandline.py 2021-12-02 08:48:19.000000000 +0100 @@ -131,7 +131,7 @@ return optparser - def postoptparse(self, try_again = True): + def postoptparse(self): """merge commandline options into the config""" try: conf.get_config(override_conffile = self.options.conffile, @@ -152,19 +152,16 @@ apiurl = self.options.apiurl conf.interactive_config_setup(e.file, apiurl) print('done', file=sys.stderr) - if try_again: - self.postoptparse(try_again = False) + self.postoptparse() except oscerr.ConfigMissingApiurl as e: print(e.msg, file=sys.stderr) conf.interactive_config_setup(e.file, e.url, initial=False) - if try_again: - self.postoptparse(try_again = False) + self.postoptparse() except oscerr.ConfigMissingCredentialsError as e: print(e.msg) print('Please enter new credentials.') conf.interactive_config_setup(e.file, e.url, initial=False) - if try_again: - self.postoptparse(try_again = False) + self.postoptparse() self.options.verbose = conf.config['verbose'] self.download_progress = None @@ -771,9 +768,11 @@ @cmdln.option('-d', '--delete', metavar='TOKENID', help='Delete a token') @cmdln.option('-o', '--operation', metavar='OPERATION', - help='Default is "runservice", but "branch", "release" or "rebuild" can also be used') + help='Default is "runservice", but "branch", "release", "rebuild", or "workflow" can also be used') @cmdln.option('-t', '--trigger', metavar='TOKENSTRING', help='Trigger the action of a token') + @cmdln.option('', '--scm-token', metavar ='SCM_TOKEN', + help='The scm\'s access token (only in combination with a --operation=workflow option)') def do_token(self, subcmd, opts, *args): """${cmd_name}: Show and manage authentication token @@ -790,18 +789,28 @@ args = slash_split(args) + if opts.scm_token and opts.operation != 'workflow': + msg = 'The --scm-token option requires a --operation=workflow option' + raise oscerr.WrongOptions(msg) + apiurl = self.get_api_url() - url = apiurl + "/person/" + conf.get_apiurl_usr(apiurl) + "/token" + url_path = ['person', conf.get_apiurl_usr(apiurl), 'token'] if opts.create: + if opts.operation == 'workflow' and not opts.scm_token: + msg = 'The --operation=workflow option requires a --scm-token=<token> option' + raise oscerr.WrongOptions(msg) print("Create a new token") - url += "?cmd=create" + query = {'cmd': 'create'} if opts.operation: - url += "&operation=" + opts.operation + query['operation'] = opts.operation + if opts.scm_token: + query['scm_token'] = opts.scm_token if len(args) > 1: - url += "&project=" + args[0] - url += "&package=" + args[1] + query['project'] = args[0] + query['package'] = args[1] + url = makeurl(apiurl, url_path, query) f = http_POST(url) while True: buf = f.read(16384) @@ -811,15 +820,17 @@ elif opts.delete: print("Delete token") - url += "/" + opts.delete + url_path.append(opts.delete) + url = makeurl(apiurl, url_path) http_DELETE(url) elif opts.trigger: print("Trigger token") operation = opts.operation or "runservice" - url = apiurl + "/trigger/" + operation + query = {} if len(args) > 1: - url += "?project=" + args[0] - url += "&package=" + args[1] + query['project'] = args[0] + query['package'] = args[1] + url = makeurl(apiurl, ['trigger', operation], query) req = URLRequest(url) req.get_method = lambda: "POST" req.add_header('Content-Type', 'application/octet-stream') @@ -830,6 +841,7 @@ if args and args[0] in ['create', 'delete', 'trigger']: raise oscerr.WrongArgs("Did you mean --" + args[0] + "?") # just list token + url = makeurl(apiurl, url_path) for data in streamfile(url, http_GET): sys.stdout.write(decode_it(data)) @@ -2653,7 +2665,7 @@ sr_actions = rq.get_actions('submit') for action in sr_actions: u = makeurl(apiurl, ['/search/package'], { - 'match' : "([devel/[@project='%s' and @package='%s']])" % (action.tgt_project, action.tgt_package) + 'match' : "([devel[@project='%s' and @package='%s']])" % (action.tgt_project, action.tgt_package) }) f = http_GET(u) root = ET.parse(f).getroot() @@ -2840,7 +2852,14 @@ li = Linkinfo() li.read(root.find('linkinfo')) if li.islink() and li.haserror(): - raise oscerr.LinkExpandError(project, package, li.error) + try: + show_package_meta(apiurl, li.project, li.package) + except HTTPError as e: + if e.code == 404: + print("Link target got removed, dropping link. WARNING: latest submissions in link target might be lost!") + delete_files(apiurl, project, package, ['_link']) + else: + raise oscerr.LinkExpandError(project, package, li.error) elif not li.islink(): print('package \'%s/%s\' is no link' % (project, package), file=sys.stderr) else: @@ -3320,6 +3339,8 @@ if len(args) == 0 and (is_project_dir(os.curdir) or is_package_dir(os.curdir)): source_project = store_read_project(os.curdir) + if is_package_dir(os.curdir): + source_packages = [store_read_package(os.curdir)] elif len(args) == 0: raise oscerr.WrongArgs('Too few arguments.') if len(args) > 0: @@ -7627,7 +7648,7 @@ if list_patchinfos: u = makeurl(apiurl, ['/search/package'], { - 'match' : "([kind='patchinfo' and issue/[@state='OPEN' and owner/@login='%s']])" % user + 'match' : "([kind='patchinfo' and issue[@state='OPEN' and owner/@login='%s']])" % user }) f = http_GET(u) root = ET.parse(f).getroot() @@ -7960,10 +7981,16 @@ result.append(s) if opts.verbose: - title = node.findtext('title').strip() - if len(title) > 60: - title = title[:61] + '...' - result.append(title) + if opts.binary: + result.append(node.get('repository') or '-') + result.append(node.get('arch') or '-') + result.append(node.get('version') or '-') + result.append(node.get('release') or '-') + else: + title = node.findtext('title').strip() + if len(title) > 60: + title = title[:61] + '...' + result.append(title) if opts.repos_baseurl: # FIXME: no hardcoded URL of instance @@ -7995,7 +8022,11 @@ headline.append('Rev') headline.append('Srcmd5') if opts.verbose: - headline.append('# Title') + if opts.binary: + headline.extend(['# Repository', '# Arch', '# Version', + '# Release']) + else: + headline.append('# Title') if opts.repos_baseurl: headline.append('# URL') if opts.binary: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/osc-0.174.0/osc/conf.py new/osc-0.175.0/osc/conf.py --- old/osc-0.174.0/osc/conf.py 2021-07-21 10:43:53.000000000 +0200 +++ new/osc-0.175.0/osc/conf.py 2021-12-02 08:48:19.000000000 +0100 @@ -38,6 +38,7 @@ import bz2 import base64 +import errno import os import re import sys @@ -87,13 +88,26 @@ def _get_processors(): """ get number of processors (online) based on - SC_NPROCESSORS_ONLN (returns 1 if config name does not exist). + SC_NPROCESSORS_ONLN (returns 1 if config name/os.sysconf does not exist). """ try: return os.sysconf('SC_NPROCESSORS_ONLN') - except ValueError as e: + except (AttributeError, ValueError): return 1 + +def _identify_osccookiejar(): + if os.path.isfile(os.path.join(os.path.expanduser("~"), '.osc_cookiejar')): + # For backwards compatibility, use the old location if it exists + return '~/.osc_cookiejar' + + if os.getenv('XDG_STATE_HOME', '') != '': + osc_state_dir = os.path.join(os.getenv('XDG_STATE_HOME'), 'osc') + else: + osc_state_dir = os.path.join(os.path.expanduser("~"), '.local', 'state', 'osc') + + return os.path.join(osc_state_dir, 'cookiejar') + DEFAULTS = {'apiurl': 'https://api.opensuse.org', 'user': None, 'pass': None, @@ -136,7 +150,7 @@ 'post_mortem': '0', 'use_keyring': '0', 'gnome_keyring': '0', - 'cookiejar': '~/.osc_cookiejar', + 'cookiejar': _identify_osccookiejar(), # fallback for osc build option --no-verify 'no_verify': '0', # enable project tracking by default @@ -638,6 +652,8 @@ AbstractHTTPHandler.__init__ = urllib2_debug_init cookie_file = os.path.expanduser(config['cookiejar']) + if not os.path.exists(os.path.dirname(cookie_file)): + os.makedirs(os.path.dirname(cookie_file), mode=0o700) global cookiejar cookiejar = LWPCookieJar(cookie_file) try: @@ -881,7 +897,15 @@ # okay, we made sure that oscrc exists # make sure it is not world readable, it may contain a password. - os.chmod(conffile, 0o600) + conffile_stat = os.stat(conffile) + if conffile_stat.st_mode != 0o600: + try: + os.chmod(conffile, 0o600) + except OSError as e: + if e.errno == errno.EROFS: + print('Warning: file \'%s\' may have an insecure mode.', conffile) + else: + raise e cp = get_configParser(conffile) @@ -1043,9 +1067,12 @@ if 'OSC_CONFIG' in os.environ: return os.environ.get('OSC_CONFIG') if os.path.exists(os.path.expanduser('~/.oscrc')): - conffile = '~/.oscrc' + return '~/.oscrc' + + if os.environ.get('XDG_CONFIG_HOME', '') != '': + conffile = os.environ.get('XDG_CONFIG_HOME') + '/osc/oscrc' else: - conffile = os.environ.get('XDG_CONFIG_HOME', '~/.config') + '/osc/oscrc' + conffile = '~/.config/osc/oscrc' return conffile diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/osc-0.174.0/osc/core.py new/osc-0.175.0/osc/core.py --- old/osc-0.174.0/osc/core.py 2021-07-21 10:43:53.000000000 +0200 +++ new/osc-0.175.0/osc/core.py 2021-12-02 08:48:19.000000000 +0100 @@ -5,7 +5,7 @@ from __future__ import print_function -__version__ = '0.174' +__version__ = '0.175.0' # __store_version__ is to be incremented when the format of the working copy # "store" changes in an incompatible way. Please add any needed migration @@ -33,7 +33,7 @@ try: from urllib.parse import urlsplit, urlunsplit, urlparse, quote_plus, urlencode, unquote - from urllib.error import HTTPError + from urllib.error import HTTPError, URLError from urllib.request import pathname2url, install_opener, urlopen from urllib.request import Request as URLRequest from io import StringIO @@ -42,7 +42,7 @@ #python 2.x from urlparse import urlsplit, urlunsplit, urlparse from urllib import pathname2url, quote_plus, urlencode, unquote - from urllib2 import HTTPError, install_opener, urlopen + from urllib2 import HTTPError, URLError, install_opener, urlopen from urllib2 import Request as URLRequest from cStringIO import StringIO from httplib import IncompleteRead @@ -540,7 +540,7 @@ def islink(self): """returns True if the linkinfo is not empty, otherwise False""" - if self.xsrcmd5 or self.lsrcmd5: + if self.xsrcmd5 or self.lsrcmd5 or self.error is not None: return True return False @@ -1300,7 +1300,7 @@ self.to_be_added.remove(n) self.write_addlist() elif state == 'C': - # don't remove "merge files" (*.r, *.mine...) + # don't remove "merge files" (*.mine, *.new...) # that's why we don't use clear_from_conflictlist self.in_conflict.remove(n) self.write_conflictlist() @@ -1336,15 +1336,10 @@ filename = os.path.join(self.dir, n) storefilename = os.path.join(self.storedir, n) myfilename = os.path.join(self.dir, n + '.mine') - if self.islinkrepair() or self.ispulled(): - upfilename = os.path.join(self.dir, n + '.new') - else: - upfilename = os.path.join(self.dir, n + '.r' + self.rev) + upfilename = os.path.join(self.dir, n + '.new') try: os.unlink(myfilename) - # the working copy may be updated, so the .r* ending may be obsolete... - # then we don't care os.unlink(upfilename) if self.islinkrepair() or self.ispulled(): os.unlink(os.path.join(self.dir, n + '.old')) @@ -1683,7 +1678,7 @@ filename = os.path.join(self.dir, n) storefilename = os.path.join(self.storedir, n) myfilename = os.path.join(self.dir, n + '.mine') - upfilename = os.path.join(self.dir, n + '.r' + self.rev) + upfilename = os.path.join(self.dir, n + '.new') origfile_tmp = os.path.join(self.storedir, '_in_update', '%s.copy' % n) origfile = os.path.join(self.storedir, '_in_update', n) shutil.copyfile(filename, origfile_tmp) @@ -2167,8 +2162,11 @@ url = ET.SubElement(root, 'url') url.text = self.url - u = makeurl(self.apiurl, ['source', self.prjname, self.name, '_meta']) - mf = metafile(u, ET.tostring(root, encoding=ET_ENCODING)) + delegate = lambda force=False: make_meta_url('pkg', + (self.prjname, self.name), + self.apiurl, force=force) + url_factory = metafile._URLFactory(delegate) + mf = metafile(url_factory, ET.tostring(root, encoding=ET_ENCODING)) if not force: print('*' * 36, 'old', '*' * 36) @@ -3404,6 +3402,9 @@ req.add_header('Content-Length', str(content_length)) try: return urlopen(req) + except URLError as e: + e._osc_host_port = req.host + raise finally: if hasattr(conf.cookiejar, 'save'): conf.cookiejar.save(ignore_discard=True) @@ -3679,10 +3680,29 @@ class metafile: """metafile that can be manipulated and is stored back after manipulation.""" + + class _URLFactory: + # private class which might go away again... + def __init__(self, delegate, force_supported=True): + self._delegate = delegate + self._force_supported = force_supported + + def is_force_supported(self): + return self._force_supported + + def __call__(self, **kwargs): + return self._delegate(**kwargs) + def __init__(self, url, input, change_is_required=False, file_ext='.xml'): import tempfile - self.url = url + if isinstance(url, self._URLFactory): + self._url_factory = url + else: + delegate = lambda **kwargs: url + # force is not supported for a raw url + self._url_factory = self._URLFactory(delegate, False) + self.url = self._url_factory() self.change_is_required = change_is_required (fd, self.filename) = tempfile.mkstemp(prefix = 'osc_metafile.', suffix = file_ext) @@ -3716,8 +3736,11 @@ def edit(self): try: + try_force = False while True: - run_editor(self.filename) + if not try_force: + run_editor(self.filename) + try_force = False try: self.sync() break @@ -3733,8 +3756,18 @@ summary = root.find('summary') if summary is not None: print(summary.text, file=sys.stderr) - ri = raw_input('Try again? ([y/N]): ') - if ri not in ['y', 'Y']: + if self._url_factory.is_force_supported(): + prompt = 'Try again? ([y/N/f]): ' + else: + prompt = 'Try again? ([y/N): ' + + ri = raw_input(prompt) + if ri in ('y', 'Y'): + self.url = self._url_factory() + elif ri in ('f', 'F') and self._url_factory.is_force_supported(): + self.url = self._url_factory(force='1') + try_force = True + else: break finally: self.discard() @@ -3871,8 +3904,12 @@ print(' osc meta pkg %s %s -e' % (unquote(project), package)) return - url = make_meta_url(metatype, path_args, apiurl, force, remove_linking_repositories, msg) - f = metafile(url, data, change_is_required, metatypes[metatype]['file_ext']) + delegate = lambda force=force: make_meta_url(metatype, path_args, apiurl, + force, + remove_linking_repositories, + msg) + url_factory = metafile._URLFactory(delegate) + f = metafile(url_factory, data, change_is_required, metatypes[metatype]['file_ext']) if edit: f.edit() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/osc-0.174.0/osc/fetch.py new/osc-0.175.0/osc/fetch.py --- old/osc-0.174.0/osc/fetch.py 2021-07-21 10:43:53.000000000 +0200 +++ new/osc-0.175.0/osc/fetch.py 2021-12-02 08:48:19.000000000 +0100 @@ -36,6 +36,7 @@ self.progress_obj = create_text_meter(use_pb_fallback=False) self.cachedir = cachedir + # generic download URL lists self.urllist = urllist self.modules = modules self.http_debug = http_debug @@ -193,20 +194,31 @@ print(e, file=sys.stderr) sys.exit(1) + def _build_urllist(self, buildinfo, pac): + urllist = self.urllist + key = '%s/%s' % (pac.project, pac.repository) + project_repo_url = buildinfo.urls.get(key) + if project_repo_url is not None: + urllist = [project_repo_url] + return urllist + def run(self, buildinfo): cached = 0 all = len(buildinfo.deps) for i in buildinfo.deps: - i.makeurls(self.cachedir, self.urllist) + urllist = self._build_urllist(buildinfo, i) + i.makeurls(self.cachedir, urllist) # find container extension by looking in the cache if i.name.startswith('container:') and i.fullfilename.endswith('.tar.xz'): for ext in ['.tar.xz', '.tar.gz', '.tar']: if os.path.exists(i.fullfilename[:-7] + ext): i.canonname = i.canonname[:-7] + ext - i.makeurls(self.cachedir, self.urllist) + i.makeurls(self.cachedir, urllist) if os.path.exists(i.fullfilename): cached += 1 + if not i.name.startswith('container:') and i.pacsuffix != 'rpm': + continue if i.hdrmd5: from .util import packagequery if i.name.startswith('container:'): @@ -216,6 +228,7 @@ if not hdrmd5 or hdrmd5 != i.hdrmd5: os.unlink(i.fullfilename) cached -= 1 + miss = 0 needed = all - cached if all: @@ -223,7 +236,6 @@ print("%.1f%% cache miss. %d/%d dependencies cached.\n" % (miss, cached, all)) done = 1 for i in buildinfo.deps: - i.makeurls(self.cachedir, self.urllist) if not os.path.exists(i.fullfilename): if self.offline: raise oscerr.OscIOError(None, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/osc-0.174.0/osc/util/debquery.py new/osc-0.175.0/osc/util/debquery.py --- old/osc-0.174.0/osc/util/debquery.py 2021-07-21 10:43:53.000000000 +0200 +++ new/osc-0.175.0/osc/util/debquery.py 2021-12-02 08:48:19.000000000 +0100 @@ -16,6 +16,13 @@ except ImportError: HAVE_LZMA = False +HAVE_ZSTD = True +try: + # Note: zstd is not supporting stream compression types + import zstandard +except ImportError: + HAVE_ZSTD = False + if (not hasattr(itertools, 'zip_longest') and hasattr(itertools, 'izip_longest')): @@ -52,13 +59,23 @@ tar = tarfile.open(name='control.tar.gz', fileobj=control) else: control = arfile.get_file(b'control.tar.xz') + if control: + 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=BytesIO(decompressed)) + else: + control = arfile.get_file(b'control.tar.zst') + if control: + if not HAVE_ZSTD: + raise DebError(self.__path, 'can\'t open control.tar.zst without python-zstandard') + with zstandard.ZstdDecompressor().stream_reader(BytesIO(control.read())) as reader: + decompressed = reader.read() + tar = tarfile.open(name="control.tar.zst", + fileobj=BytesIO(decompressed)) 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=BytesIO(decompressed)) try: name = './control' # workaround for python2.4's tarfile module diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/osc-0.174.0/osc/util/packagequery.py new/osc-0.175.0/osc/util/packagequery.py --- old/osc-0.174.0/osc/util/packagequery.py 2021-07-21 10:43:53.000000000 +0200 +++ new/osc-0.175.0/osc/util/packagequery.py 2021-12-02 08:48:19.000000000 +0100 @@ -87,7 +87,7 @@ f = open(filename, 'rb') magic = f.read(7) f.seek(0) - if magic[:4] == '\xed\xab\xee\xdb': + if magic[:4] == b'\xed\xab\xee\xdb': from . import rpmquery f.close() return rpmquery.RpmQuery.queryhdrmd5(filename) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/osc-0.174.0/tests/common.py new/osc-0.175.0/tests/common.py --- old/osc-0.174.0/tests/common.py 2021-07-21 10:43:53.000000000 +0200 +++ new/osc-0.175.0/tests/common.py 2021-12-02 08:48:19.000000000 +0100 @@ -182,6 +182,7 @@ class OscTestCase(unittest.TestCase): def setUp(self, copytree=True): + os.chdir(os.path.dirname(__file__)) oscrc = os.path.join(self._get_fixtures_dir(), 'oscrc') osc.core.conf.get_config(override_conffile=oscrc, override_no_keyring=True, override_no_gnome_keyring=True) ++++++ osc.dsc ++++++ --- /var/tmp/diff_new_pack.3D82Eb/_old 2021-12-02 22:31:15.774440914 +0100 +++ /var/tmp/diff_new_pack.3D82Eb/_new 2021-12-02 22:31:15.774440914 +0100 @@ -1,6 +1,6 @@ Format: 1.0 Source: osc -Version: 0.174.0-0 +Version: 0.175.0-0 Binary: osc Maintainer: Adrian Schroeter <adr...@suse.de> Architecture: any