]> git.ipfire.org Git - pakfire.git/blame - pakfire/cli.py
Fasten dependency resultion (a bit).
[pakfire.git] / pakfire / cli.py
CommitLineData
47a4cb89
MT
1#!/usr/bin/python
2
3import argparse
4import sys
5
6import packages
fa6d335b 7import repository
e9c20259 8import util
47a4cb89
MT
9
10from pakfire import Pakfire
11
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 31
47a4cb89 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()
c1962d40 53 self.parse_command_grouplist()
ce2764c1 54 self.parse_command_groupinstall()
67bc4528 55 self.parse_command_repolist()
47a4cb89
MT
56
57 # Finally parse all arguments from the command line and save them.
58 self.args = self.parser.parse_args()
59
60 # Create instance of the wonderful pakfire :)
61 self.pakfire = Pakfire(
62 self.args.instroot,
63 configs = [self.args.config],
f781b1ab 64 disable_repos = self.args.disable_repo,
47a4cb89
MT
65 )
66
67 self.action2func = {
5e87fa4f
MT
68 "install" : self.handle_install,
69 "localinstall" : self.handle_localinstall,
70 "update" : self.handle_update,
71 "info" : self.handle_info,
72 "search" : self.handle_search,
fa6d335b 73 "provides" : self.handle_provides,
c1962d40 74 "grouplist" : self.handle_grouplist,
ce2764c1 75 "groupinstall" : self.handle_groupinstall,
67bc4528 76 "repolist" : self.handle_repolist,
47a4cb89
MT
77 }
78
79 def parse_common_arguments(self):
80 self.parser.add_argument("-v", "--verbose", action="store_true",
81 help=_("Enable verbose output."))
82
83 self.parser.add_argument("-c", "--config", nargs="?",
84 help=_("Path to a configuration file to load."))
85
f781b1ab
MT
86 self.parser.add_argument("--disable-repo", nargs="*", metavar="REPO",
87 help=_("Disable a repository temporarily."))
88
47a4cb89
MT
89 def parse_command_install(self):
90 # Implement the "install" command.
91 sub_install = self.sub_commands.add_parser("install",
92 help=_("Install one or more packages to the system."))
93 sub_install.add_argument("package", nargs="+",
94 help=_("Give name of at least one package to install."))
95 sub_install.add_argument("action", action="store_const", const="install")
96
5e87fa4f
MT
97 def parse_command_localinstall(self):
98 # Implement the "localinstall" command.
99 sub_install = self.sub_commands.add_parser("localinstall",
100 help=_("Install one or more packages from the filesystem."))
101 sub_install.add_argument("package", nargs="+",
102 help=_("Give filename of at least one package."))
103 sub_install.add_argument("action", action="store_const", const="localinstall")
104
47a4cb89
MT
105 def parse_command_update(self):
106 # Implement the "update" command.
107 sub_update = self.sub_commands.add_parser("update",
108 help=_("Update the whole system or one specific package."))
109 sub_update.add_argument("package", nargs="*",
110 help=_("Give a name of a package to update or leave emtpy for all."))
111 sub_update.add_argument("action", action="store_const", const="update")
112
113 def parse_command_info(self):
114 # Implement the "info" command.
115 sub_info = self.sub_commands.add_parser("info",
116 help=_("Print some information about the given package(s)."))
117 sub_info.add_argument("package", nargs="+",
118 help=_("Give at least the name of one package."))
119 sub_info.add_argument("action", action="store_const", const="info")
120
121 def parse_command_search(self):
122 # Implement the "search" command.
123 sub_search = self.sub_commands.add_parser("search",
124 help=_("Search for a given pattern."))
125 sub_search.add_argument("pattern",
126 help=_("A pattern to search for."))
127 sub_search.add_argument("action", action="store_const", const="search")
128
fa6d335b
MT
129 def parse_command_provides(self):
130 # Implement the "provides" command
131 sub_provides = self.sub_commands.add_parser("provides",
132 help=_("Get a list of packages that provide a given file or feature."))
133 sub_provides.add_argument("pattern", nargs="+",
134 help=_("File or feature to search for."))
135 sub_provides.add_argument("action", action="store_const", const="provides")
136
c1962d40
MT
137 def parse_command_grouplist(self):
138 # Implement the "grouplist" command
139 sub_grouplist = self.sub_commands.add_parser("grouplist",
140 help=_("Get list of packages that belong to the given group."))
141 sub_grouplist.add_argument("group", nargs=1,
142 help=_("Group name to search for."))
143 sub_grouplist.add_argument("action", action="store_const", const="grouplist")
144
ce2764c1
MT
145 def parse_command_groupinstall(self):
146 # Implement the "grouplist" command
147 sub_groupinstall = self.sub_commands.add_parser("groupinstall",
148 help=_("Install all packages that belong to the given group."))
149 sub_groupinstall.add_argument("group", nargs=1,
150 help=_("Group name."))
151 sub_groupinstall.add_argument("action", action="store_const", const="groupinstall")
152
67bc4528
MT
153 def parse_command_repolist(self):
154 # Implement the "repolist" command
155 sub_repolist = self.sub_commands.add_parser("repolist",
156 help=_("List all currently enabled repositories."))
157 sub_repolist.add_argument("action", action="store_const", const="repolist")
ce2764c1 158
47a4cb89
MT
159 def run(self):
160 action = self.args.action
161
162 if not self.action2func.has_key(action):
163 raise
164
165 try:
166 func = self.action2func[action]
167 except KeyError:
168 raise # XXX catch and return better error message
169
170 return func()
171
9afa5620 172 def handle_info(self, long=False):
47a4cb89
MT
173 for pattern in self.args.package:
174 pkgs = self.pakfire.repos.get_by_glob(pattern)
175
176 pkgs = packages.PackageListing(pkgs)
177
178 for pkg in pkgs:
9afa5620 179 print pkg.dump(long=long)
47a4cb89
MT
180
181 def handle_search(self):
182 pkgs = self.pakfire.repos.search(self.args.pattern)
183
184 pkgs = packages.PackageListing(pkgs)
185
186 for pkg in pkgs:
187 print pkg.dump(short=True)
188
189 def handle_update(self):
a412c989 190 self.pakfire.update(self.args.package)
47a4cb89 191
5e87fa4f
MT
192 def handle_install(self, local=False):
193 if local:
194 repo = repository.FileSystemRepository(self.pakfire)
195
196 pkgs = []
197 for pkg in self.args.package:
198 if local and os.path.exists(pkg):
199 pkg = packages.BinaryPackage(self.pakfire, repo, pkg)
200
201 pkgs.append(pkg)
202
203 self.pakfire.install(pkgs)
204
205 def handle_localinstall(self):
206 return self.handle_install(local=True)
207
fa6d335b
MT
208 def handle_provides(self):
209 pkgs = self.pakfire.provides(self.args.pattern)
210
211 for pkg in pkgs:
212 print pkg.dump()
213
c1962d40
MT
214 def handle_grouplist(self):
215 pkgs = self.pakfire.grouplist(self.args.group[0])
216
217 for pkg in pkgs:
218 print " * %s" % pkg
219
ce2764c1
MT
220 def handle_groupinstall(self):
221 self.pakfire.groupinstall(self.args.group[0])
222
67bc4528
MT
223 def handle_repolist(self):
224 repos = self.pakfire.repolist()
225 repos.sort()
226
227 FORMAT = " %-20s %8s %12s "
228
229 title = FORMAT % (_("Repository"), _("Enabled"), _("Priority"))
230 print title
231 print "=" * len(title) # spacing line
232
233 for repo in repos:
234 # Skip the installed repository.
235 if repo.name == "installed":
236 continue
237
238 print FORMAT % (repo.name, repo.enabled, repo.priority)
239
47a4cb89
MT
240
241class CliBuilder(Cli):
242 def __init__(self):
243 self.parser = argparse.ArgumentParser(
244 description = _("Pakfire builder command line interface."),
245 )
246
247 self.parse_common_arguments()
248
249 # Add sub-commands.
250 self.sub_commands = self.parser.add_subparsers()
251
252 self.parse_command_build()
253 self.parse_command_dist()
254 self.parse_command_info()
255 self.parse_command_search()
256 self.parse_command_shell()
257 self.parse_command_update()
4fbd4216 258 self.parse_command_provides()
2c84aceb 259 self.parse_command_grouplist()
67bc4528 260 self.parse_command_repolist()
47a4cb89
MT
261
262 # Finally parse all arguments from the command line and save them.
263 self.args = self.parser.parse_args()
264
265 self.pakfire = Pakfire(
266 builder = True,
267 configs = [self.args.config],
f781b1ab 268 disable_repos = self.args.disable_repo,
47a4cb89
MT
269 )
270
271 self.action2func = {
fa6d335b
MT
272 "build" : self.handle_build,
273 "dist" : self.handle_dist,
274 "update" : self.handle_update,
275 "info" : self.handle_info,
276 "search" : self.handle_search,
277 "shell" : self.handle_shell,
4fbd4216 278 "provides" : self.handle_provides,
2c84aceb 279 "grouplist" : self.handle_grouplist,
67bc4528 280 "repolist" : self.handle_repolist,
47a4cb89
MT
281 }
282
283 def parse_command_update(self):
284 # Implement the "update" command.
285 sub_update = self.sub_commands.add_parser("update",
286 help=_("Update the package indexes."))
287 sub_update.add_argument("action", action="store_const", const="update")
288
289 def parse_command_build(self):
290 # Implement the "build" command.
291 sub_build = self.sub_commands.add_parser("build",
292 help=_("Build one or more packages."))
293 sub_build.add_argument("package", nargs=1,
294 help=_("Give name of at least one package to build."))
295 sub_build.add_argument("action", action="store_const", const="build")
296
297 sub_build.add_argument("-a", "--arch",
298 help=_("Build the package for the given architecture."))
299 sub_build.add_argument("--resultdir", nargs="?",
300 help=_("Path were the output files should be copied to."))
301
302 def parse_command_shell(self):
303 # Implement the "shell" command.
304 sub_shell = self.sub_commands.add_parser("shell",
305 help=_("Go into a shell."))
042266f3 306 sub_shell.add_argument("package", nargs="?",
47a4cb89
MT
307 help=_("Give name of a package."))
308 sub_shell.add_argument("action", action="store_const", const="shell")
309
310 sub_shell.add_argument("-a", "--arch",
311 help=_("Emulated architecture in the shell."))
312
313 def parse_command_dist(self):
314 # Implement the "dist" command.
315 sub_dist = self.sub_commands.add_parser("dist",
316 help=_("Generate a source package."))
e412b8dc
MT
317 sub_dist.add_argument("package", nargs="+",
318 help=_("Give name(s) of a package(s)."))
47a4cb89
MT
319 sub_dist.add_argument("action", action="store_const", const="dist")
320
321 sub_dist.add_argument("--resultdir", nargs="?",
322 help=_("Path were the output files should be copied to."))
323
9afa5620
MT
324 def handle_info(self):
325 Cli.handle_info(self, long=True)
326
47a4cb89 327 def handle_build(self):
47a4cb89
MT
328 # Get the package descriptor from the command line options
329 pkg = self.args.package[0]
330
331 # Check, if we got a regular file
332 if os.path.exists(pkg):
333 pkg = os.path.abspath(pkg)
334
335 if pkg.endswith(MAKEFILE_EXTENSION):
3723913b 336 pkg = packages.Makefile(self.pakfire, pkg)
47a4cb89
MT
337
338 elif pkg.endswith(PACKAGE_EXTENSION):
3723913b
MT
339 repo = repository.FileSystemRepository(self.pakfire)
340 pkg = packages.SourcePackage(self.pakfire, repo, pkg)
47a4cb89
MT
341
342 else:
343 # XXX walk through the source tree and find a matching makefile
344 pass
345
0ec833c6 346 self.pakfire.build(pkg, arch=self.args.arch, resultdirs=[self.args.resultdir,])
47a4cb89
MT
347
348 def handle_shell(self):
042266f3
MT
349 pkg = None
350
47a4cb89 351 # Get the package descriptor from the command line options
042266f3 352 if self.args.package:
ad1b844f 353 pkg = self.args.package
47a4cb89
MT
354
355 # Check, if we got a regular file
042266f3 356 if pkg and os.path.exists(pkg):
47a4cb89
MT
357 pkg = os.path.abspath(pkg)
358
359 if pkg.endswith(MAKEFILE_EXTENSION):
3723913b 360 pkg = packages.Makefile(self.pakfire, pkg)
47a4cb89
MT
361
362 elif pkg.endswith(PACKAGE_EXTENSION):
3723913b
MT
363 repo = repository.FileSystemRepository(self.pakfire)
364 pkg = packages.SourcePackage(self.pakfire, repo, pkg)
47a4cb89
MT
365
366 else:
367 # XXX walk through the source tree and find a matching makefile
368 pass
369
370 self.pakfire.shell(pkg, arch=self.args.arch)
371
372 def handle_dist(self):
e412b8dc
MT
373 # Get the packages from the command line options
374 pkgs = []
47a4cb89 375
e412b8dc
MT
376 for pkg in self.args.package:
377 # Check, if we got a regular file
378 if os.path.exists(pkg):
379 pkg = os.path.abspath(pkg)
47a4cb89 380
e412b8dc
MT
381 if pkg.endswith(MAKEFILE_EXTENSION):
382 pkg = packages.Makefile(self.pakfire, pkg)
383 pkgs.append(pkg)
47a4cb89 384
e412b8dc
MT
385 else:
386 # XXX walk through the source tree and find a matching makefile
387 pass
47a4cb89 388
e412b8dc 389 self.pakfire.dist(pkgs, resultdirs=[self.args.resultdir,])
47a4cb89 390
92806f47
MT
391class CliServer(Cli):
392 def __init__(self):
393 self.parser = argparse.ArgumentParser(
394 description = _("Pakfire server command line interface."),
395 )
396
397 self.parse_common_arguments()
398
399 # Add sub-commands.
400 self.sub_commands = self.parser.add_subparsers()
401
402 self.parse_command_repo()
403
404 # Finally parse all arguments from the command line and save them.
405 self.args = self.parser.parse_args()
406
407 self.pakfire = Pakfire(
408 builder = True,
409 configs = [self.args.config],
410 disable_repos = self.args.disable_repo,
411 )
412
413 self.action2func = {
414 "repo_create" : self.handle_repo_create,
415 }
416
417 def parse_command_repo(self):
418 sub_repo = self.sub_commands.add_parser("repo",
419 help=_("Repository management commands."))
420
421 sub_repo_commands = sub_repo.add_subparsers()
422
423 self.parse_command_repo_create(sub_repo_commands)
424
425 def parse_command_repo_create(self, sub_commands):
426 sub_create = sub_commands.add_parser("create",
427 help=_("Create a new repository index."))
428 sub_create.add_argument("path", nargs=1, help=_("Path to the packages."))
429 sub_create.add_argument("inputs", nargs="+", help=_("Path to input packages."))
430 sub_create.add_argument("action", action="store_const", const="repo_create")
431
fa6d335b
MT
432 def handle_repo_create(self):
433 path = self.args.path[0]
434
66af936c 435 self.pakfire.repo_create(path, self.args.inputs)