2 from zeroinstall
.injector
import model
, namespaces
3 from zeroinstall
.injector
.reader
import InvalidInterface
, update
4 from xml
.dom
import minidom
, Node
, XMLNS_NAMESPACE
6 from logging
import warn
, info
8 group_impl_attribs
= ['version', 'version-modifier', 'released', 'main', 'stability', 'arch', 'license', 'doc-dir', 'self-test', 'langs', 'local-path']
11 'interface' : ['uri', 'min-injector-version', 'main'], # (main is deprecated)
15 'needs-terminal' : [],
17 'category' : ['type'],
18 'icon' : ['type', 'href'],
19 'feed' : ['src', 'arch'],
20 'feed-for' : ['interface'],
22 'group' : group_impl_attribs
,
23 'implementation' : ['id'] + group_impl_attribs
,
24 'package-implementation' : ['package', 'main'],
25 'manifest-digest' : ['sha1new', 'sha256'],
26 'command' : ['name', 'path'],
29 'archive' : ['href', 'size', 'extract', 'type', 'start-offset'],
31 'requires' : ['interface', 'use'],
32 'runner' : ['interface', 'use'],
33 'version' : ['not-before', 'before'],
34 'environment' : ['name', 'insert', 'default', 'mode'],
35 'overlay' : ['src', 'mount-point'],
38 def checkElement(elem
):
39 if elem
.namespaceURI
!= namespaces
.XMLNS_IFACE
:
40 info("Note: Skipping unknown (but namespaced) element <%s>", elem
.localName
)
41 return # Namespaces elements are OK
43 if elem
.localName
not in known_elements
:
44 warn("Unknown Zero Install element <%s>.\nNon Zero-Install elements should be namespaced.", elem
.localName
)
47 known_attrs
= known_elements
[elem
.localName
]
49 for (uri
, name
), value
in elem
.attributes
.itemsNS():
50 if uri
== XMLNS_NAMESPACE
:
51 continue # Namespace declarations are fine
54 info("Note: Skipping unknown (but namespaced) attribute '%s'", name
)
57 if name
not in known_attrs
:
58 warn("Unknown Zero Install attribute '%s' on <%s>.\nNon Zero-Install attributes should be namespaced.",
61 for child
in elem
.childNodes
:
62 if child
.nodeType
== Node
.ELEMENT_NODE
:
65 def check(data
, warnings
= True):
66 fd
, tmp_name
= tempfile
.mkstemp(prefix
= '0publish-validate-')
68 tmp_iface
= model
.Interface(tmp_name
)
70 tmp_file
= file(tmp_name
, 'w')
74 update(tmp_iface
, tmp_name
, local
= True)
75 except InvalidInterface
, ex
:
78 warn("Internal error: %s", ex
)
79 raise InvalidInterface(str(ex
))
84 doc
= minidom
.parseString(data
)
85 checkElement(doc
.documentElement
)