2 from zeroinstall
.injector
import gpg
3 from optparse
import OptionParser
6 from logging
import info
, debug
11 parser
= OptionParser(usage
="usage: %prog [options] interface")
12 parser
.add_option("--add-version", help="add a new implementation", action
='store', metavar
='VERSION')
13 parser
.add_option("--archive-url", help="add archive at this URL", action
='store', metavar
='URL')
14 parser
.add_option("--archive-file", help="local copy of archive-url", action
='store', metavar
='FILE')
15 parser
.add_option("--archive-extract", help="subdirectory of archive to extract", action
='store', metavar
='DIR')
16 parser
.add_option("-e", "--edit", help="edit with $EDITOR", action
='store_true')
17 parser
.add_option("-g", "--gpgsign", help="add a GPG signature block", action
='store_true')
18 parser
.add_option("-k", "--key", help="key to use for signing")
19 parser
.add_option("-l", "--local", help="create feed from local interface")
20 parser
.add_option("--manifest-algorithm", help="select algorithm for manifests", action
='store', metavar
='ALG')
21 parser
.add_option("--set-interface-uri", help="set interface URI", action
='store', metavar
='URI')
22 parser
.add_option("--set-id", help="set implementation ID", action
='store', metavar
='DIGEST')
23 parser
.add_option("--set-main", help="set main executable", action
='store', metavar
='EXEC')
24 parser
.add_option("--set-arch", help="set architecture", action
='store', metavar
='ARCH')
25 parser
.add_option("--set-released", help="set release date", action
='store', metavar
='DATE')
26 parser
.add_option("--set-stability", help="set stability", action
='store', metavar
='STABILITY')
27 parser
.add_option("--set-version", help="set version number", action
='store', metavar
='VERSION')
28 parser
.add_option("-s", "--stable", help="mark testing version stable", action
='store_true')
29 parser
.add_option("-x", "--xmlsign", help="add an XML signature block", action
='store_true')
30 parser
.add_option("-u", "--unsign", help="remove any signature", action
='store_true')
31 parser
.add_option("-v", "--verbose", help="more verbose output", action
='count')
32 parser
.add_option("-V", "--version", help="display version information", action
='store_true')
34 (options
, args
) = parser
.parse_args()
39 print "0publish (zero-install) " + version
40 print "Copyright (C) 2005 Thomas Leonard"
41 print "This program comes with ABSOLUTELY NO WARRANTY,"
42 print "to the extent permitted by law."
43 print "You may redistribute copies of this program"
44 print "under the terms of the GNU General Public License."
45 print "For more information about these matters, see the file named COPYING."
50 logger
= logging
.getLogger()
51 if options
.verbose
== 1:
52 logger
.setLevel(logging
.INFO
)
54 logger
.setLevel(logging
.DEBUG
)
63 ans
= raw_input(q
+ " [Y/N] ").lower()
64 if ans
in ('y', 'yes'): return True
65 if ans
in ('n', 'no'): return False
67 # Load or create the starting data...
69 if os
.path
.exists(interface
):
70 contents
= file(interface
).read()
71 data
, sign_fn
, key
= signing
.check_signature(interface
)
74 if os
.path
.exists(options
.local
):
75 data
= create
.create_from_local(options
.local
)
76 sign_fn
= signing
.sign_unsigned
81 raise Exception("File '%s' does not exist." % options
.local
)
83 if confirm("Interface file '%s' does not exist. Create it?" % interface
):
84 from create
import create
85 data
= create(interface
)
86 sign_fn
= signing
.sign_unsigned
92 debug("Original data: %s", data
)
93 info("Original signing method: %s", sign_fn
.__name
__)
94 info("Original key: %s", key
)
101 # Validate the input...
103 validator
.check(data
)
105 except validator
.InvalidInterface
, ex
:
106 print "Invalid interface: " + str(ex
)
109 ans
= raw_input("Interface is invalid. (E)dit or (A)bort?").lower()
110 if ans
in ('e', 'edit'):
111 data
= edit
.edit(data
)
112 options
.edit
= False # Don't edit twice
114 if ans
in ('a', 'abort'): sys
.exit(1)
118 sign_fn
= signing
.sign_xml
120 sign_fn
= signing
.sign_unsigned
122 sign_fn
= signing
.sign_plain
124 print "Changing key from '%s' to '%s'" % (key
, options
.key
)
126 if options
.set_interface_uri
:
128 data
= release
.set_interface_uri(data
, options
.set_interface_uri
)
129 if options
.add_version
:
131 data
= release
.add_version(data
, options
.add_version
)
132 if options
.set_id
or options
.set_version
or options
.set_released
or \
133 options
.set_stability
or options
.set_arch
or options
.set_main
:
135 data
= release
.make_release(data
, options
.set_id
,
136 options
.set_version
, options
.set_released
, options
.set_stability
,
137 options
.set_main
, options
.set_arch
)
140 data
= stable
.mark_stable(data
)
141 if options
.archive_url
:
143 data
= archive
.add_archive(data
, options
.archive_url
, options
.archive_file
, options
.archive_extract
, options
.manifest_algorithm
)
144 elif options
.archive_file
or options
.archive_extract
:
145 raise Exception('Must use --archive-uri option')
148 data
= merge
.merge(data
, options
.local
)
150 data
= edit
.edit(data
)
153 # Validate the result...
155 validator
.check(data
)
157 except validator
.InvalidInterface
, ex
:
158 print "Invalid interface: " + str(ex
)
161 ans
= raw_input("Interface is invalid. (E)dit or (A)bort?").lower()
162 if ans
in ('e', 'edit'):
163 data
= edit
.edit(data
)
165 if ans
in ('a', 'abort'): sys
.exit(1)
168 if (old_data
== data
and sign_fn
== old_sign_fn
and key
== old_key
) and not force_save
:
169 print "Interface unchanged. Not writing."
173 if not data
.endswith('\n'): data
+= '\n'
174 sign_fn(interface
, data
, key
)
176 info("Wrote '%S'", interface
)
178 if sign_fn
!= signing
.sign_unsigned
:
179 # Read it back in to find out what key we signed it with
180 # and ensure that the key has been exported
181 contents
= file(interface
).read()
182 saved_data
, saved_sign_fn
, saved_key
= signing
.check_signature(interface
)
183 assert saved_data
== data
184 assert saved_sign_fn
== sign_fn
185 signing
.export_key(os
.path
.dirname(interface
), saved_key
)