]>
git.ipfire.org Git - pakfire.git/blob - python/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 ###############################################################################
32 import pakfire
.api
as pakfire
33 from constants
import *
36 # Initialize a very simple logging that is removed when a Pakfire instance
38 logger
.setup_logging()
42 self
.parser
= argparse
.ArgumentParser(
43 description
= _("Pakfire command line interface."),
46 self
.parse_common_arguments()
48 self
.parser
.add_argument("--root", metavar
="PATH",
50 help=_("The path where pakfire should operate in."))
53 self
.sub_commands
= self
.parser
.add_subparsers()
55 self
.parse_command_install()
56 self
.parse_command_localinstall()
57 self
.parse_command_remove()
58 self
.parse_command_info()
59 self
.parse_command_search()
60 self
.parse_command_check_update()
61 self
.parse_command_update()
62 self
.parse_command_provides()
63 self
.parse_command_grouplist()
64 self
.parse_command_groupinstall()
65 self
.parse_command_repolist()
66 self
.parse_command_clean()
67 self
.parse_command_check()
68 self
.parse_command_resolvdep()
70 # Finally parse all arguments from the command line and save them.
71 self
.args
= self
.parser
.parse_args()
74 "install" : self
.handle_install
,
75 "localinstall" : self
.handle_localinstall
,
76 "remove" : self
.handle_remove
,
77 "check_update" : self
.handle_check_update
,
78 "update" : self
.handle_update
,
79 "info" : self
.handle_info
,
80 "search" : self
.handle_search
,
81 "provides" : self
.handle_provides
,
82 "grouplist" : self
.handle_grouplist
,
83 "groupinstall" : self
.handle_groupinstall
,
84 "repolist" : self
.handle_repolist
,
85 "clean_all" : self
.handle_clean_all
,
86 "check" : self
.handle_check
,
87 "resolvdep" : self
.handle_resolvdep
,
91 def pakfire_args(self
):
92 ret
= { "mode" : "normal" }
94 if hasattr(self
.args
, "root"):
95 ret
["path"] = self
.args
.root
97 if hasattr(self
.args
, "disable_repo"):
98 ret
["disable_repos"] = self
.args
.disable_repo
100 if hasattr(self
.args
, "enable_repo"):
101 ret
["enable_repos"] = self
.args
.enable_repo
103 if hasattr(self
.args
, "offline"):
104 ret
["offline"] = self
.args
.offline
108 def parse_common_arguments(self
):
109 self
.parser
.add_argument("--version", action
="version",
110 version
="%(prog)s " + PAKFIRE_VERSION
)
112 self
.parser
.add_argument("-v", "--verbose", action
="store_true",
113 help=_("Enable verbose output."))
115 self
.parser
.add_argument("-c", "--config", nargs
="?",
116 help=_("Path to a configuration file to load."))
118 self
.parser
.add_argument("--disable-repo", nargs
="*", metavar
="REPO",
119 help=_("Disable a repository temporarily."))
121 self
.parser
.add_argument("--enabled-repo", nargs
="*", metavar
="REPO",
122 help=_("Enable a repository temporarily."))
124 self
.parser
.add_argument("--offline", action
="store_true",
125 help=_("Run pakfire in offline mode."))
127 def parse_command_install(self
):
128 # Implement the "install" command.
129 sub_install
= self
.sub_commands
.add_parser("install",
130 help=_("Install one or more packages to the system."))
131 sub_install
.add_argument("package", nargs
="+",
132 help=_("Give name of at least one package to install."))
133 sub_install
.add_argument("action", action
="store_const", const
="install")
135 def parse_command_localinstall(self
):
136 # Implement the "localinstall" command.
137 sub_install
= self
.sub_commands
.add_parser("localinstall",
138 help=_("Install one or more packages from the filesystem."))
139 sub_install
.add_argument("package", nargs
="+",
140 help=_("Give filename of at least one package."))
141 sub_install
.add_argument("action", action
="store_const", const
="localinstall")
143 def parse_command_remove(self
):
144 # Implement the "remove" command.
145 sub_remove
= self
.sub_commands
.add_parser("remove",
146 help=_("Remove one or more packages from the system."))
147 sub_remove
.add_argument("package", nargs
="+",
148 help=_("Give name of at least one package to remove."))
149 sub_remove
.add_argument("action", action
="store_const", const
="remove")
151 def parse_command_update(self
):
152 # Implement the "update" command.
153 sub_update
= self
.sub_commands
.add_parser("update",
154 help=_("Update the whole system or one specific package."))
155 sub_update
.add_argument("package", nargs
="*",
156 help=_("Give a name of a package to update or leave emtpy for all."))
157 sub_update
.add_argument("action", action
="store_const", const
="update")
159 def parse_command_check_update(self
):
160 # Implement the "check-update" command.
161 sub_check_update
= self
.sub_commands
.add_parser("check-update",
162 help=_("Check, if there are any updates available."))
163 sub_check_update
.add_argument("package", nargs
="*",
164 help=_("Give a name of a package to update or leave emtpy for all."))
165 sub_check_update
.add_argument("action", action
="store_const", const
="check_update")
167 def parse_command_info(self
):
168 # Implement the "info" command.
169 sub_info
= self
.sub_commands
.add_parser("info",
170 help=_("Print some information about the given package(s)."))
171 sub_info
.add_argument("package", nargs
="+",
172 help=_("Give at least the name of one package."))
173 sub_info
.add_argument("action", action
="store_const", const
="info")
175 def parse_command_search(self
):
176 # Implement the "search" command.
177 sub_search
= self
.sub_commands
.add_parser("search",
178 help=_("Search for a given pattern."))
179 sub_search
.add_argument("pattern",
180 help=_("A pattern to search for."))
181 sub_search
.add_argument("action", action
="store_const", const
="search")
183 def parse_command_provides(self
):
184 # Implement the "provides" command
185 sub_provides
= self
.sub_commands
.add_parser("provides",
186 help=_("Get a list of packages that provide a given file or feature."))
187 sub_provides
.add_argument("pattern", nargs
="+",
188 help=_("File or feature to search for."))
189 sub_provides
.add_argument("action", action
="store_const", const
="provides")
191 def parse_command_grouplist(self
):
192 # Implement the "grouplist" command
193 sub_grouplist
= self
.sub_commands
.add_parser("grouplist",
194 help=_("Get list of packages that belong to the given group."))
195 sub_grouplist
.add_argument("group", nargs
=1,
196 help=_("Group name to search for."))
197 sub_grouplist
.add_argument("action", action
="store_const", const
="grouplist")
199 def parse_command_groupinstall(self
):
200 # Implement the "grouplist" command
201 sub_groupinstall
= self
.sub_commands
.add_parser("groupinstall",
202 help=_("Install all packages that belong to the given group."))
203 sub_groupinstall
.add_argument("group", nargs
=1,
204 help=_("Group name."))
205 sub_groupinstall
.add_argument("action", action
="store_const", const
="groupinstall")
207 def parse_command_repolist(self
):
208 # Implement the "repolist" command
209 sub_repolist
= self
.sub_commands
.add_parser("repolist",
210 help=_("List all currently enabled repositories."))
211 sub_repolist
.add_argument("action", action
="store_const", const
="repolist")
213 def parse_command_clean(self
):
214 sub_clean
= self
.sub_commands
.add_parser("clean", help=_("Cleanup commands."))
216 sub_clean_commands
= sub_clean
.add_subparsers()
218 self
.parse_command_clean_all(sub_clean_commands
)
220 def parse_command_clean_all(self
, sub_commands
):
221 sub_create
= sub_commands
.add_parser("all",
222 help=_("Cleanup all temporary files."))
223 sub_create
.add_argument("action", action
="store_const", const
="clean_all")
225 def parse_command_check(self
):
226 # Implement the "check" command
227 sub_check
= self
.sub_commands
.add_parser("check",
228 help=_("Check the system for any errors."))
229 sub_check
.add_argument("action", action
="store_const", const
="check")
231 def parse_command_resolvdep(self
):
232 # Implement the "resolvdep" command.
233 sub_resolvdep
= self
.sub_commands
.add_parser("resolvdep",
234 help=_("Check the dependencies for a particular package."))
235 sub_resolvdep
.add_argument("package", nargs
="+",
236 help=_("Give name of at least one package to check."))
237 sub_resolvdep
.add_argument("action", action
="store_const", const
="resolvdep")
240 action
= self
.args
.action
242 if not self
.action2func
.has_key(action
):
246 func
= self
.action2func
[action
]
248 raise # XXX catch and return better error message
252 def handle_info(self
, long=False):
253 pkgs
= pakfire
.info(self
.args
.package
, **self
.pakfire_args
)
256 print pkg
.dump(long=long)
258 def handle_search(self
):
259 pkgs
= pakfire
.search(self
.args
.pattern
, **self
.pakfire_args
)
262 print pkg
.dump(short
=True)
264 def handle_update(self
):
265 pakfire
.update(self
.args
.package
, **self
.pakfire_args
)
267 def handle_check_update(self
):
268 pakfire
.update(self
.args
.package
, check
=True, **self
.pakfire_args
)
270 def handle_install(self
):
271 pakfire
.install(self
.args
.package
, **self
.pakfire_args
)
273 def handle_localinstall(self
):
274 pakfire
.localinstall(self
.args
.package
, **self
.pakfire_args
)
276 def handle_remove(self
):
277 pakfire
.remove(self
.args
.package
, **self
.pakfire_args
)
279 def handle_provides(self
):
280 pkgs
= pakfire
.provides(self
.args
.pattern
, **self
.pakfire_args
)
285 def handle_grouplist(self
):
286 pkgs
= pakfire
.grouplist(self
.args
.group
[0], **self
.pakfire_args
)
291 def handle_groupinstall(self
):
292 pakfire
.groupinstall(self
.args
.group
[0], **self
.pakfire_args
)
294 def handle_repolist(self
):
295 repos
= pakfire
.repo_list(**self
.pakfire_args
)
297 FORMAT
= " %-20s %8s %12s %12s "
299 title
= FORMAT
% (_("Repository"), _("Enabled"), _("Priority"), _("Packages"))
301 print "=" * len(title
) # spacing line
304 # Skip the installed repository.
305 if repo
.name
== "installed":
308 print FORMAT
% (repo
.name
, repo
.enabled
, repo
.priority
, len(repo
))
310 def handle_clean_all(self
):
311 print _("Cleaning up everything...")
313 pakfire
.clean_all(**self
.pakfire_args
)
315 def handle_check(self
):
316 pakfire
.check(**self
.pakfire_args
)
318 def handle_resolvdep(self
):
319 pakfire
.resolvdep(self
.args
.package
, **self
.pakfire_args
)
322 class CliBuilder(Cli
):
324 # Check if we are already running in a pakfire container. In that
325 # case, we cannot start another pakfire-builder.
326 if os
.environ
.get("container", None) == "pakfire-builder":
327 raise PakfireContainerError
, _("You cannot run pakfire-builder in a pakfire chroot.")
329 self
.parser
= argparse
.ArgumentParser(
330 description
= _("Pakfire builder command line interface."),
333 self
.parse_common_arguments()
336 self
.sub_commands
= self
.parser
.add_subparsers()
338 self
.parse_command_build()
339 self
.parse_command_dist()
340 self
.parse_command_info()
341 self
.parse_command_search()
342 self
.parse_command_shell()
343 self
.parse_command_update()
344 self
.parse_command_provides()
345 self
.parse_command_grouplist()
346 self
.parse_command_repolist()
347 self
.parse_command_clean()
348 self
.parse_command_resolvdep()
350 # Finally parse all arguments from the command line and save them.
351 self
.args
= self
.parser
.parse_args()
354 "build" : self
.handle_build
,
355 "dist" : self
.handle_dist
,
356 "update" : self
.handle_update
,
357 "info" : self
.handle_info
,
358 "search" : self
.handle_search
,
359 "shell" : self
.handle_shell
,
360 "provides" : self
.handle_provides
,
361 "grouplist" : self
.handle_grouplist
,
362 "repolist" : self
.handle_repolist
,
363 "clean_all" : self
.handle_clean_all
,
364 "resolvdep" : self
.handle_resolvdep
,
368 def pakfire_args(self
):
369 ret
= { "mode" : "builder" }
371 if hasattr(self
.args
, "disable_repo"):
372 ret
["disable_repos"] = self
.args
.disable_repo
374 if hasattr(self
.args
, "enable_repo"):
375 ret
["enable_repos"] = self
.args
.enable_repo
377 if hasattr(self
.args
, "offline"):
378 ret
["offline"] = self
.args
.offline
382 def parse_command_update(self
):
383 # Implement the "update" command.
384 sub_update
= self
.sub_commands
.add_parser("update",
385 help=_("Update the package indexes."))
386 sub_update
.add_argument("action", action
="store_const", const
="update")
388 def parse_command_build(self
):
389 # Implement the "build" command.
390 sub_build
= self
.sub_commands
.add_parser("build",
391 help=_("Build one or more packages."))
392 sub_build
.add_argument("package", nargs
=1,
393 help=_("Give name of at least one package to build."))
394 sub_build
.add_argument("action", action
="store_const", const
="build")
396 sub_build
.add_argument("-a", "--arch",
397 help=_("Build the package for the given architecture."))
398 sub_build
.add_argument("--resultdir", nargs
="?",
399 help=_("Path were the output files should be copied to."))
400 sub_build
.add_argument("-m", "--mode", nargs
="?", default
="development",
401 help=_("Mode to run in. Is either 'release' or 'development' (default)."))
403 def parse_command_shell(self
):
404 # Implement the "shell" command.
405 sub_shell
= self
.sub_commands
.add_parser("shell",
406 help=_("Go into a shell."))
407 sub_shell
.add_argument("package", nargs
="?",
408 help=_("Give name of a package."))
409 sub_shell
.add_argument("action", action
="store_const", const
="shell")
411 sub_shell
.add_argument("-a", "--arch",
412 help=_("Emulated architecture in the shell."))
413 sub_shell
.add_argument("-m", "--mode", nargs
="?", default
="development",
414 help=_("Mode to run in. Is either 'release' or 'development' (default)."))
416 def parse_command_dist(self
):
417 # Implement the "dist" command.
418 sub_dist
= self
.sub_commands
.add_parser("dist",
419 help=_("Generate a source package."))
420 sub_dist
.add_argument("package", nargs
="+",
421 help=_("Give name(s) of a package(s)."))
422 sub_dist
.add_argument("action", action
="store_const", const
="dist")
424 sub_dist
.add_argument("--resultdir", nargs
="?",
425 help=_("Path were the output files should be copied to."))
427 def handle_info(self
):
428 Cli
.handle_info(self
, long=True)
430 def handle_build(self
):
431 # Get the package descriptor from the command line options
432 pkg
= self
.args
.package
[0]
434 # Check, if we got a regular file
435 if os
.path
.exists(pkg
):
436 pkg
= os
.path
.abspath(pkg
)
439 raise FileNotFoundError
, pkg
441 # Create distribution configuration from command line.
443 "arch" : self
.args
.arch
,
446 pakfire
.build(pkg
, builder_mode
=self
.args
.mode
,
447 distro_config
=distro_config
, resultdirs
=[self
.args
.resultdir
,],
448 shell
=True, **self
.pakfire_args
)
450 def handle_shell(self
):
453 # Get the package descriptor from the command line options
454 if self
.args
.package
:
455 pkg
= self
.args
.package
457 # Check, if we got a regular file
458 if os
.path
.exists(pkg
):
459 pkg
= os
.path
.abspath(pkg
)
462 raise FileNotFoundError
, pkg
464 # Create distribution configuration from command line.
466 "arch" : self
.args
.arch
,
469 pakfire
.shell(pkg
, builder_mode
=self
.args
.mode
,
470 distro_config
=distro_config
, **self
.pakfire_args
)
472 def handle_dist(self
):
473 # Get the packages from the command line options
476 for pkg
in self
.args
.package
:
477 # Check, if we got a regular file
478 if os
.path
.exists(pkg
):
479 pkg
= os
.path
.abspath(pkg
)
483 raise FileNotFoundError
, pkg
485 pakfire
.dist(pkgs
, resultdirs
=[self
.args
.resultdir
,],
488 def handle_provides(self
):
489 pkgs
= pakfire
.provides(self
.args
.pattern
, **self
.pakfire_args
)
492 print pkg
.dump(long=True)
495 class CliServer(Cli
):
497 self
.parser
= argparse
.ArgumentParser(
498 description
= _("Pakfire server command line interface."),
501 self
.parse_common_arguments()
504 self
.sub_commands
= self
.parser
.add_subparsers()
506 self
.parse_command_build()
507 self
.parse_command_keepalive()
508 self
.parse_command_repoupdate()
509 self
.parse_command_repo()
511 # Finally parse all arguments from the command line and save them.
512 self
.args
= self
.parser
.parse_args()
514 self
.server
= server
.Server()
517 "build" : self
.handle_build
,
518 "keepalive" : self
.handle_keepalive
,
519 "repoupdate" : self
.handle_repoupdate
,
520 "repo_create": self
.handle_repo_create
,
524 def pakfire_args(self
):
525 ret
= { "mode" : "server" }
527 if hasattr(self
.args
, "offline"):
528 ret
["offline"] = self
.args
.offline
532 def parse_command_build(self
):
533 # Implement the "build" command.
534 sub_keepalive
= self
.sub_commands
.add_parser("build",
535 help=_("Request a build job from the server."))
536 sub_keepalive
.add_argument("action", action
="store_const", const
="build")
538 def parse_command_keepalive(self
):
539 # Implement the "keepalive" command.
540 sub_keepalive
= self
.sub_commands
.add_parser("keepalive",
541 help=_("Send a keepalive to the server."))
542 sub_keepalive
.add_argument("action", action
="store_const",
545 def parse_command_repoupdate(self
):
546 # Implement the "repoupdate" command.
547 sub_repoupdate
= self
.sub_commands
.add_parser("repoupdate",
548 help=_("Update all repositories."))
549 sub_repoupdate
.add_argument("action", action
="store_const",
552 def parse_command_repo(self
):
553 sub_repo
= self
.sub_commands
.add_parser("repo",
554 help=_("Repository management commands."))
556 sub_repo_commands
= sub_repo
.add_subparsers()
558 self
.parse_command_repo_create(sub_repo_commands
)
560 def parse_command_repo_create(self
, sub_commands
):
561 sub_create
= sub_commands
.add_parser("create",
562 help=_("Create a new repository index."))
563 sub_create
.add_argument("path", nargs
=1, help=_("Path to the packages."))
564 sub_create
.add_argument("inputs", nargs
="+", help=_("Path to input packages."))
565 sub_create
.add_argument("action", action
="store_const", const
="repo_create")
567 def handle_keepalive(self
):
568 self
.server
.update_info()
570 def handle_build(self
):
571 self
.server
.build_job()
573 def handle_repoupdate(self
):
574 self
.server
.update_repositories()
576 def handle_repo_create(self
):
577 path
= self
.args
.path
[0]
579 pakfire
.repo_create(path
, self
.args
.inputs
, **self
.pakfire_args
)
582 class CliBuilderIntern(Cli
):
584 self
.parser
= argparse
.ArgumentParser(
585 description
= _("Pakfire builder command line interface."),
588 self
.parse_common_arguments()
591 self
.sub_commands
= self
.parser
.add_subparsers()
593 self
.parse_command_build()
595 # Finally parse all arguments from the command line and save them.
596 self
.args
= self
.parser
.parse_args()
599 "build" : self
.handle_build
,
602 def parse_command_build(self
):
603 # Implement the "build" command.
604 sub_build
= self
.sub_commands
.add_parser("build",
605 help=_("Build one or more packages."))
606 sub_build
.add_argument("package", nargs
=1,
607 help=_("Give name of at least one package to build."))
608 sub_build
.add_argument("action", action
="store_const", const
="build")
610 sub_build
.add_argument("-a", "--arch",
611 help=_("Build the package for the given architecture."))
612 sub_build
.add_argument("--resultdir", nargs
="?",
613 help=_("Path were the output files should be copied to."))
614 sub_build
.add_argument("-m", "--mode", nargs
="?", default
="development",
615 help=_("Mode to run in. Is either 'release' or 'development' (default)."))
616 sub_build
.add_argument("--nodeps", action
="store_true",
617 help=_("Do not verify build dependencies."))
619 def handle_build(self
):
620 # Get the package descriptor from the command line options
621 pkg
= self
.args
.package
[0]
623 # Check, if we got a regular file
624 if os
.path
.exists(pkg
):
625 pkg
= os
.path
.abspath(pkg
)
627 raise FileNotFoundError
, pkg
629 # Create distribution configuration from command line.
631 "arch" : self
.args
.arch
,
634 pakfire
._build
(pkg
, builder_mode
=self
.args
.mode
,
635 distro_config
=distro_config
, resultdir
=self
.args
.resultdir
,
636 nodeps
=self
.args
.nodeps
, **self
.pakfire_args
)