xref: /haiku/src/bin/pkgman/command_info.cpp (revision 445d4fd926c569e7b9ae28017da86280aaecbae2)
1 /*
2  * Copyright 2013-2023, Haiku, Inc. All Rights Reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Ingo Weinhold <ingo_weinhold@gmx.de>
7  *		Humdinger <humdingerb@gmail.com>
8  */
9 
10 
11 #include <getopt.h>
12 #include <stdio.h>
13 #include <stdlib.h>
14 
15 #include <package/solver/SolverPackage.h>
16 
17 #include "Command.h"
18 #include "PackageManager.h"
19 #include "pkgman.h"
20 
21 
22 // TODO: internationalization!
23 
24 
25 using namespace BPackageKit;
26 using namespace BPackageKit::BPrivate;
27 
28 
29 static const char* const kShortUsage =
30 	"  %command% <package>\n"
31 	"    Shows summary and description of the specified package.\n";
32 
33 static const char* const kLongUsage =
34 	"Usage: %program% %command% <package>\n"
35 	"Shows summary and description of the specified package.\n"
36 	"The <package> argument is the name by which the package\n"
37 	"is looked up in a remote repository.\n"
38 	"\n";
39 
40 
41 DEFINE_COMMAND(InfoCommand, "info", kShortUsage, kLongUsage,
42 	COMMAND_CATEGORY_PACKAGES)
43 
44 
45 int
46 InfoCommand::Execute(int argc, const char* const* argv)
47 {
48 	while (true) {
49 		static struct option sLongOptions[] = {
50 			{ "debug", required_argument, 0, OPTION_DEBUG },
51 			{ "help", no_argument, 0, 'h' },
52 			{ 0, 0, 0, 0 }
53 		};
54 
55 		opterr = 0; // don't print errors
56 		int c = getopt_long(argc, (char**)argv, "h", sLongOptions, NULL);
57 
58 		if (c == -1)
59 			break;
60 
61 		if (fCommonOptions.HandleOption(c))
62 			continue;
63 
64 		switch (c) {
65 			case 'h':
66 				PrintUsageAndExit(false);
67 				break;
68 
69 			default:
70 				PrintUsageAndExit(true);
71 				break;
72 		}
73 	}
74 
75 	// The remaining argument, if any, is the package.
76 	const char* packageName = argv[optind++];
77 	if (packageName == NULL)
78 		PrintUsageAndExit(true);
79 
80 	// create the solver
81 	PackageManager packageManager(B_PACKAGE_INSTALLATION_LOCATION_SYSTEM);
82 	packageManager.SetDebugLevel(fCommonOptions.DebugLevel());
83 	packageManager.Init(
84 		PackageManager::B_ADD_INSTALLED_REPOSITORIES
85 		| PackageManager::B_ADD_REMOTE_REPOSITORIES);
86 
87 	uint32 flags = BSolver::B_FIND_CASE_INSENSITIVE | BSolver::B_FIND_IN_NAME;
88 
89 	// find packages
90 	BObjectList<BSolverPackage> packages;
91 	status_t error = packageManager.Solver()->FindPackages(packageName,
92 		flags, packages);
93 	if (error != B_OK)
94 		DIE(error, "searching packages failed");
95 
96 	if (packages.IsEmpty()) {
97 		printf("No matching packages found.\n");
98 		return 0;
99 	}
100 
101 	// print out summary and description of first exactly matching package
102 	int32 packageCount = packages.CountItems();
103 	for (int32 i = 0; i < packageCount; i++) {
104 		BSolverPackage* package = packages.ItemAt(i);
105 		if (package->Name() == packageName) {
106 			BString text("%name%: %summary%\n\n%description%\n");
107 			text.ReplaceFirst("%name%", package->Name());
108 			text.ReplaceFirst("%summary%", package->Info().Summary());
109 			text.ReplaceFirst("%description%", package->Info().Description());
110 			printf("%s\n", text.String());
111 			break;
112 		}
113 	}
114 
115 	return 0;
116 }
117