]> git.ipfire.org Git - pakfire.git/blob - pakfire/cli.py
builder: Rename function cleanup -> destroy.
[pakfire.git] / pakfire / cli.py
1 #!/usr/bin/python
2
3 import argparse
4 import sys
5
6 import packages
7 import repository
8 import util
9
10 from pakfire import Pakfire
11
12 from constants import *
13 from i18n import _
14
15 def ask_user(question):
16 """
17 Ask the user the question, he or she can answer with yes or no.
18
19 This function returns True for "yes" and False for "no".
20
21 If the software is running in a non-inteactive shell, no question
22 is asked at all and the answer is always "yes".
23 """
24 if not util.cli_is_interactive():
25 return True
26
27 print _("%s [y/N]") % question,
28 ret = raw_input()
29
30 return ret in ("y", "Y")
31
32
33 class Cli(object):
34 def __init__(self):
35 self.parser = argparse.ArgumentParser(
36 description = _("Pakfire command line interface."),
37 )
38
39 self.parse_common_arguments()
40
41 self.parser.add_argument("--instroot", metavar="PATH",
42 default="/tmp/pakfire",
43 help=_("The path where pakfire should operate in."))
44
45 # Add sub-commands.
46 self.sub_commands = self.parser.add_subparsers()
47
48 self.parse_command_install()
49 self.parse_command_localinstall()
50 self.parse_command_info()
51 self.parse_command_search()
52 self.parse_command_update()
53 self.parse_command_provides()
54
55 # Finally parse all arguments from the command line and save them.
56 self.args = self.parser.parse_args()
57
58 # Create instance of the wonderful pakfire :)
59 self.pakfire = Pakfire(
60 self.args.instroot,
61 configs = [self.args.config],
62 disable_repos = self.args.disable_repo,
63 )
64
65 self.action2func = {
66 "install" : self.handle_install,
67 "localinstall" : self.handle_localinstall,
68 "update" : self.handle_update,
69 "info" : self.handle_info,
70 "search" : self.handle_search,
71 "provides" : self.handle_provides,
72 }
73
74 def parse_common_arguments(self):
75 self.parser.add_argument("-v", "--verbose", action="store_true",
76 help=_("Enable verbose output."))
77
78 self.parser.add_argument("-c", "--config", nargs="?",
79 help=_("Path to a configuration file to load."))
80
81 self.parser.add_argument("--disable-repo", nargs="*", metavar="REPO",
82 help=_("Disable a repository temporarily."))
83
84 def parse_command_install(self):
85 # Implement the "install" command.
86 sub_install = self.sub_commands.add_parser("install",
87 help=_("Install one or more packages to the system."))
88 sub_install.add_argument("package", nargs="+",
89 help=_("Give name of at least one package to install."))
90 sub_install.add_argument("action", action="store_const", const="install")
91
92 def parse_command_localinstall(self):
93 # Implement the "localinstall" command.
94 sub_install = self.sub_commands.add_parser("localinstall",
95 help=_("Install one or more packages from the filesystem."))
96 sub_install.add_argument("package", nargs="+",
97 help=_("Give filename of at least one package."))
98 sub_install.add_argument("action", action="store_const", const="localinstall")
99
100 def parse_command_update(self):
101 # Implement the "update" command.
102 sub_update = self.sub_commands.add_parser("update",
103 help=_("Update the whole system or one specific package."))
104 sub_update.add_argument("package", nargs="*",
105 help=_("Give a name of a package to update or leave emtpy for all."))
106 sub_update.add_argument("action", action="store_const", const="update")
107
108 def parse_command_info(self):
109 # Implement the "info" command.
110 sub_info = self.sub_commands.add_parser("info",
111 help=_("Print some information about the given package(s)."))
112 sub_info.add_argument("package", nargs="+",
113 help=_("Give at least the name of one package."))
114 sub_info.add_argument("action", action="store_const", const="info")
115
116 def parse_command_search(self):
117 # Implement the "search" command.
118 sub_search = self.sub_commands.add_parser("search",
119 help=_("Search for a given pattern."))
120 sub_search.add_argument("pattern",
121 help=_("A pattern to search for."))
122 sub_search.add_argument("action", action="store_const", const="search")
123
124 def parse_command_provides(self):
125 # Implement the "provides" command
126 sub_provides = self.sub_commands.add_parser("provides",
127 help=_("Get a list of packages that provide a given file or feature."))
128 sub_provides.add_argument("pattern", nargs="+",
129 help=_("File or feature to search for."))
130 sub_provides.add_argument("action", action="store_const", const="provides")
131
132 def run(self):
133 action = self.args.action
134
135 if not self.action2func.has_key(action):
136 raise
137
138 try:
139 func = self.action2func[action]
140 except KeyError:
141 raise # XXX catch and return better error message
142
143 return func()
144
145 def handle_info(self, long=False):
146 for pattern in self.args.package:
147 pkgs = self.pakfire.repos.get_by_glob(pattern)
148
149 pkgs = packages.PackageListing(pkgs)
150
151 for pkg in pkgs:
152 print pkg.dump(long=long)
153
154 def handle_search(self):
155 pkgs = self.pakfire.repos.search(self.args.pattern)
156
157 pkgs = packages.PackageListing(pkgs)
158
159 for pkg in pkgs:
160 print pkg.dump(short=True)
161
162 def handle_update(self):
163 pass
164
165 def handle_install(self, local=False):
166 if local:
167 repo = repository.FileSystemRepository(self.pakfire)
168
169 pkgs = []
170 for pkg in self.args.package:
171 if local and os.path.exists(pkg):
172 pkg = packages.BinaryPackage(self.pakfire, repo, pkg)
173
174 pkgs.append(pkg)
175
176 self.pakfire.install(pkgs)
177
178 def handle_localinstall(self):
179 return self.handle_install(local=True)
180
181 def handle_provides(self):
182 pkgs = self.pakfire.provides(self.args.pattern)
183
184 for pkg in pkgs:
185 print pkg.dump()
186
187
188 class CliBuilder(Cli):
189 def __init__(self):
190 self.parser = argparse.ArgumentParser(
191 description = _("Pakfire builder command line interface."),
192 )
193
194 self.parse_common_arguments()
195
196 # Add sub-commands.
197 self.sub_commands = self.parser.add_subparsers()
198
199 self.parse_command_build()
200 self.parse_command_dist()
201 self.parse_command_info()
202 self.parse_command_search()
203 self.parse_command_shell()
204 self.parse_command_update()
205 self.parse_command_provides()
206
207 # Finally parse all arguments from the command line and save them.
208 self.args = self.parser.parse_args()
209
210 self.pakfire = Pakfire(
211 builder = True,
212 configs = [self.args.config],
213 disable_repos = self.args.disable_repo,
214 )
215
216 self.action2func = {
217 "build" : self.handle_build,
218 "dist" : self.handle_dist,
219 "update" : self.handle_update,
220 "info" : self.handle_info,
221 "search" : self.handle_search,
222 "shell" : self.handle_shell,
223 "provides" : self.handle_provides,
224 }
225
226 def parse_command_update(self):
227 # Implement the "update" command.
228 sub_update = self.sub_commands.add_parser("update",
229 help=_("Update the package indexes."))
230 sub_update.add_argument("action", action="store_const", const="update")
231
232 def parse_command_build(self):
233 # Implement the "build" command.
234 sub_build = self.sub_commands.add_parser("build",
235 help=_("Build one or more packages."))
236 sub_build.add_argument("package", nargs=1,
237 help=_("Give name of at least one package to build."))
238 sub_build.add_argument("action", action="store_const", const="build")
239
240 sub_build.add_argument("-a", "--arch",
241 help=_("Build the package for the given architecture."))
242 sub_build.add_argument("--resultdir", nargs="?",
243 help=_("Path were the output files should be copied to."))
244
245 def parse_command_shell(self):
246 # Implement the "shell" command.
247 sub_shell = self.sub_commands.add_parser("shell",
248 help=_("Go into a shell."))
249 sub_shell.add_argument("package", nargs=1,
250 help=_("Give name of a package."))
251 sub_shell.add_argument("action", action="store_const", const="shell")
252
253 sub_shell.add_argument("-a", "--arch",
254 help=_("Emulated architecture in the shell."))
255
256 def parse_command_dist(self):
257 # Implement the "dist" command.
258 sub_dist = self.sub_commands.add_parser("dist",
259 help=_("Generate a source package."))
260 sub_dist.add_argument("package", nargs=1,
261 help=_("Give name of a package."))
262 sub_dist.add_argument("action", action="store_const", const="dist")
263
264 sub_dist.add_argument("--resultdir", nargs="?",
265 help=_("Path were the output files should be copied to."))
266
267 def handle_info(self):
268 Cli.handle_info(self, long=True)
269
270 def handle_build(self):
271 print self.args
272 # Get the package descriptor from the command line options
273 pkg = self.args.package[0]
274
275 # Check, if we got a regular file
276 if os.path.exists(pkg):
277 pkg = os.path.abspath(pkg)
278
279 if pkg.endswith(MAKEFILE_EXTENSION):
280 pkg = packages.Makefile(self.pakfire, pkg)
281
282 elif pkg.endswith(PACKAGE_EXTENSION):
283 repo = repository.FileSystemRepository(self.pakfire)
284 pkg = packages.SourcePackage(self.pakfire, repo, pkg)
285
286 else:
287 # XXX walk through the source tree and find a matching makefile
288 pass
289
290 self.pakfire.build(pkg, arch=self.args.arch, resultdirs=[self.args.resultdir,])
291
292 def handle_shell(self):
293 print self.args
294 # Get the package descriptor from the command line options
295 pkg = self.args.package[0]
296
297 # Check, if we got a regular file
298 if os.path.exists(pkg):
299 pkg = os.path.abspath(pkg)
300
301 if pkg.endswith(MAKEFILE_EXTENSION):
302 pkg = packages.Makefile(self.pakfire, pkg)
303
304 elif pkg.endswith(PACKAGE_EXTENSION):
305 repo = repository.FileSystemRepository(self.pakfire)
306 pkg = packages.SourcePackage(self.pakfire, repo, pkg)
307
308 else:
309 # XXX walk through the source tree and find a matching makefile
310 pass
311
312 self.pakfire.shell(pkg, arch=self.args.arch)
313
314 def handle_dist(self):
315 print self.args
316 # Get the package descriptor from the command line options
317 pkg = self.args.package[0]
318
319 # Check, if we got a regular file
320 if os.path.exists(pkg):
321 pkg = os.path.abspath(pkg)
322
323 if pkg.endswith(MAKEFILE_EXTENSION):
324 pkg = packages.Makefile(self.pakfire, pkg)
325
326 else:
327 # XXX walk through the source tree and find a matching makefile
328 pass
329
330 self.pakfire.dist(pkg, resultdirs=[self.args.resultdir,])
331
332 class CliServer(Cli):
333 def __init__(self):
334 self.parser = argparse.ArgumentParser(
335 description = _("Pakfire server command line interface."),
336 )
337
338 self.parse_common_arguments()
339
340 # Add sub-commands.
341 self.sub_commands = self.parser.add_subparsers()
342
343 self.parse_command_repo()
344
345 # Finally parse all arguments from the command line and save them.
346 self.args = self.parser.parse_args()
347
348 self.pakfire = Pakfire(
349 builder = True,
350 configs = [self.args.config],
351 disable_repos = self.args.disable_repo,
352 )
353
354 self.action2func = {
355 "repo_create" : self.handle_repo_create,
356 }
357
358 def parse_command_repo(self):
359 sub_repo = self.sub_commands.add_parser("repo",
360 help=_("Repository management commands."))
361
362 sub_repo_commands = sub_repo.add_subparsers()
363
364 self.parse_command_repo_create(sub_repo_commands)
365
366 def parse_command_repo_create(self, sub_commands):
367 sub_create = sub_commands.add_parser("create",
368 help=_("Create a new repository index."))
369 sub_create.add_argument("path", nargs=1, help=_("Path to the packages."))
370 sub_create.add_argument("inputs", nargs="+", help=_("Path to input packages."))
371 sub_create.add_argument("action", action="store_const", const="repo_create")
372
373 def handle_repo_create(self):
374 path = self.args.path[0]
375
376 self.pakfire.repo_create(path, self.args.inputs)