xref: /haiku/src/bin/package_repo/command_list.cpp (revision 9642f7705b27e5c270c15fa526d14e1848c2c27d)
1 /*
2  * Copyright 2011, Oliver Tappe <zooey@hirschkaefer.de>
3  * Distributed under the terms of the MIT License.
4  */
5 
6 
7 #include <ctype.h>
8 #include <errno.h>
9 #include <getopt.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13 
14 #include <package/hpkg/PackageInfoAttributeValue.h>
15 #include <package/hpkg/RepositoryContentHandler.h>
16 #include <package/hpkg/RepositoryReader.h>
17 #include <package/hpkg/StandardErrorOutput.h>
18 #include <package/PackageInfo.h>
19 #include <package/RepositoryInfo.h>
20 
21 #include "package_repo.h"
22 #include "PackageInfoPrinter.h"
23 
24 
25 using namespace BPackageKit::BHPKG;
26 using namespace BPackageKit;
27 
28 struct RepositoryContentListHandler : BRepositoryContentHandler {
29 	RepositoryContentListHandler(bool verbose)
30 		:
31 		fPrinter(),
32 		fLevel(0),
33 		fVerbose(verbose)
34 	{
35 	}
36 
37 	virtual status_t HandlePackage(const char* packageName)
38 	{
39 		return B_OK;
40 	}
41 
42 	virtual status_t HandlePackageAttribute(
43 		const BPackageInfoAttributeValue& value)
44 	{
45 		if (value.attributeID == B_PACKAGE_INFO_NAME) {
46 			if (fVerbose) {
47 				printf("package-attributes:\n");
48 				fPrinter.PrintName(value.string);
49 			} else
50 				printf("\t%s\n", value.string);
51 		} else {
52 			if (fVerbose && !fPrinter.PrintAttribute(value)) {
53 				printf("*** Invalid package attribute section: unexpected "
54 					"package attribute id %d encountered\n", value.attributeID);
55 				return B_BAD_DATA;
56 			}
57 		}
58 
59 		return B_OK;
60 	}
61 
62 	virtual status_t HandlePackageDone(const char* packageName)
63 	{
64 		return B_OK;
65 	}
66 
67 	virtual status_t HandleRepositoryInfo(const BRepositoryInfo& repositoryInfo)
68 	{
69 		printf("repository-info:\n");
70 		printf("\tname: %s\n", repositoryInfo.Name().String());
71 		printf("\tsummary: %s\n", repositoryInfo.Summary().String());
72 		printf("\tbase-url: %s\n", repositoryInfo.BaseURL().String());
73 		printf("\turl: %s\n", repositoryInfo.URL().String());
74 		printf("\tvendor: %s\n", repositoryInfo.Vendor().String());
75 		printf("\tpriority: %u\n", repositoryInfo.Priority());
76 		printf("\tarchitecture: %s\n",
77 			BPackageInfo::kArchitectureNames[repositoryInfo.Architecture()]);
78 		const BStringList licenseNames = repositoryInfo.LicenseNames();
79 		if (!licenseNames.IsEmpty()) {
80 			printf("\tlicenses:\n");
81 			for (int i = 0; i < licenseNames.CountStrings(); ++i)
82 				printf("\t\t%s\n", licenseNames.StringAt(i).String());
83 		}
84 		printf("packages:\n");
85 
86 		return B_OK;
87 	}
88 
89 	virtual void HandleErrorOccurred()
90 	{
91 	}
92 
93 private:
94 	static void _PrintPackageVersion(const BPackageVersionData& version)
95 	{
96 		printf("%s", BPackageVersion(version).ToString().String());
97 	}
98 
99 private:
100 	PackageInfoPrinter	fPrinter;
101 	int					fLevel;
102 	bool				fVerbose;
103 };
104 
105 
106 int
107 command_list(int argc, const char* const* argv)
108 {
109 	bool verbose = false;
110 
111 	while (true) {
112 		static struct option sLongOptions[] = {
113 			{ "help", no_argument, 0, 'h' },
114 			{ "verbose", no_argument, 0, 'v' },
115 			{ 0, 0, 0, 0 }
116 		};
117 
118 		opterr = 0; // don't print errors
119 		int c = getopt_long(argc, (char**)argv, "+hv", sLongOptions, NULL);
120 		if (c == -1)
121 			break;
122 
123 		switch (c) {
124 			case 'h':
125 				print_usage_and_exit(false);
126 				break;
127 
128 			case 'v':
129 				verbose = true;
130 				break;
131 
132 			default:
133 				print_usage_and_exit(true);
134 				break;
135 		}
136 	}
137 
138 	// One argument should remain -- the repository file name.
139 	if (optind + 1 != argc)
140 		print_usage_and_exit(true);
141 
142 	const char* repositoryFileName = argv[optind++];
143 
144 	// open repository
145 	BStandardErrorOutput errorOutput;
146 	BRepositoryReader repositoryReader(&errorOutput);
147 	status_t error = repositoryReader.Init(repositoryFileName);
148 	if (error != B_OK)
149 		return 1;
150 
151 	// list
152 	RepositoryContentListHandler handler(verbose);
153 	error = repositoryReader.ParseContent(&handler);
154 	if (error != B_OK)
155 		return 1;
156 
157 	return 0;
158 }
159