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