xref: /haiku/src/bin/package_repo/command_list.cpp (revision 820dca4df6c7bf955c46e8f6521b9408f50b2900)
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_URLS:
119 				if (fVerbose)
120 					printf("\tURL: %s\n", value.string);
121 				break;
122 
123 			case B_PACKAGE_INFO_SOURCE_URLS:
124 				if (fVerbose)
125 					printf("\tsource URL: %s\n", value.string);
126 				break;
127 
128 			case B_PACKAGE_INFO_PROVIDES:
129 				if (!fVerbose)
130 					break;
131 				printf("\tprovides: %s", value.resolvable.name);
132 				if (value.resolvable.haveVersion) {
133 					printf(" = ");
134 					_PrintPackageVersion(value.resolvable.version);
135 				}
136 				printf("\n");
137 				break;
138 
139 			case B_PACKAGE_INFO_REQUIRES:
140 				if (!fVerbose)
141 					break;
142 				printf("\trequires: %s", value.resolvableExpression.name);
143 				if (value.resolvableExpression.haveOpAndVersion) {
144 					printf(" %s ", BPackageResolvableExpression::kOperatorNames[
145 							value.resolvableExpression.op]);
146 					_PrintPackageVersion(value.resolvableExpression.version);
147 				}
148 				printf("\n");
149 				break;
150 
151 			case B_PACKAGE_INFO_SUPPLEMENTS:
152 				if (!fVerbose)
153 					break;
154 				printf("\tsupplements: %s", value.resolvableExpression.name);
155 				if (value.resolvableExpression.haveOpAndVersion) {
156 					printf(" %s ", BPackageResolvableExpression::kOperatorNames[
157 							value.resolvableExpression.op]);
158 					_PrintPackageVersion(value.resolvableExpression.version);
159 				}
160 				printf("\n");
161 				break;
162 
163 			case B_PACKAGE_INFO_CONFLICTS:
164 				if (!fVerbose)
165 					break;
166 				printf("\tconflicts: %s", value.resolvableExpression.name);
167 				if (value.resolvableExpression.haveOpAndVersion) {
168 					printf(" %s ", BPackageResolvableExpression::kOperatorNames[
169 							value.resolvableExpression.op]);
170 					_PrintPackageVersion(value.resolvableExpression.version);
171 				}
172 				printf("\n");
173 				break;
174 
175 			case B_PACKAGE_INFO_FRESHENS:
176 				if (!fVerbose)
177 					break;
178 				printf("\tfreshens: %s", value.resolvableExpression.name);
179 				if (value.resolvableExpression.haveOpAndVersion) {
180 					printf(" %s ", BPackageResolvableExpression::kOperatorNames[
181 							value.resolvableExpression.op]);
182 					_PrintPackageVersion(value.resolvableExpression.version);
183 				}
184 				printf("\n");
185 				break;
186 
187 			case B_PACKAGE_INFO_REPLACES:
188 				if (!fVerbose)
189 					break;
190 				printf("\treplaces: %s\n", value.string);
191 				break;
192 
193 			case B_PACKAGE_INFO_CHECKSUM:
194 				printf("\tchecksum: %s\n", value.string);
195 				break;
196 
197 			default:
198 				printf(
199 					"*** Invalid package attribute section: unexpected "
200 					"package attribute id %d encountered\n", value.attributeID);
201 				return B_BAD_DATA;
202 		}
203 
204 		return B_OK;
205 	}
206 
207 	virtual status_t HandleRepositoryInfo(const BRepositoryInfo& repositoryInfo)
208 	{
209 		printf("repository-info:\n");
210 		printf("\tname: %s\n", repositoryInfo.Name().String());
211 		printf("\tsummary: %s\n", repositoryInfo.Summary().String());
212 		printf("\turl: %s\n", repositoryInfo.OriginalBaseURL().String());
213 		printf("\tvendor: %s\n", repositoryInfo.Vendor().String());
214 		printf("\tpriority: %u\n", repositoryInfo.Priority());
215 		printf("\tarchitecture: %s\n",
216 			BPackageInfo::kArchitectureNames[repositoryInfo.Architecture()]);
217 		const BStringList licenseNames = repositoryInfo.LicenseNames();
218 		if (!licenseNames.IsEmpty()) {
219 			printf("\tlicenses:\n");
220 			for (int i = 0; i < licenseNames.CountStrings(); ++i)
221 				printf("\t\t%s\n", licenseNames.StringAt(i).String());
222 		}
223 
224 		return B_OK;
225 	}
226 
227 	virtual void HandleErrorOccurred()
228 	{
229 	}
230 
231 private:
232 	static void _PrintPackageVersion(const BPackageVersionData& version)
233 	{
234 		printf("%s", version.major);
235 		if (version.minor != NULL && version.minor[0] != '\0')
236 			printf(".%s", version.minor);
237 		if (version.micro != NULL && version.micro[0] != '\0')
238 			printf(".%s", version.micro);
239 		if (version.preRelease != NULL && version.preRelease[0] != '\0')
240 			printf("-%s", version.preRelease);
241 		if (version.release > 0)
242 			printf("-%d", version.release);
243 	}
244 
245 private:
246 	int		fLevel;
247 	bool	fVerbose;
248 };
249 
250 
251 int
252 command_list(int argc, const char* const* argv)
253 {
254 	bool verbose = false;
255 
256 	while (true) {
257 		static struct option sLongOptions[] = {
258 			{ "help", no_argument, 0, 'h' },
259 			{ "verbose", no_argument, 0, 'v' },
260 			{ 0, 0, 0, 0 }
261 		};
262 
263 		opterr = 0; // don't print errors
264 		int c = getopt_long(argc, (char**)argv, "+hv", sLongOptions, NULL);
265 		if (c == -1)
266 			break;
267 
268 		switch (c) {
269 			case 'h':
270 				print_usage_and_exit(false);
271 				break;
272 
273 			case 'v':
274 				verbose = true;
275 				break;
276 
277 			default:
278 				print_usage_and_exit(true);
279 				break;
280 		}
281 	}
282 
283 	// One argument should remain -- the repository file name.
284 	if (optind + 1 != argc)
285 		print_usage_and_exit(true);
286 
287 	const char* repositoryFileName = argv[optind++];
288 
289 	// open repository
290 	StandardErrorOutput errorOutput;
291 	BRepositoryReader repositoryReader(&errorOutput);
292 	status_t error = repositoryReader.Init(repositoryFileName);
293 	if (error != B_OK)
294 		return 1;
295 
296 	// list
297 	RepositoryContentListHandler handler(verbose);
298 	error = repositoryReader.ParseContent(&handler);
299 	if (error != B_OK)
300 		return 1;
301 
302 	return 0;
303 }
304