]>
git.ipfire.org Git - people/ms/pakfire.git/blob - src/pakfire/base.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 ###############################################################################
27 from . import _pakfire
30 from . import packages
33 from .config
import Config
34 from .system
import system
36 from .constants
import *
39 class Pakfire(_pakfire
.Pakfire
):
40 __version__
= PAKFIRE_VERSION
42 def __init__(self
, path
=None, config
=None, arch
=None, distro
=None, offline
=False):
43 _pakfire
.Pakfire
.__init
__(self
, path
, arch
, offline
=offline
)
45 # Initialise logging system
46 self
.log
= self
._setup
_logger
()
48 # Default to system distribution
49 self
.distro
= distro
or system
.distro
52 self
.config
= config
or Config("general.conf")
54 def _setup_logger(self
):
55 log
= logging
.getLogger("pakfire")
58 # Always process all messages (include debug)
59 log
.setLevel(logging
.DEBUG
)
61 # Pass everything down to libpakfire
62 handler
= logger
.PakfireLogHandler(self
)
63 log
.addHandler(handler
)
69 Called to initialize this Pakfire instance when
70 the context is entered.
72 # Dump the configuration when we enter the context
75 # Refresh repositories
76 self
.refresh_repositories()
78 return PakfireContext(self
)
80 def __exit__(self
, type, value
, traceback
):
83 def refresh_repositories(self
, force
=False):
84 for repo
in self
.repos
:
85 repo
.refresh(force
=force
)
88 # Clean up repository caches
89 for repo
in self
.repos
:
93 class PakfireContext(object):
95 This context has functions that require
96 pakfire to be initialized.
98 That means that repository data has to be downloaded
99 and imported to be searchable, etc.
101 def __init__(self
, pakfire
):
102 self
.pakfire
= pakfire
107 Shortcut to access any configured
108 repositories for this Pakfire instance
110 return self
.pakfire
.repos
112 def check(self
, **kwargs
):
114 Try to fix any errors in the system.
116 # Detect any errors in the dependency tree.
117 # For that we create an empty request and solver and try to solve
119 request
= _pakfire
.Request(self
.pakfire
)
122 return request
.solve(**kwargs
)
124 def info(self
, args
):
127 with _pakfire
.Repo(self
.pakfire
, "tmp", clean
=True) as r
:
129 if os
.path
.exists(arg
) and not os
.path
.isdir(arg
):
130 archive
= _pakfire
.Archive(self
.pakfire
, arg
)
132 # Add the archive to the repository
133 pkg
= r
.add_archive(archive
)
137 pkgs
+= self
.pakfire
.whatprovides(arg
, name_only
=True)
141 def provides(self
, patterns
):
144 for pattern
in patterns
:
145 for pkg
in self
.pakfire
.whatprovides(pattern
):
153 def search(self
, pattern
):
154 return self
.pakfire
.search(pattern
)
156 def extract(self
, filenames
, target
=None):
157 if target
and target
== "/":
158 raise ValueError("Cannot extract to: %s" % target
)
163 for filename
in filenames
:
164 a
= _pakfire
.Archive(self
.pakfire
, filename
)
167 # Nothing to do when no archives where opened
172 for archive
in archives
:
173 archive
.extract(target
)
177 def install(self
, requires
, **kwargs
):
178 request
= _pakfire
.Request(self
.pakfire
)
180 # XXX handle files and URLs
184 # TODO should move into libpakfire
185 if req
.startswith("@"):
186 sel
= _pakfire
.Selector(self
.pakfire
)
187 sel
.set(_pakfire
.PAKFIRE_PKG_GROUP
, _pakfire
.PAKFIRE_EQ
, req
[1:])
191 # Handle everything else
192 relation
= _pakfire
.Relation(self
.pakfire
, req
)
193 request
.install(relation
)
195 return request
.solve(**kwargs
)
197 def reinstall(self
, pkgs
, strict
=False, logger
=None):
199 Reinstall one or more packages
201 raise NotImplementedError
203 def erase(self
, pkgs
, **kwargs
):
204 request
= _pakfire
.Request(self
.pakfire
)
207 relation
= _pakfire
.Relation(self
.pakfire
, pkg
)
208 request
.erase(relation
)
210 return request
.solve(**kwargs
)
212 def update(self
, reqs
=None, excludes
=None, **kwargs
):
213 request
= _pakfire
.Request(self
.pakfire
)
215 # Add all packages that should be updated to the request
216 for req
in reqs
or []:
217 relation
= _pakfire
.Relation(self
.pakfire
, req
)
218 request
.upgrade(relation
)
220 # Otherwise we will try to upgrade everything
222 request
.upgrade_all()
224 # Exclude packages that should not be updated
225 for exclude
in excludes
or []:
226 relation
= _pakfire
.Relation(self
.pakfire
, exclude
)
227 request
.lock(relation
)
229 return request
.solve(**kwargs
)
231 def downgrade(self
, pkgs
, logger
=None, **kwargs
):
235 logger
= logging
.getLogger("pakfire")
237 # Create a new request.
238 request
= self
.pakfire
.create_request()
243 for pkg
in self
.pakfire
.repos
.whatprovides(pattern
):
244 # Only consider installed packages.
245 if not pkg
.is_installed():
248 if best
and pkg
> best
:
254 logger
.warning(_("\"%s\" package does not seem to be installed.") % pattern
)
256 rel
= self
.pakfire
.create_relation("%s < %s" % (best
.name
, best
.friendly_version
))
260 solver
= self
.pakfire
.solve(request
, allow_downgrade
=True, **kwargs
)
261 assert solver
.status
is True
263 # Create the transaction.
264 t
= transaction
.Transaction
.from_solver(self
.pakfire
, solver
)
265 t
.dump(logger
=logger
)
268 logger
.info(_("Nothing to do"))
271 if not t
.cli_yesno():
277 class PakfireKey(Pakfire
):