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