diff --git a/src/controllers/Package/Dnf.py b/src/controllers/Package/Dnf.py index e27c09f..df90139 100644 --- a/src/controllers/Package/Dnf.py +++ b/src/controllers/Package/Dnf.py @@ -10,6 +10,10 @@ from pathlib import Path import configparser +# Import classes +from src.controllers.Log import Log +from src.controllers.App.Utils import Utils + class Dnf: def __init__(self): # Total count of success and failed package updates @@ -66,9 +70,6 @@ def get_available_version(self, package): # Quit if an error occurred if result.returncode != 0: raise Exception('could not retrieve available version of package ' + package + ': ' + result.stderr) - - # TODO debug - print('Available version of ' + package + ': ' + result.stdout.strip()) return result.stdout.strip() @@ -307,99 +308,100 @@ def update(self, packagesList, update_method: str = 'one_by_one', exit_on_packag if Path(log).is_file(): Path(log).unlink() - print('\n ▪ Updating ' + Fore.GREEN + pkg['name'] + Style.RESET_ALL + ' (' + pkg['current_version'] + ' → ' + pkg['available_version'] + '):') - - # Before updating, check if package is already in the latest version, if so, skip it - # It means that it has been updated previously by another package, probably because it was a dependency - # Get the current version of the package with dnf - # e.g. dnf repoquery --installed --qf="%{version}-%{release}.%{arch}" wget - result = subprocess.run( - ["dnf", "repoquery", "--installed", "--qf=%{version}-%{release}.%{arch}", pkg['name']], - stdout = subprocess.PIPE, # subprocess.PIPE & subprocess.PIPE are alias of 'capture_output = True' - stderr = subprocess.PIPE, - universal_newlines = True # Alias of 'text = True' - ) - - # Quit if an error occurred - if result.returncode != 0: - raise Exception('Could not retrieve current version of package ' + pkg['name'] + ': ' + result.stderr) - - # Retrieve current version - current_version = result.stdout.strip() + with Log(log): + print('\n ▪ Updating ' + Fore.GREEN + pkg['name'] + Style.RESET_ALL + ' (' + pkg['current_version'] + ' → ' + pkg['available_version'] + '):') + + # Before updating, check if package is already in the latest version, if so, skip it + # It means that it has been updated previously by another package, probably because it was a dependency + # Get the current version of the package with dnf + # e.g. dnf repoquery --installed --qf="%{version}-%{release}.%{arch}" wget + result = subprocess.run( + ["dnf", "repoquery", "--installed", "--qf=%{version}-%{release}.%{arch}", pkg['name']], + stdout = subprocess.PIPE, # subprocess.PIPE & subprocess.PIPE are alias of 'capture_output = True' + stderr = subprocess.PIPE, + universal_newlines = True # Alias of 'text = True' + ) + + # Quit if an error occurred + if result.returncode != 0: + raise Exception('Could not retrieve current version of package ' + pkg['name'] + ': ' + result.stderr) + + # Retrieve current version + current_version = result.stdout.strip() + + # If current version is the same the target version, skip the update + if current_version == pkg['available_version']: + print(Fore.GREEN + ' ✔ ' + Style.RESET_ALL + pkg['name'] + ' is already up to date (updated with another package).') + + # Mark the package as already updated + self.summary['update']['success']['count'] += 1 + + # Also add the package to the list of successful packages + self.summary['update']['success']['packages'][pkg['name']] = { + 'version': pkg['available_version'], + 'log': 'Already up to date (updated with another package).' + } + + # Continue to the next package + continue - # If current version is the same the target version, skip the update - if current_version == pkg['available_version']: - print(Fore.GREEN + ' ✔ ' + Style.RESET_ALL + pkg['name'] + ' is already up to date (updated with another package).') + # Define the command to update the package + cmd = ['dnf', 'update', pkg['name'] + '-' + pkg['available_version'], '-y'] - # Mark the package as already updated - self.summary['update']['success']['count'] += 1 + popen = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, bufsize=1, universal_newlines=True) - # Also add the package to the list of successful packages - self.summary['update']['success']['packages'][pkg['name']] = { - 'version': pkg['available_version'], - 'log': 'Already up to date (updated with another package).' - } + # Print lines as they are read + for line in popen.stdout: + line = line.replace('\r', '') + print(' | ' + line, end='') - # Continue to the next package - continue + # Wait for the command to finish + popen.wait() + + # If command failed, either raise an exception or print a warning + if popen.returncode != 0: + # Add the package to the list of failed packages + self.summary['update']['failed']['count'] += 1 + + # Also add the package to the list of failed packages + + # First get log content + with open(log, 'r') as file: + log_content = file.read() - # Define the command to update the package - cmd = ['dnf', 'update', pkg['name'] + '-' + pkg['available_version'], '-y'] + self.summary['update']['failed']['packages'][pkg['name']] = { + 'version': pkg['available_version'], + 'log': log_content + } - popen = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, bufsize=1, universal_newlines=True) + # If error is critical, raise an exception to quit + if (exit_on_package_update_error == True): + raise Exception('Error while updating ' + pkg['name'] + '.') - # Print lines as they are read - for line in popen.stdout: - line = line.replace('\r', '') - print(' | ' + line, end='') + # Else continue to the next package + else: + print(Fore.RED + ' ✕ ' + Style.RESET_ALL + 'Error while updating ' + pkg['name'] + '.') + continue - # Wait for the command to finish - popen.wait() + # Close the pipe + popen.stdout.close() - # If command failed, either raise an exception or print a warning - if popen.returncode != 0: - # Add the package to the list of failed packages - self.summary['update']['failed']['count'] += 1 + # If command succeeded, increment the success counter + self.summary['update']['success']['count'] += 1 - # Also add the package to the list of failed packages + # Also add the package to the list of successful packages # First get log content with open(log, 'r') as file: log_content = file.read() - self.summary['update']['failed']['packages'][pkg['name']] = { + self.summary['update']['success']['packages'][pkg['name']] = { 'version': pkg['available_version'], 'log': log_content } - # If error is critical, raise an exception to quit - if (exit_on_package_update_error == True): - raise Exception('Error while updating ' + pkg['name'] + '.') - - # Else continue to the next package - else: - print(Fore.RED + ' ✕ ' + Style.RESET_ALL + 'Error while updating ' + pkg['name'] + '.') - continue - - # Close the pipe - popen.stdout.close() - - # If command succeeded, increment the success counter - self.summary['update']['success']['count'] += 1 - - # Also add the package to the list of successful packages - - # First get log content - with open(log, 'r') as file: - log_content = file.read() - - self.summary['update']['success']['packages'][pkg['name']] = { - 'version': pkg['available_version'], - 'log': log_content - } - - # Print a success message - print(Fore.GREEN + ' ✔ ' + Style.RESET_ALL + pkg['name'] + ' updated successfully.') + # Print a success message + print(Fore.GREEN + ' ✔ ' + Style.RESET_ALL + pkg['name'] + ' updated successfully.') # If update_method is 'global', update all packages at once (one command) if update_method == 'global':