Fixed support for setting --main with 0alias
[zeroinstall.git] / zeroinstall / alias.py
blob1a197580368bad51ade2f671cebb98f836ccefc3
1 """
2 Support code for 0alias scripts.
3 @since: 0.28
4 """
6 # Copyright (C) 2009, Thomas Leonard
7 # See the README file for details, or visit http://0install.net.
9 from zeroinstall import _
11 _old_template = '''#!/bin/sh
12 if [ "$*" = "--versions" ]; then
13 exec 0launch -gd '%s' "$@"
14 else
15 exec 0launch %s '%s' "$@"
17 '''
19 _template = '''#!/bin/sh
20 exec 0launch %s'%s' "$@"
21 '''
23 class NotAnAliasScript(Exception):
24 pass
26 class ScriptInfo:
27 """@since: 1.3"""
28 uri = None
29 main = None
30 command = None
32 # For backwards compatibility
33 def __iter__(self):
34 return iter([self.uri, self.main])
36 def parse_script(pathname):
37 """Extract the URI and main values from a 0alias script.
38 @param pathname: the script to be examined
39 @return: information about the alias script
40 @rtype: L{ScriptInfo}
41 @raise NotAnAliasScript: if we can't parse the script
42 """
43 stream = file(pathname)
44 template_header = _template[:_template.index("%s'")]
45 actual_header = stream.read(len(template_header))
46 stream.seek(0)
47 if template_header == actual_header:
48 # If it's a 0alias script, it should be quite short!
49 rest = stream.read()
50 line = rest.split('\n')[1]
51 else:
52 old_template_header = \
53 _old_template[:_old_template.index("-gd '")]
54 actual_header = stream.read(len(old_template_header))
55 if old_template_header != actual_header:
56 raise NotAnAliasScript(_("'%s' does not look like a script created by 0alias") % pathname)
57 rest = stream.read()
58 line = rest.split('\n')[2]
60 info = ScriptInfo()
61 split = line.rfind("' '")
62 if split != -1:
63 # We have a --main or --command
64 info.uri = line[split + 3:].split("'")[0]
65 start, value = line[:split].split("'", 1)
66 option = start.split('--', 1)[1].strip()
67 value = value.replace("'\\''", "'")
68 if option == 'main':
69 info.main = value
70 elif option == 'command':
71 info.command = value
72 else:
73 raise NotAnAliasScript("Unknown option '{option}' in alias script".format(option = option))
74 else:
75 info.uri = line.split("'",2)[1]
77 return info
79 def write_script(stream, interface_uri, main = None, command = None):
80 """Write a shell script to stream that will launch the given program.
81 @param stream: the stream to write to
82 @param interface_uri: the program to launch
83 @param main: the --main argument to pass to 0launch, if any
84 @param command: the --command argument to pass to 0launch, if any"""
85 assert "'" not in interface_uri
86 assert "\\" not in interface_uri
87 assert main is None or command is None, "Can't set --main and --command together"
89 if main is not None:
90 option = "--main '%s' " % main.replace("'", "'\\''")
91 elif command is not None:
92 option = "--command '%s' " % command.replace("'", "'\\''")
93 else:
94 option = ""
96 stream.write(_template % (option, interface_uri))