xref: /haiku/src/bin/pkgman/command_refresh.cpp (revision cbe0a0c436162d78cc3f92a305b64918c839d079)
1 /*
2  * Copyright 2011, Oliver Tappe <zooey@hirschkaefere.de>
3  * Distributed under the terms of the MIT License.
4  */
5 
6 
7 #include <getopt.h>
8 #include <stdio.h>
9 #include <stdlib.h>
10 
11 #include <Errors.h>
12 #include <StringList.h>
13 
14 #include <package/Context.h>
15 #include <package/RefreshRepositoryRequest.h>
16 #include <package/PackageRoster.h>
17 
18 #include "Command.h"
19 #include "DecisionProvider.h"
20 #include "JobStateListener.h"
21 #include "pkgman.h"
22 
23 
24 using namespace BPackageKit;
25 
26 
27 // TODO: internationalization!
28 
29 
30 static const char* const kShortUsage =
31 	"  %command% [<repo-name> ...]\n"
32 	"    Refreshes all or just the given repositories.\n";
33 
34 static const char* const kLongUsage =
35 	"Usage: %program% %command% [<repo-name> ...]\n"
36 	"Refreshes all or just the given repositories.\n"
37 	"\n";
38 
39 
40 DEFINE_COMMAND(RefreshCommand, "refresh", kShortUsage, kLongUsage,
41 	COMMAND_CATEGORY_REPOSITORIES)
42 
43 
44 int
45 RefreshCommand::Execute(int argc, const char* const* argv)
46 {
47 	while (true) {
48 		static struct option sLongOptions[] = {
49 			{ "help", no_argument, 0, 'h' },
50 			{ 0, 0, 0, 0 }
51 		};
52 
53 		opterr = 0; // don't print errors
54 		int c = getopt_long(argc, (char**)argv, "hu", sLongOptions, NULL);
55 		if (c == -1)
56 			break;
57 
58 		switch (c) {
59 			case 'h':
60 				PrintUsageAndExit(false);
61 				break;
62 
63 			default:
64 				PrintUsageAndExit(true);
65 				break;
66 		}
67 	}
68 
69 	// The remaining arguments are repo names.
70 	const char* const* repoArgs = argv + optind;
71 	int nameCount = argc - optind;
72 
73 	BStringList repositoryNames(20);
74 
75 	BPackageRoster roster;
76 	if (nameCount == 0) {
77 		status_t result = roster.GetRepositoryNames(repositoryNames);
78 		if (result != B_OK)
79 			DIE(result, "can't collect repository names");
80 	} else {
81 		for (int i = 0; i < nameCount; ++i) {
82 			if (!repositoryNames.Add(repoArgs[i]))
83 				DIE(B_NO_MEMORY, "can't allocate repository name");
84 		}
85 	}
86 
87 	DecisionProvider decisionProvider;
88 	JobStateListener listener;
89 	BContext context(decisionProvider, listener);
90 
91 	status_t result;
92 	for (int i = 0; i < repositoryNames.CountStrings(); ++i) {
93 		const BString& repoName = repositoryNames.StringAt(i);
94 		BRepositoryConfig repoConfig;
95 		result = roster.GetRepositoryConfig(repoName, &repoConfig);
96 		if (result != B_OK) {
97 			BPath path;
98 			repoConfig.Entry().GetPath(&path);
99 			WARN(result, "skipping repository-config '%s'", path.Path());
100 			continue;
101 		}
102 
103 		BRefreshRepositoryRequest refreshRequest(context, repoConfig);
104 		result = refreshRequest.Process();
105 		if (result != B_OK) {
106 			DIE(result, "request for refreshing repository \"%s\" failed",
107 				repoName.String());
108 		}
109 	}
110 
111 	return 0;
112 }
113