@@ -28,7 +28,7 @@ from shlex import quote
2828import xml .etree .ElementTree as ET
2929
3030# Constants
31- ZYPPERONI_VERSION = "0.3.4 "
31+ ZYPPERONI_VERSION = "0.3.5 "
3232ZYPPER_PID_FILE = "/run/zypp.pid"
3333VALID_CMD = ["ref" , "force-ref" , "in" , "in-download" , "dup" , "dup-download" , "inr" , "inr-download" ]
3434VALID_OPT = ["--debug" , "--help" , "--version" , "--no-confirm" , "--max-jobs" ]
@@ -195,11 +195,11 @@ def zypperoni_cleanup():
195195 release_zypp_lock ()
196196 recursive_delete (ZYPPERONI_TMP_DIR )
197197
198- # Function to get output of shell command
198+ # Function to get output and exit code of shell command
199199def shell_exec (command ):
200200 res = subprocess .run (command , shell = True , capture_output = True , encoding = "utf8" , errors = "replace" )
201201 output = res .stdout + res .stderr
202- return output .strip ()
202+ return output .strip (), res . returncode
203203
204204# Async function to perform zypper shell commands
205205async def zypper_task (lock , UUID , task_type , task_item , total_items , item_counter ):
@@ -432,7 +432,8 @@ if os.getuid() != 0:
432432programs = ["zypper" , "echo" , "ps" , "sed" , "awk" , "mkdir" , "cat" , "dirname" , "basename" , \
433433 "readlink" , "mount" , "chroot" , "umount" , "sleep" , "rm" , "env" , "findmnt" ]
434434for program in programs :
435- if not shell_exec (f"command -v { program } " ):
435+ out , ret = shell_exec (f"command -v { program } " )
436+ if not out :
436437 logging .error (f"Bailing out, missing required dependency { program !r} in PATH ({ os .environ .get ('PATH' )} ) " \
437438 f"for user { os .environ .get ('USER' )!r} . The following shell tools " \
438439 f"are required for zypperoni to function: { ', ' .join (programs )} "
@@ -451,7 +452,7 @@ if os.path.isfile(ZYPPER_PID_FILE):
451452 except ValueError :
452453 pid = None
453454 if pid :
454- pid_program = shell_exec (f"ps -p { pid } | sed '1d' | awk '{{print $4}}'" )
455+ pid_program , ret = shell_exec (f"ps -p { pid } | sed '1d' | awk '{{print $4}}'" )
455456 if pid_program :
456457 msg = f"zypper is already invoked by the application with pid { pid } ({ pid_program } ).\n " \
457458 "Close this application before trying again."
@@ -464,7 +465,7 @@ if COMMAND in ["ref", "force-ref"]:
464465 # get all enabled repos
465466 logging .info ("Getting all enabled repos" )
466467 REPO_ALIAS = []
467- xml_output = shell_exec ("env -i zypper --non-interactive --no-cd --xmlout repos" )
468+ xml_output , ret = shell_exec ("env -i zypper --non-interactive --no-cd --xmlout repos" )
468469 logging .debug (xml_output )
469470 get_zypp_lock ()
470471 docroot = ET .fromstring (xml_output )
@@ -487,10 +488,15 @@ if COMMAND in ["ref", "force-ref"]:
487488elif COMMAND in ["dup" , "dup-download" ]:
488489 # get info about dup packages
489490 logging .info ("Getting all packages to be downloaded for distribution upgrade" )
490- xml_output = shell_exec ("env -i zypper --non-interactive --no-cd --xmlout dist-upgrade --dry-run" )
491+ xml_output , ret = shell_exec ("env -i zypper --non-interactive --no-cd --xmlout dist-upgrade --dry-run" )
491492 logging .debug (xml_output )
493+ if ret == 0 and xml_output .find ("Nothing to do" ) != - 1 :
494+ logging .info ("Nothing to do. Exiting..." )
495+ zypperoni_cleanup ()
496+ sys .exit ()
492497 get_zypp_lock ()
493498 docroot = ET .fromstring (xml_output )
499+ num_pkgs = None
494500 for item in docroot .iter ('install-summary' ):
495501 download_size_bytes = float (item .attrib ["download-size" ])
496502 diff_bytes = float (item .attrib ["space-usage-diff" ])
@@ -499,10 +505,11 @@ elif COMMAND in ["dup", "dup-download"]:
499505 logging .info (f"Total download size: { download_size_bytes / 1000 ** 2 :.2f} MB" )
500506 if COMMAND == "dup" :
501507 logging .info (f"Space usage difference after operation: { diff_bytes / 1000 ** 2 :+.2f} MB" )
502- if not num_pkgs :
503- if xml_output .find ("Choose from above solutions" ) != - 1 or xml_output .find ("nothing provides" ) != - 1 :
504- logging .warning ("There are package conflicts that must be manually resolved. See output of:\n " \
505- "zypper --non-interactive --no-cd dist-upgrade --dry-run" )
508+ if not num_pkgs :
509+ logging .warning ("There are package conflicts that must be manually resolved. See output of:\n " \
510+ "zypper --non-interactive --no-cd dist-upgrade --dry-run" )
511+ zypperoni_cleanup ()
512+ sys .exit ()
506513 # parse all packages from xml output
507514 DUP_PKG = []
508515 for item in docroot .iter ("solvable" ):
@@ -547,11 +554,16 @@ elif COMMAND in ["dup", "dup-download"]:
547554elif COMMAND in ["in" , "in-download" ]:
548555 # get info about install packages
549556 logging .info ("Getting packages and their dependencies to be downloaded for installation" )
550- xml_output = shell_exec (f"env -i zypper --non-interactive --no-cd --xmlout install --dry-run { ' ' .join (ARG )} " )
557+ xml_output , ret = shell_exec (f"env -i zypper --non-interactive --no-cd --xmlout install --dry-run { ' ' .join (ARG )} " )
551558 logging .debug (xml_output )
559+ if ret == 0 and xml_output .find ("Nothing to do" ) != - 1 :
560+ logging .info ("Nothing to do. Exiting..." )
561+ zypperoni_cleanup ()
562+ sys .exit ()
552563 get_zypp_lock ()
553564 docroot = ET .fromstring (xml_output )
554565 NO_ERR = False
566+ num_pkgs = None
555567 for item in docroot .iter ('install-summary' ):
556568 download_size_bytes = float (item .attrib ["download-size" ])
557569 diff_bytes = float (item .attrib ["space-usage-diff" ])
@@ -560,10 +572,11 @@ elif COMMAND in ["in", "in-download"]:
560572 logging .info (f"Total download size: { download_size_bytes / 1000 ** 2 :.2f} MB" )
561573 logging .info (f"Space usage difference after operation: { diff_bytes / 1000 ** 2 :+.2f} MB" )
562574 NO_ERR = True
563- if not num_pkgs :
564- if xml_output .find ("Choose from above solutions" ) != - 1 or xml_output .find ("nothing provides" ) != - 1 :
565- logging .warning ("There are package conflicts that must be manually resolved. See output of:\n " \
566- "zypper --non-interactive --no-cd dist-upgrade --dry-run" )
575+ if not num_pkgs :
576+ logging .warning ("There are package conflicts that must be manually resolved. See output of:\n " \
577+ "zypper --non-interactive --no-cd dist-upgrade --dry-run" )
578+ zypperoni_cleanup ()
579+ sys .exit ()
567580 if not NO_ERR :
568581 friendly_output = ""
569582 for item in docroot .iter ("message" ):
@@ -615,21 +628,27 @@ elif COMMAND in ["in", "in-download"]:
615628elif COMMAND in ["inr" , "inr-download" ]:
616629 # get info about recommended install packages
617630 logging .info ("Getting new packages and their dependencies to be downloaded for recommended installation" )
618- xml_output = shell_exec (f"env -i zypper --non-interactive --no-cd --xmlout install-new-recommends --dry-run" )
631+ xml_output , ret = shell_exec (f"env -i zypper --non-interactive --no-cd --xmlout install-new-recommends --dry-run" )
619632 logging .debug (xml_output )
633+ if ret == 0 and xml_output .find ("Nothing to do" ) != - 1 :
634+ logging .info ("Nothing to do. Exiting..." )
635+ zypperoni_cleanup ()
636+ sys .exit ()
620637 get_zypp_lock ()
621638 docroot = ET .fromstring (xml_output )
639+ num_pkgs = None
622640 for item in docroot .iter ('install-summary' ):
623641 download_size_bytes = float (item .attrib ["download-size" ])
624642 diff_bytes = float (item .attrib ["space-usage-diff" ])
625643 num_pkgs = int (item .attrib ["packages-to-change" ])
626644 logging .info (f"Number of packages to download: { num_pkgs } " )
627645 logging .info (f"Total download size: { download_size_bytes / 1000 ** 2 :.2f} MB" )
628646 logging .info (f"Space usage difference after operation: { diff_bytes / 1000 ** 2 :+.2f} MB" )
629- if not num_pkgs :
630- if xml_output .find ("Choose from above solutions" ) != - 1 or xml_output .find ("nothing provides" ) != - 1 :
631- logging .warning ("There are package conflicts that must be manually resolved. See output of:\n " \
632- "zypper --non-interactive --no-cd dist-upgrade --dry-run" )
647+ if not num_pkgs :
648+ logging .warning ("There are package conflicts that must be manually resolved. See output of:\n " \
649+ "zypper --non-interactive --no-cd dist-upgrade --dry-run" )
650+ zypperoni_cleanup ()
651+ sys .exit ()
633652 # parse all packages from xml output
634653 INR_PKG = []
635654 for item in docroot .iter ("solvable" ):
0 commit comments