1 """
2 Support code for 0alias scripts.
3 @since: 0.28
4 """
5
6
7
8
9 from zeroinstall import _, SafeException
10 from zeroinstall import support
11
12 _old_template = '''#!/bin/sh
13 if [ "$*" = "--versions" ]; then
14 exec 0launch -gd '%s' "$@"
15 else
16 exec 0launch %s '%s' "$@"
17 fi
18 '''
19
20 _template = '''#!/bin/sh
21 exec 0launch %s'%s' "$@"
22 '''
23
26
28 """@since: 1.3"""
29 uri = None
30 main = None
31 command = 'run'
32
33
35 return iter([self.uri, self.main])
36
38 """Parse a 0alias script, if possible.
39 This does the same as L{parse_script}, except with an existing stream.
40 The stream position at exit is undefined.
41 @type stream: file
42 @rtype: L{ScriptInfo}
43 @since: 1.12"""
44 try:
45 stream.seek(0)
46 template_header = _template[:_template.index("%s'")]
47 actual_header = stream.read(len(template_header))
48 stream.seek(0)
49 if template_header == actual_header:
50
51 rest = stream.read()
52 line = rest.split('\n')[1]
53 else:
54 old_template_header = \
55 _old_template[:_old_template.index("-gd '")]
56 actual_header = stream.read(len(old_template_header))
57 if old_template_header != actual_header:
58 return None
59 rest = stream.read()
60 line = rest.split('\n')[2]
61 except UnicodeDecodeError:
62 return None
63
64 info = ScriptInfo()
65 split = line.rfind("' '")
66 if split != -1:
67
68 info.uri = line[split + 3:].split("'")[0]
69 start, value = line[:split].split("'", 1)
70 option = start.split('--', 1)[1].strip()
71 value = value.replace("'\\''", "'")
72 if option == 'main':
73 info.main = value
74 elif option == 'command':
75 info.command = value or None
76 else:
77 return None
78 else:
79 info.uri = line.split("'", 2)[1]
80
81 return info
82
84 """Extract the URI and main values from a 0alias script.
85 @param pathname: the script to be examined
86 @type pathname: str
87 @return: information about the alias script
88 @rtype: L{ScriptInfo}
89 @raise NotAnAliasScript: if we can't parse the script"""
90 with open(pathname, 'rt') as stream:
91 info = parse_script_header(stream)
92 if info is None:
93 raise NotAnAliasScript(_("'%s' does not look like a script created by 0alias") % pathname)
94 return info
95
96 -def write_script(stream, interface_uri, main = None, command = None):
97 """Write a shell script to stream that will launch the given program.
98 @param stream: the stream to write to
99 @type stream: file
100 @param interface_uri: the program to launch
101 @type interface_uri: str
102 @param main: the --main argument to pass to 0launch, if any
103 @type main: str | None
104 @param command: the --command argument to pass to 0launch, if any
105 @type command: str | None"""
106 assert "'" not in interface_uri
107 assert "\\" not in interface_uri
108 assert main is None or command is None, "Can't set --main and --command together"
109
110 if main is not None:
111 option = "--main '%s' " % main.replace("'", "'\\''")
112 elif command is not None:
113 option = "--command '%s' " % command.replace("'", "'\\''")
114 else:
115 option = ""
116
117 stream.write(support.unicode(_template) % (option, interface_uri))
118