Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package opi for openSUSE:Factory checked in at 2025-02-16 22:49:31 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/opi (Old) and /work/SRC/openSUSE:Factory/.opi.new.8181 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "opi" Sun Feb 16 22:49:31 2025 rev:65 rq:1246255 version:5.7.0 Changes: -------- --- /work/SRC/openSUSE:Factory/opi/opi.changes 2025-02-03 21:46:44.594494070 +0100 +++ /work/SRC/openSUSE:Factory/.opi.new.8181/opi.changes 2025-02-16 22:53:49.445280831 +0100 @@ -1,0 +2,10 @@ +Sun Feb 16 16:13:58 UTC 2025 - Dominik Heidler <dheid...@suse.de> + +- Version 5.7.0 + * Add leap-only plugin to install zellij from github release + * Don't use subprocess.run user kwarg on 15.6 + * Fix tests: Use helloworld-opi-tests instead of zfs + * Perform search despite locked rpmdb + * Simplify backend code + +------------------------------------------------------------------- Old: ---- opi-5.6.0.tar.gz New: ---- opi-5.7.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ opi.spec ++++++ --- /var/tmp/diff_new_pack.EZlT7O/_old 2025-02-16 22:53:51.133351121 +0100 +++ /var/tmp/diff_new_pack.EZlT7O/_new 2025-02-16 22:53:51.149351788 +0100 @@ -20,7 +20,7 @@ %define pythons %{use_python} Name: opi -Version: 5.6.0 +Version: 5.7.0 Release: 0 Summary: OBS Package Installer (CLI) License: GPL-3.0-only @@ -36,6 +36,7 @@ BuildRequires: fdupes BuildRequires: python-rpm-macros +BuildRequires: distribution-release BuildRequires: help2man BuildRequires: python3 BuildRequires: python3-curses @@ -69,6 +70,7 @@ %setup -q %build +./bin/opi --version help2man -s8 -N ./bin/opi > opi.8 %pyproject_wheel ++++++ opi-5.6.0.tar.gz -> opi-5.7.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/opi-5.6.0/opi/__init__.py new/opi-5.7.0/opi/__init__.py --- old/opi-5.6.0/opi/__init__.py 2025-01-23 14:53:12.000000000 +0100 +++ new/opi-5.7.0/opi/__init__.py 2025-02-16 17:13:53.000000000 +0100 @@ -42,6 +42,9 @@ cpu_arch = None def get_cpu_arch(): + """ + returns e.g. x86_64, aarch64 + """ global cpu_arch if not cpu_arch: cpu_arch = os.uname().machine @@ -203,7 +206,16 @@ zc = tempfile.NamedTemporaryFile('w') zc.file.write(f'[main]\nshowAlias = true\n') zc.file.flush() - sr = subprocess.check_output(['zypper', '-ntc', zc.name, '--no-refresh', 'se', '-sx', '-tpackage', package], env={'LANG': 'c'}).decode() + os.chmod(zc.name, 0o644) + # ensure to run as non-root as this allows the cmd to run even if rpmdb is locked + user = None if os.getuid() else 'nobody' + cmd = ['zypper', '-ntc', zc.name, '--no-refresh', 'se', '-sx', '-tpackage', package] + env = {'LANG': 'c'} + try: + sr = subprocess.check_output(cmd, env=env, user=user).decode() + except TypeError: + # no user arg on old python versions + sr = subprocess.check_output(cmd, env=env).decode() for line in re.split(r'-\+-+\n', sr, re.MULTILINE)[1].strip().split('\n'): version, arch, repo_alias = [s.strip() for s in line.split('|')[3:]] version, release = version.split('-') @@ -215,6 +227,9 @@ except subprocess.CalledProcessError as e: if e.returncode != 104: # 104 ZYPPER_EXIT_INF_CAP_NOT_FOUND is returned if there are no results + if e.returncode == 7: + # 7 ZYPPER_EXIT_ZYPP_LOCKED - error is already printed by zypper + sys.exit(1) raise # TODO: don't exit program, use exception that will be handled in repo_query except block repos_by_alias = {repo.alias: repo for repo in get_repos()} @@ -351,14 +366,6 @@ args.append(action) if from_repo: args.extend(['--from', from_repo]) - elif get_backend() == BackendConstants.dnf: - args = ['sudo', 'dnf'] - if global_state.arg_non_interactive: - args.append('-y') - args.append(action) - if from_repo: - args.extend(['--repo', from_repo]) - if get_backend() == BackendConstants.zypp: if allow_downgrade: args.append('--allow-downgrade') if allow_arch_change: @@ -367,12 +374,22 @@ args.append('--allow-name-change') if allow_vendor_change: args.append('--allow-vendor-change') + if action == 'in': + args.append('--oldpackage') elif get_backend() == BackendConstants.dnf: + args = ['sudo', 'dnf'] + if global_state.arg_non_interactive: + args.append('-y') + args.append(action) + if from_repo: + args.extend(['--repo', from_repo]) # allow_downgrade and allow_name_change are default in DNF if allow_vendor_change: args.append('--setopt=allow_vendor_change=True') if allow_unsigned: args.append('--nogpgcheck') + else: + raise Exception(f"Unknown Backend: {get_backend()}") args.extend(packages) subprocess.call(args) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/opi-5.6.0/opi/plugins/zellij.py new/opi-5.7.0/opi/plugins/zellij.py --- old/opi-5.6.0/opi/plugins/zellij.py 1970-01-01 01:00:00.000000000 +0100 +++ new/opi-5.7.0/opi/plugins/zellij.py 2025-02-16 17:13:53.000000000 +0100 @@ -0,0 +1,51 @@ +import os +import subprocess +import opi +from opi.plugins import BasePlugin +from opi import github +from opi import rpmbuild +from opi import http + +# VERSION is only set on leap based distros - not tumbleweed, where this package is available via default repos +if opi.get_version(): + class Zellij(BasePlugin): + main_query = 'zellij' + description = 'A terminal workspace with batteries included' + queries = [main_query] + + @classmethod + def run(cls, query): + org = "zellij-org" + repo = "zellij" + latest_release = github.get_latest_release(org, repo) + if not latest_release: + print(f'No release found for {org}/{repo}') + return + version = latest_release['tag_name'].lstrip('v') + if not opi.ask_yes_or_no(f"Do you want to install {repo} release {version} from {org} github repo?"): + return + arch = opi.get_cpu_arch() + asset_name = f'zellij-{arch}-unknown-linux-musl.tar.gz' + asset = github.get_release_asset(latest_release, filters=[lambda e: e['name'] == asset_name]) + if not asset: + print(f"No asset found for {org}/{repo} release {version}") + return + url = asset['url'] + + binary_path = 'usr/bin/zellij' + + rpm = rpmbuild.RPMBuild('zellij', version, cls.description, arch, files=[ + f"/{binary_path}", + ]) + + bindir_abspath = os.path.join(rpm.buildroot, os.path.dirname(binary_path)) + binary_abspath = os.path.join(rpm.buildroot, binary_path) + tarball_abspath = os.path.join(rpm.tmpdir.name, asset_name) + + http.download_file(url, tarball_abspath) + os.makedirs(bindir_abspath, exist_ok=True) + subprocess.call(['tar', 'xvf', tarball_abspath, '-C', bindir_abspath, 'zellij']) + os.chmod(binary_abspath, 0o755) + + rpm.build() + opi.install_packages([rpm.rpmfile_path], allow_unsigned=True) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/opi-5.6.0/opi/version.py new/opi-5.7.0/opi/version.py --- old/opi-5.6.0/opi/version.py 2025-01-23 14:53:12.000000000 +0100 +++ new/opi-5.7.0/opi/version.py 2025-02-16 17:13:53.000000000 +0100 @@ -1 +1 @@ -__version__ = '5.6.0' +__version__ = '5.7.0' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/opi-5.6.0/opi.changes new/opi-5.7.0/opi.changes --- old/opi-5.6.0/opi.changes 2025-01-23 14:53:12.000000000 +0100 +++ new/opi-5.7.0/opi.changes 2025-02-16 17:13:53.000000000 +0100 @@ -1,4 +1,14 @@ ------------------------------------------------------------------- +Sun Feb 16 16:13:17 UTC 2025 - Dominik Heidler <dheid...@suse.de> + +- Version 5.7.0 + * Add leap-only plugin to install zellij from github release + * Don't use subprocess.run user kwarg on 15.6 + * Fix tests: Use helloworld-opi-tests instead of zfs + * Perform search despite locked rpmdb + * Simplify backend code + +------------------------------------------------------------------- Thu Jan 23 13:53:06 UTC 2025 - Dominik Heidler <dheid...@suse.de> - Version 5.6.0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/opi-5.6.0/test/06_install_non_interactive.py new/opi-5.7.0/test/06_install_non_interactive.py --- old/opi-5.6.0/test/06_install_non_interactive.py 2025-01-23 14:53:12.000000000 +0100 +++ new/opi-5.7.0/test/06_install_non_interactive.py 2025-02-16 17:13:53.000000000 +0100 @@ -19,16 +19,16 @@ subprocess.check_call(['rpm', '-qi', 'bottom']) -c = pexpect.spawn('./bin/opi -n zfs', logfile=sys.stdout.buffer, echo=False) +c = pexpect.spawn('./bin/opi -n helloworld-opi-tests', logfile=sys.stdout.buffer, echo=False) -c.expect(r'([0-9]+)\. zfs', timeout=10) +c.expect(r'([0-9]+)\. helloworld-opi-tests', timeout=10) c.expect('Pick a number') -c.expect(r'([0-9]+)\. [^ ]*(filesystems)', timeout=10) -c.expect('Adding repo \'filesystems\'', timeout=10) +c.expect(r'([0-9]+)\. [^ ]*(home:dheidler:opitests)', timeout=10) +c.expect('Adding repo \'home:dheidler:opitests\'', timeout=10) c.expect('Continue?', timeout=60) c.interact() c.wait() c.close() print() assert c.exitstatus == 0, f'Exit code: {c.exitstatus}' -subprocess.check_call(['rpm', '-qi', 'zfs']) +subprocess.check_call(['rpm', '-qi', 'helloworld-opi-tests']) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/opi-5.6.0/test/07_install_multiple.py new/opi-5.7.0/test/07_install_multiple.py --- old/opi-5.6.0/test/07_install_multiple.py 2025-01-23 14:53:12.000000000 +0100 +++ new/opi-5.7.0/test/07_install_multiple.py 2025-02-16 17:13:53.000000000 +0100 @@ -4,7 +4,7 @@ import pexpect import subprocess -c = pexpect.spawn('./bin/opi -nm zfs resilio-sync tmux', logfile=sys.stdout.buffer, echo=False) +c = pexpect.spawn('./bin/opi -nm helloworld-opi-tests resilio-sync tmux', logfile=sys.stdout.buffer, echo=False) # plugins are installed first c.expect('Do you want to install') @@ -13,10 +13,10 @@ c.expect('Do you want to keep', timeout=500) # packages come after plugins -c.expect(r'([0-9]+)\. zfs', timeout=10) +c.expect(r'([0-9]+)\. helloworld-opi-tests', timeout=10) c.expect('Pick a number') -c.expect(r'([0-9]+)\. [^ ]*(filesystems)', timeout=10) -c.expect('Adding repo \'filesystems\'', timeout=10) +c.expect(r'([0-9]+)\. [^ ]*(home:dheidler:opitests)', timeout=10) +c.expect('Adding repo \'home:dheidler:opitests\'', timeout=10) c.expect('Continue?', timeout=60) c.expect(r'([0-9]+)\. tmux', timeout=60) @@ -31,5 +31,5 @@ print() assert c.exitstatus == 0, f'Exit code: {c.exitstatus}' subprocess.check_call(['rpm', '-qi', 'resilio-sync']) -subprocess.check_call(['rpm', '-qi', 'zfs']) +subprocess.check_call(['rpm', '-qi', 'helloworld-opi-tests']) subprocess.check_call(['rpm', '-qi', 'tmux']) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/opi-5.6.0/test/09_install_with_multi_repos_in_single_file_non_interactive.py new/opi-5.7.0/test/09_install_with_multi_repos_in_single_file_non_interactive.py --- old/opi-5.6.0/test/09_install_with_multi_repos_in_single_file_non_interactive.py 2025-01-23 14:53:12.000000000 +0100 +++ new/opi-5.7.0/test/09_install_with_multi_repos_in_single_file_non_interactive.py 2025-02-16 17:13:53.000000000 +0100 @@ -23,16 +23,16 @@ subprocess.check_call(['rpm', '-qi', 'tmux']) -c = pexpect.spawn('./bin/opi -n zfs', logfile=sys.stdout.buffer, echo=False) +c = pexpect.spawn('./bin/opi -n helloworld-opi-tests', logfile=sys.stdout.buffer, echo=False) -c.expect(r'([0-9]+)\. zfs', timeout=10) +c.expect(r'([0-9]+)\. helloworld-opi-tests', timeout=10) c.expect('Pick a number') -c.expect(r'([0-9]+)\. [^ ]*(filesystems)', timeout=10) -c.expect('Adding repo \'filesystems\'', timeout=10) +c.expect(r'([0-9]+)\. [^ ]*(home:dheidler:opitests)', timeout=10) +c.expect('Adding repo \'home:dheidler:opitests\'', timeout=10) c.expect('Continue?', timeout=60) c.interact() c.wait() c.close() print() assert c.exitstatus == 0, f'Exit code: {c.exitstatus}' -subprocess.check_call(['rpm', '-qi', 'zfs']) +subprocess.check_call(['rpm', '-qi', 'helloworld-opi-tests'])