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