2 Support code for 0alias scripts.
6 # Copyright (C) 2009, Thomas Leonard
7 # See the README file for details, or visit http://0install.net.
9 from zeroinstall
import _
, SafeException
10 from zeroinstall
import support
12 _old_template
= '''#!/bin/sh
13 if [ "$*" = "--versions" ]; then
14 exec 0launch -gd '%s' "$@"
16 exec 0launch %s '%s' "$@"
20 _template
= '''#!/bin/sh
21 exec 0launch %s'%s' "$@"
24 class NotAnAliasScript(SafeException
):
33 # For backwards compatibility
35 return iter([self
.uri
, self
.main
])
37 def parse_script(pathname
):
38 """Extract the URI and main values from a 0alias script.
39 @param pathname: the script to be examined
40 @return: information about the alias script
42 @raise NotAnAliasScript: if we can't parse the script
44 with
open(pathname
, 'rt') as stream
:
46 template_header
= _template
[:_template
.index("%s'")]
47 actual_header
= stream
.read(len(template_header
))
49 if template_header
== actual_header
:
50 # If it's a 0alias script, it should be quite short!
52 line
= rest
.split('\n')[1]
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 raise NotAnAliasScript(_("'%s' does not look like a script created by 0alias") % pathname
)
60 line
= rest
.split('\n')[2]
61 except UnicodeDecodeError as ex
:
62 raise NotAnAliasScript(repr(ex
))
65 split
= line
.rfind("' '")
67 # We have a --main or --command
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("'\\''", "'")
74 elif option
== 'command':
77 raise NotAnAliasScript("Unknown option '{option}' in alias script".format(option
= option
))
79 info
.uri
= line
.split("'", 2)[1]
83 def write_script(stream
, interface_uri
, main
= None, command
= None):
84 """Write a shell script to stream that will launch the given program.
85 @param stream: the stream to write to
86 @param interface_uri: the program to launch
87 @param main: the --main argument to pass to 0launch, if any
88 @param command: the --command argument to pass to 0launch, if any"""
89 assert "'" not in interface_uri
90 assert "\\" not in interface_uri
91 assert main
is None or command
is None, "Can't set --main and --command together"
94 option
= "--main '%s' " % main
.replace("'", "'\\''")
95 elif command
is not None:
96 option
= "--command '%s' " % command
.replace("'", "'\\''")
100 stream
.write(support
.unicode(_template
) % (option
, interface_uri
))