summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam Thursfield <sam.thursfield@codethink.co.uk>2015-07-07 12:34:38 +0100
committerSam Thursfield <sam.thursfield@codethink.co.uk>2015-07-07 12:51:38 +0100
commit092d1eee88f7b1c0e083a0a4b9b5039d67e2ebfc (patch)
treea507d555d21c40c784f11b512cbc594228495f36
parent5cffbcd23a4455655396661c18a3686ceea49b35 (diff)
downloaddefinitions-092d1eee88f7b1c0e083a0a4b9b5039d67e2ebfc.tar.gz
schema: Improve handling of command lists, again
Now they are represented by rdf:Seq, which is the most practical way I think. Each list object has its own URI in a separate namespace, which is way more readable than having blank nodes with URIs like N101340613. Change-Id: I8d0f16ab43ba3d7144a4e76a01295c269156f92f
-rw-r--r--schema/parse.py89
1 files changed, 56 insertions, 33 deletions
diff --git a/schema/parse.py b/schema/parse.py
index b9c0fec8..ed520e73 100644
--- a/schema/parse.py
+++ b/schema/parse.py
@@ -92,6 +92,15 @@ class DefinitionsNamespace(rdflib.Namespace):
def cluster(self, cluster_name):
return self.term('clusters/' + cluster_name)
+ def command_sequence(self, chunk_uriref, sequence_name):
+ # We use '-' rather than '/' between chunk name and sequence name,
+ # mainly because the rdflib_web browser tool goes nuts if you have
+ # many resources with the same 'basename'. If we used '/' then there
+ # would be hundreds of URIs ending with '.../install-commands',
+ # '.../build-commands' etc.
+ chunk_name = os.path.basename(chunk_uriref)
+ return self.term('commands/' + chunk_name + '-' + sequence_name)
+
def stratum(self, stratum_name):
return self.term('strata/' + stratum_name)
@@ -119,21 +128,47 @@ def new_resource(graph, uriref, rdf_type):
return entity
-def ordered(graph, value_list, node=None):
+def ordered(graph, value_list, list_uriref=None):
'''Create an ordered RDF collection from a list of values.
+ This uses the rdf:Seq class to represent the ordered list. The rdf:Seq
+ class is apparently deprecated. However, the alternatives (rdf:List, or
+ the Ordered List Ontology) are more verbose.
+
+ Further reading:
+ - http://www.w3.org/2011/rdf-wg/track/issues/77
+ - http://purl.org/ontology/olo/core
+
To define an ordered list in RDF, you need an identifier for the list
itself. By default this function will create a 'blank node', which will end
up with a random unique URI when serialised. To make serialised data more
- readable you can create your own rdflib.URIRef term to identify the list.
+ readable you can pass in your own rdflib.URIRef term to identify the list.
'''
- node = node or rdflib.BNode()
- collection = rdflib.collection.Collection(
- graph, node, [rdflib.Literal(v) for v in value_list])
+ node = list_uriref or rdflib.BNode()
+ graph.add((node, RDF.type, RDF.Seq))
+ for i, value in enumerate(value_list):
+ index = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#_%i' % (i + 1)
+ graph.add((node, rdflib.URIRef(index), rdflib.Literal(value)))
return node
+def to_property(name):
+ '''Convert a normal property name to stupidCamelCase.'''
+ property_name = []
+ hyphen = False
+ for char in name:
+ if char == '-':
+ hyphen = True
+ else:
+ if hyphen:
+ property_name.append(char.upper())
+ else:
+ property_name.append(char)
+ hyphen = False
+ return ''.join(property_name)
+
+
def load_all_morphologies(path='.'):
'''Load Baserock Definitions serialisation format V5 as an RDFLib 'graph'.
@@ -144,7 +179,6 @@ def load_all_morphologies(path='.'):
toplevel_path = path
graph = rdflib.Graph()
-
def load_morph(toplevel_path, filename):
try:
contents = parse_morph_file(filename)
@@ -161,33 +195,22 @@ def load_all_morphologies(path='.'):
chunk_uriref = ns.chunk(contents['name'])
entity = chunk = new_resource(graph, chunk_uriref, BASEROCK.Chunk)
- if 'pre-configure-commands' in contents:
- chunk.set(BASEROCK.preConfigureCommands,
- ordered(graph, contents['pre-configure-commands']))
- if 'configure-commands' in contents:
- chunk.set(BASEROCK.configureCommands,
- ordered(graph, contents['configure-commands']))
- if 'post-configure-commands' in contents:
- chunk.set(BASEROCK.postConfigureCommands,
- ordered(graph, contents['post-configure-commands']))
- if 'pre-build-commands' in contents:
- chunk.set(BASEROCK.preBuildCommands,
- ordered(graph, contents['pre-build-commands']))
- if 'build-commands' in contents:
- chunk.set(BASEROCK.buildCommands,
- ordered(graph, contents['build-commands']))
- if 'post-build-commands' in contents:
- chunk.set(BASEROCK.postBuildCommands,
- ordered(graph, contents['post-build-commands']))
- if 'pre-install-commands' in contents:
- chunk.set(BASEROCK.preInstallCommands,
- ordered(graph, contents['pre-install-commands']))
- if 'install-commands' in contents:
- chunk.set(BASEROCK.installCommands,
- ordered(graph, contents['install-commands']))
- if 'post-install-commands' in contents:
- chunk.set(BASEROCK.postInstallCommands,
- ordered(graph, contents['post-install-commands']))
+ def set_command_sequence(resource, name):
+ if name in contents:
+ property = BASEROCK.term(to_property(name))
+ list_node = ns.command_sequence(resource.identifier, name)
+ resource.set(property,
+ ordered(graph, contents[name], list_node))
+
+ set_command_sequence(chunk, 'pre-configure-commands')
+ set_command_sequence(chunk, 'configure-commands')
+ set_command_sequence(chunk, 'post-configure-commands')
+ set_command_sequence(chunk, 'pre-build-commands')
+ set_command_sequence(chunk, 'build-commands')
+ set_command_sequence(chunk, 'post-build-commands')
+ set_command_sequence(chunk, 'pre-install-commands')
+ set_command_sequence(chunk, 'install-commands')
+ set_command_sequence(chunk, 'post-install-commands')
elif contents['kind'] == 'stratum':
stratum_uriref = ns.stratum(contents['name'])