Adder driver module
[zeroinstall.git] / zeroinstall / injector / policy.py
blob6268ae9631bd36ceb66def73628a561c79c38e5a
1 """
2 This class brings together a L{solve.Solver} to choose a set of implmentations, a
3 L{fetch.Fetcher} to download additional components, and the user's configuration
4 settings.
5 """
7 # Copyright (C) 2009, Thomas Leonard
8 # See the README file for details, or visit http://0install.net.
10 from zeroinstall import _
11 import os
12 from logging import info, debug
14 from zeroinstall import SafeException
15 from zeroinstall.injector import arch, model, driver
16 from zeroinstall.injector.model import Interface, Implementation, network_levels, network_offline, network_full
17 from zeroinstall.injector.namespaces import config_site, config_prog
18 from zeroinstall.injector.config import load_config
19 from zeroinstall.support import tasks
21 class Policy(object):
22 """@deprecated: Use Driver instead."""
23 __slots__ = ['driver']
25 help_with_testing = property(lambda self: self.config.help_with_testing,
26 lambda self, value: setattr(self.config, 'help_with_testing', bool(value)))
28 network_use = property(lambda self: self.config.network_use,
29 lambda self, value: setattr(self.config, 'network_use', value))
31 freshness = property(lambda self: self.config.freshness,
32 lambda self, value: setattr(self.config, 'freshness', str(value)))
34 target_arch = property(lambda self: self.driver.target_arch,
35 lambda self, value: setattr(self.driver, 'target_arch', value))
37 implementation = property(lambda self: self.solver.selections)
39 ready = property(lambda self: self.solver.ready)
40 config = property(lambda self: self.driver.config)
41 requirements = property(lambda self: self.driver.requirements)
43 # (was used by 0test)
44 handler = property(lambda self: self.config.handler,
45 lambda self, value: setattr(self.config, 'handler', value))
48 def __init__(self, root = None, handler = None, src = None, command = -1, config = None, requirements = None):
49 """
50 @param requirements: Details about the program we want to run
51 @type requirements: L{requirements.Requirements}
52 @param config: The configuration settings to use, or None to load from disk.
53 @type config: L{config.Config}
54 Note: all other arguments are deprecated (since 0launch 0.52)
55 """
56 if requirements is None:
57 from zeroinstall.injector.requirements import Requirements
58 requirements = Requirements(root)
59 requirements.source = bool(src) # Root impl must be a "src" machine type
60 if command == -1:
61 if src:
62 command = 'compile'
63 else:
64 command = 'run'
65 requirements.command = command
66 else:
67 assert root == src == None
68 assert command == -1
70 if config is None:
71 config = load_config(handler)
72 else:
73 assert handler is None, "can't pass a handler and a config"
75 self.driver = driver.Driver(config = config, requirements = requirements)
77 @property
78 def fetcher(self):
79 return self.config.fetcher
81 @property
82 def watchers(self):
83 return self.driver.watchers
85 @property
86 def solver(self):
87 return self.driver.solver
89 def save_config(self):
90 self.config.save_globals()
92 def usable_feeds(self, iface):
93 """Generator for C{iface.feeds} that are valid for our architecture.
94 @rtype: generator
95 @see: L{arch}"""
96 if self.requirements.source and iface.uri == self.root:
97 # Note: when feeds are recursive, we'll need a better test for root here
98 machine_ranks = {'src': 1}
99 else:
100 machine_ranks = arch.machine_ranks
102 for f in self.config.iface_cache.get_feed_imports(iface):
103 if f.os in arch.os_ranks and f.machine in machine_ranks:
104 yield f
105 else:
106 debug(_("Skipping '%(feed)s'; unsupported architecture %(os)s-%(machine)s"),
107 {'feed': f, 'os': f.os, 'machine': f.machine})
109 def is_stale(self, feed):
110 """@deprecated: use IfaceCache.is_stale"""
111 return self.config.iface_cache.is_stale(feed, self.config.freshness)
113 def get_implementation_path(self, impl):
114 """Return the local path of impl.
115 @rtype: str
116 @raise zeroinstall.zerostore.NotStored: if it needs to be added to the cache first."""
117 assert isinstance(impl, Implementation)
118 return impl.local_path or self.config.stores.lookup_any(impl.digests)
120 def get_implementation(self, interface):
121 """Get the chosen implementation.
122 @type interface: Interface
123 @rtype: L{model.Implementation}
124 @raise SafeException: if interface has not been fetched or no implementation could be
125 chosen."""
126 assert isinstance(interface, Interface)
128 try:
129 return self.implementation[interface]
130 except KeyError:
131 raise SafeException(_("No usable implementation found for '%s'.") % interface.uri)
133 def get_cached(self, impl):
134 """Check whether an implementation is available locally.
135 @type impl: model.Implementation
136 @rtype: bool
138 return impl.is_available(self.config.stores)
140 def get_uncached_implementations(self):
141 return self.driver.get_uncached_implementations()
143 def refresh_all(self, force = True):
144 """Start downloading all feeds for all selected interfaces.
145 @param force: Whether to restart existing downloads."""
146 return self.solve_with_downloads(force = True)
148 def get_feed_targets(self, feed):
149 """@deprecated: use IfaceCache.get_feed_targets"""
150 return self.config.iface_cache.get_feed_targets(feed)
152 def solve_with_downloads(self, force = False, update_local = False):
153 return self.driver.solve_with_downloads(force, update_local)
155 def solve_and_download_impls(self, refresh = False, select_only = False):
156 return self.driver.solve_and_download_impls(refresh, select_only)
158 def need_download(self):
159 return self.driver.need_download()
161 def download_uncached_implementations(self):
162 return self.driver.download_uncached_implementations()
164 def download_icon(self, interface, force = False):
165 """Download an icon for this interface and add it to the
166 icon cache. If the interface has no icon or we are offline, do nothing.
167 @return: the task doing the import, or None
168 @rtype: L{tasks.Task}"""
169 if self.network_use == network_offline:
170 info("Not downloading icon for %s as we are off-line", interface)
171 return
173 return self.fetcher.download_icon(interface, force)
175 def get_interface(self, uri):
176 """@deprecated: use L{iface_cache.IfaceCache.get_interface} instead"""
177 import warnings
178 warnings.warn("Policy.get_interface is deprecated!", DeprecationWarning, stacklevel = 2)
179 return self.config.iface_cache.get_interface(uri)
181 @property
182 def command(self):
183 return self.requirements.command
185 @property
186 def root(self):
187 return self.requirements.interface_uri
189 _config = None
190 def get_deprecated_singleton_config():
191 global _config
192 if _config is None:
193 _config = load_config()
194 return _config