2 from zeroinstall
.injector
import gpg
3 from zeroinstall
import SafeException
4 from xml
.dom
import minidom
5 from optparse
import OptionParser
8 from logging
import info
, debug
9 import edit
, validator
, create
13 parser
= OptionParser(usage
="usage: %prog [options] interface")
14 parser
.add_option("--add-version", help="add a new implementation", action
='store', metavar
='VERSION')
15 parser
.add_option("--archive-url", help="add archive at this URL", action
='store', metavar
='URL')
16 parser
.add_option("--archive-file", help="local copy of archive-url", action
='store', metavar
='FILE')
17 parser
.add_option("--archive-extract", help="subdirectory of archive to extract", action
='store', metavar
='DIR')
18 parser
.add_option("-e", "--edit", help="edit with $EDITOR", action
='store_true')
19 parser
.add_option("-g", "--gpgsign", help="add a GPG signature block", action
='store_true')
20 parser
.add_option("-k", "--key", help="key to use for signing")
21 parser
.add_option("-l", "--local", help="create feed from local interface")
22 parser
.add_option("--manifest-algorithm", help="select algorithm for manifests", action
='store', metavar
='ALG')
23 parser
.add_option("--set-interface-uri", help="set interface URI", action
='store', metavar
='URI')
24 parser
.add_option("--set-id", help="set implementation ID", action
='store', metavar
='DIGEST')
25 parser
.add_option("--set-main", help="set main executable", action
='store', metavar
='EXEC')
26 parser
.add_option("--set-arch", help="set architecture", action
='store', metavar
='ARCH')
27 parser
.add_option("--set-released", help="set release date", action
='store', metavar
='DATE')
28 parser
.add_option("--set-stability", help="set stability", action
='store', metavar
='STABILITY')
29 parser
.add_option("--set-version", help="set version number", action
='store', metavar
='VERSION')
30 parser
.add_option("-s", "--stable", help="mark testing version stable", action
='store_true')
31 parser
.add_option("-x", "--xmlsign", help="add an XML signature block", action
='store_true')
32 parser
.add_option("-u", "--unsign", help="remove any signature", action
='store_true')
33 parser
.add_option("-v", "--verbose", help="more verbose output", action
='count')
34 parser
.add_option("-V", "--version", help="display version information", action
='store_true')
36 (options
, args
) = parser
.parse_args()
41 print "0publish (zero-install) " + version
42 print "Copyright (C) 2005 Thomas Leonard"
43 print "This program comes with ABSOLUTELY NO WARRANTY,"
44 print "to the extent permitted by law."
45 print "You may redistribute copies of this program"
46 print "under the terms of the GNU General Public License."
47 print "For more information about these matters, see the file named COPYING."
52 logger
= logging
.getLogger()
53 if options
.verbose
== 1:
54 logger
.setLevel(logging
.INFO
)
56 logger
.setLevel(logging
.DEBUG
)
65 ans
= raw_input(q
+ " [Y/N] ").lower()
66 if ans
in ('y', 'yes'): return True
67 if ans
in ('n', 'no'): return False
70 # Load or create the starting data...
72 if os
.path
.exists(interface
):
73 contents
= file(interface
).read()
74 data
, sign_fn
, key
= signing
.check_signature(interface
)
76 if os
.path
.exists(options
.local
):
77 data
= create
.create_from_local(options
.local
)
78 sign_fn
= signing
.sign_unsigned
83 raise Exception("File '%s' does not exist." % options
.local
)
85 if confirm("Interface file '%s' does not exist. Create it?" % interface
):
86 data
= create
.create(interface
)
87 sign_fn
= signing
.sign_unsigned
93 debug("Original data: %s", data
)
94 info("Original signing method: %s", sign_fn
.__name
__)
95 info("Original key: %s", key
)
102 # Validate the input...
104 validator
.check(data
)
106 except validator
.InvalidInterface
, ex
:
107 print "Invalid interface: " + str(ex
)
110 ans
= raw_input("Interface is invalid. (E)dit or (A)bort?").lower()
111 if ans
in ('e', 'edit'):
112 data
= edit
.edit(data
)
113 options
.edit
= False # Don't edit twice
115 if ans
in ('a', 'abort'): sys
.exit(1)
119 sign_fn
= signing
.sign_xml
121 sign_fn
= signing
.sign_unsigned
123 sign_fn
= signing
.sign_plain
125 print "Changing key from '%s' to '%s'" % (key
, options
.key
)
127 if options
.set_interface_uri
:
129 data
= release
.set_interface_uri(data
, options
.set_interface_uri
)
130 if options
.add_version
:
132 data
= release
.add_version(data
, options
.add_version
)
133 if options
.set_id
or options
.set_version
or options
.set_released
or \
134 options
.set_stability
or options
.set_arch
or options
.set_main
:
136 data
= release
.make_release(data
, options
.set_id
,
137 options
.set_version
, options
.set_released
, options
.set_stability
,
138 options
.set_main
, options
.set_arch
)
141 data
= stable
.mark_stable(data
)
142 if options
.archive_url
:
144 data
= archive
.add_archive(data
, options
.archive_url
, options
.archive_file
, options
.archive_extract
, options
.manifest_algorithm
)
145 elif options
.archive_file
or options
.archive_extract
:
146 raise Exception('Must use --archive-uri option')
149 data
= merge
.merge(data
, options
.local
)
151 data
= edit
.edit(data
)
154 # Validate the result...
156 validator
.check(data
)
158 except validator
.InvalidInterface
, ex
:
159 print "Invalid interface: " + str(ex
)
162 ans
= raw_input("Interface is invalid. (E)dit or (A)bort?").lower()
163 if ans
in ('e', 'edit'):
164 data
= edit
.edit(data
)
166 if ans
in ('a', 'abort'): sys
.exit(1)
169 doc
= minidom
.parseString(data
)
170 data
= create
.xml_header
+ doc
.documentElement
.toxml()
172 if (old_data
== data
and sign_fn
== old_sign_fn
and key
== old_key
) and not force_save
:
173 print "Interface unchanged. Not writing."
177 if not data
.endswith('\n'): data
+= '\n'
178 sign_fn(interface
, data
, key
)
180 info("Wrote '%S'", interface
)
182 if sign_fn
!= signing
.sign_unsigned
:
183 # Read it back in to find out what key we signed it with
184 # and ensure that the key has been exported
185 contents
= file(interface
).read()
186 saved_data
, saved_sign_fn
, saved_key
= signing
.check_signature(interface
)
187 assert saved_data
== data
188 assert saved_sign_fn
== sign_fn
189 signing
.export_key(os
.path
.dirname(interface
), saved_key
)
190 except SafeException
, ex
:
191 if options
.verbose
: raise
192 print >>sys
.stderr
, ex