]> git.ipfire.org Git - pakfire.git/blame - pakfire/cli.py
Merge branch 'master' of git://git.ipfire.org/oddments/pakfire
[pakfire.git] / pakfire / cli.py
CommitLineData
47a4cb89
MT
1#!/usr/bin/python
2
3import argparse
4import sys
5
6import packages
fa6d335b 7import repository
677ff42a 8import server
e9c20259 9import util
47a4cb89 10
18edfe75 11import pakfire.api as pakfire
47a4cb89
MT
12from constants import *
13from i18n import _
14
47a4cb89 15class Cli(object):
47a4cb89
MT
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",
d2e26956 24 default="/",
47a4cb89
MT
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()
5e87fa4f 31 self.parse_command_localinstall()
a39fd08b 32 self.parse_command_remove()
47a4cb89
MT
33 self.parse_command_info()
34 self.parse_command_search()
35 self.parse_command_update()
fa6d335b 36 self.parse_command_provides()
c1962d40 37 self.parse_command_grouplist()
ce2764c1 38 self.parse_command_groupinstall()
67bc4528 39 self.parse_command_repolist()
31267a64 40 self.parse_command_clean()
47a4cb89
MT
41
42 # Finally parse all arguments from the command line and save them.
43 self.args = self.parser.parse_args()
44
47a4cb89 45 self.action2func = {
5e87fa4f
MT
46 "install" : self.handle_install,
47 "localinstall" : self.handle_localinstall,
a39fd08b 48 "remove" : self.handle_remove,
5e87fa4f
MT
49 "update" : self.handle_update,
50 "info" : self.handle_info,
51 "search" : self.handle_search,
fa6d335b 52 "provides" : self.handle_provides,
c1962d40 53 "grouplist" : self.handle_grouplist,
ce2764c1 54 "groupinstall" : self.handle_groupinstall,
67bc4528 55 "repolist" : self.handle_repolist,
31267a64 56 "clean_all" : self.handle_clean_all,
47a4cb89
MT
57 }
58
7c8f2953
MT
59 @property
60 def pakfire_args(self):
6557ff4c
MT
61 ret = { "mode" : "normal" }
62
63 if hasattr(self.args, "instroot"):
64 ret["path"] = self.args.instroot
f9a012a8
MT
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
7c8f2953 73
47a4cb89
MT
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
f781b1ab
MT
81 self.parser.add_argument("--disable-repo", nargs="*", metavar="REPO",
82 help=_("Disable a repository temporarily."))
83
f9a012a8
MT
84 self.parser.add_argument("--enabled-repo", nargs="*", metavar="REPO",
85 help=_("Enable a repository temporarily."))
86
47a4cb89
MT
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
5e87fa4f
MT
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
a39fd08b
MT
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
47a4cb89
MT
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
fa6d335b
MT
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
c1962d40
MT
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
ce2764c1
MT
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
67bc4528
MT
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")
ce2764c1 164
31267a64
MT
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
47a4cb89
MT
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
9afa5620 190 def handle_info(self, long=False):
7c8f2953 191 pkgs = pakfire.info(self.args.package, **self.pakfire_args)
47a4cb89 192
7c8f2953
MT
193 for pkg in pkgs:
194 print pkg.dump(long=long)
47a4cb89
MT
195
196 def handle_search(self):
7c8f2953 197 pkgs = pakfire.search(self.args.pattern, **self.pakfire_args)
47a4cb89
MT
198
199 for pkg in pkgs:
200 print pkg.dump(short=True)
201
202 def handle_update(self):
7c8f2953 203 pakfire.update(self.args.package, **self.pakfire_args)
47a4cb89 204
e0b99370
MT
205 def handle_install(self):
206 pakfire.install(self.args.package, **self.pakfire_args)
5e87fa4f
MT
207
208 def handle_localinstall(self):
e0b99370 209 pakfire.localinstall(self.args.package, **self.pakfire_args)
5e87fa4f 210
a39fd08b
MT
211 def handle_remove(self):
212 pakfire.remove(self.args.package, **self.pakfire_args)
213
fa6d335b 214 def handle_provides(self):
7c8f2953 215 pkgs = pakfire.provides(self.args.pattern, **self.pakfire_args)
fa6d335b
MT
216
217 for pkg in pkgs:
218 print pkg.dump()
219
c1962d40 220 def handle_grouplist(self):
7c8f2953 221 pkgs = pakfire.grouplist(self.args.group[0], **self.pakfire_args)
c1962d40
MT
222
223 for pkg in pkgs:
224 print " * %s" % pkg
225
ce2764c1 226 def handle_groupinstall(self):
7c8f2953 227 pakfire.groupinstall(self.args.group[0], **self.pakfire_args)
ce2764c1 228
67bc4528 229 def handle_repolist(self):
7c8f2953 230 repos = pakfire.repo_list(**self.pakfire_args)
67bc4528 231
c605d735 232 FORMAT = " %-20s %8s %12s %12s "
67bc4528 233
c605d735 234 title = FORMAT % (_("Repository"), _("Enabled"), _("Priority"), _("Packages"))
67bc4528
MT
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
c605d735 243 print FORMAT % (repo.name, repo.enabled, repo.priority, len(repo))
67bc4528 244
31267a64
MT
245 def handle_clean_all(self):
246 print _("Cleaning up everything...")
247
248 pakfire.clean_all(**self.pakfire_args)
249
47a4cb89
MT
250
251class 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()
4fbd4216 268 self.parse_command_provides()
2c84aceb 269 self.parse_command_grouplist()
67bc4528 270 self.parse_command_repolist()
31267a64 271 self.parse_command_clean()
47a4cb89
MT
272
273 # Finally parse all arguments from the command line and save them.
274 self.args = self.parser.parse_args()
275
47a4cb89 276 self.action2func = {
fa6d335b
MT
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,
4fbd4216 283 "provides" : self.handle_provides,
2c84aceb 284 "grouplist" : self.handle_grouplist,
67bc4528 285 "repolist" : self.handle_repolist,
31267a64 286 "clean_all" : self.handle_clean_all,
47a4cb89
MT
287 }
288
7c8f2953
MT
289 @property
290 def pakfire_args(self):
6557ff4c 291 ret = { "mode" : "builder" }
f9a012a8
MT
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
7c8f2953 300
47a4cb89
MT
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."))
042266f3 324 sub_shell.add_argument("package", nargs="?",
47a4cb89
MT
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."))
e412b8dc
MT
335 sub_dist.add_argument("package", nargs="+",
336 help=_("Give name(s) of a package(s)."))
47a4cb89
MT
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
9afa5620
MT
342 def handle_info(self):
343 Cli.handle_info(self, long=True)
344
47a4cb89 345 def handle_build(self):
47a4cb89
MT
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
47a4cb89 353 else:
7c8f2953 354 raise FileNotFoundError, pkg
47a4cb89 355
7c8f2953
MT
356 # Create distribution configuration from command line.
357 distro_config = {
358 "arch" : self.args.arch,
359 }
360
18edfe75 361 pakfire.build(pkg, distro_config=distro_config, resultdirs=[self.args.resultdir,],
dacaa18b 362 shell=True, **self.pakfire_args)
47a4cb89
MT
363
364 def handle_shell(self):
042266f3
MT
365 pkg = None
366
47a4cb89 367 # Get the package descriptor from the command line options
042266f3 368 if self.args.package:
ad1b844f 369 pkg = self.args.package
47a4cb89 370
7c8f2953
MT
371 # Check, if we got a regular file
372 if os.path.exists(pkg):
373 pkg = os.path.abspath(pkg)
47a4cb89 374
7c8f2953
MT
375 else:
376 raise FileNotFoundError, pkg
47a4cb89 377
7c8f2953
MT
378 # Create distribution configuration from command line.
379 distro_config = {
380 "arch" : self.args.arch,
381 }
47a4cb89 382
983f1a7d 383 pakfire.shell(pkg, distro_config=distro_config, **self.pakfire_args)
47a4cb89
MT
384
385 def handle_dist(self):
e412b8dc
MT
386 # Get the packages from the command line options
387 pkgs = []
47a4cb89 388
e412b8dc
MT
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)
7c8f2953 393 pkgs.append(pkg)
47a4cb89 394
e412b8dc 395 else:
7c8f2953
MT
396 raise FileNotFoundError, pkg
397
6519843a
MT
398 pakfire.dist(pkgs, resultdirs=[self.args.resultdir,],
399 **self.pakfire_args)
47a4cb89 400
c605d735
MT
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
47a4cb89 407
9613a111 408class CliRepo(Cli):
92806f47
MT
409 def __init__(self):
410 self.parser = argparse.ArgumentParser(
9613a111 411 description = _("Pakfire repo command line interface."),
92806f47
MT
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
92806f47
MT
424 self.action2func = {
425 "repo_create" : self.handle_repo_create,
426 }
427
6557ff4c
MT
428 @property
429 def pakfire_args(self):
430 ret = { "mode" : "repo" }
431
432 return ret
433
92806f47
MT
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
fa6d335b
MT
449 def handle_repo_create(self):
450 path = self.args.path[0]
451
7c8f2953 452 pakfire.repo_create(path, self.args.inputs, **self.pakfire_args)
9613a111
MT
453
454
455class CliMaster(Cli):
677ff42a
MT
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
7c8f2953 471 self.master = server.master.Master()
677ff42a
MT
472
473 self.action2func = {
474 "update" : self.handle_update,
475 }
476
6557ff4c
MT
477 @property
478 def pakfire_args(self):
479 ret = { "mode" : "master" }
480
481 return ret
482
677ff42a
MT
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()
9613a111
MT
491
492
3ad4bb5a 493class CliServer(Cli):
677ff42a
MT
494 def __init__(self):
495 self.parser = argparse.ArgumentParser(
3ad4bb5a 496 description = _("Pakfire server command line interface."),
677ff42a
MT
497 )
498
499 self.parse_common_arguments()
500
501 # Add sub-commands.
502 self.sub_commands = self.parser.add_subparsers()
503
a52f536c 504 self.parse_command_build()
677ff42a
MT
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
3ad4bb5a 510 self.server = server.Server()
677ff42a
MT
511
512 self.action2func = {
a52f536c 513 "build" : self.handle_build,
677ff42a
MT
514 "keepalive" : self.handle_keepalive,
515 }
516
6557ff4c
MT
517 @property
518 def pakfire_args(self):
519 ret = { "mode" : "server" }
520
521 return ret
522
a52f536c
MT
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
677ff42a
MT
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):
3ad4bb5a 537 self.server.update_info()
9613a111 538
a52f536c 539 def handle_build(self):
3ad4bb5a 540 self.server.build_job()