xref: /haiku/src/bin/package_repo/command_list.cpp (revision 922e7ba1f3228e6f28db69b0ded8f86eb32dea17)
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/PackageInfo.h>
18 #include <package/RepositoryInfo.h>
19 
20 #include "package.h"
21 #include "StandardErrorOutput.h"
22 
23 
24 using namespace BPackageKit::BHPKG;
25 using namespace BPackageKit;
26 
27 struct RepositoryContentListHandler : BRepositoryContentHandler {
28 	RepositoryContentListHandler(bool verbose)
29 		:
30 		fLevel(0),
31 		fVerbose(verbose)
32 	{
33 	}
34 
35 	virtual status_t HandleEntry(BPackageEntry* entry)
36 	{
37 		return B_OK;
38 	}
39 
40 	virtual status_t HandleEntryAttribute(BPackageEntry* entry,
41 		BPackageEntryAttribute* attribute)
42 	{
43 		return B_OK;
44 	}
45 
46 	virtual status_t HandleEntryDone(BPackageEntry* entry)
47 	{
48 		return B_OK;
49 	}
50 
51 	virtual status_t HandlePackageAttribute(
52 		const BPackageInfoAttributeValue& value)
53 	{
54 		switch (value.attributeID) {
55 			case B_PACKAGE_INFO_NAME:
56 				if (fVerbose) {
57 					printf("package-attributes:\n");
58 					printf("\tname: %s\n", value.string);
59 				} else
60 					printf("package: %s", value.string);
61 				break;
62 
63 			case B_PACKAGE_INFO_SUMMARY:
64 				if (fVerbose)
65 					printf("\tsummary: %s\n", value.string);
66 				break;
67 
68 			case B_PACKAGE_INFO_DESCRIPTION:
69 				if (fVerbose)
70 					printf("\tdescription: %s\n", value.string);
71 				break;
72 
73 			case B_PACKAGE_INFO_VENDOR:
74 				if (fVerbose)
75 					printf("\tvendor: %s\n", value.string);
76 				break;
77 
78 			case B_PACKAGE_INFO_PACKAGER:
79 				if (fVerbose)
80 					printf("\tpackager: %s\n", value.string);
81 				break;
82 
83 			case B_PACKAGE_INFO_FLAGS:
84 				if (value.unsignedInt == 0 || !fVerbose)
85 					break;
86 				printf("\tflags:\n");
87 				if ((value.unsignedInt & B_PACKAGE_FLAG_APPROVE_LICENSE) != 0)
88 					printf("\t\tapprove_license\n");
89 				if ((value.unsignedInt & B_PACKAGE_FLAG_SYSTEM_PACKAGE) != 0)
90 					printf("\t\tsystem_package\n");
91 				break;
92 
93 			case B_PACKAGE_INFO_ARCHITECTURE:
94 				if (fVerbose) {
95 					printf("\tarchitecture: %s\n",
96 						BPackageInfo::kArchitectureNames[value.unsignedInt]);
97 				}
98 				break;
99 
100 			case B_PACKAGE_INFO_VERSION:
101 				if (!fVerbose)
102 					printf("(");
103 				_PrintPackageVersion(value.version);
104 				if (!fVerbose)
105 					printf(")\n");
106 				break;
107 
108 			case B_PACKAGE_INFO_COPYRIGHTS:
109 				if (fVerbose)
110 					printf("\tcopyright: %s\n", value.string);
111 				break;
112 
113 			case B_PACKAGE_INFO_LICENSES:
114 				if (fVerbose)
115 					printf("\tlicense: %s\n", value.string);
116 				break;
117 
118 			case B_PACKAGE_INFO_PROVIDES:
119 				if (!fVerbose)
120 					break;
121 				printf("\tprovides: %s", value.resolvable.name);
122 				if (value.resolvable.haveVersion) {
123 					printf(" = ");
124 					_PrintPackageVersion(value.resolvable.version);
125 				}
126 				printf("\n");
127 				break;
128 
129 			case B_PACKAGE_INFO_REQUIRES:
130 				if (!fVerbose)
131 					break;
132 				printf("\trequires: %s", value.resolvableExpression.name);
133 				if (value.resolvableExpression.haveOpAndVersion) {
134 					printf(" %s ", BPackageResolvableExpression::kOperatorNames[
135 							value.resolvableExpression.op]);
136 					_PrintPackageVersion(value.resolvableExpression.version);
137 				}
138 				printf("\n");
139 				break;
140 
141 			case B_PACKAGE_INFO_SUPPLEMENTS:
142 				if (!fVerbose)
143 					break;
144 				printf("\tsupplements: %s", value.resolvableExpression.name);
145 				if (value.resolvableExpression.haveOpAndVersion) {
146 					printf(" %s ", BPackageResolvableExpression::kOperatorNames[
147 							value.resolvableExpression.op]);
148 					_PrintPackageVersion(value.resolvableExpression.version);
149 				}
150 				printf("\n");
151 				break;
152 
153 			case B_PACKAGE_INFO_CONFLICTS:
154 				if (!fVerbose)
155 					break;
156 				printf("\tconflicts: %s", value.resolvableExpression.name);
157 				if (value.resolvableExpression.haveOpAndVersion) {
158 					printf(" %s ", BPackageResolvableExpression::kOperatorNames[
159 							value.resolvableExpression.op]);
160 					_PrintPackageVersion(value.resolvableExpression.version);
161 				}
162 				printf("\n");
163 				break;
164 
165 			case B_PACKAGE_INFO_FRESHENS:
166 				if (!fVerbose)
167 					break;
168 				printf("\tfreshens: %s", value.resolvableExpression.name);
169 				if (value.resolvableExpression.haveOpAndVersion) {
170 					printf(" %s ", BPackageResolvableExpression::kOperatorNames[
171 							value.resolvableExpression.op]);
172 					_PrintPackageVersion(value.resolvableExpression.version);
173 				}
174 				printf("\n");
175 				break;
176 
177 			case B_PACKAGE_INFO_REPLACES:
178 				if (!fVerbose)
179 					break;
180 				printf("\treplaces: %s\n", value.string);
181 				break;
182 
183 			case B_PACKAGE_INFO_CHECKSUM:
184 				printf("\tchecksum: %s\n", value.string);
185 				break;
186 
187 			default:
188 				printf(
189 					"*** Invalid package attribute section: unexpected "
190 					"package attribute id %d encountered\n", value.attributeID);
191 				return B_BAD_DATA;
192 		}
193 
194 		return B_OK;
195 	}
196 
197 	virtual status_t HandleRepositoryInfo(const BRepositoryInfo& repositoryInfo)
198 	{
199 		printf("repository-info:\n");
200 		printf("\tname: %s\n", repositoryInfo.Name().String());
201 		printf("\tsummary: %s\n", repositoryInfo.Summary().String());
202 		printf("\turl: %s\n", repositoryInfo.OriginalBaseURL().String());
203 		printf("\tvendor: %s\n", repositoryInfo.Vendor().String());
204 		printf("\tpriority: %u\n", repositoryInfo.Priority());
205 		printf("\tarchitecture: %s\n",
206 			BPackageInfo::kArchitectureNames[repositoryInfo.Architecture()]);
207 		const BObjectList<BString> licenseNames = repositoryInfo.LicenseNames();
208 		if (!licenseNames.IsEmpty()) {
209 			printf("\tlicenses:\n");
210 			for (int i = 0; i < licenseNames.CountItems(); ++i)
211 				printf("\t\t%s\n", licenseNames.ItemAt(i)->String());
212 		}
213 
214 		return B_OK;
215 	}
216 
217 	virtual void HandleErrorOccurred()
218 	{
219 	}
220 
221 private:
222 	static void _PrintPackageVersion(const BPackageVersionData& version)
223 	{
224 		printf("%s", version.major);
225 		if (version.minor != NULL && version.minor[0] != '\0')
226 			printf(".%s", version.minor);
227 		if (version.micro != NULL && version.micro[0] != '\0')
228 			printf(".%s", version.micro);
229 		if (version.release > 0)
230 			printf("-%d", version.release);
231 	}
232 
233 private:
234 	int		fLevel;
235 	bool	fVerbose;
236 };
237 
238 
239 int
240 command_list(int argc, const char* const* argv)
241 {
242 	bool verbose = false;
243 
244 	while (true) {
245 		static struct option sLongOptions[] = {
246 			{ "help", no_argument, 0, 'h' },
247 			{ "verbose", no_argument, 0, 'v' },
248 			{ 0, 0, 0, 0 }
249 		};
250 
251 		opterr = 0; // don't print errors
252 		int c = getopt_long(argc, (char**)argv, "+hv", sLongOptions, NULL);
253 		if (c == -1)
254 			break;
255 
256 		switch (c) {
257 			case 'h':
258 				print_usage_and_exit(false);
259 				break;
260 
261 			case 'v':
262 				verbose = true;
263 				break;
264 
265 			default:
266 				print_usage_and_exit(true);
267 				break;
268 		}
269 	}
270 
271 	// One argument should remain -- the repository file name.
272 	if (optind + 1 != argc)
273 		print_usage_and_exit(true);
274 
275 	const char* repositoryFileName = argv[optind++];
276 
277 	// open repository
278 	StandardErrorOutput errorOutput;
279 	BRepositoryReader repositoryReader(&errorOutput);
280 	status_t error = repositoryReader.Init(repositoryFileName);
281 	if (error != B_OK)
282 		return 1;
283 
284 	// list
285 	RepositoryContentListHandler handler(verbose);
286 	error = repositoryReader.ParseContent(&handler);
287 	if (error != B_OK)
288 		return 1;
289 
290 	return 0;
291 }
292