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-05-19 17:49:22
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/osc (Old)
 and      /work/SRC/openSUSE:Factory/.osc.new.2988 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "osc"

Wed May 19 17:49:22 2021 rev:155 rq:894195 version:0.173.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/osc/osc.changes  2021-05-11 23:04:25.780883979 
+0200
+++ /work/SRC/openSUSE:Factory/.osc.new.2988/osc.changes        2021-05-19 
17:49:34.357486202 +0200
@@ -1,0 +2,18 @@
+Tue May 18 20:58:00 UTC 2021 - Marcus H??we <suse-...@gmx.de>
+
+- 0.173.0:
+  * add showlinked command to show all references of packages linking to a 
given one
+  * add build --shell-after-build flag. It can also be set via .oscrc.
+  * add build --stage flag. Useful for example for fixing file lists and just
+    running the install section to see the result of it (use --stage=i=).
+    Check the help for more details.
+  * allow to run build script as non-root, by setting su-wrapper empty
+    => osc is not guessing anymore if user builds are wanted
+  * add support for cross arch local build using a sysroot
+  * support slash notation in "osc creq -a <action type> args"
+  * add "--force" option to the "osc add" command (can be used to override
+    the exclude_glob config option)
+  * support the commit of arbitrary sized files
+  * add support for sccache
+
+-------------------------------------------------------------------

Old:
----
  osc-0.172.0.tar.gz

New:
----
  osc-0.173.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ osc.spec ++++++
--- /var/tmp/diff_new_pack.V8Iju2/_old  2021-05-19 17:49:34.957483686 +0200
+++ /var/tmp/diff_new_pack.V8Iju2/_new  2021-05-19 17:49:34.957483686 +0200
@@ -27,7 +27,7 @@
 %define use_python python
 %endif
 
-%define version_unconverted 0.172.0
+%define version_unconverted 0.173.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.172.0
+Version:        0.173.0
 Release:        0
 Summary:        Open Build Service Commander
 License:        GPL-2.0-or-later

++++++ PKGBUILD ++++++
--- /var/tmp/diff_new_pack.V8Iju2/_old  2021-05-19 17:49:34.985483570 +0200
+++ /var/tmp/diff_new_pack.V8Iju2/_new  2021-05-19 17:49:34.985483570 +0200
@@ -1,5 +1,5 @@
 pkgname=osc
-pkgver=0.172.0
+pkgver=0.173.0
 pkgrel=0
 pkgdesc="Open Build Service client"
 arch=('x86_64')

++++++ _service ++++++
--- /var/tmp/diff_new_pack.V8Iju2/_old  2021-05-19 17:49:35.001483502 +0200
+++ /var/tmp/diff_new_pack.V8Iju2/_new  2021-05-19 17:49:35.001483502 +0200
@@ -1,7 +1,7 @@
 <services>
   <service name="tar_scm" mode="disabled">
-    <param name="version">0.172.0</param>
-    <param name="revision">0.172.0</param>
+    <param name="version">0.173.0</param>
+    <param name="revision">0.173.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.V8Iju2/_old  2021-05-19 17:49:35.037483351 +0200
+++ /var/tmp/diff_new_pack.V8Iju2/_new  2021-05-19 17:49:35.037483351 +0200
@@ -1,3 +1,21 @@
+osc (0.173.0-0) unstable; urgency=low
+  - Update to 0.173.0:
+    - add showlinked command to show all references of packages linking to a 
given one
+    - add build --shell-after-build flag. It can also be set via .oscrc.
+    - add build --stage flag. Useful for example for fixing file lists and just
+      running the install section to see the result of it (use --stage=i=).
+      Check the help for more details.
+    - allow to run build script as non-root, by setting su-wrapper empty
+      => osc is not guessing anymore if user builds are wanted
+    - add support for cross arch local build using a sysroot
+    - support slash notation in "osc creq -a <action type> args"
+    - add "--force" option to the "osc add" command (can be used to override
+      the exclude_glob config option)
+    - support the commit of arbitrary sized files
+    - add support for sccache
+
+ -- Marcus Huewe <suse-...@gmx.de>  Tue, 18 May 2021 22:52:25 +0200
+
 osc (0.172.0-0) unstable; urgency=low
   - Update to 0.172.0:
     - support --lastsucceeded/--last-succeeded in "osc buildlog", "osc

++++++ osc-0.172.0.tar.gz -> osc-0.173.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/osc-0.172.0/.gitignore new/osc-0.173.0/.gitignore
--- old/osc-0.172.0/.gitignore  1970-01-01 01:00:00.000000000 +0100
+++ new/osc-0.173.0/.gitignore  2021-05-18 22:36:09.000000000 +0200
@@ -0,0 +1,5 @@
+*.pyc
+*.swp
+tags
+build
+*junit-xml-results
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/osc-0.172.0/NEWS new/osc-0.173.0/NEWS
--- old/osc-0.172.0/NEWS        2021-01-27 13:21:32.000000000 +0100
+++ new/osc-0.173.0/NEWS        2021-05-18 22:36:09.000000000 +0200
@@ -1,3 +1,18 @@
+0.173.0
+  - add showlinked command to show all references of packages linking to a 
given one
+  - add build --shell-after-build flag. It can also be set via .oscrc.
+  - add build --stage flag. Useful for example for fixing file lists and just
+    running the install section to see the result of it (use --stage=i=).
+    Check the help for more details.
+  - allow to run build script as non-root, by setting su-wrapper empty
+    => osc is not guessing anymore if user builds are wanted
+  - add support for cross arch local build using a sysroot
+  - support slash notation in "osc creq -a <action type> args"
+  - add "--force" option to the "osc add" command (can be used to override
+    the exclude_glob config option)
+  - support the commit of arbitrary sized files
+  - add support for sccache
+
 0.172.0
   - support --lastsucceeded/--last-succeeded in "osc buildlog", "osc
     remotebuildlog" + friends (perform the corresponding operation on
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/osc-0.172.0/osc/.gitignore 
new/osc-0.173.0/osc/.gitignore
--- old/osc-0.172.0/osc/.gitignore      1970-01-01 01:00:00.000000000 +0100
+++ new/osc-0.173.0/osc/.gitignore      2021-05-18 22:36:09.000000000 +0200
@@ -0,0 +1,2 @@
+*.pyc
+*.swp
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/osc-0.172.0/osc/build.py new/osc-0.173.0/osc/build.py
--- old/osc-0.172.0/osc/build.py        2021-01-27 13:21:32.000000000 +0100
+++ new/osc-0.173.0/osc/build.py        2021-05-18 22:36:09.000000000 +0200
@@ -126,11 +126,20 @@
             # snapcraft also supports rpm
             self.pacsuffix = 'deb'
 
+        # The architectures become a bit mad ...
+        # buildarch: The architecture of the build result      (host arch in 
GNU definition)
+        # hostarch:  The architecture of the build environment (build arch in 
GNU defintion)
+        # crossarch: Same as hostarch, but indicating that a sysroot with an 
incompatible architecture exists
         self.buildarch = root.find('arch').text
+        if root.find('crossarch') != None:
+            self.crossarch = root.find('crossarch').text
+        else:
+            self.crossarch = None
         if root.find('hostarch') != None:
             self.hostarch = root.find('hostarch').text
         else:
             self.hostarch = None
+
         if root.find('release') != None:
             self.release = root.find('release').text
         else:
@@ -152,8 +161,15 @@
         for node in root.findall('module'):
             self.modules.append(node.text)
         for node in root.findall('bdep'):
-            p = Pac(node, self.buildarch, self.pacsuffix,
-                    apiurl, localpkgs)
+            if node.find('sysroot'):
+                p = Pac(node, self.buildarch, self.pacsuffix,
+                        apiurl, localpkgs)
+            else:
+                pac_arch = self.crossarch
+                if pac_arch == None:
+                        pac_arch = self.buildarch
+                p = Pac(node, pac_arch, self.pacsuffix,
+                        apiurl, localpkgs)
             if p.project:
                 self.projects[p.project] = 1
             self.deps.append(p)
@@ -195,7 +211,7 @@
         self.mp = {}
         for i in ['binary', 'package',
                   'epoch', 'version', 'release', 'hdrmd5',
-                  'project', 'repository',
+                  'project', 'repository', 'sysroot',
                   'preinstall', 'vminstall', 'runscripts',
                   'noinstall', 'installonly', 'notmeta',
                  ]:
@@ -385,7 +401,7 @@
                                    
stdout=subprocess.PIPE).stdout.read().strip()
         s_built = ''
     elif buildtype == 'simpleimage':
-        b_built = subprocess.Popen(['find', os.path.join(pacdir, 
'SIMPLEIMAGE'),
+        b_built = subprocess.Popen(['find', os.path.join(pacdir, 'OTHER'),
                                     '-type', 'f'],
                                    
stdout=subprocess.PIPE).stdout.read().strip()
         s_built = ''
@@ -547,17 +563,28 @@
                             % {'repo': repo, 'arch': arch, 'project': prj, 
'package': pac, 'apihost': apihost}
     return buildroot
 
+def build_as_user():
+    if os.environ.get('OSC_SU_WRAPPER', config['su-wrapper']).split():
+        return False
+    return True
+
+def su_wrapper(cmd):
+    sucmd = os.environ.get('OSC_SU_WRAPPER', config['su-wrapper']).split()
+    if sucmd:
+        if sucmd[0] == 'su':
+            if sucmd[-1] == '-c':
+                sucmd.pop()
+            cmd = sucmd + ['-s', cmd[0], 'root', '--'] + cmd[1:]
+        else:
+            cmd = sucmd + cmd
+    return cmd
+
 def run_build(opts, *args):
     cmd = [config['build-cmd']]
     cmd += args
 
-    sucmd = os.environ.get('OSC_SU_WRAPPER', config['su-wrapper']).split()
-    if sucmd[0] == 'su':
-        if sucmd[-1] == '-c':
-            sucmd.pop()
-        cmd = sucmd + ['-s', cmd[0], 'root', '--'] + cmd[1:]
-    else:
-        cmd = sucmd + cmd
+    cmd = su_wrapper(cmd)
+
     if not opts.userootforbuild:
         cmd.append('--norootforbuild')
     return run_external(cmd[0], *cmd[1:])
@@ -571,6 +598,7 @@
     build_root = None
     cache_dir  = None
     build_uid = ''
+    build_shell_after_fail = config['build-shell-after-fail']
     vm_memory = config['build-memory']
     vm_disk_size = config['build-vmdisk-rootsize']
     vm_type = config['build-type']
@@ -637,6 +665,16 @@
     if opts.pkg_ccache:
         buildargs.append('--pkg-ccache=%s' % opts.pkg_ccache)
         xp.append('ccache')
+    if opts.sccache_uri or config['sccache_uri'] or opts.sccache or 
config['sccache']:
+        if opts.pkg_ccache or opts.ccache or config['ccache']:
+            raise oscerr.WrongArgs('Error: sccache and ccache can not be 
enabled at the same time')
+        if opts.sccache_uri:
+            buildargs.append('--sccache-uri=%s' % opts.sccache_uri)
+        elif config['sccache_uri']:
+            buildargs.append('--sccache-uri=%s' % config['sccache_uri'])
+        else:
+            buildargs.append('--sccache')
+        xp.append('sccache')
     if opts.linksources:
         buildargs.append('--linksources')
     if opts.baselibs:
@@ -665,6 +703,8 @@
         else:
             print('Error: build-uid arg must be 2 colon separated numerics: 
"uid:gid" or "caller"', file=sys.stderr)
             return 1
+    if opts.shell_after_fail:
+        build_shell_after_fail = opts.shell_after_fail
     if opts.vm_memory:
         vm_memory = opts.vm_memory
     if opts.vm_disk_size:
@@ -740,6 +780,9 @@
     if opts.shell:
         buildargs.append("--shell")
 
+    if build_shell_after_fail:
+        buildargs.append("--shell-after-fail")
+
     if opts.shell_cmd:
         buildargs.append("--shell-cmd")
         buildargs.append(opts.shell_cmd)
@@ -930,7 +973,12 @@
         bi.release = opts.release
 
     if bi.release:
-        buildargs.append('--release=%s' % bi.release)
+        buildargs.append('--release')
+        buildargs.append(bi.release)
+
+    if opts.stage:
+        buildargs.append('--stage')
+        buildargs.append(opts.stage)
 
     if opts.build_opt:
         buildargs += opts.build_opt
@@ -995,6 +1043,9 @@
     imagefile = ''
     imagesource = ''
     imagebins = []
+    if build_as_user():
+       # preinstallimage extraction will fail
+       bi.preinstallimage = None
     if (not config['no_preinstallimage'] and not opts.nopreinstallimage and
         bi.preinstallimage and
         not opts.noinit and
@@ -1243,7 +1294,13 @@
     if build_type == 'kiwi' or build_type == 'docker' or build_type == 
'podman'or build_type == 'fissile':
         rpmlist = [ '%s %s\n' % (i.name, i.fullfilename) for i in bi.deps if 
not i.noinstall ]
     else:
-        rpmlist = [ '%s %s\n' % (i.name, i.fullfilename) for i in bi.deps ]
+        rpmlist = []
+        for dep in bi.deps:
+            if dep.sysroot:
+                # packages installed in sysroot subdirectory need to get a 
prefix for init_buildsystem
+                rpmlist.append('sysroot: %s %s\n' % (dep.name, 
dep.fullfilename))
+            else:
+                rpmlist.append('%s %s\n' % (dep.name, dep.fullfilename))
     for i in imagebins:
         rpmlist.append('%s preinstallimage\n' % i)
     rpmlist += [ '%s %s\n' % (i[0], i[1]) for i in rpmlist_prefers ]
@@ -1279,7 +1336,6 @@
         # before
         my_build_device = build_root + '/img'
 
-    need_root = True
     if vm_type:
         if config['build-swap']:
             my_build_swap = config['build-swap'] % subst
@@ -1296,9 +1352,6 @@
             vm_options += [ '--vm-swap=' + my_build_swap ]
             vm_options += [ '--logfile=%s/.build.log' % build_root ]
             if vm_type == 'kvm':
-                if os.access(build_root, os.W_OK) and os.access('/dev/kvm', 
os.W_OK):
-                    # so let's hope there's also an fstab entry
-                    need_root = False
                 if config['build-kernel']:
                     vm_options += [ '--vm-kernel=' + config['build-kernel'] ]
                 if config['build-initrd']:
@@ -1328,14 +1381,7 @@
     cmd += specialcmdopts + vm_options + buildargs
     cmd += [ build_descr ]
 
-    if need_root:
-        sucmd = config['su-wrapper'].split()
-        if sucmd[0] == 'su':
-            if sucmd[-1] == '-c':
-                sucmd.pop()
-            cmd = sucmd + ['-s', cmd[0], 'root', '--' ] + cmd[1:]
-        else:
-            cmd = sucmd + cmd
+    cmd = su_wrapper(cmd)
 
     # change personality, if needed
     if hostarch != bi.buildarch and bi.buildarch in change_personality:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/osc-0.172.0/osc/commandline.py 
new/osc-0.173.0/osc/commandline.py
--- old/osc-0.172.0/osc/commandline.py  2021-01-27 13:21:32.000000000 +0100
+++ new/osc-0.173.0/osc/commandline.py  2021-05-18 22:36:09.000000000 +0200
@@ -739,12 +739,39 @@
         set_devel_project(apiurl, project, package, devprj, devpkg)
 
 
+    def do_showlinked(self, subcmd, opts, *args):
+        """${cmd_name}: Show all packages linking to a given one
+
+        Examples:
+            osc showlinked [PROJECT PACKAGE]
+        ${cmd_option_list}
+        """
+
+        args = slash_split(args)
+        apiurl = self.get_api_url()
+        localdir = os.getcwd()
+        project = package = None
+        if len(args) == 2:
+            project = args[0]
+            package = args[1]
+        elif is_package_dir(localdir):
+            project = store_read_project(localdir)
+            package = store_read_package(localdir)
+        else:
+            raise oscerr.WrongArgs('Either specify project and package or call 
it from a package working copy')
+
+        url = makeurl(apiurl, ['source', project, package], query={'cmd': 
'showlinked'})
+        f = http_POST(url)
+        root = ET.parse(f).getroot()
+        for node in root.findall('package'):
+            print(node.get('project') + " " + node.get('name'))
+
     @cmdln.option('-c', '--create', action='store_true',
                         help='Create a new token')
     @cmdln.option('-d', '--delete', metavar='TOKENID',
                         help='Delete a token')
     @cmdln.option('-o', '--operation', metavar='OPERATION',
-                        help='Default is "runservice", but "release" or 
"rebuild" can also be used')
+                        help='Default is "runservice", but "branch", "release" 
or "rebuild" can also be used')
     @cmdln.option('-t', '--trigger', metavar='TOKENSTRING',
                         help='Trigger the action of a token')
     def do_token(self, subcmd, opts, *args):
@@ -1506,7 +1533,7 @@
 
         parser.values.actions.append(value[0])
         del value[0]
-        parser.values.actiondata.append(value)
+        parser.values.actiondata.append(slash_split(value))
 
     def _submit_request(self, args, opts, options_block):
         actionxml = ""
@@ -4732,6 +4759,8 @@
             print('\n'.join(lines))
 
 
+    @cmdln.option('-f', '--force', action='store_true',
+                  help='add files even if they are excluded by the 
exclude_glob config option')
     def do_add(self, subcmd, opts, *args):
         """${cmd_name}: Mark files to be added upon the next commit
 
@@ -4757,7 +4786,7 @@
             elif arg.startswith('http://') or arg.startswith('https://') or 
arg.startswith('ftp://'):
                 addDownloadUrlService(arg)
             else:
-                addFiles([arg])
+                addFiles([arg], force=opts.force)
 
 
     def do_mkpac(self, subcmd, opts, *args):
@@ -6434,6 +6463,10 @@
                   help='use ccache to speed up rebuilds')
     @cmdln.option('--pkg-ccache', metavar='/path/to/_ccache.tar',
                   help='path to an existing uncompressed archive ccache. Using 
this option implies --ccache')
+    @cmdln.option('--sccache', action='store_true',
+                  help='use sccache to speed up rebuilds. Conflicts with 
--cache')
+    @cmdln.option('--sccache-uri', metavar='redis://127.0.0.1:6389',
+                  help='Optional remote URI for sccache storage. Implies 
--sccache.')
     @cmdln.option('--with', metavar='X', dest='_with', action='append',
                   help='enable feature X for build')
     @cmdln.option('--without', metavar='X', action='append',
@@ -6451,6 +6484,11 @@
                   'unprivileged "abuild" user or use "caller" to use the 
current user uid:gid')
     @cmdln.option('--local-package', action='store_true',
                   help='build a package which does not exist on the server')
+    @cmdln.option('--stage', metavar='STAGE',
+                  help='runs a specific stage, default is "a" for all. Append 
a trailing "="'
+                       'to only run the specified stage. Append a trailing "+" 
to run'
+                       'the specified stage and all stages coming after it. 
With no'
+                       'suffix, stages up to and included the specified stage 
are run.')
     @cmdln.option('--linksources', action='store_true',
                   help='use hard links instead of a deep copied source')
     @cmdln.option('--vm-memory', metavar='MEMORY',
@@ -6485,6 +6523,8 @@
                   help=SUPPRESS_HELP)
     @cmdln.option('--shell', action='store_true',
                   help=SUPPRESS_HELP)
+    @cmdln.option('--shell-after-fail', action='store_true',
+                  help="run a shell if the build tool fails")
     @cmdln.option('--shell-cmd', metavar='COMMAND',
                   help='run specified command instead of bash')
     @cmdln.option('-f', '--force', action='store_true',
@@ -6544,6 +6584,7 @@
 
             --noinit             # for faster run
             --shell-cmd=COMMAND
+            --shell-after-fail
             --extra-pkgs=PACKAGE # install additional packages
 
         To clean up the build environment run
@@ -6999,9 +7040,9 @@
             osc service wait [PROJECT PACKAGE]
 
             COMMAND can be:
-            run         r  run defined services with modes "trylocal", 
"localonly", or no mode set locally, may take an optional parameter to run only 
a
-                           specified source service. In case parameters exist 
for this one in _service file
-                           they are used.
+            run         r  run defined services with modes "trylocal", 
"localonly", or no mode set locally,
+                           may take an optional parameter to run only a 
specified source service. In case
+                           parameters exist for this one in _service file they 
are used.
             runall      ra run all services independent of the used mode
             manualrun   mr run all services with mode "manual", may take an 
optional parameter to run only a
                            specified source service
@@ -8976,21 +9017,30 @@
             url = makeurl(apiurl, ['source', prj, "_pubkey"])
             f = http_DELETE(url)
         else:
-            while True:
-                try:
-                    url = makeurl(apiurl, ['source', prj, '_pubkey'])
-                    if opts.sslcert:
-                        url = makeurl(apiurl, ['source', prj, '_project', 
'_sslcert'], 'meta=1')
-                    f = http_GET(url)
-                    break
-                except HTTPError as e:
-                    l = prj.rsplit(':', 1)
-                    # try key from parent project
-                    if not opts.notraverse and len(l) > 1 and l[0] and l[1] 
and e.code == 404:
-                        print('%s has no key, trying %s' % (prj, l[0]))
-                        prj = l[0]
-                    else:
-                        raise
+            try:
+                # use current api, supporting fallback to higher project and 
server side scripts
+                query = {}
+                if opts.sslcert:
+                    query['withsslcert'] = 1
+                url = makeurl(apiurl, ['source', prj, '_keyinfo'], query)
+                f = http_GET(url)
+            except HTTPError as e:
+                # old way to do it
+                while True:
+                    try:
+                        url = makeurl(apiurl, ['source', prj, '_pubkey'])
+                        if opts.sslcert:
+                            url = makeurl(apiurl, ['source', prj, '_project', 
'_sslcert'], 'meta=1')
+                        f = http_GET(url)
+                        break
+                    except HTTPError as e:
+                        l = prj.rsplit(':', 1)
+                        # try key from parent project
+                        if not opts.notraverse and len(l) > 1 and l[0] and 
l[1] and e.code == 404:
+                            print('%s has no key, trying %s' % (prj, l[0]))
+                            prj = l[0]
+                        else:
+                            raise
 
         while True:
             buf = f.read(16384)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/osc-0.172.0/osc/conf.py new/osc-0.173.0/osc/conf.py
--- old/osc-0.172.0/osc/conf.py 2021-01-27 13:21:32.000000000 +0100
+++ new/osc-0.173.0/osc/conf.py 2021-05-18 22:36:09.000000000 +0200
@@ -108,6 +108,7 @@
             'build-uid': '',                    # use the default provided by 
build
             'build-device': '',                 # required for VM builds
             'build-memory': '',                 # required for VM builds
+            'build-shell-after-fail': '0',      # optional for VM builds
             'build-swap': '',                   # optional for VM builds
             'build-vmdisk-rootsize': '',        # optional for VM builds
             'build-vmdisk-swapsize': '',        # optional for VM builds
@@ -120,6 +121,8 @@
             'builtin_signature_check': '1',     # by default use builtin check 
for verify pkgs
             'icecream': '0',
             'ccache': '0',
+            'sccache': '0',
+            'sccache_uri': '',
 
             'buildlog_strip_time': '0',  # strips the build time from the 
build log
 
@@ -201,7 +204,7 @@
     'checkout_no_colon', 'checkout_rooted', 'check_for_request_on_action', 
'linkcontrol', 'show_download_progress', 'request_show_interactive',
     'request_show_source_buildstatus', 'review_inherit_group', 'use_keyring', 
'gnome_keyring', 'no_verify', 'builtin_signature_check',
     'http_full_debug', 'include_request_from_project', 'local_service_run', 
'buildlog_strip_time', 'no_preinstallimage',
-    'status_mtime_heuristic', 'print_web_links', 'ccache']
+    'status_mtime_heuristic', 'print_web_links', 'ccache', 'sccache', 
'build-shell-after-fail']
 integer_opts = ['build-jobs']
 
 api_host_options = ['user', 'pass', 'passx', 'aliases', 'http_headers', 
'realname', 'email', 'sslcertck', 'cafile', 'capath', 'trusted_prj']
@@ -218,6 +221,8 @@
 
 # Wrapper to call build as root (sudo, su -, ...)
 #su-wrapper = %(su-wrapper)s
+# set it empty to run build script as user (works only with KVM atm):
+#su-wrapper =
 
 # rootdir to setup the chroot environment
 # can contain %%(repo)s, %%(arch)s, %%(project)s, %%(package)s and 
%%(apihost)s (apihost is the hostname
@@ -238,6 +243,9 @@
 #     lxc  -  lxc build
 #build-type =
 
+# Execute always a shell prompt on build failure inside of the build 
environment
+#build-shell-after-fail = 1
+
 # 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
@@ -281,6 +289,12 @@
 # Enable ccache in build roots.
 # ccache = 1
 
+# Enable sccache in build roots. Conflicts with ccache.
+# sccache = 1
+
+# Optional remote URI for sccache storage.
+# sccache_uri = redis://127.0.0.1:6379
+
 # 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
@@ -472,6 +486,25 @@
 def _build_opener(apiurl):
     from osc.core import __version__
     global config
+
+    class OscHTTPBasicAuthHandler(HTTPBasicAuthHandler, object):
+        # python2: inherit from object in order to make it a new-style class
+        # (HTTPBasicAuthHandler is not a new-style class)
+        def _rewind_request(self, req):
+            if hasattr(req.data, 'seek'):
+                # if the request is issued again (this time with an
+                # Authorization header), the file's offset has to be
+                # repositioned to the beginning of the file (otherwise,
+                # a 0-length body is sent which most likely does not match
+                # the Content-Length header (if present))
+                req.data.seek(0)
+
+        def retry_http_basic_auth(self, host, req, realm):
+            self._rewind_request(req)
+            return super(self.__class__, self).retry_http_basic_auth(host, req,
+                                                                     realm)
+
+
     if 'last_opener' not in _build_opener.__dict__:
         _build_opener.last_opener = (None, None)
     if apiurl == _build_opener.last_opener[0]:
@@ -485,10 +518,10 @@
         # read proxies from env
         proxyhandler = ProxyHandler()
 
+    authhandler_class = OscHTTPBasicAuthHandler
     # workaround for http://bugs.python.org/issue9639
-    authhandler_class = HTTPBasicAuthHandler
     if sys.version_info >= (2, 6, 6) and sys.version_info < (2, 7, 9):
-        class OscHTTPBasicAuthHandler(HTTPBasicAuthHandler):
+        class OscHTTPBasicAuthHandlerCompat(OscHTTPBasicAuthHandler):
             # The following two functions were backported from upstream 2.7.
             def http_error_auth_reqed(self, authreq, host, req, headers):
                 authreq = headers.get(authreq, None)
@@ -504,6 +537,7 @@
                             return self.retry_http_basic_auth(host, req, realm)
 
             def retry_http_basic_auth(self, host, req, realm):
+                self._rewind_request(req)
                 user, pw = self.passwd.find_user_password(realm, host)
                 if pw is not None:
                     raw = "%s:%s" % (user, pw)
@@ -515,7 +549,7 @@
                 else:
                     return None
 
-        authhandler_class = OscHTTPBasicAuthHandler
+        authhandler_class = OscHTTPBasicAuthHandlerCompat
 
     options = config['api_host_options'][apiurl]
     # with None as first argument, it will always use this username/password
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/osc-0.172.0/osc/core.py new/osc-0.173.0/osc/core.py
--- old/osc-0.172.0/osc/core.py 2021-01-27 13:21:32.000000000 +0100
+++ new/osc-0.173.0/osc/core.py 2021-05-18 22:36:09.000000000 +0200
@@ -5,7 +5,7 @@
 
 from __future__ import print_function
 
-__version__ = '0.172.0'
+__version__ = '0.173'
 
 # __store_version__ is to be incremented when the format of the working copy
 # "store" changes in an incompatible way. Please add any needed migration
@@ -3340,22 +3340,28 @@
 def http_request(method, url, headers={}, data=None, file=None):
     """wrapper around urllib2.urlopen for error handling,
     and to support additional (PUT, DELETE) methods"""
-    def create_memoryview(obj):
-        if sys.version_info < (2, 7, 99):
-            # obj might be a mmap and python 2.7's mmap does not
-            # behave like a bytearray (a bytearray in turn can be used
-            # to create the memoryview). For now simply return a buffer
-            return buffer(obj)
-        return memoryview(obj)
+    class DataContext:
+        """Wrap a data value (or None) in a context manager."""
 
-    filefd = None
+        def __init__(self, data):
+            self._data = data
+
+        def __enter__(self):
+            return self._data
+
+        def __exit__(self, exc_type, exc_val, exc_tb):
+            return None
+
+
+    if file is not None and data is not None:
+        raise RuntimeError('file and data are mutually exclusive')
 
     if conf.config['http_debug']:
         print('\n\n--', method, url, file=sys.stderr)
 
     if method == 'POST' and not file and not data:
         # adding data to an urllib2 request transforms it into a POST
-        data = ''
+        data = b''
 
     req = URLRequest(url)
     api_host_options = {}
@@ -3379,43 +3385,28 @@
             print(headers[i])
             req.add_header(i, headers[i])
 
-    if file and not data:
-        size = os.path.getsize(file)
-        if size < 1024*512:
-            data = open(file, 'rb').read()
-        else:
-            import mmap
-            filefd = open(file, 'rb')
-            try:
-                if sys.platform[:3] != 'win':
-                    data = mmap.mmap(filefd.fileno(), os.path.getsize(file), 
mmap.MAP_SHARED, mmap.PROT_READ)
-                else:
-                    data = mmap.mmap(filefd.fileno(), os.path.getsize(file))
-                data = create_memoryview(data)
-            except EnvironmentError as e:
-                if e.errno == 19:
-                    sys.exit('\n\n%s\nThe file \'%s\' could not be memory 
mapped. It is ' \
-                             '\non a filesystem which does not support this.' 
% (e, file))
-                elif hasattr(e, 'winerror') and e.winerror == 5:
-                    # falling back to the default io
-                    data = open(file, 'rb').read()
-                else:
-                    raise
-
     if conf.config['debug']: print(method, url, file=sys.stderr)
 
-    try:
+    content_length = None
+    if data is not None:
         if isinstance(data, str):
-            data = bytes(data, "utf-8")
-        fd = urlopen(req, data=data)
-
-    finally:
-        if hasattr(conf.cookiejar, 'save'):
-            conf.cookiejar.save(ignore_discard=True)
-
-    if filefd: filefd.close()
-
-    return fd
+            data = data.encode('utf-8')
+        content_length = len(data)
+    elif file is not None:
+        content_length = os.path.getsize(file)
+
+    with (open(file, 'rb') if file is not None else DataContext(data)) as d:
+        req.data = d
+        if content_length is not None:
+            # do this after setting req.data because the corresponding setter
+            # kills an existing Content-Length header (see urllib.Request class
+            # (python38))
+            req.add_header('Content-Length', str(content_length))
+        try:
+            return urlopen(req)
+        finally:
+            if hasattr(conf.cookiejar, 'save'):
+                conf.cookiejar.save(ignore_discard=True)
 
 
 def http_GET(*args, **kwargs):    return http_request('GET', *args, **kwargs)
@@ -7139,7 +7130,7 @@
     node.tail = None
     if node.text != None:
         node.text = node.text.replace(" ", "").replace("\n", "")
-    for child in node.getchildren():
+    for child in node:
         stripETxml(child)
 
 def addGitSource(url):
@@ -7208,7 +7199,7 @@
     f.close()
 
 
-def addFiles(filenames, prj_obj = None):
+def addFiles(filenames, prj_obj = None, force=False):
     for filename in filenames:
         if not os.path.exists(filename):
             raise oscerr.OscIOError(None, 'file \'%s\' does not exist' % 
filename)
@@ -7267,7 +7258,7 @@
         for filename in pac.todo:
             if filename in pac.skipped:
                 continue
-            if filename in pac.excluded:
+            if filename in pac.excluded and not force:
                 print('osc: warning: \'%s\' is excluded from a working copy' % 
filename, file=sys.stderr)
                 continue
             try:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/osc-0.172.0/osc-wrapper.py 
new/osc-0.173.0/osc-wrapper.py
--- old/osc-0.172.0/osc-wrapper.py      2021-01-27 13:21:32.000000000 +0100
+++ new/osc-0.173.0/osc-wrapper.py      2021-05-18 22:36:09.000000000 +0200
@@ -23,6 +23,7 @@
     pass
 
 # avoid buffering output on pipes (bnc#930137)
+# Note: the following only applies to python2
 # Basically, a "print('foo')" call is translated to a corresponding
 # fwrite call that writes to the stdout stream (cf. string_print
 # (Objects/stringobject.c) and builtin_print (Python/bltinmodule.c));
@@ -36,6 +37,9 @@
 if not os.isatty(sys.stdout.fileno()):
     sys.stdout = os.fdopen(sys.stdout.fileno(), sys.stdout.mode, 1)
 
+if not os.isatty(sys.stderr.fileno()):
+    sys.stderr = os.fdopen(sys.stderr.fileno(), sys.stderr.mode, 1)
+
 osccli = commandline.Osc()
 
 r = babysitter.run(osccli)

++++++ osc.dsc ++++++
--- /var/tmp/diff_new_pack.V8Iju2/_old  2021-05-19 17:49:35.329482126 +0200
+++ /var/tmp/diff_new_pack.V8Iju2/_new  2021-05-19 17:49:35.329482126 +0200
@@ -1,6 +1,6 @@
 Format: 1.0
 Source: osc
-Version: 0.172.0-0
+Version: 0.173.0-0
 Binary: osc
 Maintainer: Adrian Schroeter <adr...@suse.de>
 Architecture: any

Reply via email to