xref: /haiku/src/bin/pkgman/command_add_repo.cpp (revision 52a61976d4915e59c8d7cfe97c5962798cb094a2)
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 <SupportDefs.h>
13 #include <Url.h>
14 
15 #include <package/AddRepositoryRequest.h>
16 #include <package/Context.h>
17 #include <package/RefreshRepositoryRequest.h>
18 #include <package/PackageRoster.h>
19 
20 #include "Command.h"
21 #include "DecisionProvider.h"
22 #include "JobStateListener.h"
23 #include "pkgman.h"
24 
25 
26 using namespace BPackageKit;
27 
28 
29 // TODO: internationalization!
30 
31 
32 static const char* const kShortUsage =
33 	"  %command% <repo-base-url>\n"
34 	"    Adds the repository with the given <repo-base-URL>.\n";
35 
36 static const char* const kLongUsage =
37 	"Usage: %program% %command% <repo-URL> [<repo-URL> ...]\n"
38 	"Adds one or more repositories by downloading them from the given URL(s).\n"
39 	"\n";
40 
41 
42 DEFINE_COMMAND(AddRepoCommand, "add-repo", kShortUsage, kLongUsage,
43 	COMMAND_CATEGORY_REPOSITORIES)
44 
45 
46 int
Execute(int argc,const char * const * argv)47 AddRepoCommand::Execute(int argc, const char* const* argv)
48 {
49 	bool asUserRepository = false;
50 
51 	while (true) {
52 		static struct option sLongOptions[] = {
53 			{ "help", no_argument, 0, 'h' },
54 			{ "user", no_argument, 0, 'u' },
55 			{ 0, 0, 0, 0 }
56 		};
57 
58 		opterr = 0; // don't print errors
59 		int c = getopt_long(argc, (char**)argv, "hu", sLongOptions, NULL);
60 		if (c == -1)
61 			break;
62 
63 		switch (c) {
64 			case 'h':
65 				PrintUsageAndExit(false);
66 				break;
67 
68 			case 'u':
69 				asUserRepository = true;
70 				break;
71 
72 			default:
73 				PrintUsageAndExit(true);
74 				break;
75 		}
76 	}
77 
78 	// The remaining arguments are repo URLs, i. e. at least one more argument.
79 	if (argc < optind + 1)
80 		PrintUsageAndExit(true);
81 
82 	const char* const* repoURLs = argv + optind;
83 	int urlCount = argc - optind;
84 
85 	DecisionProvider decisionProvider;
86 	JobStateListener listener;
87 	BContext context(decisionProvider, listener);
88 
89 	status_t result;
90 	for (int i = 0; i < urlCount; ++i) {
91 		// Test if a valid URL has been supplied before attempting to add
92 		BUrl repoURL(repoURLs[i]);
93 		if (!repoURL.IsValid()) {
94 			result = B_BAD_VALUE;
95 			DIE(result, "request for adding repository \"%s\" failed",
96 				repoURLs[i]);
97 		}
98 		AddRepositoryRequest addRequest(context, repoURLs[i], asUserRepository);
99 		result = addRequest.Process(true);
100 		if (result != B_OK) {
101 			if (result != B_CANCELED) {
102 				DIE(result, "request for adding repository \"%s\" failed",
103 					repoURLs[i]);
104 			}
105 			return 1;
106 		}
107 
108 		// now refresh the repo-cache of the new repository
109 		BString repoName = addRequest.RepositoryName();
110 		BPackageRoster roster;
111 		BRepositoryConfig repoConfig;
112 		roster.GetRepositoryConfig(repoName, &repoConfig);
113 
114 		BRefreshRepositoryRequest refreshRequest(context, repoConfig);
115 		result = refreshRequest.Process(true);
116 		if (result != B_OK) {
117 			if (result != B_CANCELED) {
118 				DIE(result, "request for refreshing repository \"%s\" failed",
119 					repoName.String());
120 			}
121 			return 1;
122 		}
123 	}
124 
125 	return 0;
126 }
127