]> git.ipfire.org Git - pakfire.git/blob - pakfire/cli.py
Merge branch 'master' of git://git.ipfire.org/oddments/pakfire
[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 server
9 import util
10
11 import pakfire.api as pakfire
12 from constants import *
13 from i18n import _
14
15 class Cli(object):
16 def __init__(self):
17 self.parser = argparse.ArgumentParser(
18 description = _("Pakfire command line interface."),
19 )
20
21 self.parse_common_arguments()
22
23 self.parser.add_argument("--instroot", metavar="PATH",
24 default="/",
25 help=_("The path where pakfire should operate in."))
26
27 # Add sub-commands.
28 self.sub_commands = self.parser.add_subparsers()
29
30 self.parse_command_install()
31 self.parse_command_localinstall()
32 self.parse_command_remove()
33 self.parse_command_info()
34 self.parse_command_search()
35 self.parse_command_update()
36 self.parse_command_provides()
37 self.parse_command_grouplist()
38 self.parse_command_groupinstall()
39 self.parse_command_repolist()
40 self.parse_command_clean()
41
42 # Finally parse all arguments from the command line and save them.
43 self.args = self.parser.parse_args()
44
45 self.action2func = {
46 "install" : self.handle_install,
47 "localinstall" : self.handle_localinstall,
48 "remove" : self.handle_remove,
49 "update" : self.handle_update,
50 "info" : self.handle_info,
51 "search" : self.handle_search,
52 "provides" : self.handle_provides,
53 "grouplist" : self.handle_grouplist,
54 "groupinstall" : self.handle_groupinstall,
55 "repolist" : self.handle_repolist,
56 "clean_all" : self.handle_clean_all,
57 }
58
59 @property
60 def pakfire_args(self):
61 ret = { "mode" : "normal" }
62
63 if hasattr(self.args, "instroot"):
64 ret["path"] = self.args.instroot
65
66 if hasattr(self.args, "disable_repo"):
67 ret["disable_repos"] = self.args.disable_repo
68
69 if hasattr(self.args, "enable_repo"):
70 ret["enable_repos"] = self.args.enable_repo
71
72 return ret
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 self.parser.add_argument("--enabled-repo", nargs="*", metavar="REPO",
85 help=_("Enable a repository temporarily."))
86
87 def parse_command_install(self):
88 # Implement the "install" command.
89 sub_install = self.sub_commands.add_parser("install",
90 help=_("Install one or more packages to the system."))
91 sub_install.add_argument("package", nargs="+",
92 help=_("Give name of at least one package to install."))
93 sub_install.add_argument("action", action="store_const", const="install")
94
95 def parse_command_localinstall(self):
96 # Implement the "localinstall" command.
97 sub_install = self.sub_commands.add_parser("localinstall",
98 help=_("Install one or more packages from the filesystem."))
99 sub_install.add_argument("package", nargs="+",
100 help=_("Give filename of at least one package."))
101 sub_install.add_argument("action", action="store_const", const="localinstall")
102
103 def parse_command_remove(self):
104 # Implement the "remove" command.
105 sub_remove = self.sub_commands.add_parser("remove",
106 help=_("Remove one or more packages from the system."))
107 sub_remove.add_argument("package", nargs="+",
108 help=_("Give name of at least one package to remove."))
109 sub_remove.add_argument("action", action="store_const", const="remove")
110
111 def parse_command_update(self):
112 # Implement the "update" command.
113 sub_update = self.sub_commands.add_parser("update",
114 help=_("Update the whole system or one specific package."))
115 sub_update.add_argument("package", nargs="*",
116 help=_("Give a name of a package to update or leave emtpy for all."))
117 sub_update.add_argument("action", action="store_const", const="update")
118
119 def parse_command_info(self):
120 # Implement the "info" command.
121 sub_info = self.sub_commands.add_parser("info",
122 help=_("Print some information about the given package(s)."))
123 sub_info.add_argument("package", nargs="+",
124 help=_("Give at least the name of one package."))
125 sub_info.add_argument("action", action="store_const", const="info")
126
127 def parse_command_search(self):
128 # Implement the "search" command.
129 sub_search = self.sub_commands.add_parser("search",
130 help=_("Search for a given pattern."))
131 sub_search.add_argument("pattern",
132 help=_("A pattern to search for."))
133 sub_search.add_argument("action", action="store_const", const="search")
134
135 def parse_command_provides(self):
136 # Implement the "provides" command
137 sub_provides = self.sub_commands.add_parser("provides",
138 help=_("Get a list of packages that provide a given file or feature."))
139 sub_provides.add_argument("pattern", nargs="+",
140 help=_("File or feature to search for."))
141 sub_provides.add_argument("action", action="store_const", const="provides")
142
143 def parse_command_grouplist(self):
144 # Implement the "grouplist" command
145 sub_grouplist = self.sub_commands.add_parser("grouplist",
146 help=_("Get list of packages that belong to the given group."))
147 sub_grouplist.add_argument("group", nargs=1,
148 help=_("Group name to search for."))
149 sub_grouplist.add_argument("action", action="store_const", const="grouplist")
150
151 def parse_command_groupinstall(self):
152 # Implement the "grouplist" command
153 sub_groupinstall = self.sub_commands.add_parser("groupinstall",
154 help=_("Install all packages that belong to the given group."))
155 sub_groupinstall.add_argument("group", nargs=1,
156 help=_("Group name."))
157 sub_groupinstall.add_argument("action", action="store_const", const="groupinstall")
158
159 def parse_command_repolist(self):
160 # Implement the "repolist" command
161 sub_repolist = self.sub_commands.add_parser("repolist",
162 help=_("List all currently enabled repositories."))
163 sub_repolist.add_argument("action", action="store_const", const="repolist")
164
165 def parse_command_clean(self):
166 sub_clean = self.sub_commands.add_parser("clean", help=_("Cleanup commands."))
167
168 sub_clean_commands = sub_clean.add_subparsers()
169
170 self.parse_command_clean_all(sub_clean_commands)
171
172 def parse_command_clean_all(self, sub_commands):
173 sub_create = sub_commands.add_parser("all",
174 help=_("Cleanup all temporary files."))
175 sub_create.add_argument("action", action="store_const", const="clean_all")
176
177 def run(self):
178 action = self.args.action
179
180 if not self.action2func.has_key(action):
181 raise
182
183 try:
184 func = self.action2func[action]
185 except KeyError:
186 raise # XXX catch and return better error message
187
188 return func()
189
190 def handle_info(self, long=False):
191 pkgs = pakfire.info(self.args.package, **self.pakfire_args)
192
193 for pkg in pkgs:
194 print pkg.dump(long=long)
195
196 def handle_search(self):
197 pkgs = pakfire.search(self.args.pattern, **self.pakfire_args)
198
199 for pkg in pkgs:
200 print pkg.dump(short=True)
201
202 def handle_update(self):
203 pakfire.update(self.args.package, **self.pakfire_args)
204
205 def handle_install(self):
206 pakfire.install(self.args.package, **self.pakfire_args)
207
208 def handle_localinstall(self):
209 pakfire.localinstall(self.args.package, **self.pakfire_args)
210
211 def handle_remove(self):
212 pakfire.remove(self.args.package, **self.pakfire_args)
213
214 def handle_provides(self):
215 pkgs = pakfire.provides(self.args.pattern, **self.pakfire_args)
216
217 for pkg in pkgs:
218 print pkg.dump()
219
220 def handle_grouplist(self):
221 pkgs = pakfire.grouplist(self.args.group[0], **self.pakfire_args)
222
223 for pkg in pkgs:
224 print " * %s" % pkg
225
226 def handle_groupinstall(self):
227 pakfire.groupinstall(self.args.group[0], **self.pakfire_args)
228
229 def handle_repolist(self):
230 repos = pakfire.repo_list(**self.pakfire_args)
231
232 FORMAT = " %-20s %8s %12s %12s "
233
234 title = FORMAT % (_("Repository"), _("Enabled"), _("Priority"), _("Packages"))
235 print title
236 print "=" * len(title) # spacing line
237
238 for repo in repos:
239 # Skip the installed repository.
240 if repo.name == "installed":
241 continue
242
243 print FORMAT % (repo.name, repo.enabled, repo.priority, len(repo))
244
245 def handle_clean_all(self):
246 print _("Cleaning up everything...")
247
248 pakfire.clean_all(**self.pakfire_args)
249
250
251 class CliBuilder(Cli):
252 def __init__(self):
253 self.parser = argparse.ArgumentParser(
254 description = _("Pakfire builder command line interface."),
255 )
256
257 self.parse_common_arguments()
258
259 # Add sub-commands.
260 self.sub_commands = self.parser.add_subparsers()
261
262 self.parse_command_build()
263 self.parse_command_dist()
264 self.parse_command_info()
265 self.parse_command_search()
266 self.parse_command_shell()
267 self.parse_command_update()
268 self.parse_command_provides()
269 self.parse_command_grouplist()
270 self.parse_command_repolist()
271 self.parse_command_clean()
272
273 # Finally parse all arguments from the command line and save them.
274 self.args = self.parser.parse_args()
275
276 self.action2func = {
277 "build" : self.handle_build,
278 "dist" : self.handle_dist,
279 "update" : self.handle_update,
280 "info" : self.handle_info,
281 "search" : self.handle_search,
282 "shell" : self.handle_shell,
283 "provides" : self.handle_provides,
284 "grouplist" : self.handle_grouplist,
285 "repolist" : self.handle_repolist,
286 "clean_all" : self.handle_clean_all,
287 }
288
289 @property
290 def pakfire_args(self):
291 ret = { "mode" : "builder" }
292
293 if hasattr(self.args, "disable_repo"):
294 ret["disable_repos"] = self.args.disable_repo
295
296 if hasattr(self.args, "enable_repo"):
297 ret["enable_repos"] = self.args.enable_repo
298
299 return ret
300
301 def parse_command_update(self):
302 # Implement the "update" command.
303 sub_update = self.sub_commands.add_parser("update",
304 help=_("Update the package indexes."))
305 sub_update.add_argument("action", action="store_const", const="update")
306
307 def parse_command_build(self):
308 # Implement the "build" command.
309 sub_build = self.sub_commands.add_parser("build",
310 help=_("Build one or more packages."))
311 sub_build.add_argument("package", nargs=1,
312 help=_("Give name of at least one package to build."))
313 sub_build.add_argument("action", action="store_const", const="build")
314
315 sub_build.add_argument("-a", "--arch",
316 help=_("Build the package for the given architecture."))
317 sub_build.add_argument("--resultdir", nargs="?",
318 help=_("Path were the output files should be copied to."))
319
320 def parse_command_shell(self):
321 # Implement the "shell" command.
322 sub_shell = self.sub_commands.add_parser("shell",
323 help=_("Go into a shell."))
324 sub_shell.add_argument("package", nargs="?",
325 help=_("Give name of a package."))
326 sub_shell.add_argument("action", action="store_const", const="shell")
327
328 sub_shell.add_argument("-a", "--arch",
329 help=_("Emulated architecture in the shell."))
330
331 def parse_command_dist(self):
332 # Implement the "dist" command.
333 sub_dist = self.sub_commands.add_parser("dist",
334 help=_("Generate a source package."))
335 sub_dist.add_argument("package", nargs="+",
336 help=_("Give name(s) of a package(s)."))
337 sub_dist.add_argument("action", action="store_const", const="dist")
338
339 sub_dist.add_argument("--resultdir", nargs="?",
340 help=_("Path were the output files should be copied to."))
341
342 def handle_info(self):
343 Cli.handle_info(self, long=True)
344
345 def handle_build(self):
346 # Get the package descriptor from the command line options
347 pkg = self.args.package[0]
348
349 # Check, if we got a regular file
350 if os.path.exists(pkg):
351 pkg = os.path.abspath(pkg)
352
353 else:
354 raise FileNotFoundError, pkg
355
356 # Create distribution configuration from command line.
357 distro_config = {
358 "arch" : self.args.arch,
359 }
360
361 pakfire.build(pkg, distro_config=distro_config, resultdirs=[self.args.resultdir,],
362 shell=True, **self.pakfire_args)
363
364 def handle_shell(self):
365 pkg = None
366
367 # Get the package descriptor from the command line options
368 if self.args.package:
369 pkg = self.args.package
370
371 # Check, if we got a regular file
372 if os.path.exists(pkg):
373 pkg = os.path.abspath(pkg)
374
375 else:
376 raise FileNotFoundError, pkg
377
378 # Create distribution configuration from command line.
379 distro_config = {
380 "arch" : self.args.arch,
381 }
382
383 pakfire.shell(pkg, distro_config=distro_config, **self.pakfire_args)
384
385 def handle_dist(self):
386 # Get the packages from the command line options
387 pkgs = []
388
389 for pkg in self.args.package:
390 # Check, if we got a regular file
391 if os.path.exists(pkg):
392 pkg = os.path.abspath(pkg)
393 pkgs.append(pkg)
394
395 else:
396 raise FileNotFoundError, pkg
397
398 pakfire.dist(pkgs, resultdirs=[self.args.resultdir,],
399 **self.pakfire_args)
400
401 def handle_provides(self):
402 pkgs = pakfire.provides(self.args.pattern, **self.pakfire_args)
403
404 for pkg in pkgs:
405 print pkg.dump(long=True)
406
407
408 class CliRepo(Cli):
409 def __init__(self):
410 self.parser = argparse.ArgumentParser(
411 description = _("Pakfire repo command line interface."),
412 )
413
414 self.parse_common_arguments()
415
416 # Add sub-commands.
417 self.sub_commands = self.parser.add_subparsers()
418
419 self.parse_command_repo()
420
421 # Finally parse all arguments from the command line and save them.
422 self.args = self.parser.parse_args()
423
424 self.action2func = {
425 "repo_create" : self.handle_repo_create,
426 }
427
428 @property
429 def pakfire_args(self):
430 ret = { "mode" : "repo" }
431
432 return ret
433
434 def parse_command_repo(self):
435 sub_repo = self.sub_commands.add_parser("repo",
436 help=_("Repository management commands."))
437
438 sub_repo_commands = sub_repo.add_subparsers()
439
440 self.parse_command_repo_create(sub_repo_commands)
441
442 def parse_command_repo_create(self, sub_commands):
443 sub_create = sub_commands.add_parser("create",
444 help=_("Create a new repository index."))
445 sub_create.add_argument("path", nargs=1, help=_("Path to the packages."))
446 sub_create.add_argument("inputs", nargs="+", help=_("Path to input packages."))
447 sub_create.add_argument("action", action="store_const", const="repo_create")
448
449 def handle_repo_create(self):
450 path = self.args.path[0]
451
452 pakfire.repo_create(path, self.args.inputs, **self.pakfire_args)
453
454
455 class CliMaster(Cli):
456 def __init__(self):
457 self.parser = argparse.ArgumentParser(
458 description = _("Pakfire master command line interface."),
459 )
460
461 self.parse_common_arguments()
462
463 # Add sub-commands.
464 self.sub_commands = self.parser.add_subparsers()
465
466 self.parse_command_update()
467
468 # Finally parse all arguments from the command line and save them.
469 self.args = self.parser.parse_args()
470
471 self.master = server.master.Master()
472
473 self.action2func = {
474 "update" : self.handle_update,
475 }
476
477 @property
478 def pakfire_args(self):
479 ret = { "mode" : "master" }
480
481 return ret
482
483 def parse_command_update(self):
484 # Implement the "update" command.
485 sub_update = self.sub_commands.add_parser("update",
486 help=_("Update the sources."))
487 sub_update.add_argument("action", action="store_const", const="update")
488
489 def handle_update(self):
490 self.master.update_sources()
491
492
493 class CliServer(Cli):
494 def __init__(self):
495 self.parser = argparse.ArgumentParser(
496 description = _("Pakfire server command line interface."),
497 )
498
499 self.parse_common_arguments()
500
501 # Add sub-commands.
502 self.sub_commands = self.parser.add_subparsers()
503
504 self.parse_command_build()
505 self.parse_command_keepalive()
506
507 # Finally parse all arguments from the command line and save them.
508 self.args = self.parser.parse_args()
509
510 self.server = server.Server()
511
512 self.action2func = {
513 "build" : self.handle_build,
514 "keepalive" : self.handle_keepalive,
515 }
516
517 @property
518 def pakfire_args(self):
519 ret = { "mode" : "server" }
520
521 return ret
522
523 def parse_command_build(self):
524 # Implement the "build" command.
525 sub_keepalive = self.sub_commands.add_parser("build",
526 help=_("Request a build job from the server."))
527 sub_keepalive.add_argument("action", action="store_const", const="build")
528
529 def parse_command_keepalive(self):
530 # Implement the "keepalive" command.
531 sub_keepalive = self.sub_commands.add_parser("keepalive",
532 help=_("Send a keepalive to the server."))
533 sub_keepalive.add_argument("action", action="store_const",
534 const="keepalive")
535
536 def handle_keepalive(self):
537 self.server.update_info()
538
539 def handle_build(self):
540 self.server.build_job()