]>
git.ipfire.org Git - pakfire.git/blob - pakfire/cli.py
2 ###############################################################################
4 # Pakfire - The IPFire package management system #
5 # Copyright (C) 2011 Pakfire development team #
7 # This program is free software: you can redistribute it and/or modify #
8 # it under the terms of the GNU General Public License as published by #
9 # the Free Software Foundation, either version 3 of the License, or #
10 # (at your option) any later version. #
12 # This program is distributed in the hope that it will be useful, #
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of #
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
15 # GNU General Public License for more details. #
17 # You should have received a copy of the GNU General Public License #
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. #
20 ###############################################################################
31 import pakfire
.api
as pakfire
32 from constants
import *
35 # Initialize a very simple logging that is removed when a Pakfire instance
37 logger
.setup_logging()
41 self
.parser
= argparse
.ArgumentParser(
42 description
= _("Pakfire command line interface."),
45 self
.parse_common_arguments()
47 self
.parser
.add_argument("--root", metavar
="PATH",
49 help=_("The path where pakfire should operate in."))
52 self
.sub_commands
= self
.parser
.add_subparsers()
54 self
.parse_command_install()
55 self
.parse_command_localinstall()
56 self
.parse_command_remove()
57 self
.parse_command_info()
58 self
.parse_command_search()
59 self
.parse_command_check_update()
60 self
.parse_command_update()
61 self
.parse_command_provides()
62 self
.parse_command_grouplist()
63 self
.parse_command_groupinstall()
64 self
.parse_command_repolist()
65 self
.parse_command_clean()
66 self
.parse_command_check()
67 self
.parse_command_resolvdep()
69 # Finally parse all arguments from the command line and save them.
70 self
.args
= self
.parser
.parse_args()
73 "install" : self
.handle_install
,
74 "localinstall" : self
.handle_localinstall
,
75 "remove" : self
.handle_remove
,
76 "check_update" : self
.handle_check_update
,
77 "update" : self
.handle_update
,
78 "info" : self
.handle_info
,
79 "search" : self
.handle_search
,
80 "provides" : self
.handle_provides
,
81 "grouplist" : self
.handle_grouplist
,
82 "groupinstall" : self
.handle_groupinstall
,
83 "repolist" : self
.handle_repolist
,
84 "clean_all" : self
.handle_clean_all
,
85 "check" : self
.handle_check
,
86 "resolvdep" : self
.handle_resolvdep
,
90 def pakfire_args(self
):
91 ret
= { "mode" : "normal" }
93 if hasattr(self
.args
, "root"):
94 ret
["path"] = self
.args
.root
96 if hasattr(self
.args
, "disable_repo"):
97 ret
["disable_repos"] = self
.args
.disable_repo
99 if hasattr(self
.args
, "enable_repo"):
100 ret
["enable_repos"] = self
.args
.enable_repo
102 if hasattr(self
.args
, "offline"):
103 ret
["offline"] = self
.args
.offline
107 def parse_common_arguments(self
):
108 self
.parser
.add_argument("--version", action
="version",
109 version
="%(prog)s " + PAKFIRE_VERSION
)
111 self
.parser
.add_argument("-v", "--verbose", action
="store_true",
112 help=_("Enable verbose output."))
114 self
.parser
.add_argument("-c", "--config", nargs
="?",
115 help=_("Path to a configuration file to load."))
117 self
.parser
.add_argument("--disable-repo", nargs
="*", metavar
="REPO",
118 help=_("Disable a repository temporarily."))
120 self
.parser
.add_argument("--enabled-repo", nargs
="*", metavar
="REPO",
121 help=_("Enable a repository temporarily."))
123 self
.parser
.add_argument("--offline", action
="store_true",
124 help=_("Run pakfire in offline mode."))
126 def parse_command_install(self
):
127 # Implement the "install" command.
128 sub_install
= self
.sub_commands
.add_parser("install",
129 help=_("Install one or more packages to the system."))
130 sub_install
.add_argument("package", nargs
="+",
131 help=_("Give name of at least one package to install."))
132 sub_install
.add_argument("action", action
="store_const", const
="install")
134 def parse_command_localinstall(self
):
135 # Implement the "localinstall" command.
136 sub_install
= self
.sub_commands
.add_parser("localinstall",
137 help=_("Install one or more packages from the filesystem."))
138 sub_install
.add_argument("package", nargs
="+",
139 help=_("Give filename of at least one package."))
140 sub_install
.add_argument("action", action
="store_const", const
="localinstall")
142 def parse_command_remove(self
):
143 # Implement the "remove" command.
144 sub_remove
= self
.sub_commands
.add_parser("remove",
145 help=_("Remove one or more packages from the system."))
146 sub_remove
.add_argument("package", nargs
="+",
147 help=_("Give name of at least one package to remove."))
148 sub_remove
.add_argument("action", action
="store_const", const
="remove")
150 def parse_command_update(self
):
151 # Implement the "update" command.
152 sub_update
= self
.sub_commands
.add_parser("update",
153 help=_("Update the whole system or one specific package."))
154 sub_update
.add_argument("package", nargs
="*",
155 help=_("Give a name of a package to update or leave emtpy for all."))
156 sub_update
.add_argument("action", action
="store_const", const
="update")
158 def parse_command_check_update(self
):
159 # Implement the "check-update" command.
160 sub_check_update
= self
.sub_commands
.add_parser("check-update",
161 help=_("Check, if there are any updates available."))
162 sub_check_update
.add_argument("package", nargs
="*",
163 help=_("Give a name of a package to update or leave emtpy for all."))
164 sub_check_update
.add_argument("action", action
="store_const", const
="check_update")
166 def parse_command_info(self
):
167 # Implement the "info" command.
168 sub_info
= self
.sub_commands
.add_parser("info",
169 help=_("Print some information about the given package(s)."))
170 sub_info
.add_argument("package", nargs
="+",
171 help=_("Give at least the name of one package."))
172 sub_info
.add_argument("action", action
="store_const", const
="info")
174 def parse_command_search(self
):
175 # Implement the "search" command.
176 sub_search
= self
.sub_commands
.add_parser("search",
177 help=_("Search for a given pattern."))
178 sub_search
.add_argument("pattern",
179 help=_("A pattern to search for."))
180 sub_search
.add_argument("action", action
="store_const", const
="search")
182 def parse_command_provides(self
):
183 # Implement the "provides" command
184 sub_provides
= self
.sub_commands
.add_parser("provides",
185 help=_("Get a list of packages that provide a given file or feature."))
186 sub_provides
.add_argument("pattern", nargs
="+",
187 help=_("File or feature to search for."))
188 sub_provides
.add_argument("action", action
="store_const", const
="provides")
190 def parse_command_grouplist(self
):
191 # Implement the "grouplist" command
192 sub_grouplist
= self
.sub_commands
.add_parser("grouplist",
193 help=_("Get list of packages that belong to the given group."))
194 sub_grouplist
.add_argument("group", nargs
=1,
195 help=_("Group name to search for."))
196 sub_grouplist
.add_argument("action", action
="store_const", const
="grouplist")
198 def parse_command_groupinstall(self
):
199 # Implement the "grouplist" command
200 sub_groupinstall
= self
.sub_commands
.add_parser("groupinstall",
201 help=_("Install all packages that belong to the given group."))
202 sub_groupinstall
.add_argument("group", nargs
=1,
203 help=_("Group name."))
204 sub_groupinstall
.add_argument("action", action
="store_const", const
="groupinstall")
206 def parse_command_repolist(self
):
207 # Implement the "repolist" command
208 sub_repolist
= self
.sub_commands
.add_parser("repolist",
209 help=_("List all currently enabled repositories."))
210 sub_repolist
.add_argument("action", action
="store_const", const
="repolist")
212 def parse_command_clean(self
):
213 sub_clean
= self
.sub_commands
.add_parser("clean", help=_("Cleanup commands."))
215 sub_clean_commands
= sub_clean
.add_subparsers()
217 self
.parse_command_clean_all(sub_clean_commands
)
219 def parse_command_clean_all(self
, sub_commands
):
220 sub_create
= sub_commands
.add_parser("all",
221 help=_("Cleanup all temporary files."))
222 sub_create
.add_argument("action", action
="store_const", const
="clean_all")
224 def parse_command_check(self
):
225 # Implement the "check" command
226 sub_check
= self
.sub_commands
.add_parser("check",
227 help=_("Check the system for any errors."))
228 sub_check
.add_argument("action", action
="store_const", const
="check")
230 def parse_command_resolvdep(self
):
231 # Implement the "resolvdep" command.
232 sub_resolvdep
= self
.sub_commands
.add_parser("resolvdep",
233 help=_("Check the dependencies for a particular package."))
234 sub_resolvdep
.add_argument("package", nargs
="+",
235 help=_("Give name of at least one package to check."))
236 sub_resolvdep
.add_argument("action", action
="store_const", const
="resolvdep")
239 action
= self
.args
.action
241 if not self
.action2func
.has_key(action
):
245 func
= self
.action2func
[action
]
247 raise # XXX catch and return better error message
251 def handle_info(self
, long=False):
252 pkgs
= pakfire
.info(self
.args
.package
, **self
.pakfire_args
)
255 print pkg
.dump(long=long)
257 def handle_search(self
):
258 pkgs
= pakfire
.search(self
.args
.pattern
, **self
.pakfire_args
)
261 print pkg
.dump(short
=True)
263 def handle_update(self
):
264 pakfire
.update(self
.args
.package
, **self
.pakfire_args
)
266 def handle_check_update(self
):
267 pakfire
.update(self
.args
.package
, check
=True, **self
.pakfire_args
)
269 def handle_install(self
):
270 pakfire
.install(self
.args
.package
, **self
.pakfire_args
)
272 def handle_localinstall(self
):
273 pakfire
.localinstall(self
.args
.package
, **self
.pakfire_args
)
275 def handle_remove(self
):
276 pakfire
.remove(self
.args
.package
, **self
.pakfire_args
)
278 def handle_provides(self
):
279 pkgs
= pakfire
.provides(self
.args
.pattern
, **self
.pakfire_args
)
284 def handle_grouplist(self
):
285 pkgs
= pakfire
.grouplist(self
.args
.group
[0], **self
.pakfire_args
)
290 def handle_groupinstall(self
):
291 pakfire
.groupinstall(self
.args
.group
[0], **self
.pakfire_args
)
293 def handle_repolist(self
):
294 repos
= pakfire
.repo_list(**self
.pakfire_args
)
296 FORMAT
= " %-20s %8s %12s %12s "
298 title
= FORMAT
% (_("Repository"), _("Enabled"), _("Priority"), _("Packages"))
300 print "=" * len(title
) # spacing line
303 # Skip the installed repository.
304 if repo
.name
== "installed":
307 print FORMAT
% (repo
.name
, repo
.enabled
, repo
.priority
, len(repo
))
309 def handle_clean_all(self
):
310 print _("Cleaning up everything...")
312 pakfire
.clean_all(**self
.pakfire_args
)
314 def handle_check(self
):
315 pakfire
.check(**self
.pakfire_args
)
317 def handle_resolvdep(self
):
318 pakfire
.resolvdep(self
.args
.package
, **self
.pakfire_args
)
321 class CliBuilder(Cli
):
323 self
.parser
= argparse
.ArgumentParser(
324 description
= _("Pakfire builder command line interface."),
327 self
.parse_common_arguments()
330 self
.sub_commands
= self
.parser
.add_subparsers()
332 self
.parse_command_build()
333 self
.parse_command_dist()
334 self
.parse_command_info()
335 self
.parse_command_search()
336 self
.parse_command_shell()
337 self
.parse_command_update()
338 self
.parse_command_provides()
339 self
.parse_command_grouplist()
340 self
.parse_command_repolist()
341 self
.parse_command_clean()
342 self
.parse_command_resolvdep()
344 # Finally parse all arguments from the command line and save them.
345 self
.args
= self
.parser
.parse_args()
348 "build" : self
.handle_build
,
349 "dist" : self
.handle_dist
,
350 "update" : self
.handle_update
,
351 "info" : self
.handle_info
,
352 "search" : self
.handle_search
,
353 "shell" : self
.handle_shell
,
354 "provides" : self
.handle_provides
,
355 "grouplist" : self
.handle_grouplist
,
356 "repolist" : self
.handle_repolist
,
357 "clean_all" : self
.handle_clean_all
,
358 "resolvdep" : self
.handle_resolvdep
,
362 def pakfire_args(self
):
363 ret
= { "mode" : "builder" }
365 if hasattr(self
.args
, "disable_repo"):
366 ret
["disable_repos"] = self
.args
.disable_repo
368 if hasattr(self
.args
, "enable_repo"):
369 ret
["enable_repos"] = self
.args
.enable_repo
371 if hasattr(self
.args
, "offline"):
372 ret
["offline"] = self
.args
.offline
376 def parse_command_update(self
):
377 # Implement the "update" command.
378 sub_update
= self
.sub_commands
.add_parser("update",
379 help=_("Update the package indexes."))
380 sub_update
.add_argument("action", action
="store_const", const
="update")
382 def parse_command_build(self
):
383 # Implement the "build" command.
384 sub_build
= self
.sub_commands
.add_parser("build",
385 help=_("Build one or more packages."))
386 sub_build
.add_argument("package", nargs
=1,
387 help=_("Give name of at least one package to build."))
388 sub_build
.add_argument("action", action
="store_const", const
="build")
390 sub_build
.add_argument("-a", "--arch",
391 help=_("Build the package for the given architecture."))
392 sub_build
.add_argument("--resultdir", nargs
="?",
393 help=_("Path were the output files should be copied to."))
394 sub_build
.add_argument("-m", "--mode", nargs
="?", default
="development",
395 help=_("Mode to run in. Is either 'release' or 'development' (default)."))
397 def parse_command_shell(self
):
398 # Implement the "shell" command.
399 sub_shell
= self
.sub_commands
.add_parser("shell",
400 help=_("Go into a shell."))
401 sub_shell
.add_argument("package", nargs
="?",
402 help=_("Give name of a package."))
403 sub_shell
.add_argument("action", action
="store_const", const
="shell")
405 sub_shell
.add_argument("-a", "--arch",
406 help=_("Emulated architecture in the shell."))
407 sub_shell
.add_argument("-m", "--mode", nargs
="?", default
="development",
408 help=_("Mode to run in. Is either 'release' or 'development' (default)."))
410 def parse_command_dist(self
):
411 # Implement the "dist" command.
412 sub_dist
= self
.sub_commands
.add_parser("dist",
413 help=_("Generate a source package."))
414 sub_dist
.add_argument("package", nargs
="+",
415 help=_("Give name(s) of a package(s)."))
416 sub_dist
.add_argument("action", action
="store_const", const
="dist")
418 sub_dist
.add_argument("--resultdir", nargs
="?",
419 help=_("Path were the output files should be copied to."))
421 def handle_info(self
):
422 Cli
.handle_info(self
, long=True)
424 def handle_build(self
):
425 # Get the package descriptor from the command line options
426 pkg
= self
.args
.package
[0]
428 # Check, if we got a regular file
429 if os
.path
.exists(pkg
):
430 pkg
= os
.path
.abspath(pkg
)
433 raise FileNotFoundError
, pkg
435 # Create distribution configuration from command line.
437 "arch" : self
.args
.arch
,
440 pakfire
.build(pkg
, builder_mode
=self
.args
.mode
,
441 distro_config
=distro_config
, resultdirs
=[self
.args
.resultdir
,],
442 shell
=True, **self
.pakfire_args
)
444 def handle_shell(self
):
447 # Get the package descriptor from the command line options
448 if self
.args
.package
:
449 pkg
= self
.args
.package
451 # Check, if we got a regular file
452 if os
.path
.exists(pkg
):
453 pkg
= os
.path
.abspath(pkg
)
456 raise FileNotFoundError
, pkg
458 # Create distribution configuration from command line.
460 "arch" : self
.args
.arch
,
463 pakfire
.shell(pkg
, builder_mode
=self
.args
.mode
,
464 distro_config
=distro_config
, **self
.pakfire_args
)
466 def handle_dist(self
):
467 # Get the packages from the command line options
470 for pkg
in self
.args
.package
:
471 # Check, if we got a regular file
472 if os
.path
.exists(pkg
):
473 pkg
= os
.path
.abspath(pkg
)
477 raise FileNotFoundError
, pkg
479 pakfire
.dist(pkgs
, resultdirs
=[self
.args
.resultdir
,],
482 def handle_provides(self
):
483 pkgs
= pakfire
.provides(self
.args
.pattern
, **self
.pakfire_args
)
486 print pkg
.dump(long=True)
489 class CliServer(Cli
):
491 self
.parser
= argparse
.ArgumentParser(
492 description
= _("Pakfire server command line interface."),
495 self
.parse_common_arguments()
498 self
.sub_commands
= self
.parser
.add_subparsers()
500 self
.parse_command_build()
501 self
.parse_command_keepalive()
502 self
.parse_command_repoupdate()
503 self
.parse_command_repo()
505 # Finally parse all arguments from the command line and save them.
506 self
.args
= self
.parser
.parse_args()
508 self
.server
= server
.Server()
511 "build" : self
.handle_build
,
512 "keepalive" : self
.handle_keepalive
,
513 "repoupdate" : self
.handle_repoupdate
,
514 "repo_create": self
.handle_repo_create
,
518 def pakfire_args(self
):
519 ret
= { "mode" : "server" }
521 if hasattr(self
.args
, "offline"):
522 ret
["offline"] = self
.args
.offline
526 def parse_command_build(self
):
527 # Implement the "build" command.
528 sub_keepalive
= self
.sub_commands
.add_parser("build",
529 help=_("Request a build job from the server."))
530 sub_keepalive
.add_argument("action", action
="store_const", const
="build")
532 def parse_command_keepalive(self
):
533 # Implement the "keepalive" command.
534 sub_keepalive
= self
.sub_commands
.add_parser("keepalive",
535 help=_("Send a keepalive to the server."))
536 sub_keepalive
.add_argument("action", action
="store_const",
539 def parse_command_repoupdate(self
):
540 # Implement the "repoupdate" command.
541 sub_repoupdate
= self
.sub_commands
.add_parser("repoupdate",
542 help=_("Update all repositories."))
543 sub_repoupdate
.add_argument("action", action
="store_const",
546 def parse_command_repo(self
):
547 sub_repo
= self
.sub_commands
.add_parser("repo",
548 help=_("Repository management commands."))
550 sub_repo_commands
= sub_repo
.add_subparsers()
552 self
.parse_command_repo_create(sub_repo_commands
)
554 def parse_command_repo_create(self
, sub_commands
):
555 sub_create
= sub_commands
.add_parser("create",
556 help=_("Create a new repository index."))
557 sub_create
.add_argument("path", nargs
=1, help=_("Path to the packages."))
558 sub_create
.add_argument("inputs", nargs
="+", help=_("Path to input packages."))
559 sub_create
.add_argument("action", action
="store_const", const
="repo_create")
561 def handle_keepalive(self
):
562 self
.server
.update_info()
564 def handle_build(self
):
565 self
.server
.build_job()
567 def handle_repoupdate(self
):
568 self
.server
.update_repositories()
570 def handle_repo_create(self
):
571 path
= self
.args
.path
[0]
573 pakfire
.repo_create(path
, self
.args
.inputs
, **self
.pakfire_args
)
576 class CliBuilderIntern(Cli
):
578 self
.parser
= argparse
.ArgumentParser(
579 description
= _("Pakfire builder command line interface."),
582 self
.parse_common_arguments()
585 self
.sub_commands
= self
.parser
.add_subparsers()
587 self
.parse_command_build()
589 # Finally parse all arguments from the command line and save them.
590 self
.args
= self
.parser
.parse_args()
593 "build" : self
.handle_build
,
596 def parse_command_build(self
):
597 # Implement the "build" command.
598 sub_build
= self
.sub_commands
.add_parser("build",
599 help=_("Build one or more packages."))
600 sub_build
.add_argument("package", nargs
=1,
601 help=_("Give name of at least one package to build."))
602 sub_build
.add_argument("action", action
="store_const", const
="build")
604 sub_build
.add_argument("-a", "--arch",
605 help=_("Build the package for the given architecture."))
606 sub_build
.add_argument("--resultdir", nargs
="?",
607 help=_("Path were the output files should be copied to."))
608 sub_build
.add_argument("-m", "--mode", nargs
="?", default
="development",
609 help=_("Mode to run in. Is either 'release' or 'development' (default)."))
610 sub_build
.add_argument("--nodeps", action
="store_true",
611 help=_("Do not verify build dependencies."))
613 def handle_build(self
):
614 # Get the package descriptor from the command line options
615 pkg
= self
.args
.package
[0]
617 # Check, if we got a regular file
618 if os
.path
.exists(pkg
):
619 pkg
= os
.path
.abspath(pkg
)
621 raise FileNotFoundError
, pkg
623 # Create distribution configuration from command line.
625 "arch" : self
.args
.arch
,
628 pakfire
._build
(pkg
, builder_mode
=self
.args
.mode
,
629 distro_config
=distro_config
, resultdir
=self
.args
.resultdir
,
630 nodeps
=self
.args
.nodeps
, **self
.pakfire_args
)