[v2,09/10] pakfire: Add getmetadata function

Message ID 20220728112136.30218-10-robin.roevens@disroot.org
State Accepted
Commit 2be67e384101f152b37b4bfc6dc1927414021d66
Headers
Series pakfire: remove dup. code + seperate ui/logic |

Commit Message

Robin Roevens July 28, 2022, 11:21 a.m. UTC
  - Added new getmetadata function for easy access to all available
  metadata of a pak without knowledge about or need to parse
  pakfire internal db files.
- Added new 'pakfire info' functionality for displaying all available
  metadata of (a) pak(s) to the user, using the new getmetadata.

Signed-off-by: Robin Roevens <robin.roevens@disroot.org>
---
 src/pakfire/lib/functions.pl | 55 ++++++++++++++++++++++++++++++++++
 src/pakfire/pakfire          | 58 ++++++++++++++++++++++++++++++++++++
 2 files changed, 113 insertions(+)
  

Patch

diff --git a/src/pakfire/lib/functions.pl b/src/pakfire/lib/functions.pl
index f87589bc4..1ebf98775 100644
--- a/src/pakfire/lib/functions.pl
+++ b/src/pakfire/lib/functions.pl
@@ -115,6 +115,7 @@  sub usage {
   &Pakfire::message("               <update> - Contacts the servers for new lists of paks.");
   &Pakfire::message("               <upgrade> - Installs the latest version of all paks.");
   &Pakfire::message("               <list> [installed/notinstalled/upgrade] - Outputs a list with all, installed, available or upgradeable paks.");
+  &Pakfire::message("               <info> <pak> [<pak> ...] - Output pak metadata.");
   &Pakfire::message("               <status> - Outputs a summary about available core upgrades, updates and a required reboot");
   &Pakfire::message("");
   &Pakfire::message("       Global options:");
@@ -706,6 +707,60 @@  sub parsemetafile {
 	return %metadata;
 }
 
+sub getmetadata {
+	### This subroutine returns a hash of available info for a package
+	#   Pass package name and type of info as argument: Pakfire::getmetadata(package, type_of_info) 
+	#	Type_of_info can be "latest" or "installed"
+	#   Usage is always with two argument.
+	my ($pak, $type) = @_;
+
+	my %metadata = (
+		Name => $pak, 
+		Installed => "no",
+		Available => "no");
+	my %installed_metadata = ();
+
+	my @templine;
+	my @file;
+
+	### Get available version information
+	if ("$type" eq "latest") {
+		### Check if package is in packages_list and get latest available version
+		my %db = Pakfire::dblist("all");
+		
+		if (defined $db{$pak}) {
+			### Get and parse latest available metadata
+			if (getmetafile("$pak")) {
+				%metadata = parsemetafile("$Conf::dbdir/meta/meta-$pak");
+
+				$metadata{'Available'} = "yes";
+				### Rename version info fields
+				$metadata{'AvailableProgVersion'} = delete $metadata{'ProgVersion'};
+				$metadata{'AvailableRelease'} = delete $metadata{'Release'};
+			}
+		}
+	}
+	
+	### Parse installed pak metadata
+	if (&isinstalled($pak) == 0) {
+	    %installed_metadata = parsemetafile("$Conf::dbdir/installed/meta-$pak");
+
+		if ("$type" eq "latest" && exists($metadata{'AvailableProgVersion'})) {
+			### Add installed version info to latest metadata
+			$metadata{'ProgVersion'} = $installed_metadata{'ProgVersion'};
+			$metadata{'Release'} = $installed_metadata{'Release'};
+		} else {
+			### Use metadata of installed pak
+			%metadata = %installed_metadata;
+		}
+		$metadata{'Installed'} = 'yes';
+	} else {
+		$metadata{'Installed'} = 'no';
+	}
+
+	return %metadata;
+}
+
 sub decryptpak {
 	my $pak = shift;
 
diff --git a/src/pakfire/pakfire b/src/pakfire/pakfire
index 331204a00..389c1399d 100644
--- a/src/pakfire/pakfire
+++ b/src/pakfire/pakfire
@@ -393,6 +393,64 @@ 
 				exit 1;
 			}
 		}
+	} elsif ("$ARGV[0]" eq "info") {
+		shift;
+
+		my @paks;
+		my $pak;
+		foreach $pak (@ARGV) {
+			unless ("$pak" =~ "^-") {
+				push(@paks,$pak);
+			}
+		}
+
+		unless ("@paks") {
+			Pakfire::message("PAKFIRE ERROR: missing package name");
+			Pakfire::usage;
+			exit 1;
+		}
+
+		foreach $pak (@paks) {
+			my %metadata = Pakfire::getmetadata($pak, "latest");
+
+			### Check if pakfile was actually found
+			if ($metadata{'Installed'} eq "no" && $metadata{'Available'} eq "no") {
+				Pakfire::message("PAKFIRE WARN: Pak '$pak' not found.");
+				last;
+			}
+
+			unless (defined $metadata{'Available'}) {
+				Pakfire::message("PAKFIRE WARN: Unable to retrieve latest metadata for $pak. Information may be outdated.")
+			}
+
+			### Printout metadata in a user friendly format
+			print "Name: $metadata{'Name'}\n";
+			print "Summary: $metadata{'Summary'}\n";
+			if ($metadata{'Available'} eq "yes") {
+				print "Version: $metadata{'AvailableProgVersion'}-$metadata{'AvailableRelease'}\n";
+			} else {
+				print "Version: $metadata{'ProgVersion'}-$metadata{'Release'}\n";
+			}
+			print "Size: " . Pakfire::beautifysize("$metadata{'Size'}") . "\n";
+			print "Dependencies: $metadata{'Dependencies'}\n";
+			print "Pakfile: $metadata{'File'}\n";
+			print "Service InitScripts: $metadata{'Services'}\n";
+			print "Installed: $metadata{'Installed'}\n";
+			### Generate a pak status message
+			if (! defined $metadata{'Available'}) {
+				print "Status: unknown (an error occured retrieving latest pak metadata)";
+			} elsif ($metadata{'Available'} eq "no") {
+				print "Status: obsolete (version $metadata{'ProgVersion'}-$metadata{'Release'} is installed)\n";
+			} elsif ($metadata{'Installed'} eq "yes" && "$metadata{'Release'}" < "$metadata{'AvailableRelease'}") {
+				print "Status: outdated (version $metadata{'ProgVersion'}-$metadata{'Release'} is installed)\n";
+			} elsif ($metadata{'Installed'} eq "yes") {
+				print "Status: up-to-date\n";
+			} else {
+				print "Status: not installed\n";
+			}
+			print "\n";
+		}
+
 	} elsif ("$ARGV[0]" eq "resolvedeps") {
 		foreach (@ARGV) {
 			next if ("$_" eq "resolvedeps");