Added support for --verbose
[zeroinstall/solver.git] / zeroinstall / injector / cli_solve.py
blob47e79259fd040d737842dcb4081a1087d2504d67
1 """
2 The B{0solve} command-line interface.
4 This code is here, rather than in B{0solve} itself, simply so that it gets byte-compiled at
5 install time.
6 """
8 from zeroinstall import _
9 import os, sys
10 import logging
11 from optparse import OptionParser
13 from zeroinstall import SafeException
14 from zeroinstall.support import tasks
15 from zeroinstall.injector import model, selections, config, requirements, iface_cache
16 from zeroinstall.injector.policy import Policy
17 from zeroinstall.injector.handler import BatchHandler
19 def main(command_args):
20 """Act as if 0solve was run with the given arguments.
21 @arg command_args: array of arguments (e.g. C{sys.argv[1:]})
22 @type command_args: [str]
23 """
24 parser = OptionParser(usage=_("usage: %prog [options] interface [args]"))
25 parser.add_option("", "--before", help=_("choose a version before this"), metavar='VERSION')
26 parser.add_option("", "--command", help=_("command to select"), metavar='COMMAND')
27 parser.add_option("", "--cpu", help=_("target CPU type"), metavar='CPU')
28 parser.add_option("", "--message", help=_("message to display when interacting with user"))
29 parser.add_option("", "--not-before", help=_("minimum version to choose"), metavar='VERSION')
30 parser.add_option("", "--os", help=_("target operation system type"), metavar='OS')
31 parser.add_option("-o", "--offline", help=_("try to avoid using the network"), action='store_true')
32 parser.add_option("-r", "--refresh", help=_("refresh all used interfaces"), action='store_true')
33 parser.add_option("-s", "--source", help=_("select source code"), action='store_true')
34 parser.add_option("", "--with-store", help=_("add an implementation cache"), action='append', metavar='DIR')
35 parser.add_option("-v", "--verbose", help=_("more verbose output"), action='count')
37 (options, args) = parser.parse_args(command_args)
39 if options.verbose:
40 logger = logging.getLogger()
41 if options.verbose == 1:
42 logger.setLevel(logging.INFO)
43 else:
44 logger.setLevel(logging.DEBUG)
45 import zeroinstall
46 logging.info(_("Running 0install %(version)s %(args)s; Python %(python_version)s"), {'version': zeroinstall.version, 'args': repr(command_args), 'python_version': sys.version})
48 if len(args) != 1:
49 logging.error("Incorrect number of aruments")
50 sys.exit(1)
52 if options.with_store:
53 from zeroinstall import zerostore
54 for x in options.with_store:
55 iface_cache.stores.stores.append(zerostore.Store(os.path.abspath(x)))
57 try:
58 iface_uri = model.canonical_iface_uri(args[0])
59 (sels, stale_feeds) = get_selections(config.load_config(handler = BatchHandler()), options, iface_uri)
60 show_xml(sels)
61 if stale_feeds:
62 sys.stdout.write('<!-- STALE_FEEDS -->\n')
64 except SafeException, ex:
65 logging.error(unicode(ex))
66 sys.exit(1)
68 def get_selections(config, options, iface_uri):
69 """Get selections for iface_uri, according to the options passed.
70 Will switch to GUI mode if necessary.
71 @param options: options from OptionParser
72 @param iface_uri: canonical URI of the interface
73 @return: the selected versions, or None if the user cancels
74 @rtype: L{selections.Selections} | None
75 """
76 if options.offline:
77 config.network_use = model.network_offline
79 iface_cache = config.iface_cache
81 # Try to load it as a feed. If it is a feed, it'll get cached. If not, it's a
82 # selections document and we return immediately.
83 maybe_selections = iface_cache.get_feed(iface_uri, selections_ok = True)
84 if isinstance(maybe_selections, selections.Selections):
85 return maybe_selections
87 r = requirements.Requirements(iface_uri)
88 r.parse_options(options)
89 policy = Policy(requirements = r, config = config)
91 downloaded = policy.solve_and_download_impls(refresh = options.refresh, select_only = True)
92 if downloaded:
93 tasks.wait_for_blocker(downloaded)
95 stale_feeds = [feed for feed in policy.solver.feeds_used if
96 not os.path.isabs(feed) and # Ignore local feeds (note: file might be missing too)
97 not feed.startswith('distribution:') and # Ignore (memory-only) PackageKit feeds
98 iface_cache.is_stale(iface_cache.get_feed(feed), config.freshness)]
100 return (selections.Selections(policy), stale_feeds)
102 def show_xml(sels):
103 doc = sels.toDOM()
104 doc.writexml(sys.stdout)
105 sys.stdout.write('\n')