Fixed setup.py to install locale files
[zeroinstall/zeroinstall-afb.git] / 0alias
blob851ddfd915ba48aeca28556f6686fbc9d08d4e8d
1 #!/usr/bin/env python
3 import locale
4 from logging import warn
5 try:
6 locale.setlocale(locale.LC_ALL, '')
7 except locale.Error:
8 warn('Error setting locale (eg. Invalid locale)')
10 import os, sys
12 ## PATH ##
14 from optparse import OptionParser
16 from zeroinstall.injector import reader, model
17 from zeroinstall import support, alias, helpers
18 from zeroinstall.support import basedir
20 def export(name, value):
21 """Try to guess the command to set an environment variable."""
22 shell = os.environ.get('SHELL', '?')
23 if 'csh' in shell:
24 return "setenv %s %s" % (name, value)
25 return "export %s=%s" % (name, value)
27 def find_path(paths):
28 """Find the first writable path in : separated list."""
29 for path in paths:
30 if os.path.realpath(path).startswith(basedir.xdg_cache_home):
31 pass # print "Skipping cache", first_path
32 elif not os.access(path, os.W_OK):
33 pass # print "No access", first_path
34 else:
35 break
36 else:
37 return None
39 return path
41 # Do this here so we can include it in the help message.
42 # But, don't abort if there isn't one because we might
43 # be doing something else (e.g. --manpage)
44 first_path = find_path(os.environ['PATH'].split(':'))
46 parser = OptionParser(usage="usage: %%prog [options] alias [interface [command]]\n\n"
47 "Creates a script in the first usable directory in $PATH\n"
48 "(%s) to run 'interface' unless overridden by --dir.\n"
49 "If no interface is given, edits the policy for an existing alias.\n"
50 "For interfaces providing more than one command, the desired command\n"
51 "may also be given." % first_path)
52 parser.add_option("-m", "--manpage", help="show the manual page for an existing alias", action='store_true')
53 parser.add_option("-r", "--resolve", help="show the URI for an alias", action='store_true')
54 parser.add_option("-V", "--version", help="display version information", action='store_true')
55 parser.add_option("-d", "--dir", help="install in DIR", dest="user_path", metavar="DIR")
56 parser.disable_interspersed_args()
58 (options, args) = parser.parse_args()
60 if options.version:
61 import zeroinstall
62 print "0alias (zero-install) " + zeroinstall.version
63 print "Copyright (C) 2009 Thomas Leonard"
64 print "This program comes with ABSOLUTELY NO WARRANTY,"
65 print "to the extent permitted by law."
66 print "You may redistribute copies of this program"
67 print "under the terms of the GNU Lesser General Public License."
68 print "For more information about these matters, see the file named COPYING."
69 sys.exit(0)
71 if options.manpage:
72 if len(args) != 1:
73 os.execlp('man', 'man', *args)
74 sys.exit(1)
76 if len(args) < 1 or len(args) > 3:
77 parser.print_help()
78 sys.exit(1)
79 alias_prog, interface_uri, main = (list(args) + [None, None])[:3]
81 if options.resolve or options.manpage:
82 if interface_uri is not None:
83 parser.print_help()
84 sys.exit(1)
86 if options.user_path:
87 first_path = options.user_path
88 if not os.path.isdir(first_path):
89 print >>sys.stderr, "Directory '%s' does not exist." % first_path
90 sys.exit(1)
92 if interface_uri is None:
93 try:
94 if not os.path.isabs(alias_prog):
95 full_path = support.find_in_path(alias_prog)
96 if not full_path:
97 raise alias.NotAnAliasScript("Not found in $PATH: " + alias_prog)
98 else:
99 full_path = alias_prog
101 interface_uri, main = alias.parse_script(full_path)
102 except alias.NotAnAliasScript, ex:
103 if options.manpage:
104 os.execlp('man', 'man', *args)
105 print >>sys.stderr, str(ex)
106 sys.exit(1)
108 interface_uri = model.canonical_iface_uri(interface_uri)
110 if options.resolve:
111 print interface_uri
112 sys.exit(0)
114 if options.manpage:
115 sels = helpers.ensure_cached(interface_uri)
116 if not sels:
117 # Cancelled by user
118 sys.exit(1)
120 selected_impl = sels.selections[interface_uri]
122 from zeroinstall.injector.iface_cache import iface_cache
123 impl_path = selected_impl.local_path or iface_cache.stores.lookup(selected_impl.id)
125 if main is None:
126 main = selected_impl.main
127 if main is None:
128 print >>sys.stderr, "No main program for interface '%s'" % interface_uri
129 sys.exit(1)
131 prog_name = os.path.basename(main)
132 alias_name = os.path.basename(args[0])
134 assert impl_path
136 # TODO: the feed should say where the man-pages are, but for now we'll accept
137 # a directory called man in some common locations...
138 for mandir in ['man', 'share/man', 'usr/man', 'usr/share/man']:
139 manpath = os.path.join(impl_path, mandir)
140 if os.path.isdir(manpath):
141 # Note: unlike "man -M", this also copes with LANG settings...
142 os.environ['MANPATH'] = manpath
143 os.execlp('man', 'man', prog_name)
144 sys.exit(1)
146 # No man directory given or found, so try searching for man files
148 manpages = []
149 for root, dirs, files in os.walk(impl_path):
150 for f in files:
151 if f.endswith('.gz'):
152 manpage_file = f[:-3]
153 else:
154 manpage_file = f
155 if manpage_file.endswith('.1') or \
156 manpage_file.endswith('.6') or \
157 manpage_file.endswith('.8'):
158 manpage_prog = manpage_file[:-2]
159 if manpage_prog == prog_name or manpage_prog == alias_name:
160 os.execlp('man', 'man', os.path.join(root, f))
161 sys.exit(1)
162 else:
163 manpages.append((root, f))
165 print "No matching manpage was found for '%s' (%s)" % (alias_name, interface_uri)
166 if manpages:
167 print "These non-matching man-pages were found, however:"
168 for root, file in manpages:
169 print os.path.join(root, file)
170 sys.exit(1)
172 if first_path is None:
173 print >>sys.stderr, ("No writable non-cache directory in $PATH, which currently contains:\n\n%s\n\n"
174 "To create a directory for your scripts, use these commands:\n"
175 "$ mkdir ~/bin\n"
176 "$ %s\n"
177 "or specify a writable path with --path"
178 % ('\n'.join(os.environ['PATH'].split(':')), export('PATH', '$HOME/bin:$PATH')))
179 sys.exit(1)
181 if len(args) == 1:
182 os.execlp('0launch', '0launch', '-gd', '--', interface_uri)
183 sys.exit(1)
185 try:
186 interface = model.Interface(interface_uri)
187 if not reader.update_from_cache(interface):
188 print >>sys.stderr, "Interface '%s' not currently in cache. Fetching..." % interface_uri
189 if os.spawnlp(os.P_WAIT, '0launch', '0launch', '-d', interface_uri):
190 raise model.SafeException("0launch failed")
191 if not reader.update_from_cache(interface):
192 raise model.SafeException("Interface still not in cache. Aborting.")
194 script = os.path.join(first_path, alias_prog)
195 if os.path.exists(script):
196 raise model.SafeException("File '%s' already exists. Delete it first." % script)
197 sys.exit(1)
198 except model.SafeException, ex:
199 print >>sys.stderr, ex
200 sys.exit(1)
202 wrapper = file(script, 'w')
203 alias.write_script(wrapper, interface_uri, main)
205 # Make new script executable
206 os.chmod(script, 0111 | os.fstat(wrapper.fileno()).st_mode)
207 wrapper.close()
209 print "Created script '%s'." % script
210 print "To edit policy: 0alias %s" % alias_prog
211 print "(note: some shells require you to type 'rehash' now)"