Also merge implementations from local file.
[0publish.git] / 0publish
blob575201be14aedb92cd9e365f061b853e7bd672fe
1 #!/usr/bin/env python
2 from zeroinstall.injector import gpg
3 from optparse import OptionParser
4 import os, sys
5 import signing
6 from logging import info, debug
7 import edit, validator
9 version = '0.1'
11 parser = OptionParser(usage="usage: %prog [options] interface")
12 parser.add_option("-k", "--key", help="key to use for signing")
13 parser.add_option("-e", "--edit", help="edit with $EDITOR", action='store_true')
14 parser.add_option("-l", "--local", help="create feed from local interface")
15 parser.add_option("-r", "--release", help="set versions and dates", action='store_true')
16 parser.add_option("-x", "--xmlsign", help="add an XML signature block", action='store_true')
17 parser.add_option("-v", "--verbose", help="more verbose output", action='count')
18 parser.add_option("-V", "--version", help="display version information", action='store_true')
20 (options, args) = parser.parse_args()
22 force_save = False
24 if options.version:
25 print "0publish (zero-install) " + version
26 print "Copyright (C) 2005 Thomas Leonard"
27 print "This program comes with ABSOLUTELY NO WARRANTY,"
28 print "to the extent permitted by law."
29 print "You may redistribute copies of this program"
30 print "under the terms of the GNU General Public License."
31 print "For more information about these matters, see the file named COPYING."
32 sys.exit(0)
34 if options.verbose:
35 import logging
36 logger = logging.getLogger()
37 if options.verbose == 1:
38 logger.setLevel(logging.INFO)
39 else:
40 logger.setLevel(logging.DEBUG)
42 if len(args) != 1:
43 parser.print_help()
44 sys.exit(1)
45 interface = args[0]
47 def confirm(q):
48 while True:
49 ans = raw_input(q + " [Y/N] ").lower()
50 if ans in ('y', 'yes'): return True
51 if ans in ('n', 'no'): return False
53 # Load or create the starting data...
55 if os.path.exists(interface):
56 contents = file(interface).read()
57 data, sign_fn, key = signing.check_signature(interface)
58 elif options.local:
59 import create
60 if os.path.exists(options.local):
61 data = create.create_from_local(options.local)
62 sign_fn = signing.sign_unsigned
63 key = None
64 force_save = True
65 else:
66 raise Exception("File '%s' does not exist." % options.local)
67 else:
68 if confirm("Interface file '%s' does not exist. Create it?" % interface):
69 from create import create
70 data = create(interface)
71 sign_fn = signing.sign_unsigned
72 key = None
73 options.edit = True
74 else:
75 sys.exit(1)
77 debug("Original data: %s", data)
78 info("Original signing method: %s", sign_fn.__name__)
79 info("Original key: %s", key)
81 old_data = data
82 old_sign_fn = sign_fn
83 old_key = key
85 while True:
86 # Validate the input...
87 try:
88 validator.check(data)
89 break
90 except validator.InvalidInterface, ex:
91 print "Invalid interface: " + str(ex)
93 while True:
94 ans = raw_input("Interface is invalid. (E)dit or (A)bort?").lower()
95 if ans in ('e', 'edit'):
96 data = edit.edit(data)
97 options.edit = False # Don't edit twice
98 break
99 if ans in ('a', 'abort'): sys.exit(1)
101 # Process it...
102 if options.xmlsign:
103 sign_fn = signing.sign_xml
104 if options.key:
105 print "Changing key from '%s' to '%s'" % (key, options.key)
106 key = options.key
107 if options.release:
108 import release
109 data = release.make_release(data)
110 if options.local:
111 import merge
112 data = merge.merge(data, options.local)
113 if options.edit:
114 data = edit.edit(data)
116 while True:
117 # Validate the result...
118 try:
119 validator.check(data)
120 break
121 except validator.InvalidInterface, ex:
122 print "Invalid interface: " + str(ex)
124 while True:
125 ans = raw_input("Interface is invalid. (E)dit or (A)bort?").lower()
126 if ans in ('e', 'edit'):
127 data = edit.edit(data)
128 break
129 if ans in ('a', 'abort'): sys.exit(1)
132 if (old_data == data and sign_fn == old_sign_fn and key == old_key) and not force_save:
133 print "Interface unchanged. Not writing."
134 sys.exit(1)
136 # Write it back out
137 if not data.endswith('\n'): data += '\n'
138 sign_fn(interface, data, key)
140 print "Wrote", interface