2 The B{0launch} command-line interface.
4 This code is here, rather than in B{0launch} itself, simply so that it gets byte-compiled at
8 from zeroinstall
import _
10 from optparse
import OptionParser
13 from zeroinstall
import SafeException
, NeedDownload
14 from zeroinstall
.injector
import model
, autopolicy
, selections
15 from zeroinstall
.injector
.iface_cache
import iface_cache
16 from zeroinstall
.cmd
import UsageError
18 #def program_log(msg): os.access('MARK: 0launch: ' + msg, os.F_OK)
20 #__main__.__builtins__.program_log = program_log
21 #program_log('0launch ' + ' '.join((sys.argv[1:])))
23 def _manage_feeds(options
, args
):
24 from zeroinstall
.injector
import writer
25 from zeroinstall
.injector
.handler
import Handler
26 from zeroinstall
.injector
.policy
import Policy
28 def find_feed_import(iface
, feed_url
):
29 for f
in iface
.extra_feeds
:
34 handler
= Handler(dry_run
= options
.dry_run
)
35 if not args
: raise UsageError()
37 print _("Feed '%s':") % x
+ '\n'
38 x
= model
.canonical_iface_uri(x
)
39 policy
= Policy(x
, handler
)
41 policy
.network_use
= model
.network_offline
43 feed
= iface_cache
.get_feed(x
)
44 if policy
.network_use
!= model
.network_offline
and policy
.is_stale(feed
):
45 blocker
= policy
.fetcher
.download_and_import_feed(x
, iface_cache
.iface_cache
)
46 print _("Downloading feed; please wait...")
47 handler
.wait_for_blocker(blocker
)
50 interfaces
= policy
.get_feed_targets(x
)
51 for i
in range(len(interfaces
)):
52 if find_feed_import(interfaces
[i
], x
):
53 print _("%(index)d) Remove as feed for '%(uri)s'") % {'index': i
+ 1, 'uri': interfaces
[i
].uri
}
55 print _("%(index)d) Add as feed for '%(uri)s'") % {'index': i
+ 1, 'uri': interfaces
[i
].uri
}
59 i
= raw_input(_('Enter a number, or CTRL-C to cancel [1]: ')).strip()
60 except KeyboardInterrupt:
62 raise SafeException(_("Aborted at user request."))
70 if i
> 0 and i
<= len(interfaces
):
72 print _("Invalid number. Try again. (1 to %d)") % len(interfaces
)
73 iface
= interfaces
[i
- 1]
74 feed_import
= find_feed_import(iface
, x
)
76 iface
.extra_feeds
.remove(feed_import
)
78 iface
.extra_feeds
.append(model
.Feed(x
, arch
= None, user_override
= True))
79 writer
.save_interface(iface
)
80 print '\n' + _("Feed list for interface '%s' is now:") % iface
.get_name()
82 for f
in iface
.extra_feeds
:
87 def main(command_args
):
88 """Act as if 0launch was run with the given arguments.
89 @arg command_args: array of arguments (e.g. C{sys.argv[1:]})
90 @type command_args: [str]
92 # Ensure stdin, stdout and stderr FDs exist, to avoid confusion
97 fd
= os
.open('/dev/null', os
.O_RDONLY
)
102 parser
= OptionParser(usage
=_("usage: %prog [options] interface [args]\n"
103 " %prog --list [search-term]\n"
104 " %prog --import [signed-interface-files]\n"
105 " %prog --feed [interface]"))
106 parser
.add_option("", "--before", help=_("choose a version before this"), metavar
='VERSION')
107 parser
.add_option("", "--command", help=_("command to select"), metavar
='COMMAND')
108 parser
.add_option("-c", "--console", help=_("never use GUI"), action
='store_false', dest
='gui')
109 parser
.add_option("", "--cpu", help=_("target CPU type"), metavar
='CPU')
110 parser
.add_option("-d", "--download-only", help=_("fetch but don't run"), action
='store_true')
111 parser
.add_option("-D", "--dry-run", help=_("just print actions"), action
='store_true')
112 parser
.add_option("-f", "--feed", help=_("add or remove a feed"), action
='store_true')
113 parser
.add_option("", "--get-selections", help=_("write selected versions as XML"), action
='store_true', dest
='xml')
114 parser
.add_option("-g", "--gui", help=_("show graphical policy editor"), action
='store_true')
115 parser
.add_option("-i", "--import", help=_("import from files, not from the network"), action
='store_true')
116 parser
.add_option("-l", "--list", help=_("list all known interfaces"), action
='store_true')
117 parser
.add_option("-m", "--main", help=_("name of the file to execute"))
118 parser
.add_option("", "--message", help=_("message to display when interacting with user"))
119 parser
.add_option("", "--not-before", help=_("minimum version to choose"), metavar
='VERSION')
120 parser
.add_option("", "--os", help=_("target operation system type"), metavar
='OS')
121 parser
.add_option("-o", "--offline", help=_("try to avoid using the network"), action
='store_true')
122 parser
.add_option("-r", "--refresh", help=_("refresh all used interfaces"), action
='store_true')
123 parser
.add_option("", "--select-only", help=_("only download the feeds"), action
='store_true')
124 parser
.add_option("", "--set-selections", help=_("run versions specified in XML file"), metavar
='FILE')
125 parser
.add_option("", "--show", help=_("show where components are installed"), action
='store_true')
126 parser
.add_option("-s", "--source", help=_("select source code"), action
='store_true')
127 parser
.add_option("", "--systray", help=_("download in the background"), action
='store_true')
128 parser
.add_option("-v", "--verbose", help=_("more verbose output"), action
='count')
129 parser
.add_option("-V", "--version", help=_("display version information"), action
='store_true')
130 parser
.add_option("", "--with-store", help=_("add an implementation cache"), action
='append', metavar
='DIR')
131 parser
.add_option("-w", "--wrapper", help=_("execute program using a debugger, etc"), metavar
='COMMAND')
132 parser
.disable_interspersed_args()
134 (options
, args
) = parser
.parse_args(command_args
)
137 logger
= logging
.getLogger()
138 if options
.verbose
== 1:
139 logger
.setLevel(logging
.INFO
)
141 logger
.setLevel(logging
.DEBUG
)
143 logging
.info(_("Running 0launch %(version)s %(args)s; Python %(python_version)s"), {'version': zeroinstall
.version
, 'args': repr(args
), 'python_version': sys
.version
})
145 if options
.select_only
or options
.show
:
146 options
.download_only
= True
148 if options
.with_store
:
149 from zeroinstall
import zerostore
150 for x
in options
.with_store
:
151 iface_cache
.stores
.stores
.append(zerostore
.Store(os
.path
.abspath(x
)))
152 logging
.info(_("Stores search path is now %s"), iface_cache
.stores
.stores
)
154 if options
.set_selections
:
155 args
= [options
.set_selections
] + args
159 from zeroinstall
.cmd
import list
160 list.handle(options
, args
)
161 elif options
.version
:
163 print "0launch (zero-install) " + zeroinstall
.version
164 print "Copyright (C) 2010 Thomas Leonard"
165 print _("This program comes with ABSOLUTELY NO WARRANTY,"
166 "\nto the extent permitted by law."
167 "\nYou may redistribute copies of this program"
168 "\nunder the terms of the GNU Lesser General Public License."
169 "\nFor more information about these matters, see the file named COPYING.")
170 elif getattr(options
, 'import'):
171 # (import is a keyword)
172 cmd
= __import__('zeroinstall.cmd.import', globals(), locals(), ["import"], 0)
173 cmd
.handle(options
, args
)
175 _manage_feeds(options
, args
)
176 elif options
.select_only
:
177 from zeroinstall
.cmd
import select
180 select
.handle(options
, args
)
181 elif options
.download_only
or options
.xml
or options
.show
:
182 from zeroinstall
.cmd
import download
183 download
.handle(options
, args
)
187 from zeroinstall
import helpers
188 return helpers
.get_selections_gui(None, [])
192 from zeroinstall
.cmd
import run
193 run
.handle(options
, args
)
194 except NeedDownload
, ex
:
195 # This only happens for dry runs
200 except SafeException
, ex
:
201 if options
.verbose
: raise
203 print >>sys
.stderr
, unicode(ex
)
205 print >>sys
.stderr
, repr(ex
)